205 lines
5.5 KiB
TypeScript
205 lines
5.5 KiB
TypeScript
import {
|
|
AllowanceType,
|
|
CusProductStatus,
|
|
Entitlement,
|
|
Feature,
|
|
FeatureOptions,
|
|
FeatureType,
|
|
FullProduct,
|
|
UsagePriceConfig,
|
|
} from "@autumn/shared";
|
|
import { expect } from "chai";
|
|
import { AutumnCli } from "tests/cli/AutumnCli.js";
|
|
import { creditSystems } from "tests/global.js";
|
|
import { Decimal } from "decimal.js";
|
|
|
|
export const checkProductIsScheduled = ({
|
|
cusRes,
|
|
product,
|
|
}: {
|
|
cusRes: any;
|
|
product: any;
|
|
}) => {
|
|
const { products, add_ons, entitlements } = cusRes;
|
|
const prod = products.find((p: any) => p.id === product.id);
|
|
try {
|
|
expect(prod).to.exist;
|
|
expect(prod.status).to.equal(CusProductStatus.Scheduled);
|
|
} catch (error) {
|
|
console.group();
|
|
console.log(`Expected product ${product.id} to be scheduled`);
|
|
console.log("Received: ", cusRes.products);
|
|
console.groupEnd();
|
|
throw error;
|
|
}
|
|
};
|
|
|
|
export const compareMainProduct = ({
|
|
sent,
|
|
cusRes,
|
|
status = CusProductStatus.Active,
|
|
optionsList = [],
|
|
}: {
|
|
sent: any;
|
|
cusRes: any;
|
|
status?: CusProductStatus;
|
|
optionsList?: FeatureOptions[];
|
|
}) => {
|
|
const { products, add_ons, entitlements } = cusRes;
|
|
const prod = products.find(
|
|
(p: any) => p.id === sent.id && p.status == status && !sent.is_add_on,
|
|
);
|
|
|
|
try {
|
|
expect(prod).to.exist;
|
|
expect(sent.id).to.equal(prod.id);
|
|
} catch (error) {
|
|
console.log(`Failed to compare main product ${sent.id}`);
|
|
console.log("Sent: ", sent);
|
|
console.log("Received: ", cusRes);
|
|
throw error;
|
|
}
|
|
|
|
// Check entitlements
|
|
let sentEntitlements = Object.values(sent.entitlements) as Entitlement[];
|
|
let recEntitlements = entitlements;
|
|
|
|
// expect(sentEntitlements.length).to.equal(recEntitlements.length);
|
|
for (const entitlement of sentEntitlements) {
|
|
// Corresponding entitlement in received
|
|
const recEntitlement = recEntitlements.find((e: any) => {
|
|
if (e.feature_id !== entitlement.feature_id) return false;
|
|
if (entitlement.interval && e.interval !== entitlement.interval)
|
|
return false;
|
|
return true;
|
|
});
|
|
|
|
// If options list provideed, and feature
|
|
let options = optionsList.find(
|
|
(o: any) => o.feature_id === entitlement.feature_id,
|
|
);
|
|
|
|
let expectedBalance = entitlement.allowance;
|
|
if (options?.quantity) {
|
|
// Get price from sent
|
|
const price = sent.prices.find(
|
|
(p: any) => p.config.feature_id === entitlement.feature_id,
|
|
);
|
|
const config = price.config as UsagePriceConfig;
|
|
expectedBalance = new Decimal(expectedBalance || 0)
|
|
.add(options.quantity * (config.billing_units || 1))
|
|
.toNumber();
|
|
}
|
|
|
|
try {
|
|
expect(recEntitlement).to.exist;
|
|
if (entitlement.allowance_type === AllowanceType.Unlimited) {
|
|
expect(recEntitlement.unlimited).to.equal(true);
|
|
expect(recEntitlement.balance).to.equal(null);
|
|
expect(recEntitlement.used).to.equal(null);
|
|
} else if ("balance" in entitlement) {
|
|
expect(recEntitlement.balance).to.equal(expectedBalance);
|
|
}
|
|
} catch (error) {
|
|
console.log(
|
|
`Failed to compare main product (entitlements) ${entitlement.feature_id}`,
|
|
);
|
|
console.log("Looking for entitlement: ", entitlement);
|
|
console.log("Received entitlements: ", entitlements);
|
|
throw error;
|
|
}
|
|
}
|
|
};
|
|
|
|
export const checkFeatureHasCorrectBalance = async ({
|
|
customerId,
|
|
feature,
|
|
entitlement,
|
|
expectedBalance,
|
|
}: {
|
|
customerId: string;
|
|
feature: Feature;
|
|
entitlement: Entitlement;
|
|
expectedBalance: number;
|
|
}) => {
|
|
const [entitledRes, cusRes] = await Promise.all([
|
|
AutumnCli.entitled(customerId, feature.id, true),
|
|
AutumnCli.getCustomer(customerId),
|
|
]);
|
|
|
|
if (feature.type === FeatureType.Boolean) {
|
|
console.log(" - Checking boolean feature: ", feature.id);
|
|
const { allowed, balanceObj }: any = entitledRes;
|
|
expect(allowed).to.equal(true);
|
|
return;
|
|
}
|
|
|
|
// console.log(
|
|
// ` - Checking entitlement ${feature.id} has ${
|
|
// entitlement.allowance_type == AllowanceType.Unlimited
|
|
// ? "unlimited balance"
|
|
// : `balance of ${expectedBalance}`
|
|
// }`
|
|
// );
|
|
|
|
// Get ent from cusRes
|
|
const { entitlements: cusEnts }: any = cusRes;
|
|
const { allowed, balanceObj }: any = entitledRes;
|
|
const cusEnt = cusEnts.find(
|
|
(e: any) =>
|
|
e.feature_id === feature.id && e.interval == entitlement.interval,
|
|
);
|
|
|
|
expect(cusEnt).to.exist;
|
|
|
|
if (entitlement.allowance_type === AllowanceType.Unlimited) {
|
|
// Cus ent
|
|
expect(cusEnt.balance).to.equal(null);
|
|
expect(cusEnt.used).to.equal(null);
|
|
expect(cusEnt.unlimited).to.equal(true);
|
|
|
|
// Entitled res
|
|
expect(allowed).to.equal(true);
|
|
expect(balanceObj?.balance).to.equal(null);
|
|
expect(balanceObj?.unlimited).to.equal(true);
|
|
return;
|
|
}
|
|
|
|
if (expectedBalance === 0) {
|
|
expect(allowed).to.equal(false);
|
|
expect(balanceObj?.balance).to.equal(0);
|
|
expect(cusEnt.balance).to.equal(0);
|
|
return;
|
|
}
|
|
|
|
expect(balanceObj?.balance).to.equal(expectedBalance);
|
|
expect(cusEnt.balance).to.equal(expectedBalance);
|
|
};
|
|
|
|
export const compareProductEntitlements = ({
|
|
customerId,
|
|
product,
|
|
features,
|
|
quantity = 1,
|
|
}: {
|
|
customerId: string;
|
|
product: any;
|
|
features: Record<string, Feature>;
|
|
quantity?: number;
|
|
}) => {
|
|
for (const entitlement of Object.values(
|
|
product.entitlements,
|
|
) as Entitlement[]) {
|
|
let feature =
|
|
features[entitlement.feature_id!] ||
|
|
creditSystems[entitlement.feature_id as keyof typeof creditSystems];
|
|
|
|
checkFeatureHasCorrectBalance({
|
|
customerId,
|
|
feature,
|
|
entitlement,
|
|
expectedBalance: (entitlement.allowance || 0) * quantity,
|
|
});
|
|
}
|
|
};
|