Compare commits

...

2 Commits

Author SHA1 Message Date
LiBr
855862255c Merge pull request #6 from Zach677/fix-two-factor-modal-tests
fix: two-factor modal tests
2026-05-19 22:05:06 +08:00
Zach
c86846d651 test: update two-factor modal tests for context props 2026-05-19 11:11:28 +08:00

View File

@@ -1,57 +1,68 @@
import { fireEvent, render, screen } from '@testing-library/react'; import { fireEvent, render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event'; import userEvent from '@testing-library/user-event';
import { describe, expect, it, vi } from 'vitest'; import { describe, expect, it, vi } from 'vitest';
import type { TwoFactorContext } from '../apple-signing';
import { TwoFactorModal } from './TwoFactorModal'; import { TwoFactorModal } from './TwoFactorModal';
function createTwoFactorContext(overrides: Partial<TwoFactorContext> = {}): TwoFactorContext {
return {
submitDeviceCode: vi.fn(),
trustedPhoneNumbers: [],
requestSms: vi.fn(),
submitSmsCode: vi.fn(),
...overrides,
};
}
describe('TwoFactorModal', () => { describe('TwoFactorModal', () => {
it('is hidden when closed', () => { it('is hidden when closed', () => {
const { container } = render(<TwoFactorModal open={false} onSubmit={() => {}} onCancel={() => {}} />); const { container } = render(<TwoFactorModal open={false} ctx={null} onCancel={() => {}} />);
expect(container.querySelector('.modal')).not.toHaveClass('open'); expect(container.querySelector('.modal')).not.toHaveClass('open');
}); });
it('focuses the input when opened', async () => { it('focuses the input when opened', async () => {
render(<TwoFactorModal open onSubmit={() => {}} onCancel={() => {}} />); render(<TwoFactorModal open ctx={createTwoFactorContext()} onCancel={() => {}} />);
// useEffect runs a setTimeout(0) before focusing — let it tick. // useEffect runs a setTimeout(0) before focusing — let it tick.
await new Promise((resolve) => setTimeout(resolve, 10)); await new Promise((resolve) => setTimeout(resolve, 10));
expect(screen.getByLabelText('Verification Code')).toHaveFocus(); expect(screen.getByLabelText('Verification Code')).toHaveFocus();
}); });
it('shows an inline error when submitting an empty code', async () => { it('shows an inline error when submitting an empty code', async () => {
const onSubmit = vi.fn(); const ctx = createTwoFactorContext();
render(<TwoFactorModal open onSubmit={onSubmit} onCancel={() => {}} />); render(<TwoFactorModal open ctx={ctx} onCancel={() => {}} />);
await userEvent.click(screen.getByRole('button', { name: 'Verify' })); await userEvent.click(screen.getByRole('button', { name: 'Verify' }));
expect(screen.getByText('Please enter verification code.')).toBeInTheDocument(); expect(screen.getByText('Please enter the verification code.')).toBeInTheDocument();
expect(onSubmit).not.toHaveBeenCalled(); expect(ctx.submitDeviceCode).not.toHaveBeenCalled();
}); });
it('clears the error once the user starts typing', async () => { it('clears the error once the user starts typing', async () => {
render(<TwoFactorModal open onSubmit={() => {}} onCancel={() => {}} />); render(<TwoFactorModal open ctx={createTwoFactorContext()} onCancel={() => {}} />);
await userEvent.click(screen.getByRole('button', { name: 'Verify' })); await userEvent.click(screen.getByRole('button', { name: 'Verify' }));
expect(screen.getByText('Please enter verification code.')).toBeInTheDocument(); expect(screen.getByText('Please enter the verification code.')).toBeInTheDocument();
await userEvent.type(screen.getByLabelText('Verification Code'), '1'); await userEvent.type(screen.getByLabelText('Verification Code'), '1');
expect(screen.queryByText('Please enter verification code.')).not.toBeInTheDocument(); expect(screen.queryByText('Please enter the verification code.')).not.toBeInTheDocument();
}); });
it('submits a trimmed code on Enter', async () => { it('submits a trimmed code on Enter', async () => {
const onSubmit = vi.fn(); const ctx = createTwoFactorContext();
render(<TwoFactorModal open onSubmit={onSubmit} onCancel={() => {}} />); render(<TwoFactorModal open ctx={ctx} onCancel={() => {}} />);
const input = screen.getByLabelText('Verification Code'); const input = screen.getByLabelText('Verification Code');
await userEvent.type(input, ' 123456 '); await userEvent.type(input, ' 123456 ');
fireEvent.keyDown(input, { key: 'Enter' }); fireEvent.keyDown(input, { key: 'Enter' });
expect(onSubmit).toHaveBeenLastCalledWith('123456'); expect(ctx.submitDeviceCode).toHaveBeenLastCalledWith('123456');
}); });
it('submits via the Verify button', async () => { it('submits via the Verify button', async () => {
const onSubmit = vi.fn(); const ctx = createTwoFactorContext();
render(<TwoFactorModal open onSubmit={onSubmit} onCancel={() => {}} />); render(<TwoFactorModal open ctx={ctx} onCancel={() => {}} />);
await userEvent.type(screen.getByLabelText('Verification Code'), '654321'); await userEvent.type(screen.getByLabelText('Verification Code'), '654321');
await userEvent.click(screen.getByRole('button', { name: 'Verify' })); await userEvent.click(screen.getByRole('button', { name: 'Verify' }));
expect(onSubmit).toHaveBeenLastCalledWith('654321'); expect(ctx.submitDeviceCode).toHaveBeenLastCalledWith('654321');
}); });
it('calls onCancel when Cancel is clicked', async () => { it('calls onCancel when Cancel is clicked', async () => {
const onCancel = vi.fn(); const onCancel = vi.fn();
render(<TwoFactorModal open onSubmit={() => {}} onCancel={onCancel} />); render(<TwoFactorModal open ctx={createTwoFactorContext()} onCancel={onCancel} />);
await userEvent.click(screen.getByRole('button', { name: 'Cancel' })); await userEvent.click(screen.getByRole('button', { name: 'Cancel' }));
expect(onCancel).toHaveBeenCalledTimes(1); expect(onCancel).toHaveBeenCalledTimes(1);
}); });