Prechádzať zdrojové kódy

fix(clients): preserve traffic reset schedule when toggling enable (#6502)

Carry the hydrated reset cycle and day into the enable update payload so toggling a client does not normalize its schedule to never. Cover both toggle directions with a regression test.
Alireza Arezoumandan 6 hodín pred
rodič
commit
d0ad773edf

+ 2 - 0
frontend/src/hooks/useClients.ts

@@ -697,6 +697,8 @@ export function useClients(options: UseClientsOptions = {}) {
         reset: Number(base.reset) || 0,
         resetDay: Number(base.resetDay) || 0,
         resetMax: Number(base.resetMax) || 0,
+        trafficReset: base.trafficReset || 'never',
+        trafficResetDay: Number(base.trafficResetDay) || 1,
         group: base.group || '',
         comment: base.comment || '',
         enable: !!enable,

+ 52 - 0
frontend/src/test/client-toggle-traffic-reset.test.tsx

@@ -0,0 +1,52 @@
+import type { ReactNode } from 'react';
+import { act, renderHook } from '@testing-library/react';
+import { QueryClientProvider } from '@tanstack/react-query';
+import { afterEach, describe, expect, it, vi } from 'vitest';
+
+import { useClients } from '@/hooks/useClients';
+import { makeTestQueryClient } from '@/test/test-utils';
+import { HttpUtil, Msg } from '@/utils';
+
+afterEach(() => {
+  vi.restoreAllMocks();
+});
+
+describe('client enable toggle', () => {
+  it.each([false, true])(
+    'preserves the hydrated traffic reset cycle when enable=%s',
+    async (enable) => {
+      const email = '[email protected]';
+      vi.spyOn(HttpUtil, 'get').mockResolvedValue(
+        new Msg(true, '', {
+          client: { email, enable: !enable, trafficReset: 'monthly', trafficResetDay: 15 },
+          inboundIds: [],
+        }),
+      );
+      const post = vi
+        .spyOn(HttpUtil, 'post')
+        .mockImplementation(
+          async (url: string) =>
+            new Msg(true, '', url.includes('/setting/defaultSettings') ? {} : null),
+        );
+      const queryClient = makeTestQueryClient();
+      const wrapper = ({ children }: { children: ReactNode }) => (
+        <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
+      );
+      const { result } = renderHook(() => useClients({ list: false }), { wrapper });
+
+      await act(async () => {
+        await result.current.setEnable(
+          { email, trafficReset: 'never', trafficResetDay: 1 },
+          enable,
+        );
+      });
+
+      expect(HttpUtil.get).toHaveBeenCalledWith('/panel/api/clients/get/scheduled%40example.com');
+      expect(post).toHaveBeenCalledWith(
+        '/panel/api/clients/update/scheduled%40example.com',
+        expect.objectContaining({ email, enable, trafficReset: 'monthly', trafficResetDay: 15 }),
+        { headers: { 'Content-Type': 'application/json' } },
+      );
+    },
+  );
+});