From 4217e2571fd5d99b94c52036370314b1bb39bd6f Mon Sep 17 00:00:00 2001 From: Fabien 'egg' O'Carroll Date: Tue, 24 May 2022 16:38:25 +0100 Subject: [PATCH] Included monthly_price,yearly_price&benefits defaults for Content API (#14912) We have to update the output serializer to only clean includes for the Admin API, so that these includes aren't stripped for not being in the original include query param. This also rejigs the other Content API only logic to sit together in the input serializer. --- .../canary/utils/serializers/input/tiers.js | 25 ++++++++++----- .../canary/utils/serializers/output/tiers.js | 31 ++++++++++--------- test/e2e-api/content/tiers.test.js | 2 +- 3 files changed, 34 insertions(+), 24 deletions(-) diff --git a/core/server/api/canary/utils/serializers/input/tiers.js b/core/server/api/canary/utils/serializers/input/tiers.js index 603ff770cb..2572829ff1 100644 --- a/core/server/api/canary/utils/serializers/input/tiers.js +++ b/core/server/api/canary/utils/serializers/input/tiers.js @@ -45,10 +45,26 @@ function convertTierInput(input) { module.exports = { all(_apiConfig, frame) { + if (localUtils.isContentAPI(frame)) { + // CASE: content api can only have active tiers + forceActiveFilter(frame); + + // CASE: content api includes these by default + const defaultRelations = ['monthly_price', 'yearly_price', 'benefits']; + if (!frame.options.withRelated) { + frame.options.withRelated = defaultRelations; + } else { + for (const relation of defaultRelations) { + if (!frame.options.withRelated.includes(relation)) { + frame.options.withRelated.push(relation); + } + } + } + } + if (!frame.options.withRelated) { return; } - frame.options.withRelated = frame.options.withRelated.map((relation) => { if (relation === 'stripe_prices') { return 'stripePrices'; @@ -63,13 +79,6 @@ module.exports = { }); }, - browse(_apiConfig, frame) { - if (localUtils.isContentAPI(frame)) { - // CASE: content api can only has active tiers - forceActiveFilter(frame); - } - }, - add(_apiConfig, frame) { if (frame.data.products) { frame.data = convertTierInput(frame.data.products[0]); diff --git a/core/server/api/canary/utils/serializers/output/tiers.js b/core/server/api/canary/utils/serializers/output/tiers.js index 2bd3220ab1..87116d5176 100644 --- a/core/server/api/canary/utils/serializers/output/tiers.js +++ b/core/server/api/canary/utils/serializers/output/tiers.js @@ -2,6 +2,7 @@ const debug = require('@tryghost/debug')('api:canary:utils:serializers:output:tiers'); const allowedIncludes = ['monthly_price', 'yearly_price']; +const localUtils = require('../../index'); const utils = require('../../../../shared/utils'); module.exports = { @@ -21,15 +22,9 @@ module.exports = { * @returns {{tiers: SerializedTier[], meta: PageMeta}} */ function paginatedTiers(page, _apiConfig, frame) { - const requestedQueryIncludes = frame.original && frame.original.query && frame.original.query.include && frame.original.query.include.split(',') || []; - const requestedOptionsIncludes = utils.options.trimAndLowerCase(frame.original && frame.original.options && frame.original.options.include || []); return { tiers: page.data.map((model) => { - return cleanIncludes( - allowedIncludes, - requestedQueryIncludes.concat(requestedOptionsIncludes), - serializeTier(model, frame.options, frame.apiType) - ); + return serializeTier(model, frame.options, frame); }), meta: page.meta }; @@ -43,15 +38,9 @@ function paginatedTiers(page, _apiConfig, frame) { * @returns {{tiers: SerializedTier[]}} */ function singleTier(model, _apiConfig, frame) { - const requestedQueryIncludes = frame.original && frame.original.query && frame.original.query.include && frame.original.query.include.split(',') || []; - const requestedOptionsIncludes = frame.original && frame.original.options && frame.original.options.include || []; return { tiers: [ - cleanIncludes( - allowedIncludes, - requestedQueryIncludes.concat(requestedOptionsIncludes), - serializeTier(model, frame.options, frame.apiType) - ) + serializeTier(model, frame.options, frame) ] }; } @@ -59,10 +48,11 @@ function singleTier(model, _apiConfig, frame) { /** * @param {import('bookshelf').Model} tier * @param {object} options + * @param {object} frame * * @returns {SerializedTier} */ -function serializeTier(tier, options) { +function serializeTier(tier, options, frame) { const json = tier.toJSON(options); const serialized = { @@ -91,6 +81,17 @@ function serializeTier(tier, options) { serialized.yearly_price = json.yearlyPrice?.amount; } + if (!localUtils.isContentAPI(frame)) { + const requestedQueryIncludes = frame.original && frame.original.query && frame.original.query.include && frame.original.query.include.split(',') || []; + const requestedOptionsIncludes = utils.options.trimAndLowerCase(frame.original && frame.original.options && frame.original.options.include || []); + + return cleanIncludes( + allowedIncludes, + requestedQueryIncludes.concat(requestedOptionsIncludes), + serialized + ); + } + return serialized; } diff --git a/test/e2e-api/content/tiers.test.js b/test/e2e-api/content/tiers.test.js index 3972079794..1d31ae1dce 100644 --- a/test/e2e-api/content/tiers.test.js +++ b/test/e2e-api/content/tiers.test.js @@ -10,7 +10,7 @@ describe('Tiers Content API', function () { }); it('Can request only active tiers', async function () { - await agent.get('/tiers/?include=monthly_price,yearly_price,benefits') + await agent.get('/tiers/?include=monthly_price') .expectStatus(200) .matchHeaderSnapshot({ etag: matchers.anyEtag