mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-06-01 21:31:36 +02:00
666 lines
23 KiB
JavaScript
666 lines
23 KiB
JavaScript
// @ts-check
|
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
const { expect } = require('chai')
|
|
const Errors = require('../../../../app/src/Features/Subscription/Errors')
|
|
const {
|
|
PaymentProviderSubscriptionChangeRequest,
|
|
PaymentProviderSubscriptionUpdateRequest,
|
|
PaymentProviderSubscriptionChange,
|
|
PaymentProviderSubscription,
|
|
PaymentProviderSubscriptionAddOnUpdate,
|
|
} = require('../../../../app/src/Features/Subscription/PaymentProviderEntities')
|
|
const {
|
|
AI_ADD_ON_CODE,
|
|
} = require('../../../../app/src/Features/Subscription/AiHelper')
|
|
const SubscriptionHelper = require('../../../../app/src/Features/Subscription/SubscriptionHelper')
|
|
|
|
const MODULE_PATH =
|
|
'../../../../app/src/Features/Subscription/PaymentProviderEntities'
|
|
|
|
describe('PaymentProviderEntities', function () {
|
|
describe('PaymentProviderSubscription', function () {
|
|
beforeEach(function () {
|
|
this.Settings = {
|
|
plans: [
|
|
{ planCode: 'assistant-annual', price_in_cents: 5900 },
|
|
{ planCode: 'cheap-plan', price_in_cents: 500 },
|
|
{ planCode: 'regular-plan', price_in_cents: 1000 },
|
|
{ planCode: 'premium-plan', price_in_cents: 2000 },
|
|
{
|
|
planCode: 'group_collaborator_10_enterprise',
|
|
price_in_cents: 10000,
|
|
},
|
|
],
|
|
features: [],
|
|
}
|
|
|
|
this.PaymentProviderEntities = SandboxedModule.require(MODULE_PATH, {
|
|
requires: {
|
|
'@overleaf/settings': this.Settings,
|
|
'./Errors': Errors,
|
|
'./SubscriptionHelper': SubscriptionHelper,
|
|
},
|
|
})
|
|
})
|
|
|
|
describe('with add-ons', function () {
|
|
beforeEach(function () {
|
|
const {
|
|
PaymentProviderSubscription,
|
|
PaymentProviderSubscriptionAddOn,
|
|
} = this.PaymentProviderEntities
|
|
this.addOn = new PaymentProviderSubscriptionAddOn({
|
|
code: 'add-on-code',
|
|
name: 'My Add-On',
|
|
quantity: 1,
|
|
unitPrice: 2,
|
|
})
|
|
this.subscription = new PaymentProviderSubscription({
|
|
id: 'subscription-id',
|
|
userId: 'user-id',
|
|
planCode: 'regular-plan',
|
|
planName: 'My Plan',
|
|
planPrice: 10,
|
|
addOns: [this.addOn],
|
|
subtotal: 10.99,
|
|
taxRate: 0.2,
|
|
taxAmount: 2.4,
|
|
total: 14.4,
|
|
currency: 'USD',
|
|
})
|
|
})
|
|
|
|
describe('hasAddOn()', function () {
|
|
it('returns true if the subscription has the given add-on', function () {
|
|
expect(this.subscription.hasAddOn(this.addOn.code)).to.be.true
|
|
})
|
|
|
|
it("returns false if the subscription doesn't have the given add-on", function () {
|
|
expect(this.subscription.hasAddOn('another-add-on')).to.be.false
|
|
})
|
|
})
|
|
|
|
describe('getRequestForPlanChange()', function () {
|
|
it('returns a change request for upgrades', function () {
|
|
const { PaymentProviderSubscriptionChangeRequest } =
|
|
this.PaymentProviderEntities
|
|
const changeRequest = this.subscription.getRequestForPlanChange(
|
|
'premium-plan',
|
|
1,
|
|
this.subscription.shouldPlanChangeAtTermEnd('premium-plan')
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
planCode: 'premium-plan',
|
|
})
|
|
)
|
|
})
|
|
|
|
it('returns a change request for downgrades', function () {
|
|
const { PaymentProviderSubscriptionChangeRequest } =
|
|
this.PaymentProviderEntities
|
|
const changeRequest = this.subscription.getRequestForPlanChange(
|
|
'cheap-plan',
|
|
1,
|
|
this.subscription.shouldPlanChangeAtTermEnd('cheap-plan')
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'term_end',
|
|
planCode: 'cheap-plan',
|
|
})
|
|
)
|
|
})
|
|
|
|
it('returns a change request for downgrades while on trial', function () {
|
|
const fiveDaysFromNow = new Date()
|
|
fiveDaysFromNow.setDate(fiveDaysFromNow.getDate() + 5)
|
|
this.subscription.trialPeriodEnd = fiveDaysFromNow
|
|
const { PaymentProviderSubscriptionChangeRequest } =
|
|
this.PaymentProviderEntities
|
|
const changeRequest = this.subscription.getRequestForPlanChange(
|
|
'cheap-plan',
|
|
1,
|
|
this.subscription.shouldPlanChangeAtTermEnd('cheap-plan')
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
planCode: 'cheap-plan',
|
|
})
|
|
)
|
|
})
|
|
|
|
it('preserves the AI add-on on upgrades', function () {
|
|
const { PaymentProviderSubscriptionChangeRequest } =
|
|
this.PaymentProviderEntities
|
|
this.addOn.code = AI_ADD_ON_CODE
|
|
const changeRequest = this.subscription.getRequestForPlanChange(
|
|
'premium-plan',
|
|
1,
|
|
this.subscription.shouldPlanChangeAtTermEnd('premium-plan')
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
planCode: 'premium-plan',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: AI_ADD_ON_CODE,
|
|
quantity: 1,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
|
|
it('preserves the AI add-on on downgrades', function () {
|
|
const { PaymentProviderSubscriptionChangeRequest } =
|
|
this.PaymentProviderEntities
|
|
this.addOn.code = AI_ADD_ON_CODE
|
|
const changeRequest = this.subscription.getRequestForPlanChange(
|
|
'cheap-plan',
|
|
1,
|
|
this.subscription.shouldPlanChangeAtTermEnd('cheap-plan')
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'term_end',
|
|
planCode: 'cheap-plan',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: AI_ADD_ON_CODE,
|
|
quantity: 1,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
|
|
it('preserves the AI add-on on upgrades from the standalone AI plan', function () {
|
|
const { PaymentProviderSubscriptionChangeRequest } =
|
|
this.PaymentProviderEntities
|
|
this.subscription.planCode = 'assistant-annual'
|
|
this.subscription.addOns = []
|
|
const changeRequest = this.subscription.getRequestForPlanChange(
|
|
'cheap-plan',
|
|
1,
|
|
this.subscription.shouldPlanChangeAtTermEnd('cheap-plan')
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
planCode: 'cheap-plan',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: AI_ADD_ON_CODE,
|
|
quantity: 1,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
|
|
it('upgrade from individual to group plan for Stripe subscription', function () {
|
|
this.subscription.service = 'stripe-uk'
|
|
const { PaymentProviderSubscriptionChangeRequest } =
|
|
this.PaymentProviderEntities
|
|
const changeRequest = this.subscription.getRequestForPlanChange(
|
|
'group_collaborator',
|
|
10,
|
|
this.subscription.shouldPlanChangeAtTermEnd(
|
|
'group_collaborator_10_enterprise'
|
|
)
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
planCode: 'group_collaborator',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: 'additional-license',
|
|
quantity: 10,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
|
|
it('upgrade from individual to group plan and preserves the AI add-on for Stripe subscription', function () {
|
|
this.subscription.service = 'stripe-uk'
|
|
const { PaymentProviderSubscriptionChangeRequest } =
|
|
this.PaymentProviderEntities
|
|
this.addOn.code = AI_ADD_ON_CODE
|
|
const changeRequest = this.subscription.getRequestForPlanChange(
|
|
'group_collaborator',
|
|
10,
|
|
this.subscription.shouldPlanChangeAtTermEnd(
|
|
'group_collaborator_10_enterprise'
|
|
)
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
planCode: 'group_collaborator',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: 'additional-license',
|
|
quantity: 10,
|
|
}),
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: AI_ADD_ON_CODE,
|
|
quantity: 1,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForAddOnPurchase()', function () {
|
|
it('returns a change request', function () {
|
|
const {
|
|
PaymentProviderSubscriptionChangeRequest,
|
|
PaymentProviderSubscriptionAddOnUpdate,
|
|
} = this.PaymentProviderEntities
|
|
const changeRequest =
|
|
this.subscription.getRequestForAddOnPurchase('another-add-on')
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: this.addOn.code,
|
|
quantity: this.addOn.quantity,
|
|
unitPrice: this.addOn.unitPrice,
|
|
}),
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: 'another-add-on',
|
|
quantity: 1,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
|
|
it('returns a change request with quantity and unit price specified', function () {
|
|
const {
|
|
PaymentProviderSubscriptionChangeRequest,
|
|
PaymentProviderSubscriptionAddOnUpdate,
|
|
} = this.PaymentProviderEntities
|
|
const quantity = 5
|
|
const unitPrice = 10
|
|
const changeRequest = this.subscription.getRequestForAddOnPurchase(
|
|
'another-add-on',
|
|
quantity,
|
|
unitPrice
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: this.addOn.code,
|
|
quantity: this.addOn.quantity,
|
|
unitPrice: this.addOn.unitPrice,
|
|
}),
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: 'another-add-on',
|
|
quantity,
|
|
unitPrice,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
|
|
it('throws a DuplicateAddOnError if the subscription already has the add-on', function () {
|
|
expect(() =>
|
|
this.subscription.getRequestForAddOnPurchase(this.addOn.code)
|
|
).to.throw(Errors.DuplicateAddOnError)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForAddOnUpdate()', function () {
|
|
it('returns a change request', function () {
|
|
const {
|
|
PaymentProviderSubscriptionChangeRequest,
|
|
PaymentProviderSubscriptionAddOnUpdate,
|
|
} = this.PaymentProviderEntities
|
|
const newQuantity = 2
|
|
const changeRequest = this.subscription.getRequestForAddOnUpdate(
|
|
'add-on-code',
|
|
newQuantity
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: this.addOn.code,
|
|
quantity: newQuantity,
|
|
unitPrice: this.addOn.unitPrice,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
|
|
it("throws a AddOnNotPresentError if the subscription doesn't have the add-on", function () {
|
|
expect(() =>
|
|
this.subscription.getRequestForAddOnUpdate('another-add-on', 2)
|
|
).to.throw(Errors.AddOnNotPresentError)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForAddOnRemoval()', function () {
|
|
it('returns a change request', function () {
|
|
const changeRequest = this.subscription.getRequestForAddOnRemoval(
|
|
this.addOn.code
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'term_end',
|
|
addOnUpdates: [],
|
|
})
|
|
)
|
|
})
|
|
|
|
it('returns a change request when in trial', function () {
|
|
const fiveDaysFromNow = new Date()
|
|
fiveDaysFromNow.setDate(fiveDaysFromNow.getDate() + 5)
|
|
this.subscription.trialPeriodEnd = fiveDaysFromNow
|
|
const changeRequest = this.subscription.getRequestForAddOnRemoval(
|
|
this.addOn.code
|
|
)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
addOnUpdates: [],
|
|
})
|
|
)
|
|
})
|
|
|
|
it("throws an AddOnNotPresentError if the subscription doesn't have the add-on", function () {
|
|
expect(() =>
|
|
this.subscription.getRequestForAddOnRemoval('another-add-on')
|
|
).to.throw(Errors.AddOnNotPresentError)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForAddOnReactivation()', function () {
|
|
it('throws an AddOnNotPresentError', function () {
|
|
expect(() =>
|
|
this.subscription.getRequestForAddOnReactivation(this.addOn.code)
|
|
).to.throw(Errors.AddOnNotPresentError)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForGroupPlanUpgrade()', function () {
|
|
it('returns a correct change request', function () {
|
|
const changeRequest =
|
|
this.subscription.getRequestForGroupPlanUpgrade('test_plan_code')
|
|
const addOns = [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: 'add-on-code',
|
|
quantity: 1,
|
|
}),
|
|
]
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
addOnUpdates: addOns,
|
|
planCode: 'test_plan_code',
|
|
})
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForPoNumberAndTermsAndConditionsUpdate()', function () {
|
|
it('returns a correct update request', function () {
|
|
const updateRequest =
|
|
this.subscription.getRequestForPoNumberAndTermsAndConditionsUpdate(
|
|
'O12345',
|
|
'T&C copy'
|
|
)
|
|
expect(updateRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionUpdateRequest({
|
|
subscription: this.subscription,
|
|
poNumber: 'O12345',
|
|
termsAndConditions: 'T&C copy',
|
|
})
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForTermsAndConditionsUpdate()', function () {
|
|
it('returns a correct update request', function () {
|
|
const updateRequest =
|
|
this.subscription.getRequestForTermsAndConditionsUpdate('T&C copy')
|
|
expect(updateRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionUpdateRequest({
|
|
subscription: this.subscription,
|
|
termsAndConditions: 'T&C copy',
|
|
})
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('with an add-on pending cancellation', function () {
|
|
beforeEach(function () {
|
|
this.subscription.pendingChange =
|
|
new PaymentProviderSubscriptionChange({
|
|
subscription: this.subscription,
|
|
nextPlanCode: this.subscription.planCode,
|
|
nextPlanName: this.subscription.planName,
|
|
nextPlanPrice: this.subscription.planPrice,
|
|
nextAddOns: [],
|
|
})
|
|
})
|
|
|
|
describe('getRequestForAddOnReactivation()', function () {
|
|
it('returns a change request', function () {
|
|
const changeRequest =
|
|
this.subscription.getRequestForAddOnReactivation(this.addOn.code)
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'term_end',
|
|
addOnUpdates: [this.addOn.toAddOnUpdate()],
|
|
})
|
|
)
|
|
})
|
|
|
|
it('throws an AddOnNotPresentError if given the wrong add-on', function () {
|
|
expect(() =>
|
|
this.subscription.getRequestForAddOnReactivation('some-add-on')
|
|
).to.throw(Errors.AddOnNotPresentError)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForPlanRevert()', function () {
|
|
beforeEach(function () {
|
|
const { PaymentProviderSubscription } = this.PaymentProviderEntities
|
|
this.subscription = new PaymentProviderSubscription({
|
|
id: 'subscription-id',
|
|
userId: 'user-id',
|
|
planCode: 'regular-plan',
|
|
planName: 'My Plan',
|
|
planPrice: 10,
|
|
addOns: [
|
|
{
|
|
addOnCode: 'addon-1',
|
|
quantity: 2,
|
|
unitAmountInCents: 500,
|
|
},
|
|
{
|
|
addOnCode: 'addon-2',
|
|
quantity: 1,
|
|
unitAmountInCents: 600,
|
|
},
|
|
],
|
|
subtotal: 10.99,
|
|
taxRate: 0.2,
|
|
taxAmount: 2.4,
|
|
total: 14.4,
|
|
currency: 'USD',
|
|
})
|
|
})
|
|
|
|
it('throws if the plan to revert to doesnt exist', function () {
|
|
const invalidPlanCode = 'non-existent-plan'
|
|
expect(() =>
|
|
this.subscription.getRequestForPlanRevert(invalidPlanCode, null)
|
|
).to.throw('Unable to find plan in settings')
|
|
})
|
|
|
|
it('creates a change request with the restore point', function () {
|
|
const previousPlanCode = 'cheap-plan'
|
|
const previousAddOns = [
|
|
{ addOnCode: 'addon-1', quantity: 1, unitAmountInCents: 500 },
|
|
]
|
|
const changeRequest = this.subscription.getRequestForPlanRevert(
|
|
previousPlanCode,
|
|
previousAddOns
|
|
)
|
|
expect(changeRequest).to.be.an.instanceOf(
|
|
this.PaymentProviderEntities
|
|
.PaymentProviderSubscriptionChangeRequest
|
|
)
|
|
expect(changeRequest.planCode).to.equal(previousPlanCode)
|
|
expect(changeRequest.addOnUpdates).to.deep.equal([
|
|
{
|
|
code: 'addon-1',
|
|
quantity: 1,
|
|
unitPrice: 5,
|
|
},
|
|
])
|
|
})
|
|
|
|
it('defaults to addons to an empty array to clear the addon state', function () {
|
|
const previousPlanCode = 'cheap-plan'
|
|
const changeRequest = this.subscription.getRequestForPlanRevert(
|
|
previousPlanCode,
|
|
null
|
|
)
|
|
expect(changeRequest.addOnUpdates).to.deep.equal([])
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('without add-ons', function () {
|
|
beforeEach(function () {
|
|
const { PaymentProviderSubscription } = this.PaymentProviderEntities
|
|
this.subscription = new PaymentProviderSubscription({
|
|
id: 'subscription-id',
|
|
userId: 'user-id',
|
|
planCode: 'regular-plan',
|
|
planName: 'My Plan',
|
|
planPrice: 10,
|
|
subtotal: 10.99,
|
|
taxRate: 0.2,
|
|
taxAmount: 2.4,
|
|
total: 14.4,
|
|
currency: 'USD',
|
|
})
|
|
})
|
|
|
|
describe('hasAddOn()', function () {
|
|
it('returns false for any add-on', function () {
|
|
expect(this.subscription.hasAddOn('some-add-on')).to.be.false
|
|
})
|
|
})
|
|
|
|
describe('getRequestForAddOnPurchase()', function () {
|
|
it('returns a change request', function () {
|
|
const {
|
|
PaymentProviderSubscriptionChangeRequest,
|
|
PaymentProviderSubscriptionAddOnUpdate,
|
|
} = this.PaymentProviderEntities
|
|
const changeRequest =
|
|
this.subscription.getRequestForAddOnPurchase('some-add-on')
|
|
expect(changeRequest).to.deep.equal(
|
|
new PaymentProviderSubscriptionChangeRequest({
|
|
subscription: this.subscription,
|
|
timeframe: 'now',
|
|
addOnUpdates: [
|
|
new PaymentProviderSubscriptionAddOnUpdate({
|
|
code: 'some-add-on',
|
|
quantity: 1,
|
|
}),
|
|
],
|
|
})
|
|
)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForAddOnRemoval()', function () {
|
|
it('throws an AddOnNotPresentError', function () {
|
|
expect(() =>
|
|
this.subscription.getRequestForAddOnRemoval('some-add-on')
|
|
).to.throw(Errors.AddOnNotPresentError)
|
|
})
|
|
})
|
|
|
|
describe('getRequestForAddOnReactivation()', function () {
|
|
it('throws an AddOnNotPresentError', function () {
|
|
expect(() =>
|
|
this.subscription.getRequestForAddOnReactivation('some-add-on')
|
|
).to.throw(Errors.AddOnNotPresentError)
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
describe('PaymentProviderSubscriptionChange', function () {
|
|
describe('constructor', function () {
|
|
it('rounds the amounts when calculating the taxes', function () {
|
|
const subscription = new PaymentProviderSubscription({
|
|
id: 'subscription-id',
|
|
userId: 'user-id',
|
|
planCode: 'premium-plan',
|
|
planName: 'Premium plan',
|
|
planPrice: 10,
|
|
subtotal: 10,
|
|
taxRate: 0.15,
|
|
taxAmount: 1.5,
|
|
currency: 'USD',
|
|
total: 11.5,
|
|
periodStart: new Date(),
|
|
periodEnd: new Date(),
|
|
collectionMethod: 'automatic',
|
|
netTerms: 0,
|
|
poNumber: '012345',
|
|
termsAndConditions: 'T&C copy',
|
|
})
|
|
const change = new PaymentProviderSubscriptionChange({
|
|
subscription,
|
|
nextPlanCode: 'promotional-plan',
|
|
nextPlanName: 'Promotial plan',
|
|
nextPlanPrice: 8.99,
|
|
nextAddOns: [],
|
|
})
|
|
expect(change.tax).to.equal(1.35)
|
|
expect(change.total).to.equal(10.34)
|
|
})
|
|
})
|
|
})
|
|
})
|