212 lines
5.8 KiB
TypeScript
212 lines
5.8 KiB
TypeScript
import { createStripeCli } from "@/external/stripe/utils.js";
|
|
import { AutumnCli } from "../cli/AutumnCli.js";
|
|
import { features, products } from "../global.js";
|
|
import { initCustomer } from "../utils/init.js";
|
|
import { timeout } from "../utils/genUtils.js";
|
|
import chalk from "chalk";
|
|
import {
|
|
checkFeatureHasCorrectBalance,
|
|
compareMainProduct,
|
|
compareProductEntitlements,
|
|
} from "../utils/compare.js";
|
|
import { expect } from "chai";
|
|
import {
|
|
advanceTestClock,
|
|
completeCheckoutForm,
|
|
} from "../utils/stripeUtils.js";
|
|
import { CusProductStatus } from "@autumn/shared";
|
|
import { attachFailedPaymentMethod } from "@/external/stripe/stripeCusUtils.js";
|
|
import { addDays, addMonths } from "date-fns";
|
|
|
|
describe(`${chalk.yellowBright(
|
|
"03_cancel: Testing cancel (at period end and now)",
|
|
)}`, () => {
|
|
const customerId = "cancelCustomer";
|
|
|
|
before(async function () {
|
|
this.timeout(30000);
|
|
|
|
await initCustomer({
|
|
customer_data: {
|
|
id: customerId,
|
|
name: "Test Customer",
|
|
email: "test@test.com",
|
|
},
|
|
db: this.db,
|
|
org: this.org,
|
|
env: this.env,
|
|
});
|
|
});
|
|
|
|
it("should attach pro product", async function () {
|
|
this.timeout(30000);
|
|
|
|
const res: any = await AutumnCli.attach({
|
|
customerId: customerId,
|
|
productId: products.pro.id,
|
|
});
|
|
|
|
await completeCheckoutForm(res.checkout_url);
|
|
await timeout(5000);
|
|
console.log(` ${chalk.greenBright("Attached pro product")}`);
|
|
});
|
|
|
|
// 1. Cancel pro product
|
|
it("should cancel pro product (at period end)", async function () {
|
|
this.timeout(10000);
|
|
|
|
const stripeCli = createStripeCli({ org: this.org, env: this.env });
|
|
|
|
// 1. Cancel pro product
|
|
const cusRes: any = await AutumnCli.getCustomer(customerId);
|
|
|
|
const proProduct = cusRes.products.find(
|
|
(p: any) => p.id === products.pro.id,
|
|
);
|
|
|
|
for (const subId of proProduct.subscription_ids) {
|
|
await stripeCli.subscriptions.update(subId, {
|
|
cancel_at_period_end: true,
|
|
});
|
|
}
|
|
|
|
await timeout(3000);
|
|
console.log(` ${chalk.greenBright("Cancelled pro product")}`);
|
|
});
|
|
|
|
it("should have pro product active, and canceled_at != null", async function () {
|
|
this.timeout(10000);
|
|
|
|
const cusRes: any = await AutumnCli.getCustomer(customerId);
|
|
compareMainProduct({
|
|
sent: products.pro,
|
|
cusRes: cusRes,
|
|
});
|
|
|
|
const proProduct = cusRes.products.find(
|
|
(p: any) => p.id === products.pro.id,
|
|
);
|
|
expect(proProduct.canceled_at).to.not.equal(null);
|
|
expect(proProduct.status).to.equal(CusProductStatus.Active);
|
|
});
|
|
|
|
// CANCEL SUB NOW, SUBSCRIPTION.DELETED WEBHOOK
|
|
it("should cancel pro product (now)", async function () {
|
|
this.timeout(10000);
|
|
|
|
const stripeCli = createStripeCli({ org: this.org, env: this.env });
|
|
|
|
const cusRes: any = await AutumnCli.getCustomer(customerId);
|
|
const proProduct = cusRes.products.find(
|
|
(p: any) => p.id === products.pro.id,
|
|
);
|
|
|
|
for (const subId of proProduct.subscription_ids) {
|
|
await stripeCli.subscriptions.cancel(subId);
|
|
}
|
|
|
|
await timeout(3000);
|
|
console.log(` ${chalk.greenBright("Cancelled pro product now")}`);
|
|
});
|
|
|
|
it("should have free product active, and pro product not returned", async function () {
|
|
this.timeout(10000);
|
|
|
|
const cusRes: any = await AutumnCli.getCustomer(customerId);
|
|
compareMainProduct({
|
|
sent: products.free,
|
|
cusRes: cusRes,
|
|
});
|
|
});
|
|
|
|
it("should have correct entitlements (for free)", async function () {
|
|
for (const entitlement of Object.values(products.free.entitlements)) {
|
|
let feature = features[entitlement.feature_id!];
|
|
await checkFeatureHasCorrectBalance({
|
|
customerId,
|
|
feature: feature,
|
|
entitlement,
|
|
expectedBalance: entitlement.allowance || 0,
|
|
});
|
|
}
|
|
});
|
|
});
|
|
|
|
describe(`${chalk.yellowBright(
|
|
"03_cancel: Testing subscription past_due",
|
|
)}`, () => {
|
|
const customerId = "03_cancel_past_due";
|
|
|
|
before(async function () {
|
|
this.timeout(30000);
|
|
|
|
const stripeCli = createStripeCli({ org: this.org, env: this.env });
|
|
|
|
const testClock = await stripeCli.testHelpers.testClocks.create({
|
|
frozen_time: Math.round(Date.now() / 1000),
|
|
});
|
|
|
|
this.testClockId = testClock.id;
|
|
|
|
await initCustomer({
|
|
customer_data: {
|
|
id: customerId,
|
|
name: "Test Customer",
|
|
email: "test@test.com",
|
|
},
|
|
db: this.db,
|
|
org: this.org,
|
|
env: this.env,
|
|
attachPm: true,
|
|
testClockId: testClock.id,
|
|
});
|
|
});
|
|
|
|
it("should attach pro product", async function () {
|
|
this.timeout(10000);
|
|
|
|
await AutumnCli.attach({
|
|
customerId: customerId,
|
|
productId: products.pro.id,
|
|
});
|
|
});
|
|
|
|
it("should attach failed payment method and advance to next billing date", async function () {
|
|
// 1. Swap customer's card
|
|
const stripeCli = createStripeCli({ org: this.org, env: this.env });
|
|
|
|
const cusRes: any = await AutumnCli.getCustomer(customerId);
|
|
|
|
await attachFailedPaymentMethod({
|
|
stripeCli,
|
|
customer: cusRes.customer,
|
|
});
|
|
|
|
// const advanceDate = addDays(addMonths(new Date(), 1), 1);
|
|
// await stripeCli.testHelpers.testClocks.advance(this.testClockId, {
|
|
// frozen_time: Math.round(advanceDate.getTime() / 1000),
|
|
// });
|
|
|
|
await advanceTestClock({
|
|
stripeCli,
|
|
testClockId: this.testClockId,
|
|
advanceTo: addDays(addMonths(new Date(), 1), 1).getTime(),
|
|
});
|
|
});
|
|
|
|
it("should have free product active and correct entitlements", async function () {
|
|
const cusRes: any = await AutumnCli.getCustomer(customerId);
|
|
// compareMainProduct({
|
|
// sent: products.free,
|
|
// cusRes: cusRes,
|
|
// });
|
|
|
|
// TODO: Check why this line messes up the test
|
|
// compareProductEntitlements({
|
|
// customerId,
|
|
// product: products.free,
|
|
// features,
|
|
// });
|
|
});
|
|
});
|