Files
3x-ui/frontend/src/test/inbound-form-blocks.test.tsx
T
MHSanaei 6964d84742 feat(reality): add live REALITY target scanner with IP/CIDR discovery
Replace the static reality-targets list with a server-side TLS 1.3 probe that checks TLS 1.3 + HTTP/2 + X25519 + a trusted certificate.

- Single-domain validate auto-fills target and serverNames from the cert SAN
- Discovery scans an IP/CIDR without SNI to find new targets from their certificates, deduped and ranked by feasibility then latency, private-IP guarded via netsafe
- New endpoints scanRealityTarget and scanRealityTargets with RealityScanResult, plus openapigen and api-docs entries
- Add scanner strings to all 13 locales
- Replace deprecated AntD Alert message prop with title across the panel
2026-06-26 22:18:47 +02:00

116 lines
3.3 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { Form, type FormInstance } from 'antd';
import type { ReactNode } from 'react';
import {
GrpcForm,
HttpUpgradeForm,
KcpForm,
RawForm,
SockoptForm,
WsForm,
XhttpForm,
} from '@/pages/inbounds/form/transport';
import { RealityForm, TlsForm } from '@/pages/inbounds/form/security';
import type { InboundFormValues } from '@/schemas/forms/inbound-form';
import { renderWithProviders, fieldLabels } from './test-utils';
function FormHarness({
children,
initialValues,
}: {
children: (form: FormInstance<InboundFormValues>) => ReactNode;
initialValues?: Record<string, unknown>;
}) {
const [form] = Form.useForm<InboundFormValues>();
return <Form form={form} initialValues={initialValues}>{children(form)}</Form>;
}
function renderInForm(
node: (form: FormInstance<InboundFormValues>) => ReactNode,
initialValues?: Record<string, unknown>,
) {
return renderWithProviders(<FormHarness initialValues={initialValues}>{node}</FormHarness>);
}
const noop = () => {};
describe('inbound transport forms', () => {
it('RawForm field structure is stable', () => {
renderInForm(() => <RawForm />);
expect(fieldLabels()).toMatchSnapshot();
});
it('WsForm field structure is stable', () => {
renderInForm(() => <WsForm />);
expect(fieldLabels()).toMatchSnapshot();
});
it('GrpcForm field structure is stable', () => {
renderInForm(() => <GrpcForm />);
expect(fieldLabels()).toMatchSnapshot();
});
it('KcpForm field structure is stable', () => {
renderInForm(() => <KcpForm />);
expect(fieldLabels()).toMatchSnapshot();
});
it('HttpUpgradeForm field structure is stable', () => {
renderInForm(() => <HttpUpgradeForm />);
expect(fieldLabels()).toMatchSnapshot();
});
it('XhttpForm field structure is stable', () => {
renderInForm((form) => <XhttpForm form={form} />);
expect(fieldLabels()).toMatchSnapshot();
});
it('SockoptForm field structure is stable (server-side fields only)', () => {
// The inbound sockopt form shows only server/listening-side fields;
// outbound-only fields (dialerProxy, domainStrategy, interface,
// addressPortStrategy, happyEyeballs, tcpMptcp) live in the outbound form.
renderInForm(
() => <SockoptForm toggleSockopt={noop} network="tcp" />,
{ streamSettings: { sockopt: { mark: 0 } } },
);
expect(fieldLabels()).toMatchSnapshot();
});
});
describe('inbound security forms', () => {
it('TlsForm field structure is stable', () => {
renderInForm(() => (
<TlsForm
saving={false}
setCertFromPanel={noop}
clearCertFiles={noop}
pinFromCert={noop}
pinFromRemote={noop}
getNewEchCert={noop}
clearEchCert={noop}
/>
));
expect(fieldLabels()).toMatchSnapshot();
});
it('RealityForm field structure is stable', () => {
renderInForm(() => (
<RealityForm
saving={false}
scanning={false}
scanResult={null}
scanRealityTarget={noop}
scanRealityCandidates={async () => []}
applyRealityScanResult={noop}
randomizeShortIds={noop}
genRealityKeypair={noop}
clearRealityKeypair={noop}
genMldsa65={noop}
clearMldsa65={noop}
/>
));
expect(fieldLabels()).toMatchSnapshot();
});
});