diff --git a/server/shell/g1.sh b/server/shell/g1.sh index 1fe4a6a59..68777cac2 100755 --- a/server/shell/g1.sh +++ b/server/shell/g1.sh @@ -4,8 +4,8 @@ source "$(dirname "$0")/config.sh" # If contains setup then run $MOCHA_SETUP - MOCHA_PARALLEL=true $MOCHA_SETUP # if [[ "$2" == *"setup"* ]]; then +# MOCHA_PARALLEL=true $MOCHA_SETUP # fi $MOCHA_CMD \ @@ -16,6 +16,7 @@ $MOCHA_CMD \ $MOCHA_CMD \ 'tests/attach/entities/*.ts' \ -'tests/attach/free/*.ts' +'tests/attach/free/*.ts'\ +'tests/attach/addOn/*.ts' # 'tests/attach/basic/basic2.ts' \ \ No newline at end of file diff --git a/server/src/internal/customers/attach/attachFunctions/upgradeSameIntFlow/handleUpgradeSameInt.ts b/server/src/internal/customers/attach/attachFunctions/upgradeSameIntFlow/handleUpgradeSameInt.ts index 6a04c0187..7795a5582 100644 --- a/server/src/internal/customers/attach/attachFunctions/upgradeSameIntFlow/handleUpgradeSameInt.ts +++ b/server/src/internal/customers/attach/attachFunctions/upgradeSameIntFlow/handleUpgradeSameInt.ts @@ -2,7 +2,10 @@ import { AttachParams, AttachResultSchema, } from "@/internal/customers/cusProducts/AttachParams.js"; -import { attachParamToCusProducts } from "../../attachUtils/convertAttachParams.js"; +import { + attachParamsToCurCusProduct, + attachParamToCusProducts, +} from "../../attachUtils/convertAttachParams.js"; import { CusProductService } from "@/internal/customers/cusProducts/CusProductService.js"; import { createFullCusProduct } from "@/internal/customers/add-product/createFullCusProduct.js"; import { attachToInsertParams } from "@/internal/products/productUtils.js"; @@ -24,13 +27,11 @@ export const handleUpgradeSameInterval = async ({ attachParams: AttachParams; config: AttachConfig; }) => { - const { curMainProduct: curCusProduct } = attachParamToCusProducts({ - attachParams, - }); + const curCusProduct = attachParamsToCurCusProduct({ attachParams }); const stripeSubs = await getStripeSubs({ stripeCli: attachParams.stripeCli, - subIds: curCusProduct!.subscription_ids || [], + subIds: curCusProduct?.subscription_ids || [], expand: ["items.data.price.tiers"], }); diff --git a/server/src/internal/invoices/previewItemUtils/getItemsForCurProduct.ts b/server/src/internal/invoices/previewItemUtils/getItemsForCurProduct.ts index 565637e4e..3c0172396 100644 --- a/server/src/internal/invoices/previewItemUtils/getItemsForCurProduct.ts +++ b/server/src/internal/invoices/previewItemUtils/getItemsForCurProduct.ts @@ -53,7 +53,7 @@ export const getItemsForCurProduct = async ({ const curPrices = cusProductToPrices({ cusProduct: curCusProduct }); let items: PreviewLineItem[] = []; - let onTrial = isTrialing(curMainProduct!); + let onTrial = isTrialing(curCusProduct); for (const sub of stripeSubs) { for (const item of sub.items.data) { diff --git a/server/tests/attach/addOn/addOn1.ts b/server/tests/attach/addOn/addOn1.ts new file mode 100644 index 000000000..91b87b130 --- /dev/null +++ b/server/tests/attach/addOn/addOn1.ts @@ -0,0 +1,158 @@ +import { AutumnInt } from "@/external/autumn/autumnCli.js"; +import { initCustomer } from "@/utils/scriptUtils/initCustomer.js"; +import { APIVersion, AppEnv, Organization } from "@autumn/shared"; +import chalk from "chalk"; +import Stripe from "stripe"; +import { DrizzleCli } from "@/db/initDrizzle.js"; +import { setupBefore } from "tests/before.js"; +import { createProducts } from "tests/utils/productUtils.js"; +import { addPrefixToProducts, replaceItems } from "../utils.js"; +import { + constructProduct, + constructRawProduct, +} from "@/utils/scriptUtils/createTestProducts.js"; +import { + constructArrearProratedItem, + constructFeatureItem, +} from "@/utils/scriptUtils/constructItem.js"; +import { TestFeature } from "tests/setup/v2Features.js"; +import { attachAndExpectCorrect } from "tests/utils/expectUtils/expectAttach.js"; +import { expect } from "chai"; +import { expectProductAttached } from "tests/utils/expectUtils/expectProductAttached.js"; + +export let pro = constructProduct({ + items: [ + constructFeatureItem({ + featureId: TestFeature.Messages, + includedUsage: 100, + }), + ], + type: "pro", +}); + +export let addOn = constructRawProduct({ + id: "add_on_1", + items: [ + constructFeatureItem({ + featureId: TestFeature.Messages, + includedUsage: 200, + }), + ], + isAddOn: true, +}); + +const testCase = "addOn1"; + +describe(`${chalk.yellowBright(`${testCase}: Testing free add on, and updating free add on`)}`, () => { + let customerId = testCase; + let autumn: AutumnInt = new AutumnInt({ version: APIVersion.v1_4 }); + let testClockId: string; + let db: DrizzleCli, org: Organization, env: AppEnv; + let stripeCli: Stripe; + + let curUnix = new Date().getTime(); + + before(async function () { + await setupBefore(this); + const { autumnJs } = this; + db = this.db; + org = this.org; + env = this.env; + + stripeCli = this.stripeCli; + + addPrefixToProducts({ + products: [pro, addOn], + prefix: testCase, + }); + + await createProducts({ + autumn, + products: [pro, addOn], + customerId, + db, + orgId: org.id, + env, + }); + + const { testClockId: testClockId1 } = await initCustomer({ + autumn: autumnJs, + customerId, + db, + org, + env, + attachPm: "success", + }); + + testClockId = testClockId1!; + }); + + it("should should attach pro product, then add on product", async function () { + await attachAndExpectCorrect({ + autumn, + db, + org, + env, + stripeCli, + customerId, + product: pro, + }); + }); + + it("should should attach add on product", async function () { + const preview = await autumn.attachPreview({ + customer_id: customerId, + product_id: addOn.id, + }); + + await autumn.attach({ + customer_id: customerId, + product_id: addOn.id, + }); + + const customer = await autumn.customers.get(customerId); + + expect(customer.products.length).to.equal(2); + expectProductAttached({ + customer, + product: addOn, + }); + expectProductAttached({ + customer, + product: pro, + }); + }); + + const customItems = replaceItems({ + items: pro.items, + featureId: TestFeature.Messages, + newItem: constructFeatureItem({ + featureId: TestFeature.Messages, + includedUsage: 400, + }), + }); + + it("should update add on product", async function () { + const preview = await autumn.attachPreview({ + customer_id: customerId, + product_id: addOn.id, + is_custom: true, + items: customItems, + }); + + await autumn.attach({ + customer_id: customerId, + product_id: addOn.id, + is_custom: true, + items: customItems, + }); + + const customer = await autumn.customers.get(customerId); + + expect(customer.products.length).to.equal(2); + expectProductAttached({ + customer, + product: addOn, + }); + }); +});