// ============================================================ // Accounts 页面冒烟测试 // ============================================================ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { render, screen, waitFor } from '@testing-library/react' import { http, HttpResponse } from 'msw' import { setupServer } from 'msw/node' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' import Accounts from '@/pages/Accounts' // ── Mock data ──────────────────────────────────────────────── const mockAccounts = { items: [ { id: 'acc-001', username: 'zclaw_admin', display_name: 'Admin', email: 'admin@zclaw.ai', role: 'super_admin' as const, status: 'active' as const, totp_enabled: true, last_login_at: '2026-03-30T10:00:00Z', created_at: '2026-01-01T00:00:00Z', llm_routing: 'relay' as const, }, { id: 'acc-002', username: 'test_user', display_name: 'Test', email: 'test@zclaw.ai', role: 'user' as const, status: 'active' as const, totp_enabled: false, last_login_at: null, created_at: '2026-02-15T00:00:00Z', llm_routing: 'local' as const, }, ], total: 2, page: 1, page_size: 20, } // ── MSW server ─────────────────────────────────────────────── const server = setupServer() beforeEach(() => { server.listen({ onUnhandledRequest: 'bypass' }) }) afterEach(() => { server.close() }) // ── Helper: render with QueryClient ────────────────────────── function renderWithProviders(ui: React.ReactElement) { const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false }, }, }) return render( {ui} , ) } // ── Tests ──────────────────────────────────────────────────── describe('Accounts page', () => { it('renders account usernames in the table', async () => { server.use( http.get('*/api/v1/accounts', () => { return HttpResponse.json(mockAccounts) }), ) renderWithProviders() // Wait for data to load and usernames to appear await waitFor(() => { expect(screen.getByText('zclaw_admin')).toBeInTheDocument() }) expect(screen.getByText('test_user')).toBeInTheDocument() }) it('shows loading state before data arrives', async () => { // Use a delayed response to observe loading state server.use( http.get('*/api/v1/accounts', async () => { await new Promise((resolve) => setTimeout(resolve, 500)) return HttpResponse.json(mockAccounts) }), ) renderWithProviders() // Ant Design ProTable renders a spinner while loading // Check that a .ant-spin element exists const spinner = document.querySelector('.ant-spin') expect(spinner).toBeTruthy() // Wait for loading to complete so afterEach cleanup is clean await waitFor(() => { expect(screen.getByText('zclaw_admin')).toBeInTheDocument() }) }) })