fix: fix at tests + /api proxy

This commit is contained in:
2026-08-17 13:04:29 +07:00
parent 76f26430ba
commit 4e788312ab
5 changed files with 33 additions and 19 deletions

View File

@@ -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 });

View File

@@ -87,7 +87,7 @@ async function refreshTokens(): Promise<boolean> {
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<T>(path: string, opts: RequestOptions = {}): Promise<T> {
/* ── Public API ───────────────────────────────────────────── */
export const api = {
signup(payload: SignupPayload): Promise<LoginResponse> {
return request<LoginResponse>('/auth/signup', { method: 'POST', body: payload, auth: false });
return request<LoginResponse>('/api/auth/signup', { method: 'POST', body: payload, auth: false });
},
login(payload: LoginPayload): Promise<LoginResponse> {
return request<LoginResponse>('/auth/login', { method: 'POST', body: payload, auth: false });
return request<LoginResponse>('/api/auth/login', { method: 'POST', body: payload, auth: false });
},
getPlans(): Promise<PricingPlans> {
return request<PricingPlans>('/plans/', { auth: false });
return request<PricingPlans>('/api/plans/', { auth: false });
},
checkout(order: OrderDetails): Promise<CheckoutResponse> {
return request<CheckoutResponse>('/orders/checkout', { method: 'POST', body: order });
return request<CheckoutResponse>('/api/orders/checkout', { method: 'POST', body: order });
},
getMe(): Promise<UserInfo> {
return request<UserInfo>('/users/me');
return request<UserInfo>('/api/users/me');
},
getSubscription(): Promise<SubscriptionData> {
return request<SubscriptionData>('/users/subscription');
return request<SubscriptionData>('/api/users/subscription');
},
getDevices(): Promise<Device[]> {
return request<Device[]>('/users/subscription/hwid');
return request<Device[]>('/api/users/subscription/hwid');
},
deleteDevice(hwid: string): Promise<OperationResult> {
return request<OperationResult>(
`/users/subscription/hwid?hwid=${encodeURIComponent(hwid)}`,
`/api/users/subscription/hwid?hwid=${encodeURIComponent(hwid)}`,
{ method: 'DELETE' },
);
},

View File

@@ -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);
});

View File

@@ -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<string, string>();
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();