mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-29 13:52:10 +03:00
🐛 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:
parent
791bcc6adb
commit
eb8c0fcff9
@ -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'
|
||||
]);
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -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) => {
|
||||
|
@ -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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user