@@ -13,17 +13,17 @@ import { FREE_TRIAL_COUPONS, PLANS_TO_LINE_ITEMS_MAPPING } from '../constants.js
1313
1414dotenv . config ( { path : fileURLToPath ( new URL ( '../../.env.local' , import . meta. url ) ) } )
1515
16+ /** @import { DidMailto as AccountDID } from '@storacha/did-mailto' */
17+
1618/**
1719 * @typedef {object } BillingContext
1820 * @property {import('../../billing/lib/api.js').CustomerStore } BillingContext.customerStore
1921 * @property {Stripe } BillingContext.stripe
2022 * @property {import('../types.js').BillingProvider } BillingContext.billingProvider
2123 */
2224
23- const customerDID = /** @type {import('@storacha/did-mailto').DidMailto } */ (
24- `did:mailto:example.com:w3up-billing-test-${ Date . now ( ) } `
25- )
26- const email = toEmail ( customerDID )
25+ /** @returns {AccountDID } */
26+ const randomAccount = ( ) => `did:mailto:example.com:w3up-billing-test-${ Date . now ( ) } `
2727const initialPlan = 'did:web:starter.storacha.network'
2828
2929/**
@@ -42,16 +42,16 @@ async function getCustomerSubscriptionPricesByEmail(stripe, email) {
4242}
4343
4444/**
45- *
46- * @param {Stripe } stripe
47- * @param {string } email
45+ * @param {Stripe } stripe
46+ * @param {AccountDID } account
4847 * @param {import('../../billing/lib/api.js').CustomerStore } customerStore
4948 * @returns {Promise<Stripe.Customer> }
5049 */
51- async function setupCustomer ( stripe , email , customerStore ) {
50+ async function setupCustomer ( stripe , account , customerStore ) {
51+ const email = toEmail ( account )
5252 const customer = await stripe . customers . create ( { email } )
5353 const customerCreation = await customerStore . put ( {
54- customer : customerDID ,
54+ customer : account ,
5555 account : stripeIDToAccountID ( customer . id ) ,
5656 product : initialPlan ,
5757 insertedAt : new Date ( )
@@ -84,15 +84,16 @@ async function setupCustomer(stripe, email, customerStore) {
8484/**
8585 *
8686 * @param {BillingContext } context
87- * @param {(c: BillingContext) => Promise<void> } testFn
87+ * @param {(c: BillingContext & { account: AccountDID, customer: Stripe.Customer } ) => Promise<void> } testFn
8888 */
8989async function withCustomer ( context , testFn ) {
9090 const { stripe, customerStore } = context
9191 let customer
9292 try {
93+ const account = randomAccount ( )
9394 // create a new customer and set up its subscription with "initialPlan"
94- customer = await setupCustomer ( stripe , email , customerStore )
95- await testFn ( context )
95+ customer = await setupCustomer ( stripe , account , customerStore )
96+ await testFn ( { ... context , account , customer } )
9697 } finally {
9798 if ( customer ) {
9899 // clean up the user we created
@@ -137,19 +138,39 @@ test('stripe plan can be updated', async (t) => {
137138 const context = /** @type {typeof t.context & BillingContext } */ ( t . context )
138139 const { stripe, billingProvider } = context
139140
140- await withCustomer ( context , async ( ) => {
141+ await withCustomer ( context , async ( { account } ) => {
141142 // use the stripe API to verify plan has been initialized correctly
142- const initialStripePrices = await getCustomerSubscriptionPricesByEmail ( stripe , email )
143+ const initialStripePrices = await getCustomerSubscriptionPricesByEmail ( stripe , toEmail ( account ) )
143144 t . deepEqual ( expectedPriceIdsByPlanId ( initialPlan ) , initialStripePrices )
144145
145146 // this is the actual code under test!
146147 const updatedPlan = 'did:web:lite.storacha.network'
147- const result = await billingProvider . setPlan ( customerDID , updatedPlan )
148+ const result = await billingProvider . setPlan ( account , updatedPlan )
149+ console . log ( result )
150+ t . assert ( result . ok )
151+
152+ // use the stripe API to verify plan has been updated
153+ const updatedStripePrices = await getCustomerSubscriptionPricesByEmail ( stripe , toEmail ( account ) )
154+ t . deepEqual ( expectedPriceIdsByPlanId ( updatedPlan ) , updatedStripePrices )
155+ } )
156+ } )
157+
158+ test ( 'stripe plan can be updated when customer has updated their email address' , async ( t ) => {
159+ const context = /** @type {typeof t.context & BillingContext } */ ( t . context )
160+ const { stripe, billingProvider } = context
161+
162+ await withCustomer ( context , async ( { customer, account } ) => {
163+ const updatedEmail = toEmail ( randomAccount ( ) )
164+ await stripe . customers . update ( customer . id , { email : updatedEmail } )
165+
166+ const updatedPlan = 'did:web:lite.storacha.network'
167+ // use the account ID with the old email
168+ const result = await billingProvider . setPlan ( account , updatedPlan )
148169 console . log ( result )
149170 t . assert ( result . ok )
150171
151172 // use the stripe API to verify plan has been updated
152- const updatedStripePrices = await getCustomerSubscriptionPricesByEmail ( stripe , email )
173+ const updatedStripePrices = await getCustomerSubscriptionPricesByEmail ( stripe , updatedEmail )
153174 t . deepEqual ( expectedPriceIdsByPlanId ( updatedPlan ) , updatedStripePrices )
154175 } )
155176} )
@@ -158,8 +179,8 @@ test('stripe billing admin session can be generated', async (t) => {
158179 const context = /** @type {typeof t.context & BillingContext } */ ( t . context )
159180 const { billingProvider } = context
160181
161- await withCustomer ( context , async ( ) => {
162- const response = await billingProvider . createAdminSession ( customerDID , 'https://example.com/return-url' )
182+ await withCustomer ( context , async ( { account } ) => {
183+ const response = await billingProvider . createAdminSession ( account , 'https://example.com/return-url' )
163184 t . assert ( response . ok )
164185 t . assert ( response . ok ?. url )
165186 } )
@@ -169,9 +190,9 @@ test('stripe checkout session can be generated', async (t) => {
169190 const context = /** @type {typeof t.context & BillingContext } */ ( t . context )
170191 const { billingProvider } = context
171192
172- await withCustomer ( context , async ( ) => {
193+ await withCustomer ( context , async ( { account } ) => {
173194 const response = await billingProvider . createCheckoutSession (
174- customerDID ,
195+ account ,
175196 'did:web:starter.storacha.network' ,
176197 {
177198 successURL : 'https://example.com/return-url' ,
0 commit comments