diff --git a/core/server/api/v2/utils/serializers/input/authors.js b/core/server/api/v2/utils/serializers/input/authors.js new file mode 100644 index 0000000000..46dd2e16dd --- /dev/null +++ b/core/server/api/v2/utils/serializers/input/authors.js @@ -0,0 +1,26 @@ +const debug = require('ghost-ignition').debug('api:v2:utils:serializers:input:authors'); +const utils = require('../../index'); + +function setDefaultOrder(frame) { + if (!frame.options.order) { + frame.options.order = 'name asc'; + } +} + +module.exports = { + browse(apiConfig, frame) { + debug('browse'); + + if (utils.isContentAPI(frame)) { + setDefaultOrder(frame); + } + }, + + read(apiConfig, frame) { + debug('read'); + + if (utils.isContentAPI(frame)) { + setDefaultOrder(frame); + } + } +}; diff --git a/core/server/api/v2/utils/serializers/input/pages.js b/core/server/api/v2/utils/serializers/input/pages.js index bfaf5b94e9..10c35e9590 100644 --- a/core/server/api/v2/utils/serializers/input/pages.js +++ b/core/server/api/v2/utils/serializers/input/pages.js @@ -1,3 +1,4 @@ +const _ = require('lodash'); const debug = require('ghost-ignition').debug('api:v2:utils:serializers:input:pages'); function removeMobiledocFormat(frame) { @@ -8,6 +9,19 @@ function removeMobiledocFormat(frame) { } } +function setDefaultOrder(frame) { + let includesOrderedRelations = false; + + if (frame.options.withRelated) { + const orderedRelations = ['author', 'authors', 'tag', 'tags']; + includesOrderedRelations = _.intersection(orderedRelations, frame.options.withRelated).length > 0; + } + + if (!frame.options.order && !includesOrderedRelations) { + frame.options.order = 'title asc'; + } +} + module.exports = { browse(apiConfig, frame) { debug('browse'); @@ -28,6 +42,8 @@ module.exports = { removeMobiledocFormat(frame); + setDefaultOrder(frame); + debug(frame.options); }, @@ -37,6 +53,8 @@ module.exports = { frame.data.page = true; removeMobiledocFormat(frame); + setDefaultOrder(frame); + debug(frame.options); } }; diff --git a/core/server/api/v2/utils/serializers/input/posts.js b/core/server/api/v2/utils/serializers/input/posts.js index f18e0a016b..10109db399 100644 --- a/core/server/api/v2/utils/serializers/input/posts.js +++ b/core/server/api/v2/utils/serializers/input/posts.js @@ -20,6 +20,19 @@ function includeTags(frame) { } } +function setDefaultOrder(frame) { + let includesOrderedRelations = false; + + if (frame.options.withRelated) { + const orderedRelations = ['author', 'authors', 'tag', 'tags']; + includesOrderedRelations = _.intersection(orderedRelations, frame.options.withRelated).length > 0; + } + + if (!frame.options.order && !includesOrderedRelations) { + frame.options.order = 'published_at desc'; + } +} + module.exports = { browse(apiConfig, frame) { debug('browse'); @@ -53,6 +66,8 @@ module.exports = { if (labs.isSet('members')) { includeTags(frame); } + + setDefaultOrder(frame); } debug(frame.options); @@ -76,6 +91,8 @@ module.exports = { // CASE: Members needs to have the tags to check if its allowed access includeTags(frame); } + + setDefaultOrder(frame); } debug(frame.options); diff --git a/core/server/api/v2/utils/serializers/input/tags.js b/core/server/api/v2/utils/serializers/input/tags.js index 97bf0a34ed..21ce4f0e80 100644 --- a/core/server/api/v2/utils/serializers/input/tags.js +++ b/core/server/api/v2/utils/serializers/input/tags.js @@ -1,7 +1,28 @@ const debug = require('ghost-ignition').debug('api:v2:utils:serializers:input:tags'); const url = require('./utils/url'); +const utils = require('../../index'); + +function setDefaultOrder(frame) { + if (!frame.options.order) { + frame.options.order = 'name asc'; + } +} module.exports = { + browse(apiConfig, frame) { + debug('browse'); + + if (utils.isContentAPI(frame)) { + setDefaultOrder(frame); + } + }, + + read() { + debug('read'); + + this.browse(...arguments); + }, + add(apiConfig, frame) { debug('add'); frame.data.tags[0] = url.forTag(Object.assign({}, frame.data.tags[0])); diff --git a/core/test/functional/api/v2/content/authors_spec.js b/core/test/functional/api/v2/content/authors_spec.js index e2992ce966..b81086b30c 100644 --- a/core/test/functional/api/v2/content/authors_spec.js +++ b/core/test/functional/api/v2/content/authors_spec.js @@ -50,6 +50,10 @@ describe('Authors Content API V2', function () { // We don't expose the email address, status and other attrs. localUtils.API.checkResponse(jsonResponse.authors[0], 'author', ['url'], null, null); + // Default order 'name asc' check + jsonResponse.authors[0].name.should.eql('Ghost'); + jsonResponse.authors[2].name.should.eql('Slimer McEctoplasm'); + should.exist(res.body.authors[0].url); should.exist(url.parse(res.body.authors[0].url).protocol); should.exist(url.parse(res.body.authors[0].url).host); diff --git a/core/test/functional/api/v2/content/posts_spec.js b/core/test/functional/api/v2/content/posts_spec.js index 44aa449da4..b1ce881432 100644 --- a/core/test/functional/api/v2/content/posts_spec.js +++ b/core/test/functional/api/v2/content/posts_spec.js @@ -52,7 +52,7 @@ describe('Posts', function () { localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination'); _.isBoolean(jsonResponse.posts[0].featured).should.eql(true); - // Default order check + // Default order 'published_at desc' check jsonResponse.posts[0].slug.should.eql('welcome'); jsonResponse.posts[6].slug.should.eql('themes'); diff --git a/core/test/functional/api/v2/content/tags_spec.js b/core/test/functional/api/v2/content/tags_spec.js index 292c92f1d5..f678eb52a2 100644 --- a/core/test/functional/api/v2/content/tags_spec.js +++ b/core/test/functional/api/v2/content/tags_spec.js @@ -46,6 +46,17 @@ describe('Tags Content API V2', function () { localUtils.API.checkResponse(jsonResponse.tags[0], 'tag', ['url']); localUtils.API.checkResponse(jsonResponse.meta.pagination, 'pagination'); + // Default order 'name asc' check + // the ordering difference is described in https://github.com/TryGhost/Ghost/issues/6104 + // this condition should be removed once issue mentioned above ^ is resolved + if (process.env.NODE_ENV === 'testing-mysql') { + jsonResponse.tags[0].name.should.eql('bacon'); + jsonResponse.tags[3].name.should.eql('kitchen sink'); + } else { + jsonResponse.tags[0].name.should.eql('Getting Started'); + jsonResponse.tags[3].name.should.eql('kitchen sink'); + } + should.exist(res.body.tags[0].url); should.exist(url.parse(res.body.tags[0].url).protocol); should.exist(url.parse(res.body.tags[0].url).host);