964290c641
样式 before:   after:   逻辑: 每次打开报告modal会再次查询队列中的错误 <video src="attachments/6d9d9bd7-5b7b-4a05-a7c3-ca64b6fb77f3" title="2026-09-05 19-46-02.mp4" controls></video> --------- Co-authored-by: 段舒康 <kdletters@qq.com> Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/286 Reviewed-by: 段舒康 <kdletters@qq.com> Co-authored-by: 王德宇 <kvtodev@outlook.com> Co-committed-by: 王德宇 <kvtodev@outlook.com>
99 lines
2.6 KiB
TypeScript
99 lines
2.6 KiB
TypeScript
/** @vitest-environment jsdom */
|
|
|
|
import {
|
|
cleanup,
|
|
fireEvent,
|
|
render,
|
|
screen,
|
|
waitFor,
|
|
} from '@testing-library/react';
|
|
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
|
|
const mockState = vi.hoisted(() => ({
|
|
getPending: vi.fn(),
|
|
listeners: [] as Array<() => void>,
|
|
}));
|
|
|
|
const dialogState = vi.hoisted(() => ({
|
|
fallbackEvents: [] as (typeof event)[],
|
|
}));
|
|
|
|
vi.mock('../src/services/errorReporting', () => ({
|
|
getPendingClientErrorEvents: mockState.getPending,
|
|
subscribeClientErrorEvents: (listener: () => void) => {
|
|
mockState.listeners.push(listener);
|
|
return () => {
|
|
mockState.listeners = mockState.listeners.filter(
|
|
(item) => item !== listener,
|
|
);
|
|
};
|
|
},
|
|
}));
|
|
|
|
vi.mock('../src/components/error-report/ErrorReportDialog', () => ({
|
|
ErrorReportDialog: ({
|
|
fallbackEvents,
|
|
open,
|
|
}: {
|
|
fallbackEvents?: (typeof event)[];
|
|
open: boolean;
|
|
}) => {
|
|
dialogState.fallbackEvents = fallbackEvents ?? [];
|
|
return open ? <div data-testid="error-report-dialog" /> : null;
|
|
},
|
|
}));
|
|
|
|
import { ErrorReportNotice } from '../src/components/error-report/ErrorReportNotice';
|
|
|
|
const event = {
|
|
eventId: 'rust-error-1',
|
|
fingerprint: 'fingerprint-1',
|
|
source: 'test',
|
|
message: '错过 emit 的错误',
|
|
occurredAt: '1',
|
|
count: 1,
|
|
};
|
|
|
|
describe('ErrorReportNotice', () => {
|
|
afterEach(() => {
|
|
cleanup();
|
|
mockState.getPending.mockReset();
|
|
mockState.listeners = [];
|
|
});
|
|
|
|
it('挂载时查询快照,即使错过唤醒事件也能显示通知', async () => {
|
|
mockState.getPending.mockResolvedValue([event]);
|
|
|
|
render(<ErrorReportNotice />);
|
|
|
|
expect(await screen.findByText('发现问题')).toBeTruthy();
|
|
expect(mockState.getPending).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('收到唤醒后重新查询权威快照', async () => {
|
|
mockState.getPending
|
|
.mockResolvedValueOnce([])
|
|
.mockResolvedValueOnce([event]);
|
|
|
|
render(<ErrorReportNotice />);
|
|
await waitFor(() => expect(mockState.getPending).toHaveBeenCalledTimes(1));
|
|
|
|
mockState.listeners[0]?.();
|
|
|
|
expect(await screen.findByText('发现问题')).toBeTruthy();
|
|
expect(mockState.getPending).toHaveBeenCalledTimes(2);
|
|
});
|
|
|
|
it('打开报告时保留通知快照作为对话框 fallback', async () => {
|
|
mockState.getPending.mockResolvedValue([event]);
|
|
|
|
render(<ErrorReportNotice />);
|
|
await screen.findByText('发现问题');
|
|
|
|
fireEvent.click(screen.getByRole('button', { name: '查看并报告' }));
|
|
|
|
expect(await screen.findByTestId('error-report-dialog')).toBeTruthy();
|
|
expect(dialogState.fallbackEvents).toEqual([event]);
|
|
});
|
|
});
|