diff --git a/jest-component-unit-tests/babel.config.json b/jest-component-unit-tests/babel.config.json
deleted file mode 100644
index 4cd0f6e82..000000000
--- a/jest-component-unit-tests/babel.config.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "presets": ["babel-preset-vite"]
-}
diff --git a/jest-component-unit-tests/billing.jesttest.tsx b/jest-component-unit-tests/billing.jesttest.tsx
deleted file mode 100644
index 263cf6e13..000000000
--- a/jest-component-unit-tests/billing.jesttest.tsx
+++ /dev/null
@@ -1,299 +0,0 @@
-// Test runner
-import {expect, test, beforeAll, afterEach, afterAll} from '@jest/globals';
-
-// Render mocking, DOM querying
-import {act, render, within} from '@testing-library/react'
-import '@testing-library/jest-dom' // Required for .toHaveStyle
-
-// Request mocking
-import {http, HttpResponse} from 'msw'
-import {setupServer} from 'msw/node'
-
-// React and XState code to test
-import { Models } from '@kittycad/lib'
-import { createActor } from 'xstate'
-import {
- BillingRemaining,
- BillingRemainingMode,
-} from '@src/components/BillingRemaining'
-import { BillingDialog, } from '@src/components/BillingDialog'
-import { BILLING_CONTEXT_DEFAULTS, billingMachine, BillingTransition } from '@src/machines/billingMachine'
-
-// Setup basic request mocking
-const server = setupServer()
-beforeAll(() => server.listen())
-afterEach(() => server.resetHandlers())
-afterAll(() => server.close())
-
-// Data ripped from docs.zoo.dev
-const createUserPaymentBalanceResponse = (opts: {
- monthlyApiCreditsRemaining,
- stableApiCreditsRemaining,
-}): Models['CustomerBalance_type'] => ({
- "created_at": "2025-05-05T16:05:47.317Z",
- "id": "de607b7e-90ba-4977-8561-16e8a9ea0e50",
- "map_id": "d7f7de34-9bc3-4b8b-9951-cdee03fc792d",
- "modeling_app_enterprise_price": {
- "type": "enterprise"
- },
- "monthly_api_credits_remaining": opts.monthlyApiCreditsRemaining,
- "monthly_api_credits_remaining_monetary_value": "22.47",
- "stable_api_credits_remaining": opts.stableApiCreditsRemaining,
- "stable_api_credits_remaining_monetary_value": "18.91",
- "subscription_details": undefined,
- "subscription_id": "Hnd3jalJkHA3lb1YexOTStZtPYHTM",
- "total_due": "100.08",
- "updated_at": "2025-05-05T16:05:47.317Z"
-})
-
-const createOrgResponse = (opts: {
-}): Models['Org_type'] => ({
- "allow_users_in_domain_to_auto_join": true,
- "billing_email": "m@dN9MCH.com",
- "billing_email_verified": "2025-05-05T18:52:02.021Z",
- "block": "payment_method_failed",
- "can_train_on_data": true,
- "created_at": "2025-05-05T18:52:02.021Z",
- "domain": "Ctxde1hpG8xTvvlef5SEPm7",
- "id": "78432284-8660-46bf-ac65-d00bf9b18c3e",
- "image": "https://Rt0.yK.com/R2SoRtl/tpUdckyDJ",
- "name": "AevRR4w42KdkA487dh",
- "phone": "+1-696-641-2790",
- "stripe_id": "sCfjVscpLyOBYUWO7Vlx",
- "updated_at": "2025-05-05T18:52:02.021Z"
-})
-
-const createUserPaymentSubscriptionsResponse = (opts: {
- monthlyPayAsYouGoApiCreditsTotal,
- name,
-}): Models['ZooProductSubscriptions_type'] => ({
- "modeling_app": {
- "annual_discount": 10,
- "description": "1ztERftrU3L3yOnv5epTLcM",
- "endpoints_included": [
- "modeling"
- ],
- "features": [
- {
- "info": "zZcZKHejXabT5HMZDkSkDGD2bfzkAt"
- }
- ],
- "monthly_pay_as_you_go_api_credits": opts.monthlyPayAsYouGoApiCreditsTotal,
- "monthly_pay_as_you_go_api_credits_monetary_value": "55.85",
- "name": opts.name,
- "pay_as_you_go_api_credit_price": "18.49",
- "price": {
- "interval": "year",
- "price": "50.04",
- "type": "per_user"
- },
- "share_links": [
- "password_protected"
- ],
- "support_tier": "community",
- "training_data_behavior": "default_on",
- "type": {
- "saml_sso": true,
- "type": "organization"
- },
- "zoo_tools_included": [
- "text_to_cad"
- ]
- }
-})
-
-test('Shows a loading spinner when uninitialized credit count', async () => {
- server.use(
- http.get('*/user/payment/balance', (req, res, ctx) => {
- return HttpResponse.json({})
- }),
- http.get('*/user/payment/subscriptions', (req, res, ctx) => {
- return HttpResponse.json({})
- }),
- http.get('*/org', (req, res, ctx) => {
- return new HttpResponse(403)
- }),
- )
-
- const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
-
- const { queryByTestId } = render()
-
- await expect(queryByTestId('spinner')).toBeVisible()
-})
-
-test('Shows the total credits for Unknown subscription', async () => {
- const data = {
- balance: {
- monthlyApiCreditsRemaining: 10,
- stableApiCreditsRemaining: 25,
- },
- subscriptions: {
- monthlyPayAsYouGoApiCreditsTotal: 20,
- name: "unknown",
- }
- }
-
- server.use(
- http.get('*/user/payment/balance', (req, res, ctx) => {
- return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
- }),
- http.get('*/user/payment/subscriptions', (req, res, ctx) => {
- return HttpResponse.json(createUserPaymentSubscriptionsResponse(data.subscriptions))
- }),
- http.get('*/org', (req, res, ctx) => {
- return new HttpResponse(403)
- }),
- )
-
- const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
-
- const { queryByTestId } = render()
-
- await act(() => {
- billingActor.send({ type: BillingTransition.Update, apiToken: "it doesn't matter wtf this is :)" })
- })
-
- const totalCredits = data.balance.monthlyApiCreditsRemaining + data.balance.stableApiCreditsRemaining
- await expect(billingActor.getSnapshot().context.credits).toBe(totalCredits)
- await within(queryByTestId('billing-credits')).getByText(totalCredits)
-})
-
-test('Progress bar reflects ratio left of Free subscription', async () => {
- const data = {
- balance: {
- monthlyApiCreditsRemaining: 10,
- stableApiCreditsRemaining: 0,
- },
- subscriptions: {
- monthlyPayAsYouGoApiCreditsTotal: 20,
- name: "free",
- }
- }
-
- server.use(
- http.get('*/user/payment/balance', (req, res, ctx) => {
- return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
- }),
- http.get('*/user/payment/subscriptions', (req, res, ctx) => {
- return HttpResponse.json(createUserPaymentSubscriptionsResponse(data.subscriptions))
- }),
- http.get('*/org', (req, res, ctx) => {
- return new HttpResponse(403)
- }),
- )
-
- const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
-
- const { queryByTestId } = render()
-
- await act(() => {
- billingActor.send({ type: BillingTransition.Update, apiToken: "it doesn't matter wtf this is :)" })
- })
-
- const totalCredits = data.balance.monthlyApiCreditsRemaining + data.balance.stableApiCreditsRemaining
- const monthlyCredits = data.subscriptions.monthlyPayAsYouGoApiCreditsTotal
- const context = billingActor.getSnapshot().context
- await expect(context.credits).toBe(totalCredits)
- await expect(context.allowance).toBe(monthlyCredits)
-
- await within(queryByTestId('billing-credits')).getByText(totalCredits)
- await expect(queryByTestId('billing-remaining-progress-bar-inner')).toHaveStyle({
- width: "50.00%"
- })
-})
-test('Shows infinite credits for Pro subscription', async () => {
- const data = {
- // These are all ignored
- balance: {
- monthlyApiCreditsRemaining: 10,
- stableApiCreditsRemaining: 0,
- },
- subscriptions: {
- // This should be ignored because it's Pro tier.
- monthlyPayAsYouGoApiCreditsTotal: 20,
- name: "pro",
- }
- }
-
- server.use(
- http.get('*/user/payment/balance', (req, res, ctx) => {
- return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
- }),
- http.get('*/user/payment/subscriptions', (req, res, ctx) => {
- return HttpResponse.json(createUserPaymentSubscriptionsResponse(data.subscriptions))
- }),
- http.get('*/org', (req, res, ctx) => {
- return new HttpResponse(403)
- }),
- )
-
- const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
-
- const { queryByTestId } = render()
-
- await act(() => {
- billingActor.send({ type: BillingTransition.Update, apiToken: "aosetuhsatuh" })
- })
-
- await expect(queryByTestId('infinity')).toBeVisible()
- // You can't do `.not.toBeVisible` folks. When the query fails it's because
- // no element could be found. toBeVisible should be used on an element
- // that's found but may not be visible due to `display` or others.
- await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
-})
-test('Shows infinite credits for Enterprise subscription', async () => {
- const data = {
- // These are all ignored, user is part of an org.
- balance: {
- monthlyApiCreditsRemaining: 10,
- stableApiCreditsRemaining: 0,
- },
- subscriptions: {
- // This should be ignored because it's Pro tier.
- monthlyPayAsYouGoApiCreditsTotal: 20,
- // This should be ignored because the user is part of an Org.
- name: "free",
- }
- }
-
- server.use(
- http.get('*/user/payment/balance', (req, res, ctx) => {
- return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
- }),
- http.get('*/user/payment/subscriptions', (req, res, ctx) => {
- return HttpResponse.json(createUserPaymentSubscriptionsResponse(data.subscriptions))
- }),
- // Ok finally the first use of an org lol
- http.get('*/org', (req, res, ctx) => {
- return HttpResponse.json(createOrgResponse())
- }),
- )
-
- const billingActor = createActor(billingMachine, { input: BILLING_CONTEXT_DEFAULTS }).start()
-
- const { queryByTestId } = render()
-
- await act(() => {
- billingActor.send({ type: BillingTransition.Update, apiToken: "aosetuhsatuh" })
- })
-
- // The result should be the same as Pro users.
- await expect(queryByTestId('infinity')).toBeVisible()
- await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(null)
-})
diff --git a/jest-component-unit-tests/jest.config.ts b/jest-component-unit-tests/jest.config.ts
deleted file mode 100644
index 29ede1387..000000000
--- a/jest-component-unit-tests/jest.config.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { pathsToModuleNameMapper } from 'ts-jest'
-// In the following statement, replace `./tsconfig` with the path to your `tsconfig` file
-// which contains the path mapping (ie the `compilerOptions.paths` option):
-import { compilerOptions } from './tsconfig.json'
-import type { Config } from 'jest'
-
-const jestConfig: Config = {
- // [...]
- preset: "ts-jest",
- transform: {
- "^.+\.tsx?$": ["ts-jest",{ babelConfig: true }],
- },
- testEnvironment: "jest-fixed-jsdom",
- // Include both standard test patterns and our custom .jesttest. pattern
- testMatch: [
- "**/__tests__/**/*.[jt]s?(x)",
- "**/?(*.)+(spec|test).[tj]s?(x)",
- "**/?(*.)+(jesttest).[tj]s?(x)"
- ],
- // TAG: paths, path, baseUrl, alias
- // This is necessary to use tsconfig path aliases.
- moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/../' }),
-}
-
-export default jestConfig
diff --git a/jest-component-unit-tests/tsconfig.json b/jest-component-unit-tests/tsconfig.json
deleted file mode 100644
index 8e8f9e738..000000000
--- a/jest-component-unit-tests/tsconfig.json
+++ /dev/null
@@ -1,35 +0,0 @@
-{
- "compilerOptions": {
- "noErrorTruncation": true,
- "baseUrl": "../../",
- "paths": {
- "@kittycad/codemirror-lsp-client": [
- "./packages/codemirror-lsp-client/src/index.ts"
- ],
- "@kittycad/codemirror-lang-kcl": [
- "./packages/codemirror-lang-kcl/src/index.ts"
- ],
- "@rust/*": ["./rust/*"],
- "@e2e/*": ["./e2e/*"],
- "@src/*": ["./src/*"],
- "@public/*": ["./public/*"],
- "@root/*": ["./*"]
- },
- "target": "esnext",
- "lib": ["dom", "dom.iterable", "esnext"],
- "allowJs": true,
- "skipLibCheck": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true,
- "strict": true,
- "forceConsistentCasingInFileNames": true,
- "noFallthroughCasesInSwitch": true,
- "module": "commonjs",
- "moduleResolution": "node",
- "resolveJsonModule": true,
- "composite": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "react-jsx"
- }
-}
diff --git a/package.json b/package.json
index 5d56502a2..8b12ab3c2 100644
--- a/package.json
+++ b/package.json
@@ -131,8 +131,7 @@
"test": "vitest --mode development",
"test:rust": "(cd rust && just test && just lint)",
"test:snapshots": "cross-env TARGET=web NODE_ENV=development playwright test --config=playwright.config.ts --grep=@snapshot --trace=on",
- "test:unit": "vitest run --mode development --exclude **/jest-component-unit-tests/*",
- "test:unit:components": "jest -c jest-component-unit-tests/jest.config.ts --rootDir jest-component-unit-tests/",
+ "test:unit": "vitest run --mode development",
"test:e2e:web": "cross-env TARGET=web NODE_ENV=development playwright test --config=playwright.config.ts --project=\"Google Chrome\" --grep=@web",
"test:e2e:desktop": "cross-env TARGET=desktop playwright test --config=playwright.electron.config.ts --grep-invert=\"@snapshot|@web\"",
"test:e2e:desktop:local": "cross-env TARGET=desktop npm run tronb:vite:dev && playwright test --config=playwright.electron.config.ts --grep-invert=\"@snapshot|@web\" --grep-invert=\"$(curl --silent https://test-analysis-bot.hawk-dinosaur.ts.net/projects/KittyCAD/modeling-app/tests/disabled/regex)\"",
diff --git a/src/components/billing.test.tsx b/src/components/billing.test.tsx
new file mode 100644
index 000000000..f98b4cf56
--- /dev/null
+++ b/src/components/billing.test.tsx
@@ -0,0 +1,347 @@
+// @ts-nocheck
+// This was moved out of the Jest workflow. Needs proper TS TLC.
+
+// Test runner
+
+// Render mocking, DOM querying
+import { act, render, within } from '@testing-library/react'
+import '@testing-library/jest-dom' // Required for .toHaveStyle
+
+// Request mocking
+import { http, HttpResponse } from 'msw'
+import { setupServer } from 'msw/node'
+
+// React and XState code to test
+import type { Models } from '@kittycad/lib'
+import { createActor } from 'xstate'
+import {
+ BillingRemaining,
+ BillingRemainingMode,
+} from '@src/components/BillingRemaining'
+import {
+ BILLING_CONTEXT_DEFAULTS,
+ billingMachine,
+ BillingTransition,
+} from '@src/machines/billingMachine'
+
+// Setup basic request mocking
+const server = setupServer()
+beforeAll(() => server.listen())
+afterEach(() => server.resetHandlers())
+afterAll(() => server.close())
+
+// Data ripped from docs.zoo.dev
+const createUserPaymentBalanceResponse = (opts: {
+ monthlyApiCreditsRemaining
+ stableApiCreditsRemaining
+}): Models['CustomerBalance_type'] => ({
+ created_at: '2025-05-05T16:05:47.317Z',
+ id: 'de607b7e-90ba-4977-8561-16e8a9ea0e50',
+ map_id: 'd7f7de34-9bc3-4b8b-9951-cdee03fc792d',
+ modeling_app_enterprise_price: {
+ type: 'enterprise',
+ },
+ monthly_api_credits_remaining: opts.monthlyApiCreditsRemaining,
+ monthly_api_credits_remaining_monetary_value: '22.47',
+ stable_api_credits_remaining: opts.stableApiCreditsRemaining,
+ stable_api_credits_remaining_monetary_value: '18.91',
+ subscription_details: undefined,
+ subscription_id: 'Hnd3jalJkHA3lb1YexOTStZtPYHTM',
+ total_due: '100.08',
+ updated_at: '2025-05-05T16:05:47.317Z',
+})
+
+const createOrgResponse = (): Models['Org_type'] => ({
+ allow_users_in_domain_to_auto_join: true,
+ billing_email: 'm@dN9MCH.com',
+ billing_email_verified: '2025-05-05T18:52:02.021Z',
+ block: 'payment_method_failed',
+ can_train_on_data: true,
+ created_at: '2025-05-05T18:52:02.021Z',
+ domain: 'Ctxde1hpG8xTvvlef5SEPm7',
+ id: '78432284-8660-46bf-ac65-d00bf9b18c3e',
+ image: 'https://Rt0.yK.com/R2SoRtl/tpUdckyDJ',
+ name: 'AevRR4w42KdkA487dh',
+ phone: '+1-696-641-2790',
+ stripe_id: 'sCfjVscpLyOBYUWO7Vlx',
+ updated_at: '2025-05-05T18:52:02.021Z',
+})
+
+const createUserPaymentSubscriptionsResponse = (opts: {
+ monthlyPayAsYouGoApiCreditsTotal
+ name
+}): Models['ZooProductSubscriptions_type'] => ({
+ modeling_app: {
+ annual_discount: 10,
+ description: '1ztERftrU3L3yOnv5epTLcM',
+ endpoints_included: ['modeling'],
+ features: [
+ {
+ info: 'zZcZKHejXabT5HMZDkSkDGD2bfzkAt',
+ },
+ ],
+ monthly_pay_as_you_go_api_credits: opts.monthlyPayAsYouGoApiCreditsTotal,
+ monthly_pay_as_you_go_api_credits_monetary_value: '55.85',
+ name: opts.name,
+ pay_as_you_go_api_credit_price: '18.49',
+ price: {
+ interval: 'year',
+ price: '50.04',
+ type: 'per_user',
+ },
+ share_links: ['password_protected'],
+ support_tier: 'community',
+ training_data_behavior: 'default_on',
+ type: {
+ saml_sso: true,
+ type: 'organization',
+ },
+ zoo_tools_included: ['text_to_cad'],
+ },
+})
+
+test('Shows a loading spinner when uninitialized credit count', async () => {
+ server.use(
+ http.get('*/user/payment/balance', (req, res, ctx) => {
+ return HttpResponse.json({})
+ }),
+ http.get('*/user/payment/subscriptions', (req, res, ctx) => {
+ return HttpResponse.json({})
+ }),
+ http.get('*/org', (req, res, ctx) => {
+ return new HttpResponse(403)
+ })
+ )
+
+ const billingActor = createActor(billingMachine, {
+ input: BILLING_CONTEXT_DEFAULTS,
+ }).start()
+
+ const { queryByTestId } = render(
+
+ )
+
+ await expect(queryByTestId('spinner')).toBeVisible()
+})
+
+test('Shows the total credits for Unknown subscription', async () => {
+ const data = {
+ balance: {
+ monthlyApiCreditsRemaining: 10,
+ stableApiCreditsRemaining: 25,
+ },
+ subscriptions: {
+ monthlyPayAsYouGoApiCreditsTotal: 20,
+ name: 'unknown',
+ },
+ }
+
+ server.use(
+ http.get('*/user/payment/balance', (req, res, ctx) => {
+ return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
+ }),
+ http.get('*/user/payment/subscriptions', (req, res, ctx) => {
+ return HttpResponse.json(
+ createUserPaymentSubscriptionsResponse(data.subscriptions)
+ )
+ }),
+ http.get('*/org', (req, res, ctx) => {
+ return new HttpResponse(403)
+ })
+ )
+
+ const billingActor = createActor(billingMachine, {
+ input: BILLING_CONTEXT_DEFAULTS,
+ }).start()
+
+ const { queryByTestId } = render(
+
+ )
+
+ await act(() => {
+ billingActor.send({
+ type: BillingTransition.Update,
+ apiToken: "it doesn't matter wtf this is :)",
+ })
+ })
+
+ const totalCredits =
+ data.balance.monthlyApiCreditsRemaining +
+ data.balance.stableApiCreditsRemaining
+ await expect(billingActor.getSnapshot().context.credits).toBe(totalCredits)
+ await within(queryByTestId('billing-credits')).getByText(totalCredits)
+})
+
+test('Progress bar reflects ratio left of Free subscription', async () => {
+ const data = {
+ balance: {
+ monthlyApiCreditsRemaining: 10,
+ stableApiCreditsRemaining: 0,
+ },
+ subscriptions: {
+ monthlyPayAsYouGoApiCreditsTotal: 20,
+ name: 'free',
+ },
+ }
+
+ server.use(
+ http.get('*/user/payment/balance', (req, res, ctx) => {
+ return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
+ }),
+ http.get('*/user/payment/subscriptions', (req, res, ctx) => {
+ return HttpResponse.json(
+ createUserPaymentSubscriptionsResponse(data.subscriptions)
+ )
+ }),
+ http.get('*/org', (req, res, ctx) => {
+ return new HttpResponse(403)
+ })
+ )
+
+ const billingActor = createActor(billingMachine, {
+ input: BILLING_CONTEXT_DEFAULTS,
+ }).start()
+
+ const { queryByTestId } = render(
+
+ )
+
+ await act(() => {
+ billingActor.send({
+ type: BillingTransition.Update,
+ apiToken: "it doesn't matter wtf this is :)",
+ })
+ })
+
+ const totalCredits =
+ data.balance.monthlyApiCreditsRemaining +
+ data.balance.stableApiCreditsRemaining
+ const monthlyCredits = data.subscriptions.monthlyPayAsYouGoApiCreditsTotal
+ const context = billingActor.getSnapshot().context
+ await expect(context.credits).toBe(totalCredits)
+ await expect(context.allowance).toBe(monthlyCredits)
+
+ await within(queryByTestId('billing-credits')).getByText(totalCredits)
+ await expect(
+ queryByTestId('billing-remaining-progress-bar-inner')
+ ).toHaveStyle({
+ width: '50.00%',
+ })
+})
+test('Shows infinite credits for Pro subscription', async () => {
+ const data = {
+ // These are all ignored
+ balance: {
+ monthlyApiCreditsRemaining: 10,
+ stableApiCreditsRemaining: 0,
+ },
+ subscriptions: {
+ // This should be ignored because it's Pro tier.
+ monthlyPayAsYouGoApiCreditsTotal: 20,
+ name: 'pro',
+ },
+ }
+
+ server.use(
+ http.get('*/user/payment/balance', (req, res, ctx) => {
+ return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
+ }),
+ http.get('*/user/payment/subscriptions', (req, res, ctx) => {
+ return HttpResponse.json(
+ createUserPaymentSubscriptionsResponse(data.subscriptions)
+ )
+ }),
+ http.get('*/org', (req, res, ctx) => {
+ return new HttpResponse(403)
+ })
+ )
+
+ const billingActor = createActor(billingMachine, {
+ input: BILLING_CONTEXT_DEFAULTS,
+ }).start()
+
+ const { queryByTestId } = render(
+
+ )
+
+ await act(() => {
+ billingActor.send({
+ type: BillingTransition.Update,
+ apiToken: 'aosetuhsatuh',
+ })
+ })
+
+ await expect(queryByTestId('infinity')).toBeVisible()
+ // You can't do `.not.toBeVisible` folks. When the query fails it's because
+ // no element could be found. toBeVisible should be used on an element
+ // that's found but may not be visible due to `display` or others.
+ await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(
+ null
+ )
+})
+test('Shows infinite credits for Enterprise subscription', async () => {
+ const data = {
+ // These are all ignored, user is part of an org.
+ balance: {
+ monthlyApiCreditsRemaining: 10,
+ stableApiCreditsRemaining: 0,
+ },
+ subscriptions: {
+ // This should be ignored because it's Pro tier.
+ monthlyPayAsYouGoApiCreditsTotal: 20,
+ // This should be ignored because the user is part of an Org.
+ name: 'free',
+ },
+ }
+
+ server.use(
+ http.get('*/user/payment/balance', (req, res, ctx) => {
+ return HttpResponse.json(createUserPaymentBalanceResponse(data.balance))
+ }),
+ http.get('*/user/payment/subscriptions', (req, res, ctx) => {
+ return HttpResponse.json(
+ createUserPaymentSubscriptionsResponse(data.subscriptions)
+ )
+ }),
+ // Ok finally the first use of an org lol
+ http.get('*/org', (req, res, ctx) => {
+ return HttpResponse.json(createOrgResponse())
+ })
+ )
+
+ const billingActor = createActor(billingMachine, {
+ input: BILLING_CONTEXT_DEFAULTS,
+ }).start()
+
+ const { queryByTestId } = render(
+
+ )
+
+ await act(() => {
+ billingActor.send({
+ type: BillingTransition.Update,
+ apiToken: 'aosetuhsatuh',
+ })
+ })
+
+ // The result should be the same as Pro users.
+ await expect(queryByTestId('infinity')).toBeVisible()
+ await expect(queryByTestId('billing-remaining-progress-bar-inline')).toBe(
+ null
+ )
+})