| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- import { App as AntApp, ConfigProvider } from 'antd';
- import { act, render, screen, waitFor } from '@testing-library/react';
- import userEvent from '@testing-library/user-event';
- import { createMemoryRouter, RouterProvider } from 'react-router-dom';
- import { describe, expect, it, vi } from 'vitest';
- import { I18nProvider } from '../../src/frontend/i18n/react';
- import { api } from '../../src/frontend/services/api';
- import { mailhubTheme } from '../../src/frontend/theme';
- import type { SendEvent } from '../../src/frontend/types';
- import SendingLogs from '../../src/pages/SendingLogs';
- describe('Activity direct detail navigation', () => {
- it('restores direct-link tabs with history and closes past them to the filtered list', async () => {
- const user = userEvent.setup();
- mockActivityApis();
- const router = renderPage({
- initialEntries: ['/overview', '/activity/11?page=2&pageSize=25&status=failed&tab=raw'],
- initialIndex: 1
- });
- expect(await screen.findByRole('tab', { name: '原始日志', selected: true })).not.toBeNull();
- await user.click(screen.getByRole('tab', { name: 'Webhook' }));
- await waitFor(() => expect(currentTab(router)).toBe('webhooks'));
- await user.click(screen.getByRole('tab', { name: '互动跟踪' }));
- await waitFor(() => expect(currentTab(router)).toBe('tracking'));
- await act(async () => {
- await router.navigate(-1);
- });
- expect(currentTab(router)).toBe('webhooks');
- expect(screen.getByRole('tab', { name: 'Webhook', selected: true })).not.toBeNull();
- await act(async () => {
- await router.navigate(-1);
- });
- expect(currentTab(router)).toBe('raw');
- expect(screen.getByRole('tab', { name: '原始日志', selected: true })).not.toBeNull();
- await act(async () => {
- await router.navigate(1);
- });
- expect(currentTab(router)).toBe('webhooks');
- await act(async () => {
- await router.navigate(1);
- });
- expect(currentTab(router)).toBe('tracking');
- await user.click(screen.getByRole('button', { name: 'Close' }));
- await waitFor(() => expect(router.state.location.pathname).toBe('/activity'));
- const listParams = new URLSearchParams(router.state.location.search);
- expect(listParams.get('page')).toBe('2');
- expect(listParams.get('pageSize')).toBe('25');
- expect(listParams.get('status')).toBe('failed');
- expect(listParams.has('tab')).toBe(false);
- await act(async () => {
- await router.navigate(-1);
- });
- expect(router.state.location.pathname).toBe('/overview');
- });
- it('replaces an untouched direct detail with its list even without prior history', async () => {
- const user = userEvent.setup();
- mockActivityApis();
- const router = renderPage({
- initialEntries: ['/activity/11?page=1&pageSize=25'],
- initialIndex: 0
- });
- await screen.findByRole('dialog', { name: '发送详情' });
- await user.click(screen.getByRole('button', { name: 'Close' }));
- await waitFor(() => expect(router.state.location.pathname).toBe('/activity'));
- await act(async () => {
- await router.navigate(-1);
- });
- expect(router.state.location.pathname).toBe('/activity');
- });
- });
- function mockActivityApis() {
- vi.spyOn(api, 'events').mockResolvedValue({ events: [sendEvent], total: 1, page: 2, pageSize: 25 });
- vi.spyOn(api, 'domains').mockResolvedValue({ domains: [] });
- vi.spyOn(api, 'event').mockResolvedValue({ event: sendEvent });
- }
- function renderPage({ initialEntries, initialIndex }: { initialEntries: string[]; initialIndex: number }) {
- const router = createMemoryRouter([
- { path: '/activity', element: <SendingLogs /> },
- { path: '/activity/:eventId', element: <SendingLogs /> },
- { path: '*', element: <div>other</div> }
- ], { initialEntries, initialIndex });
- render(
- <ConfigProvider theme={{ ...mailhubTheme, token: { ...mailhubTheme.token, motion: false } }}>
- <AntApp>
- <I18nProvider>
- <RouterProvider router={router} />
- </I18nProvider>
- </AntApp>
- </ConfigProvider>
- );
- return router;
- }
- function currentTab(router: ReturnType<typeof createMemoryRouter>) {
- return new URLSearchParams(router.state.location.search).get('tab');
- }
- const sendEvent: SendEvent = {
- id: 11,
- userId: 1,
- domainId: null,
- smtpRelayId: null,
- domain: 'example.test',
- sender: 'sender@example.test',
- recipients: ['recipient@example.test'],
- subject: 'Delivery test',
- status: 'failed',
- detail: '550 mailbox unavailable',
- queueId: 'QUEUE-11',
- messageId: 'mh-11',
- createdAt: '2026-07-14T00:00:00.000Z'
- };
|