wip
This commit is contained in:
@@ -37,6 +37,44 @@ const autumn = new AutumnInt({
|
||||
|
||||
## Common Test Patterns
|
||||
|
||||
### Product IDs - Use Variable References, Not Hardcoded Strings
|
||||
|
||||
When using `initScenario`, products are automatically prefixed with the `customerId`. When referencing product IDs in API calls or assertions, **always use the product variable's `.id` property** instead of hardcoding the prefixed string:
|
||||
|
||||
```typescript
|
||||
const pro = products.pro({ id: "pro", items: [messagesItem] });
|
||||
const premium = constructProduct({ id: "premium", items: [...], type: "premium" });
|
||||
|
||||
const { autumnV1, ctx, entities } = await initScenario({
|
||||
customerId,
|
||||
options: [
|
||||
s.products({ list: [pro, premium] }),
|
||||
s.attach({ productId: "pro", entityIndex: 0 }), // s.attach uses unprefixed ID
|
||||
],
|
||||
});
|
||||
|
||||
// ✅ GOOD - Use product variable's .id (includes prefix automatically)
|
||||
await autumnV1.attach({
|
||||
customer_id: customerId,
|
||||
product_id: pro.id, // Returns prefixed ID like "my-test_pro"
|
||||
entity_id: entities[0].id,
|
||||
});
|
||||
|
||||
await expectProductActive({
|
||||
customer: customerData,
|
||||
productId: premium.id, // Use variable reference
|
||||
});
|
||||
|
||||
// ❌ BAD - Don't hardcode prefixed product IDs
|
||||
await autumnV1.attach({
|
||||
customer_id: customerId,
|
||||
product_id: `${customerId}_pro`, // Avoid hardcoding
|
||||
entity_id: entities[0].id,
|
||||
});
|
||||
```
|
||||
|
||||
**Note:** The `s.attach()` and `s.cancel()` helpers in `initScenario` take the **unprefixed** product ID (e.g., `"pro"`), but direct API calls require the **full prefixed ID** which you get from `pro.id`.
|
||||
|
||||
### Wait for Async Processing
|
||||
```typescript
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
|
||||
@@ -1,418 +0,0 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { expectCustomerFeatureCorrect } from "@tests/billing/utils/expectCustomerFeatureCorrect";
|
||||
import { expectCustomerInvoiceCorrect } from "@tests/billing/utils/expectCustomerInvoiceCorrect";
|
||||
import { expectSubToBeCorrect } from "@tests/merged/mergeUtils/expectSubCorrect";
|
||||
import { TestFeature } from "@tests/setup/v2Features.js";
|
||||
import { items } from "@tests/utils/fixtures/items.js";
|
||||
import { products } from "@tests/utils/fixtures/products.js";
|
||||
import { initTestScenario } from "@tests/utils/testInitUtils/initTestScenario.js";
|
||||
import chalk from "chalk";
|
||||
|
||||
// 1. Adding a monthly base price to free product
|
||||
test.concurrent(`${chalk.yellowBright("free-to-paid: add monthly base price")}`, async () => {
|
||||
const messagesItem = items.monthlyMessages({ includedUsage: 300 });
|
||||
const free = products.base({ items: [messagesItem] });
|
||||
|
||||
const { customerId, autumnV1, ctx } = await initTestScenario({
|
||||
customerId: "f2p-add-base",
|
||||
products: [free],
|
||||
attachProducts: [free.id],
|
||||
customerOptions: {
|
||||
withTestClock: true,
|
||||
attachPm: "success",
|
||||
},
|
||||
});
|
||||
|
||||
await autumnV1.track(
|
||||
{
|
||||
customer_id: customerId,
|
||||
feature_id: TestFeature.Messages,
|
||||
value: 100,
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
|
||||
const priceItem = items.monthlyPrice();
|
||||
|
||||
// Preview should show $20 charge
|
||||
const preview = await autumnV1.subscriptions.previewUpdate({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [messagesItem, priceItem],
|
||||
});
|
||||
|
||||
expect(preview.total).toEqual(20);
|
||||
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [messagesItem, priceItem],
|
||||
});
|
||||
|
||||
const customer = await autumnV1.customers.get(customerId);
|
||||
|
||||
expectCustomerFeatureCorrect({
|
||||
customer,
|
||||
featureId: TestFeature.Messages,
|
||||
includedUsage: messagesItem.included_usage,
|
||||
balance: messagesItem.included_usage - 100,
|
||||
usage: 100,
|
||||
});
|
||||
|
||||
expectCustomerInvoiceCorrect({
|
||||
customer,
|
||||
count: 1,
|
||||
latestTotal: 20,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
db: ctx.db,
|
||||
customerId,
|
||||
org: ctx.org,
|
||||
env: ctx.env,
|
||||
});
|
||||
});
|
||||
|
||||
// 2. Adding monthly base price + consumable to free product
|
||||
test.concurrent(`${chalk.yellowBright("free-to-paid: add monthly base + consumable")}`, async () => {
|
||||
const messagesItem = items.monthlyMessages({ includedUsage: 100 });
|
||||
const free = products.base({ items: [messagesItem] });
|
||||
|
||||
const { customerId, autumnV1, ctx } = await initTestScenario({
|
||||
customerId: "f2p-add-base-cons",
|
||||
products: [free],
|
||||
attachProducts: [free.id],
|
||||
customerOptions: {
|
||||
withTestClock: true,
|
||||
attachPm: "success",
|
||||
},
|
||||
});
|
||||
|
||||
// Track some usage before update
|
||||
const messagesUsage = 30;
|
||||
await autumnV1.track(
|
||||
{
|
||||
customer_id: customerId,
|
||||
feature_id: TestFeature.Messages,
|
||||
value: messagesUsage,
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
|
||||
const priceItem = items.monthlyPrice();
|
||||
const consumableItem = items.consumableMessages({ includedUsage: 50 });
|
||||
|
||||
const preview = await autumnV1.subscriptions.previewUpdate({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [consumableItem, priceItem],
|
||||
});
|
||||
|
||||
expect(preview.total).toEqual(20);
|
||||
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [consumableItem, priceItem],
|
||||
});
|
||||
|
||||
const customer = await autumnV1.customers.get(customerId);
|
||||
|
||||
expectCustomerFeatureCorrect({
|
||||
customer,
|
||||
featureId: TestFeature.Messages,
|
||||
includedUsage: consumableItem.included_usage,
|
||||
balance: consumableItem.included_usage - messagesUsage,
|
||||
usage: messagesUsage,
|
||||
});
|
||||
|
||||
expectCustomerInvoiceCorrect({
|
||||
customer,
|
||||
count: 1,
|
||||
latestTotal: 20,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
db: ctx.db,
|
||||
customerId,
|
||||
org: ctx.org,
|
||||
env: ctx.env,
|
||||
});
|
||||
});
|
||||
|
||||
// 3. Adding annual base price + monthly consumable to free product
|
||||
test.concurrent(`${chalk.yellowBright("free-to-paid: add annual base + monthly consumable")}`, async () => {
|
||||
const messagesItem = items.monthlyMessages({ includedUsage: 100 });
|
||||
const free = products.base({ items: [messagesItem] });
|
||||
|
||||
const { customerId, autumnV1, ctx } = await initTestScenario({
|
||||
customerId: "f2p-add-annual-cons",
|
||||
products: [free],
|
||||
attachProducts: [free.id],
|
||||
customerOptions: {
|
||||
withTestClock: true,
|
||||
attachPm: "success",
|
||||
},
|
||||
});
|
||||
|
||||
const priceItem = items.annualPrice();
|
||||
const consumableItem = items.consumableMessages({ includedUsage: 50 });
|
||||
|
||||
const preview = await autumnV1.subscriptions.previewUpdate({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [consumableItem, priceItem],
|
||||
});
|
||||
|
||||
expect(preview.total).toEqual(200);
|
||||
|
||||
await autumnV1.subscriptions.update(
|
||||
{
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [consumableItem, priceItem],
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
|
||||
const customer = await autumnV1.customers.get(customerId);
|
||||
|
||||
expectCustomerFeatureCorrect({
|
||||
customer,
|
||||
featureId: TestFeature.Messages,
|
||||
includedUsage: consumableItem.included_usage,
|
||||
balance: consumableItem.included_usage,
|
||||
usage: 0,
|
||||
});
|
||||
|
||||
expectCustomerInvoiceCorrect({
|
||||
customer,
|
||||
count: 1,
|
||||
latestTotal: 200,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
db: ctx.db,
|
||||
customerId,
|
||||
org: ctx.org,
|
||||
env: ctx.env,
|
||||
});
|
||||
});
|
||||
|
||||
// 4. Updating free feature item to consumable
|
||||
test.concurrent(`${chalk.yellowBright("free-to-paid: update free item to consumable")}`, async () => {
|
||||
const messagesItem = items.monthlyMessages({ includedUsage: 100 });
|
||||
const free = products.base({ items: [messagesItem] });
|
||||
|
||||
const { customerId, autumnV1, ctx } = await initTestScenario({
|
||||
customerId: "f2p-update-to-cons",
|
||||
products: [free],
|
||||
attachProducts: [free.id],
|
||||
customerOptions: {
|
||||
withTestClock: true,
|
||||
attachPm: "success",
|
||||
},
|
||||
});
|
||||
|
||||
// Track some usage first
|
||||
const messagesUsage = 50;
|
||||
await autumnV1.track(
|
||||
{
|
||||
customer_id: customerId,
|
||||
feature_id: TestFeature.Messages,
|
||||
value: messagesUsage,
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
|
||||
// Update to consumable (pay-per-use after included usage)
|
||||
const consumableItem = items.consumableMessages({ includedUsage: 100 });
|
||||
|
||||
const preview = await autumnV1.subscriptions.previewUpdate({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [consumableItem],
|
||||
});
|
||||
|
||||
// No immediate charge - consumable bills in arrears
|
||||
expect(preview.total).toEqual(0);
|
||||
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [consumableItem],
|
||||
});
|
||||
|
||||
const customer = await autumnV1.customers.get(customerId);
|
||||
|
||||
expectCustomerFeatureCorrect({
|
||||
customer,
|
||||
featureId: TestFeature.Messages,
|
||||
includedUsage: consumableItem.included_usage,
|
||||
balance: consumableItem.included_usage - messagesUsage,
|
||||
usage: messagesUsage,
|
||||
});
|
||||
|
||||
// No invoice - consumable bills in arrears, no immediate charge
|
||||
expectCustomerInvoiceCorrect({
|
||||
customer,
|
||||
count: 0,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
db: ctx.db,
|
||||
customerId,
|
||||
org: ctx.org,
|
||||
env: ctx.env,
|
||||
});
|
||||
});
|
||||
|
||||
// 5. Updating free feature item to prepaid
|
||||
test.concurrent(`${chalk.yellowBright("free-to-paid: update free item to prepaid")}`, async () => {
|
||||
const messagesItem = items.monthlyMessages({ includedUsage: 100 });
|
||||
const free = products.base({ items: [messagesItem] });
|
||||
|
||||
const { customerId, autumnV1, ctx } = await initTestScenario({
|
||||
customerId: "f2p-update-to-prepaid",
|
||||
products: [free],
|
||||
attachProducts: [free.id],
|
||||
customerOptions: {
|
||||
withTestClock: true,
|
||||
attachPm: "success",
|
||||
},
|
||||
});
|
||||
|
||||
// Track some usage first
|
||||
const messagesUsage = 30;
|
||||
await autumnV1.track(
|
||||
{
|
||||
customer_id: customerId,
|
||||
feature_id: TestFeature.Messages,
|
||||
value: messagesUsage,
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
|
||||
// Update to prepaid (purchase units upfront)
|
||||
const prepaidItem = items.prepaidMessages();
|
||||
|
||||
const preview = await autumnV1.subscriptions.previewUpdate({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [prepaidItem],
|
||||
});
|
||||
|
||||
// No immediate charge for switching to prepaid model
|
||||
expect(preview.total).toEqual(0);
|
||||
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [prepaidItem],
|
||||
options: [
|
||||
{
|
||||
feature_id: TestFeature.Messages,
|
||||
quantity: 100,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const customer = await autumnV1.customers.get(customerId);
|
||||
|
||||
expectCustomerFeatureCorrect({
|
||||
customer,
|
||||
featureId: TestFeature.Messages,
|
||||
includedUsage: 100,
|
||||
balance: 100 - messagesUsage,
|
||||
usage: messagesUsage,
|
||||
});
|
||||
|
||||
// Prepaid charges upfront - $10 for 100 units
|
||||
expectCustomerInvoiceCorrect({
|
||||
customer,
|
||||
count: 1,
|
||||
latestTotal: 10,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
db: ctx.db,
|
||||
customerId,
|
||||
org: ctx.org,
|
||||
env: ctx.env,
|
||||
});
|
||||
});
|
||||
|
||||
// 6. Updating free users to allocated users
|
||||
test.concurrent(`${chalk.yellowBright("free-to-paid: update free users to allocated")}`, async () => {
|
||||
const usersItem = items.monthlyUsers({ includedUsage: 5 });
|
||||
const free = products.base({ items: [usersItem] });
|
||||
|
||||
const { customerId, autumnV1, ctx } = await initTestScenario({
|
||||
customerId: "f2p-free-to-allocated",
|
||||
products: [free],
|
||||
attachProducts: [free.id],
|
||||
customerOptions: {
|
||||
withTestClock: true,
|
||||
attachPm: "success",
|
||||
},
|
||||
});
|
||||
|
||||
// Use some users (continuous use feature)
|
||||
const usersUsed = 3;
|
||||
await autumnV1.track(
|
||||
{
|
||||
customer_id: customerId,
|
||||
feature_id: TestFeature.Users,
|
||||
value: usersUsed,
|
||||
},
|
||||
{ timeout: 2000 },
|
||||
);
|
||||
|
||||
// Verify initial state
|
||||
const initialCustomer = await autumnV1.customers.get(customerId);
|
||||
expect(initialCustomer.features[TestFeature.Users].balance).toEqual(
|
||||
usersItem.included_usage - usersUsed,
|
||||
);
|
||||
|
||||
// Update to allocated users ($10/seat prorated billing)
|
||||
const allocatedUsersItem = items.allocatedUsers({ includedUsage: 2 });
|
||||
|
||||
const preview = await autumnV1.subscriptions.previewUpdate({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [allocatedUsersItem],
|
||||
});
|
||||
|
||||
// Should charge for (usersUsed - includedUsage) extra seats = (3 - 2) = 1 seat @ $10
|
||||
expect(preview.total).toEqual(10);
|
||||
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
product_id: free.id,
|
||||
items: [allocatedUsersItem],
|
||||
});
|
||||
|
||||
const customer = await autumnV1.customers.get(customerId);
|
||||
|
||||
expectCustomerFeatureCorrect({
|
||||
customer,
|
||||
featureId: TestFeature.Users,
|
||||
includedUsage: allocatedUsersItem.included_usage,
|
||||
balance: allocatedUsersItem.included_usage - usersUsed,
|
||||
usage: usersUsed,
|
||||
});
|
||||
|
||||
// Invoice for the extra seat
|
||||
expectCustomerInvoiceCorrect({
|
||||
customer,
|
||||
count: 1,
|
||||
latestTotal: 10,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
db: ctx.db,
|
||||
customerId,
|
||||
org: ctx.org,
|
||||
env: ctx.env,
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,95 @@ import { products } from "@tests/utils/fixtures/products.js";
|
||||
import { initScenario, s } from "@tests/utils/testInitUtils/initScenario.js";
|
||||
import chalk from "chalk";
|
||||
|
||||
// 1. Entity 1 has paid sub, entity 2 upgrades free to paid
|
||||
// 1. Entity 1 pro, Entity 2 free - Entity 2 updates free items (stays free)
|
||||
test.concurrent(`${chalk.yellowBright("multi-entity-from-free: update free items")}`, async () => {
|
||||
const customerId = "multi-ent-update-free";
|
||||
|
||||
const messagesItem = items.monthlyMessages({ includedUsage: 100 });
|
||||
|
||||
const pro = products.pro({
|
||||
id: "pro",
|
||||
items: [messagesItem],
|
||||
});
|
||||
|
||||
const free = products.base({
|
||||
id: "free",
|
||||
items: [messagesItem],
|
||||
});
|
||||
|
||||
const { autumnV1, ctx, entities } = await initScenario({
|
||||
customerId,
|
||||
options: [
|
||||
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 }),
|
||||
],
|
||||
});
|
||||
|
||||
// Verify entity 2 starts with 100 included usage
|
||||
const entity2Before = await autumnV1.entities.get(customerId, entities[1].id);
|
||||
await expectProductActive({ customer: entity2Before, productId: free.id });
|
||||
expectCustomerFeatureCorrect({
|
||||
customer: entity2Before,
|
||||
featureId: TestFeature.Messages,
|
||||
includedUsage: 100,
|
||||
balance: 100,
|
||||
usage: 0,
|
||||
});
|
||||
|
||||
// Entity 2 updates free product to have more included usage (still free)
|
||||
const updatedMessagesItem = items.monthlyMessages({ includedUsage: 200 });
|
||||
|
||||
const preview = await autumnV1.subscriptions.previewUpdate({
|
||||
customer_id: customerId,
|
||||
entity_id: entities[1].id,
|
||||
product_id: free.id,
|
||||
items: [updatedMessagesItem],
|
||||
});
|
||||
|
||||
// Should be $0 since it's still a free product
|
||||
expect(preview.total).toEqual(0);
|
||||
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
entity_id: entities[1].id,
|
||||
product_id: free.id,
|
||||
items: [updatedMessagesItem],
|
||||
});
|
||||
|
||||
// Verify entity 2 has updated included usage
|
||||
const entity2After = await autumnV1.entities.get(customerId, entities[1].id);
|
||||
await expectProductActive({ customer: entity2After, productId: free.id });
|
||||
expectCustomerFeatureCorrect({
|
||||
customer: entity2After,
|
||||
featureId: TestFeature.Messages,
|
||||
includedUsage: 200,
|
||||
balance: 200,
|
||||
usage: 0,
|
||||
});
|
||||
|
||||
// Verify only 1 invoice (from entity1's pro attachment)
|
||||
const customer = await autumnV1.customers.get(customerId);
|
||||
expectCustomerInvoiceCorrect({
|
||||
customer,
|
||||
count: 1,
|
||||
latestTotal: 20, // Only entity 1's pro
|
||||
});
|
||||
|
||||
// Should still have 1 subscription (entity 1's pro)
|
||||
await expectSubToBeCorrect({
|
||||
db: ctx.db,
|
||||
customerId,
|
||||
org: ctx.org,
|
||||
env: ctx.env,
|
||||
entityId: entities[0].id,
|
||||
subCount: 1,
|
||||
});
|
||||
});
|
||||
|
||||
// 2. Entity 1 has paid sub, entity 2 upgrades free to paid
|
||||
test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: entity 2 upgrades free to paid")}`, async () => {
|
||||
const customerId = "multi-ent-free-to-paid";
|
||||
|
||||
@@ -87,7 +175,7 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: entity 2 upgra
|
||||
});
|
||||
});
|
||||
|
||||
// 2. Free to paid with base price + consumable + prepaid
|
||||
// 3. Free to paid with base price + consumable + prepaid
|
||||
test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: base + consumable + prepaid")}`, async () => {
|
||||
const customerId = "multi-ent-f2p-combo";
|
||||
|
||||
@@ -182,7 +270,7 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: base + consuma
|
||||
});
|
||||
});
|
||||
|
||||
// 3. Free to paid with annual price
|
||||
// 4. Free to paid with annual price
|
||||
test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: annual price")}`, async () => {
|
||||
const customerId = "multi-ent-f2p-annual";
|
||||
|
||||
@@ -260,7 +348,7 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: annual price")
|
||||
});
|
||||
});
|
||||
|
||||
// 4. Free to paid with annual price MID-CYCLE
|
||||
// 5. Free to paid with annual price MID-CYCLE
|
||||
test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: annual mid-cycle")}`, async () => {
|
||||
const customerId = "multi-ent-f2p-annual-mid";
|
||||
|
||||
@@ -340,7 +428,7 @@ test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: annual mid-cyc
|
||||
});
|
||||
});
|
||||
|
||||
// 5. Monthly price mid-cycle (existing test)
|
||||
// 6. Monthly price mid-cycle
|
||||
test.concurrent(`${chalk.yellowBright("multi-entity-free-to-paid: monthly mid-cycle")}`, async () => {
|
||||
const customerId = "multi-ent-f2p-midcycle";
|
||||
|
||||
@@ -50,7 +50,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: cancel entity 1, update en
|
||||
);
|
||||
await expectProductCanceled({
|
||||
customer: entity1AfterCancel,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
|
||||
// Entity 2 updates pro's items (change price)
|
||||
@@ -59,7 +59,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: cancel entity 1, update en
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
entity_id: entities[1].id,
|
||||
product_id: `${customerId}_pro`,
|
||||
product_id: pro.id,
|
||||
items: [messagesItem, newPriceItem],
|
||||
});
|
||||
|
||||
@@ -67,7 +67,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: cancel entity 1, update en
|
||||
const entity2Data = await autumnV1.entities.get(customerId, entities[1].id);
|
||||
await expectProductActive({
|
||||
customer: entity2Data,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
@@ -96,11 +96,11 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: cancel entity 1, update en
|
||||
|
||||
await expectProductNotPresent({
|
||||
customer: entity1AfterCycle,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
await expectProductActive({
|
||||
customer: entity2AfterCycle,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
@@ -144,7 +144,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade entity 1, update
|
||||
// Entity 1 downgrades from Premium to Pro (scheduled)
|
||||
await autumnV1.attach({
|
||||
customer_id: customerId,
|
||||
product_id: `${customerId}_pro`,
|
||||
product_id: pro.id,
|
||||
entity_id: entities[0].id,
|
||||
});
|
||||
|
||||
@@ -164,7 +164,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade entity 1, update
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
entity_id: entities[1].id,
|
||||
product_id: `${customerId}_premium`,
|
||||
product_id: premium.id,
|
||||
items: [consumableItem, newPriceItem],
|
||||
});
|
||||
|
||||
@@ -172,7 +172,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade entity 1, update
|
||||
const entity2Data = await autumnV1.entities.get(customerId, entities[1].id);
|
||||
await expectProductActive({
|
||||
customer: entity2Data,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
@@ -202,15 +202,15 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade entity 1, update
|
||||
|
||||
await expectProductNotPresent({
|
||||
customer: entity1AfterCycle,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
await expectProductActive({
|
||||
customer: entity1AfterCycle,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
await expectProductActive({
|
||||
customer: entity2AfterCycle,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
@@ -266,14 +266,14 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: annual + monthly downgrade
|
||||
// Entity 1 downgrades from Premium Annual to Pro (scheduled for end of annual period)
|
||||
await autumnV1.attach({
|
||||
customer_id: customerId,
|
||||
product_id: `${customerId}_pro`,
|
||||
product_id: pro.id,
|
||||
entity_id: entities[0].id,
|
||||
});
|
||||
|
||||
// Entity 2 downgrades from Premium Monthly to Pro (scheduled for end of month)
|
||||
await autumnV1.attach({
|
||||
customer_id: customerId,
|
||||
product_id: `${customerId}_pro`,
|
||||
product_id: pro.id,
|
||||
entity_id: entities[1].id,
|
||||
});
|
||||
|
||||
@@ -284,7 +284,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: annual + monthly downgrade
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
entity_id: entities[2].id,
|
||||
product_id: `${customerId}_premium`,
|
||||
product_id: premium.id,
|
||||
items: [newConsumable, newPriceItem],
|
||||
});
|
||||
|
||||
@@ -292,7 +292,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: annual + monthly downgrade
|
||||
const entity3Data = await autumnV1.entities.get(customerId, entities[2].id);
|
||||
await expectProductActive({
|
||||
customer: entity3Data,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
@@ -328,23 +328,23 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: annual + monthly downgrade
|
||||
// Entity 1 should still have premium-annual (annual cycle not over)
|
||||
await expectProductActive({
|
||||
customer: entity1AfterCycle,
|
||||
productId: `${customerId}_premium-annual`,
|
||||
productId: premiumAnnual.id,
|
||||
});
|
||||
|
||||
// Entity 2 should be on pro now
|
||||
await expectProductNotPresent({
|
||||
customer: entity2AfterCycle,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
await expectProductActive({
|
||||
customer: entity2AfterCycle,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
|
||||
// Entity 3 should still have premium
|
||||
await expectProductActive({
|
||||
customer: entity3AfterCycle,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
@@ -382,18 +382,18 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: update to free item remove
|
||||
const entity2Before = await autumnV1.entities.get(customerId, entities[1].id);
|
||||
await expectProductActive({
|
||||
customer: entity1Before,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
await expectProductActive({
|
||||
customer: entity2Before,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
|
||||
// Entity 2 updates Pro's items to be free (no price items, only feature)
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
entity_id: entities[1].id,
|
||||
product_id: `${customerId}_pro`,
|
||||
product_id: pro.id,
|
||||
items: [messagesItem], // Only messages, no price - makes it free
|
||||
});
|
||||
|
||||
@@ -401,7 +401,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: update to free item remove
|
||||
const entity2Data = await autumnV1.entities.get(customerId, entities[1].id);
|
||||
await expectProductActive({
|
||||
customer: entity2Data,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
|
||||
// Should only have 1 subscription (entity 1's pro)
|
||||
@@ -432,11 +432,11 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: update to free item remove
|
||||
|
||||
await expectProductActive({
|
||||
customer: entity1AfterCycle,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
await expectProductActive({
|
||||
customer: entity2AfterCycle,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
@@ -482,7 +482,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade + update to free
|
||||
// Entity 1 downgrades from Premium to Pro (scheduled)
|
||||
await autumnV1.attach({
|
||||
customer_id: customerId,
|
||||
product_id: `${customerId}_pro`,
|
||||
product_id: pro.id,
|
||||
entity_id: entities[0].id,
|
||||
});
|
||||
|
||||
@@ -500,7 +500,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade + update to free
|
||||
await autumnV1.subscriptions.update({
|
||||
customer_id: customerId,
|
||||
entity_id: entities[1].id,
|
||||
product_id: `${customerId}_premium`,
|
||||
product_id: premium.id,
|
||||
items: [consumableItem], // Only consumable, no base price - makes it free
|
||||
});
|
||||
|
||||
@@ -508,7 +508,7 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade + update to free
|
||||
const entity2Data = await autumnV1.entities.get(customerId, entities[1].id);
|
||||
await expectProductActive({
|
||||
customer: entity2Data,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
@@ -539,15 +539,15 @@ test.concurrent(`${chalk.yellowBright("schedules-p2p: downgrade + update to free
|
||||
|
||||
await expectProductNotPresent({
|
||||
customer: entity1AfterCycle,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
await expectProductActive({
|
||||
customer: entity1AfterCycle,
|
||||
productId: `${customerId}_pro`,
|
||||
productId: pro.id,
|
||||
});
|
||||
await expectProductActive({
|
||||
customer: entity2AfterCycle,
|
||||
productId: `${customerId}_premium`,
|
||||
productId: premium.id,
|
||||
});
|
||||
|
||||
await expectSubToBeCorrect({
|
||||
|
||||
Reference in New Issue
Block a user