From 4e788312ab2aa9bcf79fcc43cd82c88df7911677 Mon Sep 17 00:00:00 2001 From: hexdev Date: Mon, 17 Aug 2026 13:04:29 +0700 Subject: [PATCH] fix: fix at tests + /api proxy --- src/api/client.test.ts | 4 ++-- src/api/client.ts | 18 +++++++++--------- src/pages/AccountPage.test.tsx | 6 +++--- src/test/setup.ts | 15 ++++++++++++++- vite.config.ts | 9 +++++---- 5 files changed, 33 insertions(+), 19 deletions(-) diff --git a/src/api/client.test.ts b/src/api/client.test.ts index 64dfadd..029b8e1 100644 --- a/src/api/client.test.ts +++ b/src/api/client.test.ts @@ -98,7 +98,7 @@ describe('api client', () => { mockFetch(async (input) => { calls++; const url = urlOf(input); - if (url.startsWith('/auth/refresh')) { + if (url.startsWith('/api/auth/refresh')) { return jsonResponse({ access_token: 'new', refresh_token: 'new-r', expires_at: 9999999999 }); } if (calls === 1) return jsonResponse({ detail: 'expired' }, 401); @@ -113,7 +113,7 @@ describe('api client', () => { setStoredTokens({ access_token: ACCESS, refresh_token: REFRESH, expires_at: 9999999999 }); mockFetch(async (input) => { const url = urlOf(input); - if (url.startsWith('/auth/refresh')) return jsonResponse({ detail: 'invalid' }, 401); + if (url.startsWith('/api/auth/refresh')) return jsonResponse({ detail: 'invalid' }, 401); return jsonResponse({ detail: 'expired' }, 401); }); await expect(api.getMe()).rejects.toMatchObject({ status: 401 }); diff --git a/src/api/client.ts b/src/api/client.ts index afd6b45..cfe0f90 100644 --- a/src/api/client.ts +++ b/src/api/client.ts @@ -87,7 +87,7 @@ async function refreshTokens(): Promise { refreshing = (async () => { try { const res = await fetch( - `/auth/refresh?refresh_token=${encodeURIComponent(refresh)}&iss=credentials`, + `/api/auth/refresh?refresh_token=${encodeURIComponent(refresh)}&iss=credentials`, { method: 'POST' }, ); if (!res.ok) return false; @@ -155,29 +155,29 @@ async function request(path: string, opts: RequestOptions = {}): Promise { /* ── Public API ───────────────────────────────────────────── */ export const api = { signup(payload: SignupPayload): Promise { - return request('/auth/signup', { method: 'POST', body: payload, auth: false }); + return request('/api/auth/signup', { method: 'POST', body: payload, auth: false }); }, login(payload: LoginPayload): Promise { - return request('/auth/login', { method: 'POST', body: payload, auth: false }); + return request('/api/auth/login', { method: 'POST', body: payload, auth: false }); }, getPlans(): Promise { - return request('/plans/', { auth: false }); + return request('/api/plans/', { auth: false }); }, checkout(order: OrderDetails): Promise { - return request('/orders/checkout', { method: 'POST', body: order }); + return request('/api/orders/checkout', { method: 'POST', body: order }); }, getMe(): Promise { - return request('/users/me'); + return request('/api/users/me'); }, getSubscription(): Promise { - return request('/users/subscription'); + return request('/api/users/subscription'); }, getDevices(): Promise { - return request('/users/subscription/hwid'); + return request('/api/users/subscription/hwid'); }, deleteDevice(hwid: string): Promise { return request( - `/users/subscription/hwid?hwid=${encodeURIComponent(hwid)}`, + `/api/users/subscription/hwid?hwid=${encodeURIComponent(hwid)}`, { method: 'DELETE' }, ); }, diff --git a/src/pages/AccountPage.test.tsx b/src/pages/AccountPage.test.tsx index d132824..a924576 100644 --- a/src/pages/AccountPage.test.tsx +++ b/src/pages/AccountPage.test.tsx @@ -1,5 +1,5 @@ import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest'; -import { render, screen, waitFor } from '@testing-library/react'; +import { render, screen, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { MemoryRouter, Routes, Route } from 'react-router-dom'; import { AccountPage } from './AccountPage'; @@ -163,9 +163,9 @@ describe('AccountPage', () => { await user.click(await screen.findByRole('button', { name: /показать клиенты для подключения/i })); expect(await screen.findByRole('dialog', { name: /выберите клиент/i })).toBeInTheDocument(); - expect(screen.getAllByRole('link', { name: 'v2raytun' })[0]).toHaveAttribute( + expect(within(screen.getByRole('region', { name: 'Android' })).getByRole('link', { name: 'v2raytun' })).toHaveAttribute( 'href', - 'https://apps.apple.com/en/app/v2raytun/id6476628951', + 'https://play.google.com/store/apps/details?id=com.v2raytun.android&hl=ru', ); expect(screen.getAllByText(/разрешить отправку hwid/i)).toHaveLength(2); }); diff --git a/src/test/setup.ts b/src/test/setup.ts index fe96724..d735a31 100644 --- a/src/test/setup.ts +++ b/src/test/setup.ts @@ -1,7 +1,20 @@ import '@testing-library/jest-dom/vitest'; -import { afterEach } from 'vitest'; +import { afterEach, vi } from 'vitest'; import { cleanup } from '@testing-library/react'; +const storage = new Map(); + +vi.stubGlobal('localStorage', { + get length() { + return storage.size; + }, + clear: () => storage.clear(), + getItem: (key: string) => storage.get(key) ?? null, + key: (index: number) => [...storage.keys()][index] ?? null, + removeItem: (key: string) => storage.delete(key), + setItem: (key: string, value: string) => storage.set(key, String(value)), +} satisfies Storage); + afterEach(() => { cleanup(); localStorage.clear(); diff --git a/vite.config.ts b/vite.config.ts index 3779ac9..f8b0e26 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -7,10 +7,11 @@ export default defineConfig({ server: { port: 5173, proxy: { - '/auth': { target: 'http://127.0.0.1:8000', changeOrigin: true }, - '/plans': { target: 'http://127.0.0.1:8000', changeOrigin: true }, - '/orders': { target: 'http://127.0.0.1:8000', changeOrigin: true }, - '/users': { target: 'http://127.0.0.1:8000', changeOrigin: true }, + '/api': { + target: 'http://127.0.0.1:8000', + changeOrigin: true, + rewrite: (path) => path.replace(/^\/api/, ''), + }, }, }, test: {