107 lines
4.1 KiB
TypeScript
107 lines
4.1 KiB
TypeScript
import { MemoryRouter, Route, Routes } from 'react-router-dom'
|
|
import { render, screen, waitFor } from '@testing-library/react'
|
|
import userEvent from '@testing-library/user-event'
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
|
|
import type { AuthCapabilities } from '@/types'
|
|
import { ActivateAccountPage } from './ActivateAccountPage'
|
|
|
|
const getAuthCapabilitiesMock = vi.fn<() => Promise<AuthCapabilities>>()
|
|
const activateEmailMock = vi.fn<(token: string) => Promise<unknown>>()
|
|
const resendActivationEmailMock = vi.fn<(payload: { email: string }) => Promise<{ message: string }>>()
|
|
|
|
vi.mock('@/services/auth', () => ({
|
|
getAuthCapabilities: () => getAuthCapabilitiesMock(),
|
|
activateEmail: (token: string) => activateEmailMock(token),
|
|
resendActivationEmail: (payload: { email: string }) => resendActivationEmailMock(payload),
|
|
}))
|
|
|
|
function renderActivateAccountPage(initialEntry: string) {
|
|
return render(
|
|
<MemoryRouter initialEntries={[initialEntry]}>
|
|
<Routes>
|
|
<Route path="/activate-account" element={<ActivateAccountPage />} />
|
|
</Routes>
|
|
</MemoryRouter>,
|
|
)
|
|
}
|
|
|
|
describe('ActivateAccountPage', () => {
|
|
beforeEach(() => {
|
|
getAuthCapabilitiesMock.mockReset()
|
|
activateEmailMock.mockReset()
|
|
resendActivationEmailMock.mockReset()
|
|
|
|
getAuthCapabilitiesMock.mockResolvedValue({
|
|
password: true,
|
|
email_activation: true,
|
|
email_code: false,
|
|
sms_code: false,
|
|
password_reset: false,
|
|
admin_bootstrap_required: false,
|
|
oauth_providers: [],
|
|
})
|
|
activateEmailMock.mockResolvedValue({ message: 'account activated successfully' })
|
|
resendActivationEmailMock.mockResolvedValue({
|
|
message: 'if the email exists, an activation email will be sent shortly',
|
|
})
|
|
})
|
|
|
|
it('activates the account when a token is present in the URL', async () => {
|
|
renderActivateAccountPage('/activate-account?token=token-123')
|
|
|
|
await waitFor(() => expect(activateEmailMock).toHaveBeenCalledWith('token-123'))
|
|
|
|
expect(await screen.findByText('邮箱验证成功')).toBeInTheDocument()
|
|
expect(screen.getByRole('button', { name: '立即登录' })).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows the resend form when activation fails', async () => {
|
|
activateEmailMock.mockRejectedValueOnce(new Error('activation token expired or missing'))
|
|
|
|
renderActivateAccountPage('/activate-account?token=expired-token&email=user@example.com')
|
|
|
|
await waitFor(() => expect(activateEmailMock).toHaveBeenCalledWith('expired-token'))
|
|
|
|
expect(await screen.findByText('激活链接不可用')).toBeInTheDocument()
|
|
expect(screen.getByPlaceholderText('邮箱地址')).toHaveValue('user@example.com')
|
|
})
|
|
|
|
it('resends the activation email from the public activation page', async () => {
|
|
const user = userEvent.setup()
|
|
renderActivateAccountPage('/activate-account?email=user@example.com')
|
|
|
|
await waitFor(() => expect(getAuthCapabilitiesMock).toHaveBeenCalledTimes(1))
|
|
|
|
await user.clear(screen.getByPlaceholderText('邮箱地址'))
|
|
await user.type(screen.getByPlaceholderText('邮箱地址'), 'user@example.com')
|
|
await user.click(screen.getByRole('button', { name: '重新发送激活邮件' }))
|
|
|
|
await waitFor(() =>
|
|
expect(resendActivationEmailMock).toHaveBeenCalledWith({ email: 'user@example.com' }),
|
|
)
|
|
|
|
expect(await screen.findByText(/请检查收件箱和垃圾邮件目录/)).toBeInTheDocument()
|
|
expect(screen.getByText('user@example.com')).toBeInTheDocument()
|
|
})
|
|
|
|
it('shows a disabled warning when email activation is not available', async () => {
|
|
getAuthCapabilitiesMock.mockResolvedValue({
|
|
password: true,
|
|
email_activation: false,
|
|
email_code: false,
|
|
sms_code: false,
|
|
password_reset: false,
|
|
admin_bootstrap_required: false,
|
|
oauth_providers: [],
|
|
})
|
|
|
|
renderActivateAccountPage('/activate-account')
|
|
|
|
await waitFor(() => expect(getAuthCapabilitiesMock).toHaveBeenCalledTimes(1))
|
|
|
|
expect(await screen.findByText('邮箱激活未启用')).toBeInTheDocument()
|
|
expect(screen.queryByRole('button', { name: '重新发送激活邮件' })).not.toBeInTheDocument()
|
|
})
|
|
})
|