mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 00:26:37 +08:00
refactor: remove unused remarks and add quick domain create
Drop remark fields from Zone, Zone domains, proxy routes, WAF rule groups and IP groups across models, APIs, UI and DB columns (keep certificate/origin remarks). Add quick-create domain input for short labels, @ apex and full FQDNs when binding domains.
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
import {describe, expect, it} from 'vitest';
|
||||
|
||||
import {resolveZoneDomainInput} from '@/app/(main)/websites/components/resolve-zone-domain-input';
|
||||
|
||||
describe('resolveZoneDomainInput', () => {
|
||||
it('maps short label and apex @ under zone root', () => {
|
||||
expect(resolveZoneDomainInput('api', 'example.com')).toEqual({
|
||||
domain: 'api.example.com',
|
||||
});
|
||||
expect(resolveZoneDomainInput('@', 'example.com')).toEqual({
|
||||
domain: 'example.com',
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts full FQDN under the zone', () => {
|
||||
expect(resolveZoneDomainInput('www.api.example.com', 'example.com')).toEqual({
|
||||
domain: 'www.api.example.com',
|
||||
});
|
||||
expect(resolveZoneDomainInput('example.com', 'example.com')).toEqual({
|
||||
domain: 'example.com',
|
||||
});
|
||||
});
|
||||
|
||||
it('rejects foreign domains and wildcards', () => {
|
||||
expect(resolveZoneDomainInput('evil.com', 'example.com').error).toBeTruthy();
|
||||
expect(resolveZoneDomainInput('*.example.com', 'example.com').error).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -31,7 +31,6 @@ describe('WebsitesPage', () => {
|
||||
{
|
||||
id: 42,
|
||||
domain: 'arctel.de',
|
||||
remark: '生产站点',
|
||||
domain_count: 3,
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
@@ -39,7 +38,6 @@ describe('WebsitesPage', () => {
|
||||
{
|
||||
id: 43,
|
||||
domain: 'example.com',
|
||||
remark: '',
|
||||
domain_count: 0,
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import {QueryClient, QueryClientProvider} from '@tanstack/react-query';
|
||||
import {render, screen} from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import {describe, expect, it, vi} from 'vitest';
|
||||
@@ -12,7 +13,7 @@ vi.mock('next/link', () => ({
|
||||
}));
|
||||
|
||||
const zones: ZoneItem[] = [
|
||||
{id: 1, domain: 'arctel.de', remark: '', created_at: '', updated_at: ''},
|
||||
{id: 1, domain: 'arctel.de', created_at: '', updated_at: ''},
|
||||
];
|
||||
|
||||
const domains: ZoneDomainItem[] = [
|
||||
@@ -22,7 +23,6 @@ const domains: ZoneDomainItem[] = [
|
||||
proxy_route_id: null,
|
||||
domain: 'api.arctel.de',
|
||||
cert_id: 9,
|
||||
remark: '',
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
},
|
||||
@@ -32,18 +32,22 @@ const domains: ZoneDomainItem[] = [
|
||||
proxy_route_id: 99,
|
||||
domain: 'bound.arctel.de',
|
||||
cert_id: null,
|
||||
remark: '',
|
||||
created_at: '',
|
||||
updated_at: '',
|
||||
},
|
||||
];
|
||||
|
||||
function renderSelector(ui: React.ReactElement) {
|
||||
const client = new QueryClient({defaultOptions: {queries: {retry: false}}});
|
||||
return render(<QueryClientProvider client={client}>{ui}</QueryClientProvider>);
|
||||
}
|
||||
|
||||
describe('ZoneDomainSelector', () => {
|
||||
it('renders domains and toggles selection', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onChange = vi.fn();
|
||||
|
||||
render(
|
||||
renderSelector(
|
||||
<ZoneDomainSelector
|
||||
value={[7]}
|
||||
onChange={onChange}
|
||||
@@ -53,29 +57,41 @@ describe('ZoneDomainSelector', () => {
|
||||
);
|
||||
|
||||
expect(screen.getByText('api.arctel.de')).toBeVisible();
|
||||
expect(screen.getByText('bound.arctel.de')).toBeVisible();
|
||||
expect(screen.getByText('路由 #99')).toBeVisible();
|
||||
// Bound to another route — hidden by default
|
||||
expect(screen.queryByText('bound.arctel.de')).not.toBeInTheDocument();
|
||||
expect(screen.getByRole('button', {name: /快捷新增域名/})).toBeVisible();
|
||||
|
||||
// Deselect already selected domain
|
||||
await user.click(screen.getByText('api.arctel.de'));
|
||||
expect(onChange).toHaveBeenCalledWith([]);
|
||||
});
|
||||
|
||||
it('does not select domains bound to another route', async () => {
|
||||
const user = userEvent.setup();
|
||||
const onChange = vi.fn();
|
||||
|
||||
render(
|
||||
it('hides domains bound to another route', () => {
|
||||
renderSelector(
|
||||
<ZoneDomainSelector
|
||||
value={[]}
|
||||
onChange={onChange}
|
||||
onChange={vi.fn()}
|
||||
domains={domains}
|
||||
zones={zones}
|
||||
currentRouteId={1}
|
||||
/>,
|
||||
);
|
||||
|
||||
await user.click(screen.getByText('bound.arctel.de'));
|
||||
expect(onChange).not.toHaveBeenCalled();
|
||||
expect(screen.getByText('api.arctel.de')).toBeVisible();
|
||||
expect(screen.queryByText('bound.arctel.de')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('still shows domains already bound to the current route', () => {
|
||||
renderSelector(
|
||||
<ZoneDomainSelector
|
||||
value={[8]}
|
||||
onChange={vi.fn()}
|
||||
domains={domains}
|
||||
zones={zones}
|
||||
currentRouteId={99}
|
||||
/>,
|
||||
);
|
||||
|
||||
expect(screen.getByText('bound.arctel.de')).toBeVisible();
|
||||
expect(screen.getByText('api.arctel.de')).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -62,7 +62,7 @@ describe('ZonePageClient', () => {
|
||||
|
||||
it('loads the overview by stable ID and exposes all tabs including empty domains', async () => {
|
||||
vi.mocked(ZoneService.getOverview).mockImplementation(async () => ({
|
||||
zone: {id: 42, domain: 'arctel.de', remark: '', created_at: '', updated_at: ''},
|
||||
zone: {id: 42, domain: 'arctel.de', created_at: '', updated_at: ''},
|
||||
domains: [],
|
||||
}));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user