2021-03-25 15:19:01 +03:00
|
|
|
const sinon = require('sinon');
|
2023-05-02 23:43:47 +03:00
|
|
|
const MemberController = require('../../../../../lib/controllers/MemberController');
|
2021-03-25 15:19:01 +03:00
|
|
|
|
|
|
|
describe('MemberController', function () {
|
|
|
|
describe('updateSubscription', function () {
|
2022-01-21 15:08:31 +03:00
|
|
|
it('Updates a subscriptions plan via the member repository if the Tier is active', async function () {
|
2021-03-25 15:19:01 +03:00
|
|
|
const tokenService = {
|
|
|
|
decodeToken: sinon.fake.resolves({sub: 'fake@email.com'})
|
|
|
|
};
|
2021-05-04 18:57:58 +03:00
|
|
|
const StripePrice = {
|
|
|
|
findOne: sinon.fake.returns({
|
|
|
|
id: 'plan_id',
|
|
|
|
stripe_price_id: 'stripe_price_id',
|
|
|
|
get: () => {
|
|
|
|
return 'stripe_price_id';
|
|
|
|
}
|
|
|
|
})
|
2021-03-25 15:19:01 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
const memberRepository = {
|
|
|
|
updateSubscription: sinon.mock('updateSubscription').once().withArgs({
|
|
|
|
email: 'fake@email.com',
|
|
|
|
subscription: {
|
|
|
|
subscription_id: 'subscription_id',
|
2021-05-04 18:57:58 +03:00
|
|
|
price: 'stripe_price_id'
|
2021-03-25 15:19:01 +03:00
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2022-11-07 11:19:26 +03:00
|
|
|
const tier = {
|
|
|
|
id: 'whatever'
|
|
|
|
};
|
|
|
|
|
|
|
|
const price = {
|
|
|
|
id: 'stripe_price_id'
|
|
|
|
};
|
|
|
|
|
|
|
|
const tiersService = {
|
|
|
|
api: {
|
|
|
|
read: sinon.fake.resolves(tier)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
const paymentsService = {
|
|
|
|
getPriceForTierCadence: sinon.fake.resolves(price)
|
|
|
|
};
|
|
|
|
|
2022-01-21 15:08:31 +03:00
|
|
|
const productRepository = {
|
|
|
|
get: sinon.fake.resolves({
|
|
|
|
get() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
const controller = new MemberController({
|
|
|
|
memberRepository,
|
|
|
|
productRepository,
|
2022-11-07 11:19:26 +03:00
|
|
|
tiersService,
|
|
|
|
paymentsService,
|
2022-01-21 15:08:31 +03:00
|
|
|
StripePrice,
|
|
|
|
tokenService
|
|
|
|
});
|
|
|
|
|
|
|
|
const req = {
|
|
|
|
body: {
|
|
|
|
identity: 'token',
|
2022-11-07 11:19:26 +03:00
|
|
|
tierId: 'tier_id',
|
|
|
|
cadence: 'yearly'
|
2022-01-21 15:08:31 +03:00
|
|
|
},
|
|
|
|
params: {
|
|
|
|
id: 'subscription_id'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const res = {
|
|
|
|
writeHead() {},
|
|
|
|
end() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
await controller.updateSubscription(req, res);
|
|
|
|
|
|
|
|
memberRepository.updateSubscription.verify();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Does not a subscriptions plan via the member repository if the Tier is not active', async function () {
|
|
|
|
const tokenService = {
|
|
|
|
decodeToken: sinon.fake.resolves({sub: 'fake@email.com'})
|
|
|
|
};
|
|
|
|
const StripePrice = {
|
|
|
|
findOne: sinon.fake.returns({
|
|
|
|
id: 'plan_id',
|
|
|
|
stripe_price_id: 'stripe_price_id',
|
|
|
|
get: () => {
|
|
|
|
return 'stripe_price_id';
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
const memberRepository = {
|
|
|
|
updateSubscription: sinon.mock('updateSubscription').never()
|
|
|
|
};
|
|
|
|
|
|
|
|
const productRepository = {
|
|
|
|
get: sinon.fake.resolves({
|
|
|
|
get() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
2021-03-25 15:19:01 +03:00
|
|
|
const controller = new MemberController({
|
|
|
|
memberRepository,
|
2022-01-21 15:08:31 +03:00
|
|
|
productRepository,
|
2021-05-04 18:57:58 +03:00
|
|
|
StripePrice,
|
2021-03-25 15:19:01 +03:00
|
|
|
tokenService
|
|
|
|
});
|
|
|
|
|
|
|
|
const req = {
|
|
|
|
body: {
|
|
|
|
identity: 'token',
|
2021-05-04 18:57:58 +03:00
|
|
|
priceId: 'plan_name'
|
2021-03-25 15:19:01 +03:00
|
|
|
},
|
|
|
|
params: {
|
|
|
|
id: 'subscription_id'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const res = {
|
|
|
|
writeHead() {},
|
|
|
|
end() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
await controller.updateSubscription(req, res);
|
|
|
|
|
|
|
|
memberRepository.updateSubscription.verify();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Updates a subscriptions cancel_at_period_end via the member repository', async function () {
|
|
|
|
const tokenService = {
|
|
|
|
decodeToken: sinon.fake.resolves({sub: 'fake@email.com'})
|
|
|
|
};
|
|
|
|
const stripePlansService = {
|
|
|
|
getPlan: sinon.fake.returns({id: 'plan_id'})
|
|
|
|
};
|
|
|
|
|
|
|
|
const memberRepository = {
|
|
|
|
updateSubscription: sinon.mock('updateSubscription').once().withArgs({
|
|
|
|
email: 'fake@email.com',
|
|
|
|
subscription: {
|
|
|
|
subscription_id: 'subscription_id',
|
|
|
|
cancellationReason: 'For reasonable reasons',
|
|
|
|
cancel_at_period_end: true
|
|
|
|
}
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
const controller = new MemberController({
|
|
|
|
memberRepository,
|
|
|
|
stripePlansService,
|
|
|
|
tokenService
|
|
|
|
});
|
|
|
|
|
|
|
|
const req = {
|
|
|
|
body: {
|
|
|
|
identity: 'token',
|
|
|
|
cancel_at_period_end: true,
|
|
|
|
cancellation_reason: 'For reasonable reasons'
|
|
|
|
},
|
|
|
|
params: {
|
|
|
|
id: 'subscription_id'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const res = {
|
|
|
|
writeHead() {},
|
|
|
|
end() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
await controller.updateSubscription(req, res);
|
|
|
|
|
|
|
|
memberRepository.updateSubscription.verify();
|
|
|
|
});
|
2021-03-25 15:21:48 +03:00
|
|
|
|
|
|
|
describe('smart_cancel', function () {
|
|
|
|
it('Updates a paid subscriptions cancel_at_period_end via the member repository', async function () {
|
|
|
|
const tokenService = {
|
|
|
|
decodeToken: sinon.fake.resolves({sub: 'fake@email.com'})
|
|
|
|
};
|
|
|
|
const stripePlansService = {
|
|
|
|
getPlan: sinon.fake.returns({id: 'plan_id'})
|
|
|
|
};
|
|
|
|
|
|
|
|
const memberRepository = {
|
|
|
|
updateSubscription: sinon.mock('updateSubscription').once().withArgs({
|
|
|
|
email: 'fake@email.com',
|
|
|
|
subscription: {
|
|
|
|
subscription_id: 'subscription_id',
|
|
|
|
cancellationReason: 'For reasonable reasons',
|
|
|
|
cancel_at_period_end: true
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
getSubscription: sinon.fake.resolves({
|
|
|
|
status: 'active'
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
const controller = new MemberController({
|
|
|
|
memberRepository,
|
|
|
|
stripePlansService,
|
|
|
|
tokenService
|
|
|
|
});
|
|
|
|
|
|
|
|
const req = {
|
|
|
|
body: {
|
|
|
|
identity: 'token',
|
|
|
|
smart_cancel: true,
|
|
|
|
cancellation_reason: 'For reasonable reasons'
|
|
|
|
},
|
|
|
|
params: {
|
|
|
|
id: 'subscription_id'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const res = {
|
|
|
|
writeHead() {},
|
|
|
|
end() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
await controller.updateSubscription(req, res);
|
|
|
|
|
|
|
|
memberRepository.updateSubscription.verify();
|
|
|
|
});
|
|
|
|
|
|
|
|
it('Cancels an unpaid subscription via the member repository', async function () {
|
|
|
|
const tokenService = {
|
|
|
|
decodeToken: sinon.fake.resolves({sub: 'fake@email.com'})
|
|
|
|
};
|
|
|
|
const stripePlansService = {
|
|
|
|
getPlan: sinon.fake.returns({id: 'plan_id'})
|
|
|
|
};
|
|
|
|
|
|
|
|
const memberRepository = {
|
|
|
|
updateSubscription: sinon.fake(),
|
|
|
|
cancelSubscription: sinon.mock('cancelSubscription').once().withArgs({
|
|
|
|
email: 'fake@email.com',
|
|
|
|
subscription: {
|
|
|
|
subscription_id: 'subscription_id',
|
|
|
|
cancellationReason: 'For reasonable reasons'
|
|
|
|
}
|
|
|
|
}),
|
|
|
|
getSubscription: sinon.fake.resolves({
|
|
|
|
status: 'unpaid'
|
|
|
|
})
|
|
|
|
};
|
|
|
|
|
|
|
|
const controller = new MemberController({
|
|
|
|
memberRepository,
|
|
|
|
stripePlansService,
|
|
|
|
tokenService
|
|
|
|
});
|
|
|
|
|
|
|
|
const req = {
|
|
|
|
body: {
|
|
|
|
identity: 'token',
|
|
|
|
smart_cancel: true,
|
|
|
|
cancellation_reason: 'For reasonable reasons'
|
|
|
|
},
|
|
|
|
params: {
|
|
|
|
id: 'subscription_id'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
const res = {
|
|
|
|
writeHead() {},
|
|
|
|
end() {}
|
|
|
|
};
|
|
|
|
|
|
|
|
await controller.updateSubscription(req, res);
|
|
|
|
|
|
|
|
memberRepository.cancelSubscription.verify();
|
|
|
|
});
|
|
|
|
});
|
2021-03-25 15:19:01 +03:00
|
|
|
});
|
|
|
|
});
|