🐛 Fixed Tags API v2 to return posts count

closes #12167

- Tags API v2 was ignoring `count.posts` include parameter.
- Regression was introduced with a3f693b472
- Introduced regression tests across all Content API versions to avoid similar bug in the future
This commit is contained in:
Nazar Gargol 2020-08-31 18:46:35 +12:00
parent 791bcc6adb
commit eb8c0fcff9
5 changed files with 131 additions and 6 deletions

View File

@ -12,7 +12,8 @@ const tag = (attrs, frame) => {
'name',
'slug',
'url',
'visibility'
'visibility',
'count'
]);
// We are standardising on returning null from the Content API for any empty values
@ -25,6 +26,8 @@ const tag = (attrs, frame) => {
if (contentAttrs.description === '') {
contentAttrs.description = null;
}
return contentAttrs;
}
return _.pick(attrs, [
@ -38,7 +41,8 @@ const tag = (attrs, frame) => {
'slug',
'updated_at',
'url',
'visibility'
'visibility',
'count'
]);
};

View File

@ -25,7 +25,7 @@ describe('api/canary/content/tags', function () {
configUtils.restore();
});
it('can read tags with fields', function () {
it('Can read tags with fields', function () {
return request
.get(localUtils.API.getApiQuery(`tags/${testUtils.DataGenerator.Content.tags[0].id}/?key=${validKey}&fields=name,slug`))
.set('Origin', testUtils.API.getURL())
@ -37,7 +37,38 @@ describe('api/canary/content/tags', function () {
});
});
it('browse tags with slug filter, should order in slug order', function () {
it('Can request all tags with count.posts field and custom order', function () {
return request
.get(localUtils.API.getApiQuery(`tags/?key=${validKey}&include=count.posts&order=name%20DESC`))
.set('Origin', testUtils.API.getURL())
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.tags);
jsonResponse.tags.should.have.length(4);
localUtils.API.checkResponse(jsonResponse.tags[0], 'tag', ['count', 'url']);
jsonResponse.meta.pagination.should.have.property('page', 1);
jsonResponse.meta.pagination.should.have.property('limit', 15);
jsonResponse.meta.pagination.should.have.property('pages', 4);
jsonResponse.meta.pagination.should.have.property('total', 56);
jsonResponse.meta.pagination.should.have.property('next', 2);
jsonResponse.meta.pagination.should.have.property('prev', null);
jsonResponse.tags[0].url.should.eql(`${config.get('url')}/tag/kitchen-sink/`);
jsonResponse.tags[1].url.should.eql(`${config.get('url')}/tag/getting-started/`);
should.exist(jsonResponse.tags[0].count.posts);
jsonResponse.tags[0].count.posts.should.equal(2);
});
});
it('Browse tags with slug filter, should order in slug order', function () {
return request.get(localUtils.API.getApiQuery(`tags/?key=${validKey}&filter=slug:[kitchen-sink,bacon,chorizo]`))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)

View File

@ -25,7 +25,7 @@ describe('api/v2/content/tags', function () {
const validKey = localUtils.getValidKey();
it('can read tags with fields', function () {
it('Can read tags with fields', function () {
return request
.get(localUtils.API.getApiQuery(`tags/${testUtils.DataGenerator.Content.tags[0].id}/?key=${validKey}&fields=name,slug`))
.set('Origin', testUtils.API.getURL())
@ -36,4 +36,35 @@ describe('api/v2/content/tags', function () {
localUtils.API.checkResponse(res.body.tags[0], 'tag', null, null, ['id', 'name', 'slug']);
});
});
it('Can request all tags with count.posts field and custom order', function () {
return request
.get(localUtils.API.getApiQuery(`tags/?key=${validKey}&include=count.posts&order=name%20DESC`))
.set('Origin', testUtils.API.getURL())
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.tags);
jsonResponse.tags.should.have.length(4);
localUtils.API.checkResponse(jsonResponse.tags[0], 'tag', ['count', 'url']);
jsonResponse.meta.pagination.should.have.property('page', 1);
jsonResponse.meta.pagination.should.have.property('limit', 15);
jsonResponse.meta.pagination.should.have.property('pages', 4);
jsonResponse.meta.pagination.should.have.property('total', 56);
jsonResponse.meta.pagination.should.have.property('next', 2);
jsonResponse.meta.pagination.should.have.property('prev', null);
jsonResponse.tags[0].url.should.eql(`${config.get('url')}/tag/kitchen-sink/`);
jsonResponse.tags[1].url.should.eql(`${config.get('url')}/tag/getting-started/`);
should.exist(jsonResponse.tags[0].count.posts);
jsonResponse.tags[0].count.posts.should.equal(2);
});
});
});

View File

@ -59,6 +59,19 @@ const expectedProperties = {
.without('parent_id', 'parent')
// v2 Tag API doesn't return date fields
.without('created_at', 'updated_at')
// v2 Tag API doesn't return extended meta fields
.without(
'og_image',
'og_title',
'og_description',
'twitter_image',
'twitter_title',
'twitter_description',
'codeinjection_head',
'codeinjection_foot',
'canonical_url',
'accent_color'
)
};
_.each(expectedProperties, (value, key) => {

View File

@ -25,7 +25,7 @@ describe('api/v3/content/tags', function () {
const validKey = localUtils.getValidKey();
it('can read tags with fields', function () {
it('Can read tags with fields', function () {
return request
.get(localUtils.API.getApiQuery(`tags/${testUtils.DataGenerator.Content.tags[0].id}/?key=${validKey}&fields=name,slug`))
.set('Origin', testUtils.API.getURL())
@ -36,4 +36,50 @@ describe('api/v3/content/tags', function () {
localUtils.API.checkResponse(res.body.tags[0], 'tag', null, null, ['id', 'name', 'slug']);
});
});
it('Can request all tags with count.posts field and custom order', function () {
return request
.get(localUtils.API.getApiQuery(`tags/?key=${validKey}&include=count.posts&order=name%20DESC`))
.set('Origin', testUtils.API.getURL())
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.tags);
jsonResponse.tags.should.have.length(4);
localUtils.API.checkResponse(jsonResponse.tags[0], 'tag', ['count', 'url']);
jsonResponse.meta.pagination.should.have.property('page', 1);
jsonResponse.meta.pagination.should.have.property('limit', 15);
jsonResponse.meta.pagination.should.have.property('pages', 4);
jsonResponse.meta.pagination.should.have.property('total', 56);
jsonResponse.meta.pagination.should.have.property('next', 2);
jsonResponse.meta.pagination.should.have.property('prev', null);
jsonResponse.tags[0].url.should.eql(`${config.get('url')}/tag/kitchen-sink/`);
jsonResponse.tags[1].url.should.eql(`${config.get('url')}/tag/getting-started/`);
should.exist(jsonResponse.tags[0].count.posts);
jsonResponse.tags[0].count.posts.should.equal(2);
});
});
it('Browse tags with slug filter, should order in slug order', function () {
return request.get(localUtils.API.getApiQuery(`tags/?key=${validKey}&filter=slug:[kitchen-sink,bacon,chorizo]`))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(200)
.then((res) => {
const jsonResponse = res.body;
jsonResponse.tags.should.be.an.Array().with.lengthOf(3);
jsonResponse.tags[0].slug.should.equal('kitchen-sink');
jsonResponse.tags[1].slug.should.equal('bacon');
jsonResponse.tags[2].slug.should.equal('chorizo');
});
});
});