mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 19:02:29 +03:00
Cleaned old members stats endpoint (#12821)
no refs - Removes old `/members/stats` endpoint in favor of new `/members/stats/count` in canary/v4 which captures members counts using new events table - Removes tests for old `/members/stats` endpoint - Added test for new `/members/stats/count` endpoint
This commit is contained in:
parent
7e51b90792
commit
72e8894eac
@ -365,27 +365,6 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
|
||||
stats: {
|
||||
options: [
|
||||
'days'
|
||||
],
|
||||
permissions: {
|
||||
method: 'browse'
|
||||
},
|
||||
validation: {
|
||||
options: {
|
||||
days: {
|
||||
values: ['30', '90', '365', 'all-time']
|
||||
}
|
||||
}
|
||||
},
|
||||
async query(frame) {
|
||||
const days = frame.options.days === 'all-time' ? 'all-time' : Number(frame.options.days || 30);
|
||||
|
||||
return await membersService.stats.fetch(days);
|
||||
}
|
||||
},
|
||||
|
||||
memberStats: {
|
||||
permissions: {
|
||||
method: 'browse'
|
||||
|
@ -95,7 +95,6 @@ module.exports = function apiRoutes() {
|
||||
router.get('/members/stats/mrr', mw.authAdminApi, http(apiCanary.members.mrrStats));
|
||||
router.get('/members/stats/subscribers', mw.authAdminApi, http(apiCanary.members.subscriberStats));
|
||||
router.get('/members/stats/gross_volume', mw.authAdminApi, http(apiCanary.members.grossVolumeStats));
|
||||
router.get('/members/stats', mw.authAdminApi, http(apiCanary.members.stats));
|
||||
|
||||
router.get('/members/events', mw.authAdminApi, http(apiCanary.members.activityFeed));
|
||||
|
||||
|
@ -376,9 +376,9 @@ describe('Members API', function () {
|
||||
importedMember2.subscriptions.length.should.equal(0);
|
||||
});
|
||||
|
||||
async function fetchStats() {
|
||||
it('Can fetch member counts stats', async function () {
|
||||
const res = await request
|
||||
.get(localUtils.API.getApiQuery('members/stats/'))
|
||||
.get(localUtils.API.getApiQuery('members/stats/count/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
@ -386,85 +386,14 @@ describe('Members API', function () {
|
||||
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
const jsonResponse = res.body;
|
||||
|
||||
should.exist(jsonResponse);
|
||||
should.exist(jsonResponse.total);
|
||||
should.exist(jsonResponse.total_in_range);
|
||||
should.exist(jsonResponse.total_on_date);
|
||||
should.exist(jsonResponse.new_today);
|
||||
|
||||
// 5 from fixtures, 2 from above posts, 2 from above import
|
||||
jsonResponse.total.should.equal(9);
|
||||
|
||||
return jsonResponse;
|
||||
}
|
||||
|
||||
function parseTotalOnDate(jsonResponse) {
|
||||
// replicate default look back date of 30 days
|
||||
const days = 30;
|
||||
// grab the timezone as mocked above
|
||||
const siteTimezone = settingsCache.get('timezone');
|
||||
|
||||
// rebuild a valid response object such that works on any date-time...
|
||||
// get the start date
|
||||
let currentRangeDate = moment.tz(siteTimezone).subtract(days - 1, 'days');
|
||||
// get the end date but ignore today because we want to set that value ourselves
|
||||
let endDate = moment.tz(siteTimezone).subtract(1, 'hour');
|
||||
|
||||
const output = {};
|
||||
let dateStr;
|
||||
|
||||
// set user count to be 1 for all dates before today to match date as outlined
|
||||
// for the user in valid-members-import.csv who was imported with a start date of '91
|
||||
while (currentRangeDate.isBefore(endDate)) {
|
||||
dateStr = currentRangeDate.format('YYYY-MM-DD');
|
||||
output[dateStr] = 1;
|
||||
|
||||
currentRangeDate = currentRangeDate.add(1, 'day');
|
||||
}
|
||||
|
||||
// format the date for the end date (right now)
|
||||
dateStr = currentRangeDate.format('YYYY-MM-DD');
|
||||
|
||||
// set the end date to match the number of members added from fixtures posts and imports
|
||||
// 5 from fixtures, 2 from above posts, 2 from above import
|
||||
output[dateStr] = 9;
|
||||
|
||||
// deep equality check that the objects match...
|
||||
jsonResponse.total_on_date.should.eql(output);
|
||||
}
|
||||
|
||||
it('Can fetch stats', function () {
|
||||
return fetchStats();
|
||||
});
|
||||
|
||||
it('Can render stats in GMT -X timezones', async function () {
|
||||
// stub the method
|
||||
const stub = sinon.stub(settingsCache, 'get');
|
||||
|
||||
// this was just a GMT -X Timezone picked at random for the test below...
|
||||
stub
|
||||
.withArgs('timezone')
|
||||
.returns('America/Caracas');
|
||||
|
||||
const jsonResponse = await fetchStats();
|
||||
parseTotalOnDate(jsonResponse);
|
||||
// restore the stub so we can use it in other tests
|
||||
stub.restore();
|
||||
});
|
||||
|
||||
it('Can render stats in GMT +X timezones', async function () {
|
||||
// stub the method
|
||||
const stub = sinon.stub(settingsCache, 'get');
|
||||
|
||||
// the tester that wrote this lives in Adelaide so shoutout to this (random) timezone!
|
||||
stub
|
||||
.withArgs('timezone')
|
||||
.returns('Australia/Adelaide');
|
||||
|
||||
const jsonResponse = await fetchStats();
|
||||
parseTotalOnDate(jsonResponse);
|
||||
// restore the stub so we can use it in other tests
|
||||
stub.restore();
|
||||
should.exist(jsonResponse.resource);
|
||||
should.exist(jsonResponse.data);
|
||||
const data = jsonResponse.data;
|
||||
// 2 from above posts, 2 from above import
|
||||
data[0].free.should.equal(4);
|
||||
data[0].paid.should.equal(0);
|
||||
data[0].comped.should.equal(0);
|
||||
});
|
||||
});
|
||||
|
@ -562,78 +562,6 @@ describe('Members API', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('Can fetch stats with no ?days param', function () {
|
||||
return request
|
||||
.get(localUtils.API.getApiQuery('members/stats/'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
// .expect(200) - doesn't surface underlying errors in tests
|
||||
.then((res) => {
|
||||
res.status.should.equal(200, JSON.stringify(res.body));
|
||||
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
const jsonResponse = res.body;
|
||||
|
||||
should.exist(jsonResponse);
|
||||
should.exist(jsonResponse.total);
|
||||
should.exist(jsonResponse.total_in_range);
|
||||
should.exist(jsonResponse.total_on_date);
|
||||
should.exist(jsonResponse.new_today);
|
||||
|
||||
// 5 from fixtures and 6 imported in previous tests
|
||||
jsonResponse.total.should.equal(11);
|
||||
});
|
||||
});
|
||||
|
||||
it('Can fetch stats with ?days=90', function () {
|
||||
return request
|
||||
.get(localUtils.API.getApiQuery('members/stats/?days=90'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
// .expect(200) - doesn't surface underlying errors in tests
|
||||
.then((res) => {
|
||||
res.status.should.equal(200, JSON.stringify(res.body));
|
||||
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
const jsonResponse = res.body;
|
||||
|
||||
should.exist(jsonResponse);
|
||||
should.exist(jsonResponse.total);
|
||||
should.exist(jsonResponse.total_in_range);
|
||||
should.exist(jsonResponse.total_on_date);
|
||||
should.exist(jsonResponse.new_today);
|
||||
|
||||
// 5 from fixtures and 6 imported in previous tests
|
||||
jsonResponse.total.should.equal(11);
|
||||
});
|
||||
});
|
||||
|
||||
it('Can fetch stats with ?days=all-time', function () {
|
||||
return request
|
||||
.get(localUtils.API.getApiQuery('members/stats/?days=all-time'))
|
||||
.set('Origin', config.get('url'))
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Cache-Control', testUtils.cacheRules.private)
|
||||
// .expect(200) - doesn't surface underlying errors in tests
|
||||
.then((res) => {
|
||||
res.status.should.equal(200, JSON.stringify(res.body));
|
||||
|
||||
should.not.exist(res.headers['x-cache-invalidate']);
|
||||
const jsonResponse = res.body;
|
||||
|
||||
should.exist(jsonResponse);
|
||||
should.exist(jsonResponse.total);
|
||||
should.exist(jsonResponse.total_in_range);
|
||||
should.exist(jsonResponse.total_on_date);
|
||||
should.exist(jsonResponse.new_today);
|
||||
|
||||
// 5 from fixtures and 6 imported in previous tests
|
||||
jsonResponse.total.should.equal(11);
|
||||
});
|
||||
});
|
||||
|
||||
it('Errors when fetching stats with unknown days param value', function () {
|
||||
return request
|
||||
.get(localUtils.API.getApiQuery('members/stats/?days=nope'))
|
||||
|
Loading…
Reference in New Issue
Block a user