Files
Genarrative/apps/admin-web/src/pages/AdminDatabaseTablesPage.test.tsx
T
2026-05-09 12:47:27 +08:00

108 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* @vitest-environment jsdom */
import {render, screen, waitFor} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import {beforeEach, expect, test, vi} from 'vitest';
import {
getAdminDatabaseTableRows,
getAdminDatabaseTables,
} from '../api/adminApiClient';
import {AdminDatabaseTablesPage} from './AdminDatabaseTablesPage';
vi.mock('../api/adminApiClient', () => ({
formatAdminApiError: vi.fn((error: unknown) =>
error instanceof Error ? error.message : '请求失败',
),
getAdminDatabaseTableRows: vi.fn(),
getAdminDatabaseTables: vi.fn(),
isAdminApiError: vi.fn(() => false),
}));
beforeEach(() => {
window.location.hash = '#tables?table=profile_referral_relation';
vi.mocked(getAdminDatabaseTables).mockResolvedValue({
fetchErrors: [],
tables: ['profile_referral_relation'],
});
vi.mocked(getAdminDatabaseTableRows).mockResolvedValue({
columns: ['invitee_user_id', 'inviter_user_id', 'invite_code', 'bound_at'],
limit: 100,
rows: [
{
cells: {
bound_at: '2026-05-02T00:00:00Z',
invitee_user_id: 'u-b',
invite_code: 'INV-1001',
inviter_user_id: 'u-a',
},
raw: [
'u-b',
'u-a',
'INV-1001',
'2026-05-02T00:00:00Z',
],
},
{
cells: {
bound_at: '2026-05-01T00:00:00Z',
invitee_user_id: 'u-a',
invite_code: 'INV-1002',
inviter_user_id: 'u-c',
},
raw: ['u-a', 'u-c', 'INV-1002', '2026-05-01T00:00:00Z'],
},
{
cells: {
bound_at: '2026-05-03T00:00:00Z',
invitee_user_id: 'u-c',
invite_code: 'INV-1003',
inviter_user_id: 'u-a',
},
raw: ['u-c', 'u-a', 'INV-1003', '2026-05-03T00:00:00Z'],
},
],
tableName: 'profile_referral_relation',
totalReturned: 3,
});
});
test('后台表查询页支持宽表滚动容器和表头排序', async () => {
const user = userEvent.setup();
const {container} = render(
<AdminDatabaseTablesPage token="admin-token" onUnauthorized={vi.fn()} />,
);
await screen.findByText('u-b');
const tableWrap = container.querySelector('.admin-table-wrap');
expect(tableWrap?.querySelector('.admin-database-table')).not.toBeNull();
expect(screen.getByRole('option', {name: '邀请关系(profile_referral_relation)'}).getAttribute('title')).toBe(
'原始表名:profile_referral_relation。邀请关系记录表。',
);
expect(screen.getByText('已选表:邀请关系(profile_referral_relation)')).toBeTruthy();
expect(screen.getByRole('heading', {name: '邀请关系'}).getAttribute('title')).toBe(
'原始表名:profile_referral_relation。邀请关系记录表。',
);
expect(screen.getByRole('button', {name: '被邀请人ID'}).getAttribute('title')).toBe(
'原始字段名:invitee_user_id。被邀请人的用户标识。点击可按此列排序。',
);
expect(readFirstColumnValues(container)).toEqual(['u-b', 'u-a', 'u-c']);
await user.click(screen.getByRole('button', {name: '邀请人ID'}));
await waitFor(() => {
expect(readFirstColumnValues(container)).toEqual(['u-b', 'u-c', 'u-a']);
});
await user.click(screen.getByRole('button', {name: '邀请人ID'}));
await waitFor(() => {
expect(readFirstColumnValues(container)).toEqual(['u-a', 'u-b', 'u-c']);
});
});
function readFirstColumnValues(container: HTMLElement) {
return Array.from(container.querySelectorAll('tbody tr')).map(
(row) => row.querySelector('td')?.textContent?.trim() ?? '',
);
}