diff --git a/core/server/api/v2/utils/serializers/output/utils/mapper.js b/core/server/api/v2/utils/serializers/output/utils/mapper.js index af4cbefcf8..3bee089d6b 100644 --- a/core/server/api/v2/utils/serializers/output/utils/mapper.js +++ b/core/server/api/v2/utils/serializers/output/utils/mapper.js @@ -18,7 +18,7 @@ const mapUser = (model, frame) => { const mapTag = (model, frame) => { const jsonModel = model.toJSON ? model.toJSON(frame.options) : model; - url.forTag(model.id, jsonModel); + url.forTag(model.id, jsonModel, frame.options); clean.tag(jsonModel, frame); return jsonModel; diff --git a/core/server/api/v2/utils/serializers/output/utils/url.js b/core/server/api/v2/utils/serializers/output/utils/url.js index 3ce4ba60e3..b92df78ae2 100644 --- a/core/server/api/v2/utils/serializers/output/utils/url.js +++ b/core/server/api/v2/utils/serializers/output/utils/url.js @@ -54,8 +54,10 @@ const forUser = (id, attrs) => { return attrs; }; -const forTag = (id, attrs) => { - attrs.url = urlService.getUrlByResourceId(id, {absolute: true}); +const forTag = (id, attrs, options) => { + if (!options.columns || (options.columns && options.columns.includes('url'))) { + attrs.url = urlService.getUrlByResourceId(id, {absolute: true}); + } if (attrs.feature_image) { attrs.feature_image = urlService.utils.urlFor('image', {image: attrs.feature_image}, true); diff --git a/core/server/models/tag.js b/core/server/models/tag.js index 702f6ff277..d554bd38ca 100644 --- a/core/server/models/tag.js +++ b/core/server/models/tag.js @@ -81,7 +81,7 @@ Tag = ghostBookshelf.Model.extend({ // these are the only options that can be passed to Bookshelf / Knex. validOptions = { findAll: ['columns'], - findOne: ['visibility'], + findOne: ['columns', 'visibility'], destroy: ['destroyAll'] }; diff --git a/core/test/regression/api/v2/content/tags_spec.js b/core/test/regression/api/v2/content/tags_spec.js new file mode 100644 index 0000000000..96a1c87ca7 --- /dev/null +++ b/core/test/regression/api/v2/content/tags_spec.js @@ -0,0 +1,39 @@ +const should = require('should'); +const supertest = require('supertest'); +const localUtils = require('./utils'); +const testUtils = require('../../../../utils'); +const configUtils = require('../../../../utils/configUtils'); +const config = require('../../../../../server/config'); + +const ghost = testUtils.startGhost; +let request; + +describe('Tags', function () { + before(function () { + return ghost() + .then(function () { + request = supertest.agent(config.get('url')); + }) + .then(function () { + return testUtils.initFixtures('users:no-owner', 'user:inactive', 'posts', 'tags:extra', 'api_keys'); + }); + }); + + afterEach(function () { + configUtils.restore(); + }); + + const validKey = localUtils.getValidKey(); + + 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()) + .expect('Content-Type', /json/) + .expect('Cache-Control', testUtils.cacheRules.private) + .expect(200) + .then((res)=> { + localUtils.API.checkResponse(res.body.tags[0], 'tag', null, null, ['id', 'name', 'slug']); + }); + }); +}); diff --git a/core/test/unit/api/v2/utils/serializers/output/utils/mapper_spec.js b/core/test/unit/api/v2/utils/serializers/output/utils/mapper_spec.js index 0bf36cf502..09c2d88f1a 100644 --- a/core/test/unit/api/v2/utils/serializers/output/utils/mapper_spec.js +++ b/core/test/unit/api/v2/utils/serializers/output/utils/mapper_spec.js @@ -74,7 +74,7 @@ describe('Unit: v2/utils/serializers/output/utils/mapper', () => { urlUtil.forTag.callCount.should.equal(1); urlUtil.forUser.callCount.should.equal(1); - urlUtil.forTag.getCall(0).args.should.eql(['id3', {id: 'id3', feature_image: 'value'}]); + urlUtil.forTag.getCall(0).args.should.eql(['id3', {id: 'id3', feature_image: 'value'}, frame.options]); urlUtil.forUser.getCall(0).args.should.eql(['id4', {name: 'Ghosty', id: 'id4'}]); }); }); @@ -131,7 +131,7 @@ describe('Unit: v2/utils/serializers/output/utils/mapper', () => { mapper.mapTag(tag, frame); urlUtil.forTag.callCount.should.equal(1); - urlUtil.forTag.getCall(0).args.should.eql(['id3', tag]); + urlUtil.forTag.getCall(0).args.should.eql(['id3', tag, frame.options]); }); });