Files
OpenFlare/frontend/tests/cloudflare/member-add-dialog.test.tsx
T
ryan 2f60329886 后端与全仓代码质量清理(golangci 扩展集 · 测试质量 · 并发安全 · 文档同步)
代码质量全量清理,零行为变化:golangci 扩展集 13 类 linter(gosec/modernize/perfsprint/canonicalheader/usestdlibvars/wastedassign/intrange/errorlint/forcetypeassert/recvcheck/exhaustive/unparam)全量修复,测试代码质量(testifylint/thelper/usetesting)25→0,frpc 进程生命周期真 bug(进程组击杀)、全仓 go test -race 6 类数据竞争(含 1 个生产竞争)、SPDX license 头补齐 131 文件、前端测试套件 next-intl 迁移后 44 失败→全绿、过期 swagger 文档重新生成、pnpm-workspace 构建审批。

Experiments: #2-#17, #18, #20, #21, #23
Metric: total_issues 108 → 8 (-92.6%)
2026-08-16 21:24:14 +08:00

138 lines
4.2 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.
import { fireEvent, render, screen, within } from '@testing-library/react';
import { describe, expect, it, vi } from 'vitest';
import { MemberAddDialog } from '@/app/(main)/cloudflare/components/member-add-dialog';
import { NextIntlClientProvider } from 'next-intl';
import zhCN from '@/messages/zh-CN.json';
import type { CloudflareAvailableDomain } from '@/lib/services/openflare';
const domains: CloudflareAvailableDomain[] = [
{
id: 1,
zone_id: 10,
domain: 'example.com',
zone_domain: 'example.com',
},
{
id: 2,
zone_id: 10,
domain: 'www.example.com',
zone_domain: 'example.com',
},
{
id: 3,
zone_id: 10,
domain: 'api.example.com',
zone_domain: 'example.com',
},
{
id: 4,
zone_id: 20,
domain: 'app.other.io',
zone_domain: 'other.io',
},
];
describe('MemberAddDialog advanced domain picker', () => {
it('groups domains under top-level zone roots and supports batch select', () => {
const onSubmit = vi.fn();
render(
<NextIntlClientProvider locale='zh-CN' messages={zhCN} timeZone='Asia/Shanghai'>
<MemberAddDialog
open
onOpenChange={vi.fn()}
domains={domains}
defaultProxied
pending={false}
onSubmit={onSubmit}
/>
</NextIntlClientProvider>,
);
expect(screen.getAllByText('example.com').length).toBeGreaterThan(0);
expect(screen.getAllByText('other.io').length).toBeGreaterThan(0);
expect(screen.getByText('www.example.com')).toBeVisible();
expect(screen.getByText('api.example.com')).toBeVisible();
fireEvent.click(screen.getByRole('button', { name: '全选可见' }));
fireEvent.click(screen.getByRole('button', { name: '添加并同步(4)' }));
expect(onSubmit).toHaveBeenCalledTimes(1);
const [ids, proxied] = onSubmit.mock.calls[0] as [number[], boolean];
expect([...ids].sort((a, b) => a - b)).toEqual([1, 2, 3, 4]);
expect(proxied).toBe(true);
});
it('filters by keyword across domain and zone root', () => {
render(
<NextIntlClientProvider locale='zh-CN' messages={zhCN} timeZone='Asia/Shanghai'>
<MemberAddDialog
open
onOpenChange={vi.fn()}
domains={domains}
defaultProxied={false}
pending={false}
onSubmit={vi.fn()}
/>
</NextIntlClientProvider>,
);
fireEvent.change(screen.getByPlaceholderText('搜索域名或顶级域…'), {
target: { value: 'other' },
});
expect(screen.queryByText('www.example.com')).not.toBeInTheDocument();
expect(screen.getByText('app.other.io')).toBeVisible();
expect(screen.getByText('other.io')).toBeVisible();
});
it('selects an entire top-level domain group', () => {
const onSubmit = vi.fn();
render(
<NextIntlClientProvider locale='zh-CN' messages={zhCN} timeZone='Asia/Shanghai'>
<MemberAddDialog
open
onOpenChange={vi.fn()}
domains={domains}
defaultProxied
pending={false}
onSubmit={onSubmit}
/>
</NextIntlClientProvider>,
);
fireEvent.click(
screen.getByRole('checkbox', { name: '选择顶级域 example.com' }),
);
fireEvent.click(screen.getByRole('button', { name: '添加并同步(3)' }));
expect(onSubmit).toHaveBeenCalledTimes(1);
const [ids, proxied] = onSubmit.mock.calls[0] as [number[], boolean];
expect([...ids].sort((a, b) => a - b)).toEqual([1, 2, 3]);
expect(proxied).toBe(true);
});
it('toggles individual domains within a group', () => {
const onSubmit = vi.fn();
render(
<NextIntlClientProvider locale='zh-CN' messages={zhCN} timeZone='Asia/Shanghai'>
<MemberAddDialog
open
onOpenChange={vi.fn()}
domains={domains}
defaultProxied={false}
pending={false}
onSubmit={onSubmit}
/>
</NextIntlClientProvider>,
);
const wwwLabel = screen.getByText('www.example.com').closest('label');
expect(wwwLabel).toBeTruthy();
fireEvent.click(within(wwwLabel as HTMLElement).getByRole('checkbox'));
fireEvent.click(screen.getByRole('button', { name: '添加并同步' }));
expect(onSubmit).toHaveBeenCalledWith([2], false);
});
});