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.
This commit is contained in:
Fabien 'egg' O'Carroll 2022-05-24 16:38:25 +01:00 committed by GitHub
parent c052652559
commit 4217e2571f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 24 deletions

View File

@ -45,10 +45,26 @@ function convertTierInput(input) {
module.exports = { module.exports = {
all(_apiConfig, frame) { 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) { if (!frame.options.withRelated) {
return; return;
} }
frame.options.withRelated = frame.options.withRelated.map((relation) => { frame.options.withRelated = frame.options.withRelated.map((relation) => {
if (relation === 'stripe_prices') { if (relation === 'stripe_prices') {
return 'stripePrices'; 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) { add(_apiConfig, frame) {
if (frame.data.products) { if (frame.data.products) {
frame.data = convertTierInput(frame.data.products[0]); frame.data = convertTierInput(frame.data.products[0]);

View File

@ -2,6 +2,7 @@
const debug = require('@tryghost/debug')('api:canary:utils:serializers:output:tiers'); const debug = require('@tryghost/debug')('api:canary:utils:serializers:output:tiers');
const allowedIncludes = ['monthly_price', 'yearly_price']; const allowedIncludes = ['monthly_price', 'yearly_price'];
const localUtils = require('../../index');
const utils = require('../../../../shared/utils'); const utils = require('../../../../shared/utils');
module.exports = { module.exports = {
@ -21,15 +22,9 @@ module.exports = {
* @returns {{tiers: SerializedTier[], meta: PageMeta}} * @returns {{tiers: SerializedTier[], meta: PageMeta}}
*/ */
function paginatedTiers(page, _apiConfig, frame) { 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 { return {
tiers: page.data.map((model) => { tiers: page.data.map((model) => {
return cleanIncludes( return serializeTier(model, frame.options, frame);
allowedIncludes,
requestedQueryIncludes.concat(requestedOptionsIncludes),
serializeTier(model, frame.options, frame.apiType)
);
}), }),
meta: page.meta meta: page.meta
}; };
@ -43,15 +38,9 @@ function paginatedTiers(page, _apiConfig, frame) {
* @returns {{tiers: SerializedTier[]}} * @returns {{tiers: SerializedTier[]}}
*/ */
function singleTier(model, _apiConfig, frame) { 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 { return {
tiers: [ tiers: [
cleanIncludes( serializeTier(model, frame.options, frame)
allowedIncludes,
requestedQueryIncludes.concat(requestedOptionsIncludes),
serializeTier(model, frame.options, frame.apiType)
)
] ]
}; };
} }
@ -59,10 +48,11 @@ function singleTier(model, _apiConfig, frame) {
/** /**
* @param {import('bookshelf').Model} tier * @param {import('bookshelf').Model} tier
* @param {object} options * @param {object} options
* @param {object} frame
* *
* @returns {SerializedTier} * @returns {SerializedTier}
*/ */
function serializeTier(tier, options) { function serializeTier(tier, options, frame) {
const json = tier.toJSON(options); const json = tier.toJSON(options);
const serialized = { const serialized = {
@ -91,6 +81,17 @@ function serializeTier(tier, options) {
serialized.yearly_price = json.yearlyPrice?.amount; 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; return serialized;
} }

View File

@ -10,7 +10,7 @@ describe('Tiers Content API', function () {
}); });
it('Can request only active tiers', async 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) .expectStatus(200)
.matchHeaderSnapshot({ .matchHeaderSnapshot({
etag: matchers.anyEtag etag: matchers.anyEtag