DocHub/frontend/tests/components/ReindexButton.test.tsx
Tianyang 542361c63a fix: natural-sort file tree, indent nested folders, fix editor layout
Also add a reindex endpoint and button to rebuild the Meilisearch
index from files already on disk, without needing to re-upload them.
2026-08-01 17:32:32 +08:00

72 lines
2.4 KiB
TypeScript

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(<ReindexButton />);
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(<ReindexButton />);
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(<ReindexButton />);
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(<ReindexButton />);
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();
});
});