108 lines
3.5 KiB
TypeScript
108 lines
3.5 KiB
TypeScript
/* @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() ?? '',
|
||
);
|
||
}
|