Files
cfw-autumn/server/tests/integration/billing/attach/errors/attach-custom-plan-errors.test.ts
2026-03-02 21:06:47 +00:00

105 lines
3.3 KiB
TypeScript

/**
* Custom Plan Error Tests (Attach V2)
*
* Tests for validation errors when using the `items` parameter in billing.attach.
*
* Key behaviors:
* - Empty items array is rejected
* - Same configuration as product is rejected (no change)
* - Invalid feature ID is rejected
* - Prepaid without quantity is rejected
*/
import { test } from "bun:test";
import { expectAutumnError } from "@tests/utils/expectUtils/expectErrUtils";
import { items } from "@tests/utils/fixtures/items";
import { products } from "@tests/utils/fixtures/products";
import { initScenario, s } from "@tests/utils/testInitUtils/initScenario";
import chalk from "chalk";
import { constructFeatureItem } from "@/utils/scriptUtils/constructItem";
// ═══════════════════════════════════════════════════════════════════════════════
// CUSTOM PLAN ATTACH ERRORS
// ═══════════════════════════════════════════════════════════════════════════════
/**
* Test 2: Same configuration as product is rejected
*
* Scenario:
* - Customer on Pro
* - Attach same Pro with identical items
*
* Expected:
* - Error: No changes to apply / already has product
*/
test.concurrent(`${chalk.yellowBright("error: attach custom plan same config as existing")}`, async () => {
const customerId = "err-custom-plan-same-config";
const messagesItem = items.monthlyMessages({ includedUsage: 100 });
const priceItem = items.monthlyPrice({ price: 20 });
const pro = products.base({ id: "pro", items: [messagesItem, priceItem] });
const { autumnV1 } = await initScenario({
customerId,
setup: [
s.customer({ paymentMethod: "success" }),
s.products({ list: [pro] }),
],
actions: [s.billing.attach({ productId: pro.id })],
});
// Try to attach same product with same items
await expectAutumnError({
func: async () => {
await autumnV1.billing.attach({
customer_id: customerId,
product_id: pro.id,
items: [messagesItem, priceItem], // Same as product
redirect_mode: "if_required",
});
},
});
});
/**
* Test 3: Invalid feature ID is rejected
*
* Scenario:
* - Attach with items referencing non-existent feature
*
* Expected:
* - Error: Feature not found
*/
test.concurrent(`${chalk.yellowBright("error: attach custom plan invalid feature id")}`, async () => {
const customerId = "err-custom-plan-invalid-feature";
const messagesItem = items.monthlyMessages({ includedUsage: 100 });
const pro = products.base({ id: "pro", items: [messagesItem] });
const { autumnV1 } = await initScenario({
customerId,
setup: [
s.customer({ paymentMethod: "success" }),
s.products({ list: [pro] }),
],
actions: [],
});
// Create item with invalid feature ID
const invalidFeatureItem = constructFeatureItem({
featureId: "non_existent_feature_12345",
includedUsage: 100,
});
await expectAutumnError({
func: async () => {
await autumnV1.billing.attach({
customer_id: customerId,
product_id: pro.id,
items: [invalidFeatureItem],
redirect_mode: "if_required",
});
},
});
});