import { render, screen, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { vi, test, expect, beforeEach } from 'vitest'; import ReindexButton from '../../src/components/ReindexButton'; import { reindexAll } from '../../src/api/client'; vi.mock('../../src/api/client'); beforeEach(() => { vi.mocked(reindexAll).mockReset(); }); test('clicking the button triggers reindexAll and shows the result summary', async () => { vi.mocked(reindexAll).mockResolvedValue({ indexed: 5, failed: 0, total: 5 }); const user = userEvent.setup(); render(); await user.click(screen.getByRole('button', { name: '重建索引' })); expect(reindexAll).toHaveBeenCalledTimes(1); await waitFor(() => { expect(screen.getByTestId('reindex-message')).toHaveTextContent('已重建索引 5/5'); }); }); test('shows an error style message when some documents fail to index', async () => { vi.mocked(reindexAll).mockResolvedValue({ indexed: 3, failed: 2, total: 5 }); const user = userEvent.setup(); render(); await user.click(screen.getByRole('button', { name: '重建索引' })); await waitFor(() => { const message = screen.getByTestId('reindex-message'); expect(message).toHaveTextContent('已重建索引 3/5'); expect(message).toHaveClass('error'); }); }); test('shows an error message when the request fails', async () => { vi.mocked(reindexAll).mockRejectedValue(new Error('Failed to reindex: 500')); const user = userEvent.setup(); render(); await user.click(screen.getByRole('button', { name: '重建索引' })); await waitFor(() => { expect(screen.getByTestId('reindex-message')).toHaveTextContent('Failed to reindex: 500'); }); }); test('disables the button while the request is in flight', async () => { let resolveFn: (value: { indexed: number; failed: number; total: number }) => void = () => {}; vi.mocked(reindexAll).mockReturnValue( new Promise((resolve) => { resolveFn = resolve; }), ); const user = userEvent.setup(); render(); const button = screen.getByRole('button', { name: '重建索引' }); await user.click(button); expect(screen.getByRole('button', { name: '重建中…' })).toBeDisabled(); resolveFn({ indexed: 1, failed: 0, total: 1 }); await waitFor(() => { expect(screen.getByRole('button', { name: '重建索引' })).not.toBeDisabled(); }); });