Files
cfw-autumn/server/tests/alex/04_topups.ts
2025-11-11 18:04:55 +00:00

220 lines
5.9 KiB
TypeScript

import {
AllowanceType,
ApiVersion,
CusProductStatus,
EntInterval,
type Entitlement,
} from "@autumn/shared";
import { expect } from "chai";
import chalk from "chalk";
import { AutumnCli } from "@tests/cli/AutumnCli.js";
import { compareMainProduct } from "@tests/utils/compare.js";
import { timeout } from "@tests/utils/genUtils.js";
import { completeCheckoutForm } from "@tests/utils/stripeUtils.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { initCustomerV2 } from "@/utils/scriptUtils/initCustomer.js";
import { alexFeatures, alexProducts } from "./init.js";
import {
checkFeatureHasCorrectBalance,
runEventsAndCheckBalances,
} from "./utils.js";
const autumn = new AutumnInt({ version: ApiVersion.V1_2 });
describe(chalk.yellowBright("Top ups"), () => {
const customerId = "alex-top-up-customer";
before("initializing customer", async function () {
await initCustomerV2({
autumn,
customerId,
org: this.org,
env: this.env,
db: this.db,
attachPm: "success",
});
// await initCustomer({
// customer_data: {
// id: customerId,
// name: "Alex Top Up Customer",
// email: "alex-top-up-customer@test.com",
// },
// db: this.db,
// org: this.org,
// env: this.env,
// attachPm: true,
// });
});
it("should attach pro product", async () => {
await timeout(5000);
await AutumnCli.attach({
customerId,
productId: alexProducts.pro.id,
});
const cusRes = await AutumnCli.getCustomer(customerId);
compareMainProduct({
sent: alexProducts.pro,
cusRes,
status: CusProductStatus.Trialing,
});
});
const overrideQuantity = 5;
const billingUnits =
alexProducts.topUpMessages.prices[0].config.billing_units;
const prodEnt = alexProducts.topUpMessages.entitlements.topUpMessage;
let leftoverBalance = 0;
it("should attach top up messages through force checkout", async () => {
const res = await AutumnCli.attach({
customerId,
productId: alexProducts.topUpMessages.id,
forceCheckout: true,
});
await completeCheckoutForm(res.checkout_url, overrideQuantity);
await timeout(10000);
const cusRes = await AutumnCli.getCustomer(customerId);
// Get product
const product = cusRes.add_ons.find(
(p: any) => p.id === alexProducts.topUpMessages.id,
);
expect(product).to.exist;
expect(product.status).to.equal(CusProductStatus.Active);
// Check quantity is correct
const cusEnt = cusRes.entitlements.find(
(e: any) => e.feature_id === alexFeatures.topUpMessage.id,
);
expect(cusEnt).to.exist;
expect(cusEnt.balance).to.equal(overrideQuantity * billingUnits);
expect(cusEnt.interval).to.equal(prodEnt.interval);
});
// Try buy again
it("should buy top ups again and have correct balance", async () => {
// 1. Update leftover balance
const { allowed, balanceObj }: any = await AutumnCli.entitled(
customerId,
alexFeatures.topUpMessage.id,
true,
);
leftoverBalance = balanceObj.balance;
const res = await AutumnCli.attach({
customerId,
productId: alexProducts.topUpMessages.id,
forceCheckout: true,
});
await completeCheckoutForm(res.checkout_url, overrideQuantity);
await timeout(10000);
const cusRes = await AutumnCli.getCustomer(customerId);
// Get product
const product = cusRes.add_ons.find(
(p: any) => p.id === alexProducts.topUpMessages.id,
);
expect(product).to.exist;
expect(product.status).to.equal(CusProductStatus.Active);
// Check quantity is correct
const cusEnt = cusRes.entitlements.find(
(e: any) => e.feature_id === alexFeatures.topUpMessage.id,
);
expect(cusEnt).to.exist;
expect(cusEnt.balance).to.equal(
leftoverBalance + overrideQuantity * billingUnits,
);
expect(cusEnt.interval).to.equal(prodEnt.interval);
});
});
describe(chalk.yellowBright("Testing o1 message top up"), () => {
const customerId = "alex-o1-top-up-customer";
const o1TopUpQuantity = Math.floor(Math.random() * 15);
const billingUnits = alexProducts.o1TopUps.prices[0].config.billing_units;
const proAllowance = alexProducts.pro.entitlements.o1Message.allowance!;
before("initializing customer", async function () {
await initCustomerV2({
autumn,
customerId,
org: this.org,
env: this.env,
db: this.db,
attachPm: "success",
});
// await initCustomer({
// customer_data: {
// id: customerId,
// name: "Alex O1 Top Up Customer",
// email: "alex-o1-top-up-customer@test.com",
// },
// db: this.db,
// org: this.org,
// env: this.env,
// attachPm: true,
// });
});
it("should attach pro product", async () => {
await AutumnCli.attach({
customerId,
productId: alexProducts.pro.id,
});
const cusRes = await AutumnCli.getCustomer(customerId);
compareMainProduct({
sent: alexProducts.pro,
cusRes,
status: CusProductStatus.Trialing,
});
});
it("should buy o1 messages and have correct balance", async () => {
const res = await AutumnCli.attach({
customerId,
productId: alexProducts.o1TopUps.id,
forceCheckout: true,
});
await completeCheckoutForm(res.checkout_url, o1TopUpQuantity);
await timeout(14000);
const cusRes = await AutumnCli.getCustomer(customerId);
// Get product
const product = cusRes.add_ons.find(
(p: any) => p.id === alexProducts.o1TopUps.id,
);
expect(product).to.exist;
expect(product.status).to.equal(CusProductStatus.Active);
// Check quantity is correct
await checkFeatureHasCorrectBalance({
customerId,
feature: alexFeatures.o1Message,
entitlement: alexProducts.o1TopUps.entitlements.o1Message,
expectedBalance: o1TopUpQuantity * billingUnits + proAllowance,
});
});
it("should send events and check balances", async () => {
const allowance = o1TopUpQuantity * billingUnits + proAllowance;
await runEventsAndCheckBalances({
customerId,
entitlements: [
{
interval: EntInterval.Lifetime,
feature_id: alexFeatures.o1Message.id,
allowance,
allowance_type: AllowanceType.Fixed,
} as Entitlement, // manual entitlement because in advance pricing
],
});
});
});