78 lines
2.9 KiB
TypeScript
78 lines
2.9 KiB
TypeScript
import { act, render, screen, waitFor } from '@testing-library/react';
|
|
import userEvent from '@testing-library/user-event';
|
|
import { beforeEach, expect, it, vi } from 'vitest';
|
|
import { ReportNotificationsPage } from './ReportNotificationsPage';
|
|
const api = vi.hoisted(() => ({ request: vi.fn() }));
|
|
vi.mock('@/api/core/httpClient', () => api);
|
|
const hour = {
|
|
id: 'hour-1',
|
|
tenantName: '验收企业',
|
|
hour: '2026-09-06T04:00:00Z',
|
|
revision: 3,
|
|
signatureCount: 2,
|
|
drainageCount: 1,
|
|
unread: true,
|
|
};
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
api.request.mockImplementation((path: string) =>
|
|
path.includes('hour-1')
|
|
? Promise.resolve({
|
|
hour,
|
|
items: [
|
|
{
|
|
id: 'event-1',
|
|
reportType: 'signature',
|
|
signatureName: '验收签名',
|
|
targetName: '验收签名',
|
|
createdAt: hour.hour,
|
|
},
|
|
],
|
|
total: 1,
|
|
page: 1,
|
|
pageSize: 20,
|
|
})
|
|
: Promise.resolve({ items: [hour], total: 1, page: 1, pageSize: 20 }),
|
|
);
|
|
});
|
|
it('uses the client API and explicitly marks the displayed revision read', async () => {
|
|
const user = userEvent.setup();
|
|
render(<ReportNotificationsPage />);
|
|
await user.click(await screen.findByRole('button', { name: '查看消息' }));
|
|
await user.click(await screen.findByRole('button', { name: '标记已读' }));
|
|
await waitFor(() =>
|
|
expect(api.request).toHaveBeenCalledWith('/client/report-notifications/hour-1/read', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ revision: 3 }),
|
|
}),
|
|
);
|
|
expect(api.request.mock.calls.some(([path]) => String(path).startsWith('/admin/'))).toBe(false);
|
|
});
|
|
it('reports a failed read without pretending success', async () => {
|
|
const user = userEvent.setup();
|
|
render(<ReportNotificationsPage portal="admin" />);
|
|
await user.click(await screen.findByRole('button', { name: '查看消息' }));
|
|
api.request.mockRejectedValueOnce(new Error('标记失败'));
|
|
await user.click(await screen.findByRole('button', { name: '标记已读' }));
|
|
expect(await screen.findByRole('alert')).toHaveTextContent('标记失败');
|
|
expect(screen.getByRole('button', { name: '标记已读' })).toBeEnabled();
|
|
});
|
|
|
|
it('does not reopen a closed dialog when the read response arrives later', async () => {
|
|
const user = userEvent.setup();
|
|
render(<ReportNotificationsPage />);
|
|
await user.click(await screen.findByRole('button', { name: '查看消息' }));
|
|
let finish!: (result: unknown) => void;
|
|
api.request.mockImplementationOnce(
|
|
() =>
|
|
new Promise((resolve) => {
|
|
finish = resolve;
|
|
}),
|
|
);
|
|
await user.click(await screen.findByRole('button', { name: '标记已读' }));
|
|
const closeButtons = screen.getAllByRole('button', { name: /^关闭$/ });
|
|
await user.click(closeButtons[closeButtons.length - 1]);
|
|
await act(async () => finish({ success: true }));
|
|
await waitFor(() => expect(screen.queryByRole('dialog')).not.toBeInTheDocument());
|
|
});
|