import { screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { FeatureFlagContext } from 'common' import { HttpResponse } from 'msw' import { beforeEach, describe, expect, test, vi } from 'vitest' import { RedeemCreditsScreen } from './RedeemCredits' import type { ProfileContextType } from '@/lib/profile' import { createMockOrganization } from '@/tests/helpers' import { customRender } from '@/tests/lib/custom-render' import { addAPIMock } from '@/tests/lib/msw' import { routerMock } from '@/tests/lib/route-mock' const { creditRedemptionProps } = vi.hoisted(() => ({ creditRedemptionProps: vi.fn(), })) const { creditRedemptionQueryCode } = vi.hoisted(() => ({ creditRedemptionQueryCode: { current: undefined as string | undefined }, })) vi.mock('@/components/interfaces/Organization/BillingSettings/CreditCodeRedemption', () => { return { CreditCodeRedemption: (props: { slug?: string }) => { creditRedemptionProps({ ...props, queryCode: creditRedemptionQueryCode.current }) return (
Credit redemption for {props.slug} with code {creditRedemptionQueryCode.current}
) }, } }) const DEFAULT_PROFILE_CONTEXT: ProfileContextType = { profile: { id: 1, auth0_id: 'auth0|test', gotrue_id: 'gotrue-test', username: 'testuser', primary_email: 'test@example.com', first_name: null, last_name: null, mobile: null, is_alpha_user: false, is_sso_user: false, disabled_features: [], free_project_limit: null, }, error: null, isLoading: false, isError: false, isSuccess: true, } const ORGANIZATION = createMockOrganization({ id: 1, name: 'Acme Production', slug: 'acme-production', plan: { id: 'pro', name: 'Pro' }, }) function renderScreen() { return customRender( , { profileContext: DEFAULT_PROFILE_CONTEXT } ) } describe('RedeemCreditsScreen', () => { beforeEach(() => { vi.clearAllMocks() creditRedemptionQueryCode.current = undefined routerMock.setCurrentUrl('/redeem') }) test('renders ready state from organizations query and opens redemption for selected organization', async () => { const user = userEvent.setup() routerMock.setCurrentUrl('/redeem?code=SUPA-CREDIT-123') creditRedemptionQueryCode.current = 'SUPA-CREDIT-123' addAPIMock({ method: 'get', path: '/platform/organizations', response: () => HttpResponse.json([ORGANIZATION]), }) renderScreen() await user.click(await screen.findByRole('button', { name: /Acme Production/ })) await user.click(screen.getByRole('button', { name: 'Redeem credits' })) expect(await screen.findByTestId('credit-redemption')).toHaveTextContent( 'Credit redemption for acme-production with code SUPA-CREDIT-123' ) expect(creditRedemptionProps).toHaveBeenCalledWith( expect.objectContaining({ slug: 'acme-production', queryCode: 'SUPA-CREDIT-123', }) ) }) test('routes new organization creation back to the current redeem URL', async () => { routerMock.setCurrentUrl('/redeem?code=SUPA-CREDIT-123') addAPIMock({ method: 'get', path: '/platform/organizations', response: () => HttpResponse.json([ORGANIZATION]), }) renderScreen() const createOrganizationLink = await screen.findByRole('link', { name: /Create new organization/, }) expect(createOrganizationLink).toHaveAttribute( 'href', '/new?returnTo=%2Fredeem%3Fcode%3DSUPA-CREDIT-123&returnToOrgParam=selected_org' ) }) test('preselects an organization returned from new organization creation', async () => { const user = userEvent.setup() routerMock.setCurrentUrl('/redeem?code=SUPA-CREDIT-123&selected_org=acme-production') creditRedemptionQueryCode.current = 'SUPA-CREDIT-123' addAPIMock({ method: 'get', path: '/platform/organizations', response: () => HttpResponse.json([ORGANIZATION]), }) renderScreen() const redeemButton = await screen.findByRole('button', { name: 'Redeem credits' }) await waitFor(() => expect(redeemButton).toBeEnabled()) await user.click(redeemButton) expect(await screen.findByTestId('credit-redemption')).toHaveTextContent( 'Credit redemption for acme-production with code SUPA-CREDIT-123' ) }) })