211 lines
5.5 KiB
TypeScript
211 lines
5.5 KiB
TypeScript
import { ApiVersion, CusProductStatus, type Customer } from "@autumn/shared";
|
|
import { expect } from "chai";
|
|
import chalk from "chalk";
|
|
import { addDays, addHours } from "date-fns";
|
|
import type Stripe from "stripe";
|
|
import { AutumnCli } from "@tests/cli/AutumnCli.js";
|
|
import { compareMainProduct } from "@tests/utils/compare.js";
|
|
import { hoursToFinalizeInvoice } from "@tests/utils/constants.js";
|
|
import { timeout } from "@tests/utils/genUtils.js";
|
|
import { advanceTestClock } from "@tests/utils/stripeUtils.js";
|
|
import { AutumnInt } from "@/external/autumn/autumnCli.js";
|
|
import { createStripeCli } from "@/external/connect/createStripeCli.js";
|
|
import { attachFailedPaymentMethod } from "@/external/stripe/stripeCusUtils.js";
|
|
import { initCustomerV2 } from "@/utils/scriptUtils/initCustomer.js";
|
|
import { alexProducts } from "./init.js";
|
|
|
|
// CANCEL AT
|
|
const getProductFromCusRes = ({
|
|
cusRes,
|
|
productId,
|
|
}: {
|
|
cusRes: any;
|
|
productId: string;
|
|
}) => {
|
|
return cusRes.products.find((p: any) => p.id === productId);
|
|
};
|
|
|
|
describe(chalk.yellowBright("05_cancel"), () => {
|
|
const autumn = new AutumnInt({ version: ApiVersion.V1_2 });
|
|
describe("Testing cancel_at_period_end and cancel now", () => {
|
|
let stripeCli: Stripe;
|
|
const customerId = "alex-cancel-customer";
|
|
const autumn: AutumnInt = new AutumnInt({ version: ApiVersion.V1_2 });
|
|
|
|
before("initializing customer", async function () {
|
|
stripeCli = createStripeCli({
|
|
org: this.org,
|
|
env: this.env,
|
|
});
|
|
|
|
await initCustomerV2({
|
|
autumn,
|
|
customerId,
|
|
org: this.org,
|
|
env: this.env,
|
|
db: this.db,
|
|
attachPm: "success",
|
|
});
|
|
});
|
|
|
|
it("should attach pro product ", async () => {
|
|
const result = await AutumnCli.attach({
|
|
customerId,
|
|
productId: alexProducts.pro.id,
|
|
});
|
|
|
|
const cusRes = await AutumnCli.getCustomer(customerId);
|
|
compareMainProduct({
|
|
sent: alexProducts.pro,
|
|
cusRes,
|
|
status: CusProductStatus.Trialing,
|
|
});
|
|
});
|
|
|
|
it("should cancel at period end", async () => {
|
|
// 1. Get pro product
|
|
const cusRes = await AutumnCli.getCustomer(customerId);
|
|
const proProduct = getProductFromCusRes({
|
|
cusRes,
|
|
productId: alexProducts.pro.id,
|
|
});
|
|
|
|
for (const subId of proProduct.subscription_ids) {
|
|
await stripeCli.subscriptions.update(subId, {
|
|
cancel_at_period_end: true,
|
|
});
|
|
}
|
|
|
|
await timeout(5000);
|
|
|
|
const newCusRes = await AutumnCli.getCustomer(customerId);
|
|
const newProProduct = getProductFromCusRes({
|
|
cusRes: newCusRes,
|
|
productId: alexProducts.pro.id,
|
|
});
|
|
|
|
expect(newProProduct).to.exist;
|
|
expect(newProProduct.canceled_at).to.not.equal(null);
|
|
expect(newProProduct.status).to.equal(CusProductStatus.Trialing);
|
|
});
|
|
|
|
it("should cancel now", async () => {
|
|
const cusRes = await AutumnCli.getCustomer(customerId);
|
|
const proProduct = getProductFromCusRes({
|
|
cusRes,
|
|
productId: alexProducts.pro.id,
|
|
});
|
|
|
|
for (const subId of proProduct.subscription_ids) {
|
|
await stripeCli.subscriptions.cancel(subId);
|
|
}
|
|
|
|
await timeout(5000);
|
|
|
|
const newCusRes = await AutumnCli.getCustomer(customerId);
|
|
const newProProduct = getProductFromCusRes({
|
|
cusRes: newCusRes,
|
|
productId: alexProducts.pro.id,
|
|
});
|
|
|
|
expect(newProProduct).to.not.exist;
|
|
|
|
const freeProduct = getProductFromCusRes({
|
|
cusRes: newCusRes,
|
|
productId: alexProducts.free.id,
|
|
});
|
|
|
|
expect(freeProduct).to.exist;
|
|
expect(freeProduct.status).to.equal(CusProductStatus.Active);
|
|
});
|
|
});
|
|
|
|
describe("Testing past due", () => {
|
|
const customerId = "alex-past-due-customer";
|
|
let customer: Customer;
|
|
let testClockId: string;
|
|
let stripeCli: Stripe;
|
|
before("initializing customer", async function () {
|
|
stripeCli = createStripeCli({
|
|
org: this.org,
|
|
env: this.env,
|
|
});
|
|
|
|
const res = await initCustomerV2({
|
|
autumn,
|
|
customerId,
|
|
org: this.org,
|
|
env: this.env,
|
|
db: this.db,
|
|
attachPm: "success",
|
|
});
|
|
|
|
testClockId = res.testClockId;
|
|
customer = res.customer;
|
|
});
|
|
|
|
it("should attach pro product ", async () => {
|
|
await AutumnCli.attach({
|
|
customerId,
|
|
productId: alexProducts.pro.id,
|
|
});
|
|
await timeout(5000);
|
|
|
|
const cusRes = await AutumnCli.getCustomer(customerId);
|
|
compareMainProduct({
|
|
sent: alexProducts.pro,
|
|
cusRes,
|
|
status: CusProductStatus.Trialing,
|
|
});
|
|
});
|
|
|
|
it("should attach failed card", async () => {
|
|
await attachFailedPaymentMethod({ stripeCli, customer });
|
|
});
|
|
|
|
it("should advance clock to next cycle", async () => {
|
|
await advanceTestClock({
|
|
stripeCli,
|
|
testClockId,
|
|
advanceTo: addHours(
|
|
addDays(new Date(), 7),
|
|
hoursToFinalizeInvoice,
|
|
).getTime(),
|
|
});
|
|
|
|
await timeout(5000);
|
|
});
|
|
|
|
// // TODO: Edit so that it doesn't auto cancel for unit test org
|
|
// it("should have expired / past_dued pro product", async function () {
|
|
// const cusRes = await AutumnCli.getCustomer(customerId);
|
|
|
|
// let org = this.org;
|
|
|
|
// console.log("Cancel on past due:", org.config.cancel_on_past_due);
|
|
// if (org.config.cancel_on_past_due) {
|
|
// const proProduct = getProductFromCusRes({
|
|
// cusRes,
|
|
// productId: alexProducts.pro.id,
|
|
// });
|
|
|
|
// expect(proProduct).to.not.exist;
|
|
|
|
// const freeProduct = getProductFromCusRes({
|
|
// cusRes,
|
|
// productId: alexProducts.free.id,
|
|
// });
|
|
|
|
// expect(freeProduct).to.exist;
|
|
// expect(freeProduct.status).to.equal(CusProductStatus.Active);
|
|
// } else {
|
|
// compareMainProduct({
|
|
// sent: alexProducts.pro,
|
|
// cusRes,
|
|
// status: CusProductStatus.PastDue,
|
|
// });
|
|
// }
|
|
// });
|
|
});
|
|
});
|