multi-tunnel-client-config.test.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. import { describe, it, expect } from 'vitest';
  2. import { screen } from '@testing-library/react';
  3. import { MemoryRouter } from 'react-router';
  4. import ClientInfoModal from '@/pages/clients/ClientInfoModal';
  5. import ClientQrModal from '@/pages/clients/ClientQrModal';
  6. import type { ClientRecord, InboundOption } from '@/hooks/useClients';
  7. import { renderWithProviders } from './test-utils';
  8. const deAwgInbound: InboundOption = {
  9. id: 101,
  10. tag: 'awg-de',
  11. remark: 'DE · Kelsterbach',
  12. port: 52716,
  13. protocol: 'amneziawg',
  14. nodeAddress: 'de.vpn.example.com',
  15. awgServer: {
  16. publicKey: 'deServerPublicKey==',
  17. primaryDns: '1.1.1.1',
  18. secondaryDns: '1.0.0.1',
  19. mtu: 1420,
  20. jc: 4,
  21. jmin: 40,
  22. jmax: 100,
  23. s1: 30,
  24. s2: 90,
  25. s3: 0,
  26. s4: 0,
  27. h1: '123',
  28. h2: '456',
  29. h3: '789',
  30. h4: '101112',
  31. },
  32. };
  33. const fiAwgInbound: InboundOption = {
  34. id: 102,
  35. tag: 'awg-fi',
  36. remark: 'FI · Helsinki',
  37. port: 26641,
  38. protocol: 'amneziawg',
  39. nodeAddress: 'fi.vpn.example.com',
  40. awgServer: {
  41. publicKey: 'fiServerPublicKey==',
  42. primaryDns: '8.8.8.8',
  43. secondaryDns: '8.8.4.4',
  44. mtu: 1380,
  45. jc: 10,
  46. jmin: 20,
  47. jmax: 80,
  48. s1: 25,
  49. s2: 50,
  50. s3: 0,
  51. s4: 0,
  52. h1: '999',
  53. h2: '888',
  54. h3: '777',
  55. h4: '666',
  56. },
  57. };
  58. const usWgInbound: InboundOption = {
  59. id: 201,
  60. tag: 'wg-us',
  61. remark: 'US · New York',
  62. port: 51820,
  63. protocol: 'wireguard',
  64. nodeAddress: 'us.vpn.example.com',
  65. wgPublicKey: 'usWgServerPublicKey==',
  66. wgDns: '1.1.1.1',
  67. wgMtu: 1420,
  68. };
  69. const euWgInbound: InboundOption = {
  70. id: 202,
  71. tag: 'wg-eu',
  72. remark: 'EU · Frankfurt',
  73. port: 51821,
  74. protocol: 'wireguard',
  75. nodeAddress: 'eu.vpn.example.com',
  76. wgPublicKey: 'euWgServerPublicKey==',
  77. wgDns: '9.9.9.9',
  78. wgMtu: 1400,
  79. };
  80. const multiAwgClient: ClientRecord = {
  81. id: 'c1',
  82. email: 'NSK-RT-01',
  83. privateKey: 'clientPrivateKey==',
  84. publicKey: 'clientPublicKey==',
  85. preSharedKey: 'clientPsk==',
  86. allowedIPs: '10.8.0.2/32',
  87. keepAlive: 25,
  88. inboundIds: [101, 102],
  89. enable: true,
  90. } as unknown as ClientRecord;
  91. const multiWgClient: ClientRecord = {
  92. id: 'c2',
  93. email: 'WG-CLIENT',
  94. privateKey: 'wgClientPrivateKey==',
  95. publicKey: 'wgClientPublicKey==',
  96. preSharedKey: 'wgClientPsk==',
  97. allowedIPs: '10.0.0.2/32',
  98. keepAlive: 25,
  99. inboundIds: [201, 202],
  100. enable: true,
  101. } as unknown as ClientRecord;
  102. const singleAwgClient: ClientRecord = {
  103. id: 'c3',
  104. email: 'SINGLE-CLIENT',
  105. privateKey: 'clientPrivateKey==',
  106. publicKey: 'clientPublicKey==',
  107. allowedIPs: '10.8.0.2/32',
  108. inboundIds: [101],
  109. enable: true,
  110. } as unknown as ClientRecord;
  111. describe('Multi-tunnel Client Modals', () => {
  112. it('renders distinct labeled ConfigBlocks in ClientInfoModal for multiple AmneziaWG inbounds', () => {
  113. renderWithProviders(
  114. <ClientInfoModal
  115. open
  116. client={multiAwgClient}
  117. inboundsById={{ 101: deAwgInbound, 102: fiAwgInbound }}
  118. isOnline={false}
  119. tunnelAllowedIPs={{ 101: '10.8.1.5/32', 102: '10.8.2.10/32' }}
  120. onOpenChange={() => {}}
  121. />,
  122. );
  123. expect(screen.getAllByText('DE · Kelsterbach')).toHaveLength(2);
  124. expect(screen.getByText('FI · Helsinki')).toBeTruthy();
  125. expect(document.querySelectorAll('.config-block')).toHaveLength(2);
  126. });
  127. it('renders distinct labeled ConfigBlocks in ClientInfoModal for multiple WireGuard inbounds', () => {
  128. renderWithProviders(
  129. <ClientInfoModal
  130. open
  131. client={multiWgClient}
  132. inboundsById={{ 201: usWgInbound, 202: euWgInbound }}
  133. isOnline={false}
  134. tunnelAllowedIPs={{ 201: '10.0.1.2/32', 202: '10.0.2.2/32' }}
  135. onOpenChange={() => {}}
  136. />,
  137. );
  138. expect(screen.getAllByText('US · New York')).toHaveLength(2);
  139. expect(screen.getByText('EU · Frankfurt')).toBeTruthy();
  140. expect(document.querySelectorAll('.config-block')).toHaveLength(2);
  141. });
  142. it('renders single default-labeled ConfigBlock in ClientInfoModal for single inbound', () => {
  143. renderWithProviders(
  144. <ClientInfoModal
  145. open
  146. client={singleAwgClient}
  147. inboundsById={{ 101: deAwgInbound }}
  148. isOnline={false}
  149. onOpenChange={() => {}}
  150. />,
  151. );
  152. expect(document.querySelectorAll('.config-block')).toHaveLength(1);
  153. expect(screen.getByText('Config')).toBeTruthy();
  154. });
  155. it('renders separate collapse panels in ClientQrModal for multiple AmneziaWG inbounds', () => {
  156. renderWithProviders(
  157. <MemoryRouter initialEntries={['/clients']}>
  158. <ClientQrModal
  159. open
  160. client={multiAwgClient}
  161. inboundsById={{ 101: deAwgInbound, 102: fiAwgInbound }}
  162. tunnelAllowedIPs={{ 101: '10.8.1.5/32', 102: '10.8.2.10/32' }}
  163. onOpenChange={() => {}}
  164. />
  165. </MemoryRouter>,
  166. );
  167. expect(screen.getByText('DE · Kelsterbach')).toBeTruthy();
  168. expect(screen.getByText('FI · Helsinki')).toBeTruthy();
  169. });
  170. });