Supported optionally cancelling subscriptions on delete

no-issue

This updates the Admin API Member resource to *not* cancel subscriptions
by default, and adds a `cancel` option. This can be used over HTTP by
including a `cancel=true` query parameter.
This commit is contained in:
Fabien O'Carroll 2020-07-24 12:39:08 +02:00 committed by Fabien 'egg' O'Carroll
parent 0ec28219f9
commit c46475f5be
2 changed files with 116 additions and 4 deletions

View File

@ -303,7 +303,8 @@ const members = {
statusCode: 204,
headers: {},
options: [
'id'
'id',
'cancel'
],
validation: {
options: {
@ -326,10 +327,12 @@ const members = {
});
}
// NOTE: move to a model layer once Members/MemberStripeCustomer relations are in place
await membersService.api.members.destroyStripeSubscriptions(member);
if (frame.options.cancel === true) {
await membersService.api.members.cancelStripeSubscriptions(member);
}
await models.Member.destroy(frame.options)
// Wrapped in bluebird promise to allow "filtered catch"
await Promise.resolve(models.Member.destroy(frame.options))
.catch(models.Member.NotFoundError, () => {
throw new errors.NotFoundError({
message: i18n.t('errors.api.resource.resourceNotFound', {

View File

@ -156,6 +156,115 @@ describe('Members API', function () {
});
});
it('Can delete a member without cancelling Stripe Subscription', async function () {
const member = {
name: 'Member 2 Delete',
email: 'Member2Delete@test.com'
};
const createdMember = await request.post(localUtils.API.getApiQuery(`members/`))
.send({members: [member]})
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(201)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.members);
jsonResponse.members.should.have.length(1);
return jsonResponse.members[0];
});
await request.delete(localUtils.API.getApiQuery(`members/${createdMember.id}/`))
.set('Origin', config.get('url'))
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(204)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
});
});
// NOTE: this test should be enabled and expanded once test suite fully supports Stripe mocking
it.skip('Can delete a member and cancel Stripe Subscription', async function () {
const member = {
name: 'Member 2 Delete',
email: 'Member2Delete@test.com',
comped: true
};
const createdMember = await request.post(localUtils.API.getApiQuery(`members/`))
.send({members: [member]})
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(201)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.members);
jsonResponse.members.should.have.length(1);
return jsonResponse.members[0];
});
await request.delete(localUtils.API.getApiQuery(`members/${createdMember.id}/?cancel=true`))
.set('Origin', config.get('url'))
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(204)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
});
});
// NOTE: this test should be enabled and expanded once test suite fully supports Stripe mocking
it.skip('Does not cancel Stripe Subscription if cancel_subscriptions is not set to "true"', async function () {
const member = {
name: 'Member 2 Delete',
email: 'Member2Delete@test.com',
comped: true
};
const createdMember = await request.post(localUtils.API.getApiQuery(`members/`))
.send({members: [member]})
.set('Origin', config.get('url'))
.expect('Content-Type', /json/)
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(201)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
should.exist(jsonResponse.members);
jsonResponse.members.should.have.length(1);
return jsonResponse.members[0];
});
await request.delete(localUtils.API.getApiQuery(`members/${createdMember.id}/?cancel=false`))
.set('Origin', config.get('url'))
.expect('Cache-Control', testUtils.cacheRules.private)
.expect(204)
.then((res) => {
should.not.exist(res.headers['x-cache-invalidate']);
const jsonResponse = res.body;
should.exist(jsonResponse);
});
});
it('Can import CSV with minimum one field and labels', function () {
return request
.post(localUtils.API.getApiQuery(`members/upload/`))