Files
3x-ui/frontend/src/test/dns-server-modal.test.tsx
T
MHSanaei b6c859f5b9 feat(xray): edit Lua DNS and routing scripts
xray-core 26.10.10 can hand DNS and routing to Lua: dns.script and
routing.script name a .lua file (absolute, or found next to the Xray
binary) that defines HandleDNSQuery / HandleRoute, and a DNS server's id
is how a DNS script picks it. The keys round-tripped through the JSON
template but had no field.

- DNS: a Lua Script field, and an ID field in the server modal;
- Basics: a Routing Script field beside the routing strategy;
- Routing: a warning above the rules while a script is set, since the
  core then routes only through the script and skips every rule, the
  panel's api rule included.

The descriptions say the script must still send the api inbound to the
api outbound, and that Xray will not start if the file is missing. An
empty field drops the key, because the core rejects an empty path.
2026-10-11 15:37:20 +02:00

46 lines
1.6 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import { act, fireEvent, screen } from '@testing-library/react';
import DnsServerModal from '@/pages/xray/dns/DnsServerModal';
import { renderWithProviders } from './test-utils';
describe('DnsServerModal', () => {
// A Lua dns.script (xray-core 26.10.10) picks servers by id; the modal rebuilds the
// server on save, and collapsing an otherwise plain one to its address lost the id.
it('keeps the server id through an edit', async () => {
const onConfirm = vi.fn();
renderWithProviders(
<DnsServerModal
open
server={{ address: '1.1.1.1', id: 'cf', timeoutMs: 4000 }}
isEdit
onClose={() => {}}
onConfirm={onConfirm}
/>,
);
const ok = document.querySelector('.ant-modal-footer .ant-btn-primary') as HTMLElement;
await act(async () => {
fireEvent.click(ok);
});
expect(onConfirm).toHaveBeenCalledTimes(1);
expect(onConfirm.mock.calls[0][0]).toMatchObject({ address: '1.1.1.1', id: 'cf' });
});
it('saves an id typed for a plain server', async () => {
const onConfirm = vi.fn();
renderWithProviders(
<DnsServerModal open server="1.1.1.1" isEdit onClose={() => {}} onConfirm={onConfirm} />,
);
fireEvent.change(screen.getByLabelText('ID'), { target: { value: 'cf' } });
const ok = document.querySelector('.ant-modal-footer .ant-btn-primary') as HTMLElement;
await act(async () => {
fireEvent.click(ok);
});
expect(onConfirm.mock.calls[0][0]).toMatchObject({ address: '1.1.1.1', id: 'cf' });
});
});