mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-10 23:36:14 -05:00
Added offer read endpoint to content API (#14794)
refs TryGhost/Team#1599 - allows offer details to be fetched via content API directly
This commit is contained in:
parent
3214186f98
commit
725c2673ea
7 changed files with 139 additions and 1 deletions
|
@ -219,5 +219,9 @@ module.exports = {
|
|||
|
||||
get newslettersPublic() {
|
||||
return shared.pipeline(require('./newsletters-public'), localUtils, 'content');
|
||||
},
|
||||
|
||||
get offersPublic() {
|
||||
return shared.pipeline(require('./offers-public'), localUtils, 'content');
|
||||
}
|
||||
};
|
||||
|
|
28
core/server/api/canary/offers-public.js
Normal file
28
core/server/api/canary/offers-public.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
const tpl = require('@tryghost/tpl');
|
||||
const errors = require('@tryghost/errors');
|
||||
const offersService = require('../../services/offers');
|
||||
|
||||
const messages = {
|
||||
offerNotFound: 'Offer not found.'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
docName: 'offers',
|
||||
|
||||
read: {
|
||||
data: ['id'],
|
||||
permissions: true,
|
||||
async query(frame) {
|
||||
const offer = await offersService.api.getOffer(frame.data);
|
||||
if (!offer) {
|
||||
throw new errors.NotFoundError({
|
||||
message: tpl(messages.offerNotFound)
|
||||
});
|
||||
}
|
||||
|
||||
frame.response = {
|
||||
offers: [offer]
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
|
@ -1,8 +1,16 @@
|
|||
const debug = require('@tryghost/debug')('api:canary:utils:serializers:output:offers');
|
||||
const utils = require('../../index');
|
||||
|
||||
module.exports = {
|
||||
all() {
|
||||
all(_models, _apiConfig, frame) {
|
||||
debug('all');
|
||||
// Offers has frame.response already set
|
||||
|
||||
// Cleanup response for content API
|
||||
// TODO: remove and set explicit allowlist when moved to mapper
|
||||
if (utils.isContentAPI(frame) && frame.response?.offers?.[0]) {
|
||||
delete frame.response.offers[0].redemption_count;
|
||||
delete frame.response.offers[0].code;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -36,5 +36,7 @@ module.exports = function apiRoutes() {
|
|||
router.get('/tiers', mw.authenticatePublic, http(api.tiersPublic.browse));
|
||||
router.get('/newsletters', mw.authenticatePublic, http(api.newslettersPublic.browse));
|
||||
|
||||
router.get('/offers/:id', mw.authenticatePublic, http(api.offersPublic.read));
|
||||
|
||||
return router;
|
||||
};
|
||||
|
|
38
test/e2e-api/content/__snapshots__/offers.test.js.snap
Normal file
38
test/e2e-api/content/__snapshots__/offers.test.js.snap
Normal file
|
@ -0,0 +1,38 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Offers Content API Can read offer details from id 1: [body] 1`] = `
|
||||
Object {
|
||||
"offers": Array [
|
||||
Object {
|
||||
"amount": 12,
|
||||
"cadence": "year",
|
||||
"currency": null,
|
||||
"currency_restriction": false,
|
||||
"display_description": "",
|
||||
"display_title": "",
|
||||
"duration": "once",
|
||||
"duration_in_months": null,
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"name": "Black Friday",
|
||||
"status": "active",
|
||||
"tier": Object {
|
||||
"id": StringMatching /\\[a-f0-9\\]\\{24\\}/,
|
||||
"name": "Default Product",
|
||||
},
|
||||
"type": "percent",
|
||||
},
|
||||
],
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`Offers Content API Can read offer details from id 2: [headers] 1`] = `
|
||||
Object {
|
||||
"access-control-allow-origin": "*",
|
||||
"cache-control": "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0",
|
||||
"content-length": "331",
|
||||
"content-type": "application/json; charset=utf-8",
|
||||
"etag": StringMatching /\\(\\?:W\\\\/\\)\\?"\\(\\?:\\[ !#-\\\\x7E\\\\x80-\\\\xFF\\]\\*\\|\\\\r\\\\n\\[\\\\t \\]\\|\\\\\\\\\\.\\)\\*"/,
|
||||
"vary": "Accept-Encoding",
|
||||
"x-powered-by": "Express",
|
||||
}
|
||||
`;
|
38
test/e2e-api/content/offers.test.js
Normal file
38
test/e2e-api/content/offers.test.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
const {agentProvider, fixtureManager, matchers} = require('../../utils/e2e-framework');
|
||||
const testUtils = require('../../utils');
|
||||
const models = require('../../../core/server/models');
|
||||
|
||||
const offerSnapshot = {
|
||||
id: matchers.anyObjectId,
|
||||
tier: {
|
||||
id: matchers.anyObjectId
|
||||
}
|
||||
};
|
||||
|
||||
describe('Offers Content API', function () {
|
||||
let agent;
|
||||
|
||||
before(async function () {
|
||||
agent = await agentProvider.getContentAPIAgent();
|
||||
await fixtureManager.init('api_keys', 'members');
|
||||
agent.authenticate();
|
||||
});
|
||||
|
||||
it('Can read offer details from id', async function () {
|
||||
const productModel = await models.Product.findOne({type: 'paid'}, testUtils.context.internal);
|
||||
|
||||
const offerData = testUtils.DataGenerator.forKnex.createOffer({
|
||||
product_id: productModel.get('id')
|
||||
});
|
||||
const offerModel = await models.Offer.add(offerData, {context: {internal: true}});
|
||||
|
||||
await agent.get(`/offers/${offerModel.get('id')}`)
|
||||
.expectStatus(200)
|
||||
.matchHeaderSnapshot({
|
||||
etag: matchers.anyEtag
|
||||
})
|
||||
.matchBodySnapshot({
|
||||
offers: Array(1).fill(offerSnapshot)
|
||||
});
|
||||
});
|
||||
});
|
|
@ -994,6 +994,25 @@ DataGenerator.forKnex = (function () {
|
|||
});
|
||||
}
|
||||
|
||||
function createOffer(overrides) {
|
||||
const newObj = _.cloneDeep(overrides);
|
||||
return _.defaults(newObj, {
|
||||
id: ObjectId().toHexString(),
|
||||
name: 'Black Friday',
|
||||
code: 'black-friday',
|
||||
display_title: 'Black Friday Sale!',
|
||||
display_description: '10% off on yearly plan',
|
||||
discount_type: 'percent',
|
||||
interval: 'year',
|
||||
discount_amount: 12,
|
||||
duration: 'once',
|
||||
duration_in_months: null,
|
||||
currency_restriction: false,
|
||||
currency: null,
|
||||
active: true
|
||||
});
|
||||
}
|
||||
|
||||
function createMember(overrides) {
|
||||
const newObj = _.cloneDeep(overrides);
|
||||
|
||||
|
@ -1554,6 +1573,7 @@ DataGenerator.forKnex = (function () {
|
|||
createCustomThemeSetting: createBasic,
|
||||
createProduct,
|
||||
createNewsletter,
|
||||
createOffer,
|
||||
|
||||
invites,
|
||||
posts,
|
||||
|
|
Loading…
Add table
Reference in a new issue