adding test cases to usage-in-arrear

This commit is contained in:
John Yeo
2025-02-09 17:51:30 +00:00
committed by Ayush
parent 8d6d3584b2
commit 1617bd3ed5
8 changed files with 974 additions and 9 deletions

View File

@@ -16,7 +16,7 @@
"cron:start": "node --no-deprecation dist/src/cron.js",
"clean": "tsx src/clean.ts",
"test-all": "mocha 'tests/**/*.ts'",
"test": "mocha 'tests/topup.ts'"
"test": "mocha 'tests/**/*.ts'"
},
"mocha": {
"node-option": [
@@ -68,7 +68,7 @@
"@types/node": "^22.13.0",
"@types/pg": "^8.11.10",
"mocha": "^11.1.0",
"puppeteer": "^24.1.1",
"puppeteer": "^24.2.0",
"ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.7.3"

View File

@@ -4,6 +4,7 @@ import { createStripeCli } from "./utils.js";
import RecaseError from "@/utils/errorUtils.js";
import { ErrCode } from "@/errors/errCodes.js";
import { StatusCodes } from "http-status-codes";
import { SupabaseClient } from "@supabase/supabase-js";
export const createStripeCustomer = async ({
org,
@@ -86,11 +87,42 @@ export const getCusPaymentMethod = async ({
};
// 2. Create a payment method and attach to customer
export const attachPmToCus = async (
stripeCli: Stripe,
stripeCusId: string,
willFail: boolean = false
) => {
export const attachPmToCus = async ({
sb,
customer,
org,
env,
willFail = false,
}: {
sb: SupabaseClient;
customer: Customer;
org: Organization;
env: AppEnv;
willFail?: boolean;
}) => {
// 1. Create stripe customer if not exists
let stripeCusId = customer.processor?.stripe_id;
if (!stripeCusId) {
const stripeCustomer = await createStripeCustomer({
org,
env,
customer,
});
await sb
.from("customers")
.update({
processor: {
stripe_id: stripeCustomer.id,
},
})
.eq("internal_id", customer.internal_id);
stripeCusId = stripeCustomer.id;
}
const stripeCli = createStripeCli({ org, env });
try {
let token = willFail ? "tok_chargeCustomerFail" : "tok_visa";
const pm = await stripeCli.paymentMethods.create({

View File

@@ -1,9 +1,11 @@
import { Router } from "express";
import RecaseError, { handleRequestError } from "@/utils/errorUtils.js";
import { z } from "zod";
import {
BillingType,
Entitlement,
FeatureOptions,
FeatureOptionsSchema,
Price,
ProcessorType,
} from "@autumn/shared";
@@ -289,11 +291,13 @@ attachRouter.post("/attach", async (req: any, res) => {
const pricesInput: PricesInput = prices || [];
const entsInput: Entitlement[] = entitlements || [];
const optionsListInput: FeatureOptions[] = options || [];
const useCheckout = force_checkout || false;
console.log("--------------------------------");
console.log("Add product request received");
try {
z.array(FeatureOptionsSchema).parse(optionsListInput);
// 1. Get full customer product data
const attachParams = await getFullCusProductData({
sb,

View File

@@ -143,9 +143,16 @@ const checkFeatureAccessAllowed = ({
quantity: number;
}) => {
if (originalFeature.type === FeatureType.Boolean) {
console.log("Boolean feature", originalFeature.id);
return {
allowed: cusEnts.some((ent) => ent.feature_id === originalFeature.id),
balances: [],
balances: [
{
feature_id: originalFeature.id,
balance: null,
},
],
};
}

742
server/tests-old/global.ts Normal file
View File

@@ -0,0 +1,742 @@
import dotenv from "dotenv";
dotenv.config();
import * as chai from "chai";
import { default as chaiHttp, request } from "chai-http";
import { createClerkCli } from "../src/external/clerkUtils.js";
import { createSupabaseClient } from "../src/external/supabaseUtils.js";
import {
AllowanceType,
AppEnv,
BillingInterval,
CusProductStatus,
EntInterval,
Feature,
FeatureType,
Organization,
PriceType,
} from "@autumn/shared";
import { OrgService } from "@/internal/orgs/OrgService.js";
import axios from "axios";
import { expect } from "chai";
import { createStripeCli } from "@/external/stripe/utils.js";
import { attachPmToCus } from "@/external/stripe/stripeCusUtils.js";
const ORG_SLUG = "unit-test-org";
const AUTUMN_API_KEY = "am_test_3ZnkWSjVEpVGjLokP6HnP7t6";
const clerkCli = createClerkCli();
const sb = createSupabaseClient();
const env = AppEnv.Sandbox;
const axiosInstance = axios.create({
baseURL: "http://localhost:8080",
headers: {
Authorization: `Bearer ${AUTUMN_API_KEY}`,
},
});
const timeout = async (ms: number) => {
return new Promise((resolve) => setTimeout(resolve, ms));
};
chai.use(chaiHttp);
const vars = {
customer_id: "test-customer",
metered_1: {
id: "metered-1",
event_name: "metered_1_event",
credit_amount: 1,
},
metered_2: {
id: "metered-2",
event_name: "metered_2_event",
credit_amount: 5,
},
credits_1: {
id: "credits-1",
event_name: "credits_1_event",
},
free: {
id: "free",
metered_1_allowance: 3,
metered_2_allowance: 2,
credits_1_allowance: 11,
},
pro: {
id: "pro",
metered_1_allowance: "unlimited",
metered_2_allowance: "unlimited",
credits_1_allowance: 100,
},
};
const clearOrg = async ({ orgId, env }: { orgId: string; env: AppEnv }) => {
// 1. Delete all customers
const { error } = await sb
.from("customers")
.delete()
.eq("org_id", orgId)
.eq("env", env);
// 2. Delete all products
const { error: productError } = await sb
.from("products")
.delete()
.eq("org_id", orgId)
.eq("env", env);
if (productError) {
console.error("Error deleting products:", productError);
}
// // 3. Delete all features
await sb.from("features").delete().eq("org_id", orgId).eq("env", env);
};
const setupOrg = async (org: Organization, env: AppEnv) => {
// 1. Create features
const features: Feature[] = [
{
id: "boolean-1",
name: "Boolean 1",
type: FeatureType.Boolean,
},
{
id: "metered-1",
name: "Metered 1",
type: FeatureType.Metered,
config: {
filters: [
{
value: ["metered_1_event"],
property: "",
operator: "",
},
],
aggregate: {
type: "count",
property: null,
},
},
},
{
id: "metered-2",
name: "Metered 2",
type: FeatureType.Metered,
config: {
filters: [
{
value: ["metered_2_event"],
property: "",
operator: "",
},
],
aggregate: {
type: "sum",
property: "value",
},
},
},
{
id: "credits-1",
name: "Credits 1",
type: FeatureType.CreditSystem,
config: {
schema: [
{
metered_feature_id: "metered-1",
feature_amount: 1,
credit_amount: vars.metered_1.credit_amount,
},
{
metered_feature_id: "metered-2",
feature_amount: 1,
credit_amount: vars.metered_2.credit_amount,
},
],
},
},
];
let insertFeatures = [];
for (const feature of features) {
insertFeatures.push(axiosInstance.post("/v1/features", feature));
}
await Promise.all(insertFeatures);
const { data: newFeatures } = await sb
.from("features")
.select("*")
.eq("org_id", org.id)
.eq("env", env);
console.log(
"✅ Inserted features (boolean-1, metered-1, metered-2, credits-1"
);
// 2. Create products
const products: any[] = [
// A. free product (3 metered-1, 1 metered-2, 5)
{
id: "free",
name: "Free",
group: "g1",
is_add_on: false,
is_default: true,
prices: [],
entitlements: [
{
feature_id: "metered-1",
allowance_type: AllowanceType.Fixed,
allowance: vars.free.metered_1_allowance,
interval: EntInterval.Month,
internal_feature_id: newFeatures?.find((f) => f.id === "metered-1")
?.internal_id,
},
{
feature_id: "metered-2",
allowance_type: AllowanceType.Fixed,
allowance: vars.free.metered_2_allowance,
interval: EntInterval.Month,
internal_feature_id: newFeatures?.find((f) => f.id === "metered-2")
?.internal_id,
},
{
feature_id: "credits-1",
allowance_type: AllowanceType.Fixed,
allowance: vars.free.credits_1_allowance,
interval: EntInterval.Month,
internal_feature_id: newFeatures?.find((f) => f.id === "credits-1")
?.internal_id,
},
],
},
// B. pro product (20 USD / month) (Unlimited metered-1, Unlimited metered-2, 10 credits-1), 7 day free trial
{
id: "pro",
name: "Pro",
group: "g1",
is_add_on: false,
is_default: false,
prices: [
{
name: "Monthly",
config: {
type: PriceType.Fixed,
amount: 20,
interval: BillingInterval.Month,
},
},
],
entitlements: [
{
feature_id: "boolean-1",
internal_feature_id: newFeatures?.find((f) => f.id === "boolean-1")
?.internal_id,
},
{
feature_id: "metered-1",
allowance_type: AllowanceType.Unlimited,
allowance: null,
interval: EntInterval.Month,
internal_feature_id: newFeatures?.find((f) => f.id === "metered-1")
?.internal_id,
},
{
feature_id: "metered-2",
allowance_type: AllowanceType.Unlimited,
allowance: null,
interval: EntInterval.Month,
internal_feature_id: newFeatures?.find((f) => f.id === "metered-2")
?.internal_id,
},
{
feature_id: "credits-1",
allowance_type: AllowanceType.Fixed,
allowance: vars.pro.credits_1_allowance,
interval: EntInterval.Month,
internal_feature_id: newFeatures?.find((f) => f.id === "credits-1")
?.internal_id,
},
],
free_trial: {
length: 7,
unique_fingerprint: true,
},
},
];
let insertProducts = [];
for (const product of products) {
const insertProduct = async () => {
await axiosInstance.post("/v1/products", {
product: {
id: product.id,
name: product.name,
group: product.group,
is_add_on: product.is_add_on,
is_default: product.is_default,
},
});
await axiosInstance.post(`/v1/products/${product.id}`, {
prices: product.prices,
entitlements: product.entitlements,
free_trial: product.free_trial,
});
};
insertProducts.push(insertProduct());
}
await Promise.all(insertProducts);
console.log("✅ Inserted products (free, pro)");
// Create test customer
const { data } = await axiosInstance.post("/v1/customers", {
id: vars.customer_id,
email: "test@test.com",
name: "Test Customer",
fingerprint: "test-fp",
});
console.log("✅ Created test customer");
return { customer: data.customer };
};
before(async function () {
console.log("Running setup");
this.timeout(5000);
const org = await OrgService.getBySlug({ sb, slug: ORG_SLUG });
this.org = org;
await clearOrg({ orgId: org.id, env });
const { customer } = await setupOrg(org, env);
this.customer = customer;
console.log("--------------------------------");
});
describe("Free tier -- checking balances before any usage", () => {
it("boolean-1", async function () {
const { data: boolean1Data } = await axiosInstance.post(`/v1/entitled`, {
customer_id: vars.customer_id,
feature_id: "boolean-1",
});
expect(boolean1Data.allowed).to.equal(false);
});
it("metered-1 / credits-1", async function () {
// 2. Check metered-1 feature
const { data: metered1Data } = await axiosInstance.post(`/v1/entitled`, {
customer_id: vars.customer_id,
feature_id: vars.metered_1.id,
});
// 1. Check that metered-1 balance is 3
let metered1Balance = metered1Data.balances.find(
(b: any) => b.feature_id === vars.metered_1.id
);
expect(metered1Balance.balance).to.equal(vars.free.metered_1_allowance);
// 2. Check that metered-2 balance is 0
let creditsBalance = metered1Data.balances.find(
(b: any) => b.feature_id === vars.credits_1.id
);
expect(creditsBalance.balance).to.equal(vars.free.credits_1_allowance);
});
it("metered-2 / credits-1", async function () {
const { data: metered2Data } = await axiosInstance.post(`/v1/entitled`, {
customer_id: vars.customer_id,
feature_id: vars.metered_2.id,
});
let metered2Balance = metered2Data.balances.find(
(b: any) => b.feature_id === vars.metered_2.id
);
expect(metered2Balance.balance).to.equal(vars.free.metered_2_allowance);
let creditsBalance = metered2Data.balances.find(
(b: any) => b.feature_id === vars.credits_1.id
);
expect(creditsBalance.balance).to.equal(vars.free.credits_1_allowance);
});
});
describe("Free tier -- checking balances after metered-1 / metered-2 events", () => {
before(async function () {
console.log(
` - Sending ${vars.free.metered_1_allowance} metered-1 events`
);
console.log(` - Sending 1 metered-2 events`);
this.timeout(10000);
const sendEvents = [];
for (let i = 0; i < vars.free.metered_1_allowance; i++) {
sendEvents.push(
axiosInstance.post(`/v1/events`, {
customer_id: vars.customer_id,
event_name: vars.metered_1.event_name,
})
);
}
sendEvents.push(
axiosInstance.post(`/v1/events`, {
customer_id: vars.customer_id,
event_name: vars.metered_2.event_name,
properties: {
value: 1,
},
})
);
await Promise.all(sendEvents);
await timeout(2000);
});
it("metered-1 / credits-1", async function () {
const { data: metered1Data } = await axiosInstance.post(`/v1/entitled`, {
customer_id: vars.customer_id,
feature_id: vars.metered_1.id,
});
const metered1Balance = metered1Data.balances.find(
(b: any) => b.feature_id === vars.metered_1.id
);
const creditsBalance = metered1Data.balances.find(
(b: any) => b.feature_id === vars.credits_1.id
);
const expectedCreditsBalance =
vars.free.credits_1_allowance -
vars.free.metered_1_allowance -
vars.metered_2.credit_amount;
expect(metered1Balance.balance).to.equal(0);
expect(creditsBalance.balance).to.equal(expectedCreditsBalance);
expect(metered1Data.allowed).to.equal(false);
});
it("metered-2 / credits-1", async function () {
const { data: metered2Data } = await axiosInstance.post(`/v1/entitled`, {
customer_id: vars.customer_id,
feature_id: vars.metered_2.id,
});
const metered2Balance = metered2Data.balances.find(
(b: any) => b.feature_id === vars.metered_2.id
);
const expectedMetered2Balance = vars.free.metered_2_allowance - 1;
expect(metered2Balance.balance).to.equal(expectedMetered2Balance);
expect(metered2Data.allowed).to.equal(false);
});
});
// CASE: Customer upgrades to pro, receives credits
describe("Upgrade to pro -- checking products & balances", () => {
before(async function () {
// 1. Attach payment method to customer
this.timeout(10000);
const org = this.org;
const customer = this.customer;
const stripeCli = createStripeCli({ org, env });
try {
if (!customer.processor || !customer.processor.id) {
const stripeCus = await stripeCli.customers.create({
email: customer.email,
name: customer.name,
});
customer.processor = {
id: stripeCus.id,
type: "stripe",
};
const { error } = await sb
.from("customers")
.update({
processor: {
id: stripeCus.id,
type: "stripe",
},
})
.eq("internal_id", customer.internal_id);
if (error) {
console.log(" - Error updating customer:", error);
}
}
await attachPmToCus(stripeCli, customer.processor.id);
console.log(" - Attached payment method");
// 2. Attach product
const { data } = await axiosInstance.post(`/v1/attach`, {
customer_id: customer.id,
product_id: vars.pro.id,
});
if (data.checkout_url) {
console.log(" - Checkout URL:", data.checkout_url);
throw new Error("checkout_url received");
}
console.log(" - Attached product");
} catch (error) {
console.log(" - Error attaching payment method", error);
}
});
it("on pro product", async function () {
const { data } = await axiosInstance.get(
`/v1/customers/${vars.customer_id}`
);
const products = data.products;
expect(products.length).to.equal(1);
expect(products[0].id).to.equal(vars.pro.id);
expect(products[0].status).to.equal(CusProductStatus.Trialing);
});
it("boolean-1", async function () {
const { data: boolean1Data } = await axiosInstance.post(`/v1/entitled`, {
customer_id: vars.customer_id,
feature_id: "boolean-1",
});
expect(boolean1Data.allowed).to.equal(true);
});
it("metered-1 / metered-2 / credits-1", async function () {
const { data: metered1Data } = await axiosInstance.post(`/v1/entitled`, {
customer_id: vars.customer_id,
feature_id: vars.metered_1.id,
});
const { data: metered2Data } = await axiosInstance.post(`/v1/entitled`, {
customer_id: vars.customer_id,
feature_id: vars.metered_2.id,
});
const metered1Balance = metered1Data.balances.find(
(b: any) => b.feature_id === vars.metered_1.id
);
const metered2Balance = metered2Data.balances.find(
(b: any) => b.feature_id === vars.metered_2.id
);
const creditBalance = metered1Data.balances.find(
(b: any) => b.feature_id === vars.credits_1.id
);
expect(metered1Balance.unlimited).to.equal(true);
expect(metered2Balance.unlimited).to.equal(true);
expect(creditBalance.balance).to.equal(vars.pro.credits_1_allowance);
expect(metered1Data.allowed).to.equal(true);
expect(metered2Data.allowed).to.equal(true);
});
});
// describe("Downgrade to free", () => {
// before(async function () {
// this.timeout(10000);
// await axiosInstance.post(`/v1/attach`, {
// customer_id: vars.customer_id,
// product_id: vars.free.id,
// });
// await timeout(3000);
// console.log(" - Attached free product");
// });
// it("Checking free product scheduled", async function () {
// const { data: products } = await axiosInstance.get(
// `/v1/customers/${vars.customer_id}/products`
// );
// expect(products.length).to.equal(2);
// const freeProduct = products.find((p: any) => p.id === vars.free.id);
// expect(freeProduct.status).to.equal(CusProductStatus.Scheduled);
// expect(freeProduct.canceled_at).to.equal(null);
// const proProduct = products.find((p: any) => p.id === vars.pro.id);
// expect(proProduct.status).to.equal(CusProductStatus.Active);
// expect(proProduct.canceled_at).to.not.equal(null);
// });
// it("boolean-1", async function () {
// const { data: boolean1Data } = await axiosInstance.post(`/v1/entitled`, {
// customer_id: vars.customer_id,
// feature_id: "boolean-1",
// });
// expect(boolean1Data.allowed).to.equal(true);
// });
// it("metered-1 / metered-2 / credits-1", async function () {
// const { data: metered1Data } = await axiosInstance.post(`/v1/entitled`, {
// customer_id: vars.customer_id,
// feature_id: vars.metered_1.id,
// });
// const { data: metered2Data } = await axiosInstance.post(`/v1/entitled`, {
// customer_id: vars.customer_id,
// feature_id: vars.metered_2.id,
// });
// const metered1Balance = metered1Data.balances.find(
// (b: any) => b.feature_id === vars.metered_1.id
// );
// const metered2Balance = metered2Data.balances.find(
// (b: any) => b.feature_id === vars.metered_2.id
// );
// const creditBalance = metered1Data.balances.find(
// (b: any) => b.feature_id === vars.credits_1.id
// );
// expect(metered1Balance.unlimited).to.equal(true);
// expect(metered1Data.allowed).to.equal(true);
// expect(metered2Balance.unlimited).to.equal(true);
// expect(metered2Data.allowed).to.equal(true);
// expect(creditBalance.balance).to.equal(vars.pro.credits_1_allowance);
// });
// });
// describe("Restore to pro", () => {
// before(async function () {
// this.timeout(10000);
// await axiosInstance.post(`/v1/attach`, {
// customer_id: vars.customer_id,
// product_id: vars.pro.id,
// });
// await timeout(3000);
// console.log(" - Attached pro product");
// });
// it("Pro product active", async function () {
// this.timeout(10000);
// const { data: products } = await axiosInstance.get(
// `/v1/customers/${vars.customer_id}/products`
// );
// expect(products.length).to.equal(1);
// expect(products[0].id).to.equal(vars.pro.id);
// expect(products[0].status).to.equal(CusProductStatus.Active);
// expect(products[0].canceled_at).to.equal(null);
// });
// });
// STRIPE CANCELLATION
describe("Stripe cancellation", () => {
before(async function () {
this.timeout(10000);
const stripeCli = createStripeCli({ org: this.org, env });
// 1. Cancel pro product
const { data } = await axiosInstance.get(
`/v1/customers/${vars.customer_id}`
);
const products = data.products;
const proProduct = products.find((p: any) => p.id === vars.pro.id);
await stripeCli.subscriptions.update(
proProduct.processor.subscription_id!,
{
cancel_at_period_end: true,
}
);
await timeout(3000);
console.log(" - Cancelled pro product");
});
it("Pro product cancelled", async function () {
const { data } = await axiosInstance.get(
`/v1/customers/${vars.customer_id}`
);
const products = data.products;
const proProduct = products.find((p: any) => p.id === vars.pro.id);
expect(proProduct.status).to.equal(CusProductStatus.Trialing);
expect(proProduct.canceled_at).to.not.equal(null);
});
});
describe("Stripe renewal", () => {
before(async function () {
this.timeout(10000);
const stripeCli = createStripeCli({ org: this.org, env });
// 1. Enable pro product
const { data } = await axiosInstance.get(
`/v1/customers/${vars.customer_id}`
);
const products = data.products;
const proProduct = products.find((p: any) => p.id === vars.pro.id);
await stripeCli.subscriptions.update(
proProduct.processor.subscription_id!,
{
cancel_at_period_end: false,
}
);
await timeout(3000);
console.log(" - Enabled pro product");
});
it("Pro product active", async function () {
const { data } = await axiosInstance.get(
`/v1/customers/${vars.customer_id}`
);
const products = data.products;
const proProduct = products.find((p: any) => p.id === vars.pro.id);
expect(proProduct.status).to.equal(CusProductStatus.Trialing);
expect(proProduct.canceled_at).to.equal(null);
});
});
describe("Stripe cancel now", () => {
before(async function () {
this.timeout(10000);
const stripeCli = createStripeCli({ org: this.org, env });
// 1. Cancel pro product
const { data } = await axiosInstance.get(
`/v1/customers/${vars.customer_id}`
);
const products = data.products;
const proProduct = products.find((p: any) => p.id === vars.pro.id);
await stripeCli.subscriptions.cancel(proProduct.processor.subscription_id!);
await timeout(3000);
console.log(" - Cancelled pro product");
});
it("Pro product cancelled", async function () {
const { data } = await axiosInstance.get(
`/v1/customers/${vars.customer_id}`
);
const products = data.products;
const freeProduct = products.find((p: any) => p.id === vars.free.id);
expect(products.length).to.equal(1);
expect(freeProduct.id).to.equal(vars.free.id);
expect(freeProduct.status).to.equal(CusProductStatus.Active);
expect(freeProduct.canceled_at).to.equal(null);
});
});

View File

@@ -0,0 +1,87 @@
import dotenv from "dotenv";
dotenv.config();
import { AppEnv } from "@autumn/shared";
import axios from "axios";
import { initCustomer } from "./utils.js";
const apiKey = "am_test_3Zbu1qcRkR6mhq5gtgqScvVN";
const apiUrl = "http://localhost:8080/v1";
const orgId = "org_2s4vfEyYVgFZDlOwcMHjsHR0eef";
const env = AppEnv.Sandbox;
const timeout = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
const sendEvent = async () => {
try {
const { data } = await axios.post(
`${apiUrl}/events`,
{
customer_id: "123",
event_name: "sonnet_message",
properties: {
value: 1,
},
},
{
headers: {
Authorization: `Bearer ${apiKey}`,
},
}
);
console.log(data);
} catch (error: any) {
console.error(error.response.data);
}
};
const main = async () => {
await initCustomer({
customerName: "Test 11",
customerId: "123",
productId: "starter",
orgId,
env,
apiKey,
apiUrl,
});
console.log("Customer initialized");
await timeout(3000);
const batchEvents = [];
for (let i = 0; i < 50; i++) {
batchEvents.push(sendEvent());
}
// await Promise.all(batchEvents);
// console.log("Done sending events");
// // View meter usage
// const sb = createSupabaseClient();
// const customer = await CusService.getById({
// sb,
// id: "123",
// orgId,
// env,
// });
// const org = await OrgService.getFullOrg({
// sb,
// orgId,
// });
// const stripeCli = createStripeCli({ org, env });
// const meterSummary = await stripeCli.billing.meters.listEventSummaries(
// "mtr_test_61RzIB9NJlpZILzUB41GHoZUApXXdRCK",
// {
// customer: customer.processor.id,
// end_time: Math.floor(Date.now() / 1000),
// start_time: Math.floor(Date.now() / 1000) - 1000 * 60 * 60 * 24,
// }
// );
// console.log(meterSummary);
// const stripeCus = await stripeCli.customers.retrieve(
// customer.processor.id
// );
};
main();

93
server/tests-old/utils.ts Normal file
View File

@@ -0,0 +1,93 @@
// Initialize customer
import axios from "axios";
import { createSupabaseClient } from "@/external/supabaseUtils.js";
import { OrgService } from "@/internal/orgs/OrgService.js";
import { AppEnv } from "@autumn/shared";
import { createStripeCli } from "@/external/stripe/utils.js";
import { attachPmToCus } from "@/external/stripe/stripeCusUtils.js";
import { CusService } from "@/internal/customers/CusService.js";
export const initCustomer = async ({
orgId,
env,
apiKey,
apiUrl,
customerId,
customerName,
productId,
}: {
orgId: string;
env: AppEnv;
apiKey: string;
apiUrl: string;
customerId: string;
customerName: string;
productId: string;
}) => {
const sb = createSupabaseClient();
const org = await OrgService.getFullOrg({
sb,
orgId,
});
// Reinitialize customer
try {
await axios.delete(`${apiUrl}/customers/123`, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});
} catch (error) {}
const { data } = await axios.post(
`${apiUrl}/customers`,
{
id: customerId,
name: customerName,
email: "test@gmail.com",
},
{
headers: {
Authorization: `Bearer ${apiKey}`,
},
}
);
const customer = data.customer;
const stripeCli = createStripeCli({ org, env });
const stripeCus = await stripeCli.customers.create({
email: data.customer.email,
name: data.customer.name,
});
customer.processor = {
id: stripeCus.id,
type: "stripe",
};
await CusService.update({
sb,
internalCusId: data.customer.internal_id,
update: {
processor: { id: stripeCus.id, type: "stripe" },
},
});
await attachPmToCus(stripeCli, data.customer.processor.id);
if (productId) {
const { data: res } = await axios.post(
`${apiUrl}/attach`,
{
customer_id: data.customer.id,
product_id: productId,
},
{
headers: {
Authorization: `Bearer ${apiKey}`,
},
}
);
console.log("res: ", res);
}
};

View File

@@ -25,7 +25,7 @@
"@shared/*": ["../shared/*"]
}
},
"include": ["src", "tests"],
"include": ["src", "tests", "tests-old/utils.ts", "tests-old/global.ts"],
"references": [
{
"path": "../shared"