63 lines
3.5 KiB
React
63 lines
3.5 KiB
React
import { afterEach, describe, expect, it, vi } from 'vitest'
|
|
import { cleanup, fireEvent, render, screen, waitFor, within } from '@testing-library/react'
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
|
import { TestDataProvider } from '../../test/providerCompat.jsx'
|
|
import { MemoryRouter } from '../../test/routerCompat.jsx'
|
|
import { AuditPage, auditCSV } from './AuditPage'
|
|
|
|
afterEach(() => { cleanup(); vi.restoreAllMocks() })
|
|
|
|
const httpQuery = () => new QueryClient({ defaultOptions: { queries: { retry: false } } })
|
|
|
|
function renderAudit(dataProvider, initialEntry = '/audit?task_id=task-a') {
|
|
return render(
|
|
<QueryClientProvider client={httpQuery()}>
|
|
<TestDataProvider dataProvider={dataProvider}>
|
|
<MemoryRouter initialEntries={[initialEntry]}><AuditPage /></MemoryRouter>
|
|
</TestDataProvider>
|
|
</QueryClientProvider>,
|
|
)
|
|
}
|
|
|
|
describe('AuditPage', () => {
|
|
it('deep-links safe correlation fields and exposes no mutation or secret details', async () => {
|
|
const dataProvider = {
|
|
getList: vi.fn().mockResolvedValue({ data: [{
|
|
id: 7, event_type: 'task_verified', account_id: 'account-a', task_id: 'task-a', attempt_id: 'attempt-a',
|
|
browser_env_alias: 'env-a', network_exit_id: 'exit-a', binding_version: 4, reason_code: 'manual_verification_recorded',
|
|
details: { token: 'must-not-render' }, created_at: '2026-08-30T00:00:00Z',
|
|
}], total: 1 }),
|
|
getOne: vi.fn(), getMany: vi.fn(), getManyReference: vi.fn(), create: vi.fn(), update: vi.fn(), updateMany: vi.fn(), delete: vi.fn(), deleteMany: vi.fn(),
|
|
}
|
|
renderAudit(dataProvider)
|
|
|
|
expect((await screen.findAllByRole('link', { name: 'task-a' })).length).toBeGreaterThan(0)
|
|
expect(screen.getAllByRole('link', { name: 'account-a' })[0].getAttribute('href')).toBe('/accounts/account-a')
|
|
expect(screen.getAllByRole('link', { name: 'attempt-a' })[0].getAttribute('href')).toBe('/attempts/attempt-a')
|
|
expect(screen.getAllByRole('link', { name: 'env-a' })[0].getAttribute('href')).toBe('/browsers/env-a')
|
|
expect(screen.getAllByRole('link', { name: 'exit-a' })[0].getAttribute('href')).toBe('/network-exits/exit-a')
|
|
expect(screen.queryByText('must-not-render')).toBeNull()
|
|
expect(screen.queryByRole('button', { name: /编辑|删除/ })).toBeNull()
|
|
})
|
|
|
|
it('exports only allowlisted correlation columns and requests the next page', async () => {
|
|
const event = {
|
|
id: 7, event_type: 'task_verified', task_id: 'task-a', attempt_id: 'attempt-a', browser_env_alias: 'env-a', network_exit_id: 'exit-a',
|
|
details: { api_key: 'api-secret', private_key: 'private-secret', credential_key: 'credential-secret', authorization_header: 'auth-secret', proxy_url: 'proxy-secret' },
|
|
created_at: '2026-08-30T00:00:00Z',
|
|
}
|
|
const csv = auditCSV([event])
|
|
expect(csv).toContain('attempt-a')
|
|
for (const secret of ['api-secret', 'private-secret', 'credential-secret', 'auth-secret', 'proxy-secret']) expect(csv).not.toContain(secret)
|
|
|
|
const getList = vi.fn().mockImplementation(() => Promise.resolve({ data: [{ ...event, id: 7 }], total: 26 }))
|
|
const dataProvider = {
|
|
getList, getOne: vi.fn(), getMany: vi.fn(), getManyReference: vi.fn(), create: vi.fn(), update: vi.fn(), updateMany: vi.fn(), delete: vi.fn(), deleteMany: vi.fn(),
|
|
}
|
|
renderAudit(dataProvider, '/audit')
|
|
|
|
fireEvent.click(await screen.findByRole('button', { name: '下一页' }))
|
|
await waitFor(() => expect(getList.mock.calls.some(([{ pagination }]) => (pagination?.currentPage || pagination?.page) === 2)).toBe(true))
|
|
})
|
|
})
|