Ghost/ghost/core/test/e2e-api/admin/tiers.test.js
Chris Raible 70304d92d4
🐛 Fixed bug preventing changes to tier benefit capitalization (#18406)
fixes TryGhost/Product#3970

- When saving a tier, it is impossible to change the capitalization of a
benefit
- The logic when saving a tier matches benefits by `name.toLowercase()`
and then overwrites the incoming change with the name from the previous
version of the benefit
- This changes the logic to match benefits the same way using
`name.toLowercase()`, but use the _incoming_ benefit's capitalization
rather than the old benefit's, to allow users to e.g. change 'TEst
benefit' to 'Test benefit'
2023-10-05 19:04:11 -07:00

244 lines
7.3 KiB
JavaScript

const assert = require('assert/strict');
const {
agentProvider,
fixtureManager,
mockManager,
matchers
} = require('../../utils/e2e-framework');
const models = require('../../../core/server/models/index');
const {anyContentVersion, anyEtag} = matchers;
describe('Tiers API', function () {
let agent;
before(async function () {
agent = await agentProvider.getAdminAPIAgent();
await fixtureManager.init('members');
await agent.loginAsOwner();
});
afterEach(function () {
mockManager.restore();
});
it('Can browse Tiers', async function () {
await agent
.get('/tiers/')
.expectStatus(200)
.matchBodySnapshot({
tiers: Array(2).fill({
id: matchers.anyObjectId,
created_at: matchers.anyISODateTime,
updated_at: matchers.anyISODateTime
})
});
});
it('Errors when price is non-integer', async function () {
const tier = {
name: 'Blah',
monthly_price: 99.99,
currency: 'usd'
};
await agent
.post('/tiers/')
.body({tiers: [tier]})
.expectStatus(422)
.matchBodySnapshot({
errors: [{
id: matchers.anyUuid
}]
});
});
it('Errors when price is negative', async function () {
const tier = {
name: 'Blah',
monthly_price: -100,
currency: 'usd'
};
await agent
.post('/tiers/')
.body({tiers: [tier]})
.expectStatus(422)
.matchBodySnapshot({
errors: [{
id: matchers.anyUuid
}]
});
});
it('Errors when price is too large', async function () {
const tier = {
name: 'Blah',
monthly_price: Number.MAX_SAFE_INTEGER,
currency: 'usd'
};
await agent
.post('/tiers/')
.body({tiers: [tier]})
.expectStatus(422)
.matchBodySnapshot({
errors: [{
id: matchers.anyUuid
}]
});
});
it('Can read Tiers', async function () {
const {body: {tiers: [tier]}} = await agent.get('/tiers/');
await agent.get(`/tiers/${tier.id}/`)
.expectStatus(200);
});
it('Can edit visibility', async function () {
const {body: {tiers: [tier]}} = await agent.get('/tiers/?filter=type:paid&limit=1');
const visibility = tier.visibility === 'none' ? 'public' : 'none';
await agent.put(`/tiers/${tier.id}/`)
.body({
tiers: [{
visibility
}]
})
.expectStatus(200);
const {body: {tiers: [updatedTier]}} = await agent.get(`/tiers/${tier.id}/`);
assert(updatedTier.visibility === visibility, `The visibility of the Tier should have been updated to ${visibility}`);
});
it('Can save with trial_days as null', async function () {
const {body: {tiers: [tier]}} = await agent.get('/tiers/?limit=1');
await agent.put(`/tiers/${tier.id}/`)
.body({
tiers: [{
trial_days: null
}]
})
.expectStatus(200);
const {body: {tiers: [updatedTier]}} = await agent.get(`/tiers/${tier.id}/`);
assert(updatedTier.trial_days === 0, `The trial_days should have been set to 0`);
});
it('Can edit tier properties and relations', async function () {
let {body: {tiers: [tier]}} = await agent.get('/tiers/?filter=type:paid&limit=1')
.expectStatus(200)
.matchHeaderSnapshot({
'content-version': anyContentVersion,
etag: anyEtag
})
.matchBodySnapshot({
tiers: Array(1).fill({
id: matchers.anyObjectId,
created_at: matchers.anyISODateTime,
updated_at: matchers.anyISODateTime
})
});
await agent.put(`/tiers/${tier.id}/`)
.body({
tiers: [{
description: 'Updated description',
benefits: ['daily cat pictures', 'delicious avo toast']
}]
})
.expectStatus(200);
await agent.get(`/tiers/${tier.id}/`)
.expectStatus(200)
.matchHeaderSnapshot({
'content-version': anyContentVersion,
etag: anyEtag
})
.matchBodySnapshot({
tiers: Array(1).fill({
id: matchers.anyObjectId,
created_at: matchers.anyISODateTime,
updated_at: matchers.anyISODateTime
})
});
});
it('Can create a new tier', async function () {
const tier = {
name: 'new premium tier',
monthly_price: 100,
currency: 'usd'
};
await agent
.post('/tiers/')
.body({tiers: [tier]})
.expectStatus(201)
.matchBodySnapshot({
tiers: Array(1).fill({
id: matchers.anyObjectId,
created_at: matchers.anyISODate,
name: 'new premium tier',
slug: 'new-premium-tier',
monthly_price: 100,
currency: 'USD'
})
});
});
it('Can update a benefit\'s capitalization', async function () {
const tierData = {
name: 'benefit test tier',
monthly_price: 100,
currency: 'usd',
benefits: ['TEST BENEFIT']
};
let {body: {tiers: [tier]}} = await agent.post('/tiers/')
.body({tiers: [tierData]})
.expectStatus(201)
.matchBodySnapshot({
tiers: Array(1).fill({
id: matchers.anyObjectId,
created_at: matchers.anyISODate,
name: 'benefit test tier',
slug: 'benefit-test-tier',
monthly_price: 100,
currency: 'USD'
})
});
await agent.put(`/tiers/${tier.id}/`)
.body({
tiers: [{
benefits: ['Test benefit']
}]
})
.expectStatus(200);
await agent.get(`/tiers/${tier.id}/`)
.expectStatus(200)
.matchHeaderSnapshot({
'content-version': anyContentVersion,
etag: anyEtag
})
.matchBodySnapshot({
tiers: Array(1).fill({
id: matchers.anyObjectId,
created_at: matchers.anyISODate,
benefits: ['Test benefit']
})
});
const benefit = await models.Benefit.findOne({slug: 'test-benefit'});
assert(benefit.attributes.name === 'Test benefit', 'The benefit should have been updated.');
const previousBenefit = await models.Benefit.findOne({slug: 'test-benefit-2'});
assert(!previousBenefit, 'The previous benefit should have been overwritten');
});
});