diff --git a/server/tests/billing/update-subscription/multi-product/multi-entity-from-free.test.ts b/server/tests/billing/update-subscription/multi-product/multi-entity-from-free.test.ts index df2289a2a..1ddff8ec4 100644 --- a/server/tests/billing/update-subscription/multi-product/multi-entity-from-free.test.ts +++ b/server/tests/billing/update-subscription/multi-product/multi-entity-from-free.test.ts @@ -116,10 +116,12 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: entity 2 upgra const { autumnV1, ctx, entities } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [pro, free] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "pro", entityIndex: 0 }), s.attach({ productId: "free", entityIndex: 1 }), ], @@ -194,10 +196,12 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: base + consuma const { autumnV1, ctx, entities } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [pro, free] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "pro", entityIndex: 0 }), s.attach({ productId: "free", entityIndex: 1 }), ], @@ -289,10 +293,12 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: annual price") const { autumnV1, ctx, entities } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [pro, free] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "pro", entityIndex: 0 }), s.attach({ productId: "free", entityIndex: 1 }), ], @@ -367,10 +373,12 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: annual mid-cyc const { autumnV1, ctx, entities } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [pro, free] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "pro", entityIndex: 0 }), s.attach({ productId: "free", entityIndex: 1 }), s.advanceTestClock({ days: 15 }), // Advance 15 days mid-cycle @@ -447,10 +455,12 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: monthly mid-cy const { autumnV1, ctx, entities } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [pro, free] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "pro", entityIndex: 0 }), s.attach({ productId: "free", entityIndex: 1 }), s.advanceTestClock({ days: 15 }), // Advance 15 days mid-cycle diff --git a/server/tests/billing/update-subscription/multi-product/schedules-free-to-paid.test.ts b/server/tests/billing/update-subscription/multi-product/schedules-free-to-paid.test.ts index 07cde3df4..c679e41f9 100644 --- a/server/tests/billing/update-subscription/multi-product/schedules-free-to-paid.test.ts +++ b/server/tests/billing/update-subscription/multi-product/schedules-free-to-paid.test.ts @@ -41,13 +41,15 @@ test.concurrent(`${chalk.yellowBright("schedules-f2p: cancel entity 1, upgrade e const { autumnV1, ctx, entities, testClockId } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [pro, free] }), s.entities({ count: 2, featureId: TestFeature.Users }), - s.attach({ productId: "pro", entityIndex: 0 }), - s.attach({ productId: "free", entityIndex: 1 }), - s.cancel({ productId: "pro", entityIndex: 0 }), // Cancel entity 1's pro + ], + actions: [ + s.attach({ productId: pro.id, entityIndex: 0 }), + s.attach({ productId: free.id, entityIndex: 1 }), + s.cancel({ productId: pro.id, entityIndex: 0 }), // Cancel entity 1's pro ], }); @@ -179,10 +181,12 @@ test.concurrent(`${chalk.yellowBright("schedules-f2p: downgrade entity 1, upgrad const { autumnV1, ctx, entities, testClockId } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [premium, pro, free] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "premium", entityIndex: 0 }), s.attach({ productId: "free", entityIndex: 1 }), ], @@ -320,10 +324,12 @@ test.concurrent(`${chalk.yellowBright("schedules-f2p: cancel to default, upgrade const { autumnV1, ctx, entities, testClockId } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success", withDefault: true }), s.products({ list: [free, pro] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "pro", entityIndex: 0 }), s.attach({ productId: "free", entityIndex: 1 }), s.cancel({ productId: "pro", entityIndex: 0 }), // Cancel entity 1's pro → free scheduled diff --git a/server/tests/billing/update-subscription/multi-product/schedules-from-paid.test.ts b/server/tests/billing/update-subscription/multi-product/schedules-from-paid.test.ts index ed1e6d7f8..6b9d81bd8 100644 --- a/server/tests/billing/update-subscription/multi-product/schedules-from-paid.test.ts +++ b/server/tests/billing/update-subscription/multi-product/schedules-from-paid.test.ts @@ -33,10 +33,12 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: cancel entity 1, update en const { autumnV1, ctx, entities, testClockId } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [pro] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "pro", entityIndex: 0 }), s.attach({ productId: "pro", entityIndex: 1 }), s.cancel({ productId: "pro", entityIndex: 0 }), // Cancel entity 1's pro @@ -132,10 +134,12 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade entity 1, update const { autumnV1, ctx, entities, testClockId } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [premium, pro] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "premium", entityIndex: 0 }), s.attach({ productId: "premium", entityIndex: 1 }), ], @@ -253,10 +257,12 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: annual + monthly downgrade const { autumnV1, ctx, entities, testClockId } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [premiumAnnual, premium, pro] }), s.entities({ count: 3, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "premium-annual", entityIndex: 0 }), s.attach({ productId: "premium", entityIndex: 1 }), s.attach({ productId: "premium", entityIndex: 2 }), @@ -368,10 +374,12 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: update to free item remove const { autumnV1, ctx, entities, testClockId } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [pro] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "pro", entityIndex: 0 }), s.attach({ productId: "pro", entityIndex: 1 }), ], @@ -470,10 +478,12 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade + update to free const { autumnV1, ctx, entities, testClockId } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [premium, pro] }), s.entities({ count: 2, featureId: TestFeature.Users }), + ], + actions: [ s.attach({ productId: "premium", entityIndex: 0 }), s.attach({ productId: "premium", entityIndex: 1 }), ], diff --git a/server/tests/billing/update-subscription/preview-total/preview-proration.test.ts b/server/tests/billing/update-subscription/preview-total/preview-proration.test.ts index 10b302a18..6619edb3a 100644 --- a/server/tests/billing/update-subscription/preview-total/preview-proration.test.ts +++ b/server/tests/billing/update-subscription/preview-total/preview-proration.test.ts @@ -21,9 +21,11 @@ test.concurrent(`${chalk.yellowBright("preview-total: mid-cycle free to paid pro const { autumnV1, advancedTo } = await initScenario({ customerId, - options: [ + setup: [ s.customer({ paymentMethod: "success" }), s.products({ list: [free] }), + ], + actions: [ s.attach({ productId: "free" }), s.advanceTestClock({ days: 15 }), // Mid-cycle ], diff --git a/server/tests/utils/testInitUtils/initScenario.ts b/server/tests/utils/testInitUtils/initScenario.ts index b5cb21c7d..c4c5268f7 100644 --- a/server/tests/utils/testInitUtils/initScenario.ts +++ b/server/tests/utils/testInitUtils/initScenario.ts @@ -247,7 +247,8 @@ const defaultConfig: ScenarioConfig = { * Uses functional composition for flexible configuration. * * @param customerId - Unique identifier used as customer ID and product prefix - * @param options - Array of configuration functions from `s.*` + * @param setup - Configuration functions (customer, products, entities) + * @param actions - Action functions (attach, cancel, advanceTestClock) * @returns autumnV1, autumnV2, ctx, testClockId, customer, entities * * @example @@ -255,9 +256,11 @@ const defaultConfig: ScenarioConfig = { * // Simple test * const { autumnV1, ctx } = await initScenario({ * customerId: "simple-test", - * options: [ + * setup: [ * s.customer({ paymentMethod: "success" }), * s.products({ list: [free] }), + * ], + * actions: [ * s.attach({ productId: "base" }), * ], * }); @@ -265,10 +268,12 @@ const defaultConfig: ScenarioConfig = { * // With entities * const { autumnV1, ctx, entities } = await initScenario({ * customerId: "entity-test", - * options: [ + * setup: [ * s.customer({ paymentMethod: "success" }), * s.products({ list: [pro, free] }), * s.entities({ count: 2, featureId: TestFeature.Users }), + * ], + * actions: [ * s.attach({ productId: "pro", entityIndex: 0 }), * s.attach({ productId: "free", entityIndex: 1 }), * ], @@ -278,13 +283,15 @@ const defaultConfig: ScenarioConfig = { */ export const initScenario = async ({ customerId, - options, + setup, + actions, }: { customerId: string; - options: ConfigFn[]; + setup: ConfigFn[]; + actions: ConfigFn[]; }) => { - // Build config from options - const config = options.reduce((c, fn) => fn(c), defaultConfig); + // Build config from setup and actions + const config = [...setup, ...actions].reduce((c, fn) => fn(c), defaultConfig); // Generate entities from config const generatedEntities = config.entityConfig