|
|
@@ -1,12 +1,16 @@
|
|
|
-import { describe, it, expect, vi } from 'vitest';
|
|
|
-import { fireEvent, screen } from '@testing-library/react';
|
|
|
+import { afterEach, describe, it, expect, vi } from 'vitest';
|
|
|
+import { fireEvent, screen, waitFor } from '@testing-library/react';
|
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
|
|
|
|
import RuleFormModal from '@/pages/xray/routing/RuleFormModal';
|
|
|
+import { keys } from '@/api/queryKeys';
|
|
|
+import { HttpUtil, Msg } from '@/utils';
|
|
|
|
|
|
-import { renderWithProviders } from './test-utils';
|
|
|
+import { chooseSelectOption, renderWithProviders } from './test-utils';
|
|
|
|
|
|
describe('RuleFormModal edit preserves unsurfaced fields', () => {
|
|
|
+ afterEach(() => vi.restoreAllMocks());
|
|
|
+
|
|
|
it('keeps a field the form does not surface (ruleTag) when saving an edit', () => {
|
|
|
const onConfirm = vi.fn();
|
|
|
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
|
|
@@ -30,4 +34,95 @@ describe('RuleFormModal edit preserves unsurfaced fields', () => {
|
|
|
expect(onConfirm).toHaveBeenCalledTimes(1);
|
|
|
expect(onConfirm.mock.calls[0][0]).toMatchObject({ ruleTag: 'my-tag' });
|
|
|
});
|
|
|
+
|
|
|
+ it('selects existing clients for the user criterion', async () => {
|
|
|
+ vi.spyOn(HttpUtil, 'get').mockResolvedValue(
|
|
|
+ new Msg(true, '', [
|
|
|
+ { id: 1, email: '[email protected]' },
|
|
|
+ { id: 2, email: '[email protected]' },
|
|
|
+ ]),
|
|
|
+ );
|
|
|
+ const onConfirm = vi.fn();
|
|
|
+ const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
|
|
|
+
|
|
|
+ renderWithProviders(
|
|
|
+ <RuleFormModal
|
|
|
+ open
|
|
|
+ rule={null}
|
|
|
+ inboundTags={[]}
|
|
|
+ outboundTags={['direct']}
|
|
|
+ balancerTags={[]}
|
|
|
+ onClose={vi.fn()}
|
|
|
+ onConfirm={onConfirm}
|
|
|
+ />,
|
|
|
+ { queryClient },
|
|
|
+ );
|
|
|
+
|
|
|
+ await waitFor(() =>
|
|
|
+ expect(HttpUtil.get).toHaveBeenCalledWith('/panel/api/clients/list', undefined, {
|
|
|
+ silent: true,
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ await waitFor(() => expect(queryClient.getQueryData(keys.clients.all())).toHaveLength(2));
|
|
|
+ const userField = screen.getByLabelText('User');
|
|
|
+ expect(screen.getByText('Select users')).toBeTruthy();
|
|
|
+ chooseSelectOption(userField.id, '[email protected]');
|
|
|
+ chooseSelectOption(userField.id, '[email protected]');
|
|
|
+ fireEvent.click(screen.getByRole('button', { name: 'Create' }));
|
|
|
+
|
|
|
+ expect(onConfirm).toHaveBeenCalledWith(
|
|
|
+ expect.objectContaining({ user: ['[email protected]', '[email protected]'] }),
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ it('preserves a saved user that is no longer in the client list', async () => {
|
|
|
+ vi.spyOn(HttpUtil, 'get').mockResolvedValue(
|
|
|
+ new Msg(true, '', [{ id: 1, email: '[email protected]' }]),
|
|
|
+ );
|
|
|
+ const onConfirm = vi.fn();
|
|
|
+
|
|
|
+ renderWithProviders(
|
|
|
+ <RuleFormModal
|
|
|
+ open
|
|
|
+ rule={{ type: 'field', user: ['[email protected]'], outboundTag: 'direct' }}
|
|
|
+ inboundTags={[]}
|
|
|
+ outboundTags={['direct']}
|
|
|
+ balancerTags={[]}
|
|
|
+ onClose={vi.fn()}
|
|
|
+ onConfirm={onConfirm}
|
|
|
+ />,
|
|
|
+ );
|
|
|
+
|
|
|
+ await waitFor(() => expect(screen.getByText('[email protected]')).toBeTruthy());
|
|
|
+ fireEvent.click(screen.getByRole('button', { name: 'Save Changes' }));
|
|
|
+
|
|
|
+ expect(onConfirm).toHaveBeenCalledWith(
|
|
|
+ expect.objectContaining({ user: ['[email protected]'] }),
|
|
|
+ );
|
|
|
+ });
|
|
|
+
|
|
|
+ it('accepts a custom user identifier that is not a client record', async () => {
|
|
|
+ vi.spyOn(HttpUtil, 'get').mockResolvedValue(
|
|
|
+ new Msg(true, '', [{ id: 1, email: '[email protected]' }]),
|
|
|
+ );
|
|
|
+ const onConfirm = vi.fn();
|
|
|
+
|
|
|
+ renderWithProviders(
|
|
|
+ <RuleFormModal
|
|
|
+ open
|
|
|
+ rule={null}
|
|
|
+ inboundTags={[]}
|
|
|
+ outboundTags={['direct']}
|
|
|
+ balancerTags={[]}
|
|
|
+ onClose={vi.fn()}
|
|
|
+ onConfirm={onConfirm}
|
|
|
+ />,
|
|
|
+ );
|
|
|
+
|
|
|
+ const userField = screen.getByLabelText('User');
|
|
|
+ fireEvent.change(userField, { target: { value: 'office-proxy,' } });
|
|
|
+ fireEvent.click(screen.getByRole('button', { name: 'Create' }));
|
|
|
+
|
|
|
+ expect(onConfirm).toHaveBeenCalledWith(expect.objectContaining({ user: ['office-proxy'] }));
|
|
|
+ });
|
|
|
});
|