-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
import { Elements } from '@stripe/react-stripe-js' | ||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query' | ||
import { render, screen } from '@testing-library/react' | ||
import userEvent from '@testing-library/user-event' | ||
import { MemoryRouter, Route } from 'react-router-dom' | ||
import { vi } from 'vitest' | ||
import { z } from 'zod' | ||
|
||
import { SubscriptionDetailSchema } from 'services/account/useAccountDetails' | ||
|
||
import AddressForm from './AddressForm' | ||
|
||
const queryClient = new QueryClient() | ||
|
||
const mockGetElement = vi.fn() | ||
const mockGetValue = vi.fn() | ||
|
||
vi.mock('@stripe/react-stripe-js', async () => { | ||
const actual = await vi.importActual('@stripe/react-stripe-js') | ||
return { | ||
...actual, | ||
useElements: () => ({ | ||
getElement: mockGetElement.mockReturnValue({ | ||
getValue: mockGetValue.mockResolvedValue({ | ||
complete: true, | ||
value: { | ||
name: 'John Doe', | ||
address: { | ||
line1: '123 Main St', | ||
line2: null, | ||
city: 'San Francisco', | ||
state: 'CA', | ||
postal_code: '94105', | ||
country: 'US', | ||
}, | ||
}, | ||
}), | ||
}), | ||
}), | ||
} | ||
}) | ||
|
||
const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => ( | ||
<QueryClientProvider client={queryClient}> | ||
<Elements stripe={null}> | ||
<MemoryRouter initialEntries={['/plan/gh/codecov']}> | ||
<Route path="/plan/:provider/:owner">{children}</Route> | ||
</MemoryRouter> | ||
</Elements> | ||
</QueryClientProvider> | ||
) | ||
|
||
const mockSubscriptionDetail: z.infer<typeof SubscriptionDetailSchema> = { | ||
defaultPaymentMethod: { | ||
billingDetails: { | ||
address: { | ||
line1: '123 Main St', | ||
city: 'San Francisco', | ||
state: 'CA', | ||
postalCode: '94105', | ||
country: 'US', | ||
line2: null, | ||
}, | ||
phone: '1234567890', | ||
name: 'John Doe', | ||
email: '[email protected]', | ||
}, | ||
card: { | ||
brand: 'visa', | ||
expMonth: 12, | ||
expYear: 2025, | ||
last4: '4242', | ||
}, | ||
}, | ||
currentPeriodEnd: 1706851492, | ||
cancelAtPeriodEnd: false, | ||
customer: { | ||
id: 'cust_123', | ||
email: '[email protected]', | ||
}, | ||
latestInvoice: null, | ||
taxIds: [], | ||
trialEnd: null, | ||
} | ||
|
||
const mocks = { | ||
useUpdateBillingAddress: vi.fn(), | ||
} | ||
|
||
vi.mock('services/account/useUpdateBillingAddress', () => ({ | ||
useUpdateBillingAddress: () => ({ | ||
mutate: mocks.useUpdateBillingAddress(), | ||
isLoading: false, | ||
error: null, | ||
reset: vi.fn(), | ||
}), | ||
})) | ||
|
||
afterEach(() => { | ||
vi.clearAllMocks() | ||
}) | ||
|
||
describe('AddressForm', () => { | ||
const setup = () => { | ||
const mutation = vi.fn() | ||
mocks.useUpdateBillingAddress.mockReturnValue(mutation) | ||
return { user: userEvent.setup() } | ||
} | ||
|
||
it('renders the form', () => { | ||
render( | ||
<AddressForm | ||
address={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.address | ||
} | ||
name={mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.name} | ||
provider="gh" | ||
owner="codecov" | ||
closeForm={() => {}} | ||
/>, | ||
{ wrapper } | ||
) | ||
|
||
expect(screen.getByRole('button', { name: /save/i })).toBeInTheDocument() | ||
expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument() | ||
}) | ||
|
||
describe('when submitting', () => { | ||
it('calls the service to update the address', async () => { | ||
const { user } = setup() | ||
const updateAddress = vi.fn() | ||
mocks.useUpdateBillingAddress.mockReturnValue(updateAddress) | ||
|
||
render( | ||
<AddressForm | ||
address={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.address | ||
} | ||
name={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.name | ||
} | ||
provider="gh" | ||
owner="codecov" | ||
closeForm={() => {}} | ||
/>, | ||
{ wrapper } | ||
) | ||
|
||
await user.click(screen.getByRole('button', { name: /save/i })) | ||
|
||
expect(updateAddress).toHaveBeenCalled() | ||
Check failure on line 151 in src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/EditPaymentMethods/Address/AddressForm.test.tsx
|
||
}) | ||
}) | ||
|
||
describe('when the user clicks on cancel', () => { | ||
it('calls the closeForm prop', async () => { | ||
const { user } = setup() | ||
const closeForm = vi.fn() | ||
mocks.useUpdateBillingAddress.mockReturnValue(vi.fn()) | ||
|
||
render( | ||
<AddressForm | ||
address={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.address | ||
} | ||
name={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.name | ||
} | ||
provider="gh" | ||
owner="codecov" | ||
closeForm={closeForm} | ||
/>, | ||
{ wrapper } | ||
) | ||
|
||
await user.click(screen.getByRole('button', { name: /cancel/i })) | ||
|
||
expect(closeForm).toHaveBeenCalled() | ||
Check failure on line 178 in src/pages/PlanPage/subRoutes/CurrentOrgPlan/BillingDetails/EditPaymentMethods/Address/AddressForm.test.tsx
|
||
}) | ||
}) | ||
|
||
describe('when there is an error in the form', () => { | ||
it('renders the error', async () => { | ||
const randomError = 'not a valid address' | ||
mocks.useUpdateBillingAddress.mockReturnValue(vi.fn()) | ||
vi.mock('services/account/useUpdateBillingAddress', () => ({ | ||
useUpdateBillingAddress: () => ({ | ||
mutate: vi.fn(), | ||
error: randomError, | ||
isLoading: false, | ||
reset: false, | ||
}), | ||
})) | ||
|
||
render( | ||
<AddressForm | ||
address={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.address | ||
} | ||
name={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.name | ||
} | ||
provider="gh" | ||
owner="codecov" | ||
closeForm={() => {}} | ||
/>, | ||
{ wrapper } | ||
) | ||
|
||
// TODO | ||
// expect(screen.getByText(randomError)).toBeInTheDocument() | ||
}) | ||
}) | ||
|
||
describe('when the form is loading', () => { | ||
it('has the save and cancel buttons disabled', () => { | ||
mocks.useUpdateBillingAddress.mockReturnValue(vi.fn()) | ||
vi.mock('services/account/useUpdateBillingAddress', () => ({ | ||
useUpdateBillingAddress: () => ({ | ||
mutate: vi.fn(), | ||
isLoading: true, | ||
error: null, | ||
reset: vi.fn(), | ||
}), | ||
})) | ||
|
||
render( | ||
<AddressForm | ||
address={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.address | ||
} | ||
name={ | ||
mockSubscriptionDetail.defaultPaymentMethod?.billingDetails?.name | ||
} | ||
provider="gh" | ||
owner="codecov" | ||
closeForm={() => {}} | ||
/>, | ||
{ wrapper } | ||
) | ||
|
||
expect(screen.getByRole('button', { name: /save/i })).toBeDisabled() | ||
expect(screen.getByRole('button', { name: /cancel/i })).toBeDisabled() | ||
}) | ||
}) | ||
}) |