otp-form.test.tsx 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
  2. import { render, type RenderResult } from 'vitest-browser-react'
  3. import { type Locator, userEvent } from 'vitest/browser'
  4. import { showSubmittedData } from '@/lib/show-submitted-data'
  5. import { OtpForm } from './otp-form'
  6. const navigate = vi.fn()
  7. vi.mock('@tanstack/react-router', async (orig) => {
  8. const actual = await orig<typeof import('@tanstack/react-router')>()
  9. return { ...actual, useNavigate: () => navigate }
  10. })
  11. vi.mock('@/lib/show-submitted-data', () => ({ showSubmittedData: vi.fn() }))
  12. describe('OtpForm', () => {
  13. let screen: RenderResult
  14. let otpInput: Locator
  15. let verifyButton: Locator
  16. beforeEach(async () => {
  17. vi.clearAllMocks()
  18. screen = await render(<OtpForm />)
  19. otpInput = screen.getByLabelText(/^One-Time Password$/i)
  20. verifyButton = screen.getByRole('button', { name: /^Verify$/i })
  21. })
  22. afterEach(() => {
  23. vi.useRealTimers()
  24. })
  25. it('disables Verify until 6 digits are entered', async () => {
  26. await expect.element(verifyButton).toBeDisabled()
  27. await userEvent.fill(otpInput, '12345')
  28. await expect.element(verifyButton).toBeDisabled()
  29. await userEvent.fill(otpInput, '123456')
  30. await expect.element(verifyButton).toBeEnabled()
  31. })
  32. it('submits the OTP and navigates after timeout', async () => {
  33. vi.useFakeTimers()
  34. await userEvent.fill(otpInput, '123456')
  35. await userEvent.click(verifyButton)
  36. expect(showSubmittedData).toHaveBeenCalledOnce()
  37. expect(showSubmittedData).toHaveBeenCalledWith({ otp: '123456' })
  38. await vi.advanceTimersByTimeAsync(1000)
  39. expect(navigate).toHaveBeenCalledWith({ to: '/' })
  40. })
  41. })