use-xray-setting.test.tsx 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import type { ReactNode } from 'react';
  2. import { act, renderHook, waitFor } from '@testing-library/react';
  3. import { QueryClientProvider } from '@tanstack/react-query';
  4. import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
  5. import { useXraySetting } from '@/hooks/useXraySetting';
  6. import { makeTestQueryClient } from '@/test/test-utils';
  7. import { HttpUtil, Msg } from '@/utils';
  8. function xrayPayload(overrides: Record<string, unknown> = {}) {
  9. return {
  10. xraySetting: {},
  11. inboundTags: [],
  12. clientReverseTags: [],
  13. outboundTestUrl: 'https://test.example',
  14. subscriptionOutbounds: [],
  15. subscriptionOutboundTags: [],
  16. ...overrides,
  17. };
  18. }
  19. afterEach(() => {
  20. vi.restoreAllMocks();
  21. });
  22. beforeEach(() => {
  23. vi.spyOn(HttpUtil, 'get').mockResolvedValue(new Msg(true, '', []));
  24. });
  25. describe('useXraySetting', () => {
  26. it('refreshes server-derived outbounds while the editor is dirty', async () => {
  27. let payload = xrayPayload({ subscriptionOutbounds: [{ tag: 'before' }] });
  28. vi.spyOn(HttpUtil, 'post').mockImplementation(async (url) => {
  29. if (url === '/panel/api/xray/') return new Msg(true, '', JSON.stringify(payload));
  30. return new Msg(true, '');
  31. });
  32. const queryClient = makeTestQueryClient();
  33. const wrapper = ({ children }: { children: ReactNode }) => (
  34. <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  35. );
  36. const { result } = renderHook(() => useXraySetting(), { wrapper });
  37. await waitFor(() => expect(result.current.fetched).toBe(true));
  38. act(() => result.current.setXraySetting('{"outbounds":[]}'));
  39. payload = xrayPayload({ subscriptionOutbounds: [{ tag: 'after' }] });
  40. await act(async () => result.current.fetchAll());
  41. await waitFor(() => expect(result.current.subscriptionOutbounds).toEqual([{ tag: 'after' }]));
  42. expect(result.current.xraySetting).toBe('{"outbounds":[]}');
  43. });
  44. it('keeps the outbound test URL input empty when it is cleared', async () => {
  45. const payload = xrayPayload({ outboundTestUrl: 'https://www.google.com/generate_204' });
  46. vi.spyOn(HttpUtil, 'post').mockImplementation(async (url) => {
  47. if (url === '/panel/api/xray/') return new Msg(true, '', JSON.stringify(payload));
  48. return new Msg(true, '');
  49. });
  50. const queryClient = makeTestQueryClient();
  51. const wrapper = ({ children }: { children: ReactNode }) => (
  52. <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
  53. );
  54. const { result } = renderHook(() => useXraySetting(), { wrapper });
  55. await waitFor(() => expect(result.current.fetched).toBe(true));
  56. act(() => result.current.setOutboundTestUrl(''));
  57. expect(result.current.outboundTestUrl).toBe('');
  58. expect(result.current.saveDisabled).toBe(true);
  59. });
  60. });