Refine users table and reconnect handling

This commit is contained in:
2026-04-02 03:14:49 +03:00
parent 2602fab6a7
commit 49b41edcb0
10 changed files with 308 additions and 73 deletions

View File

@@ -1,6 +1,6 @@
import { render, screen, waitFor, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { beforeEach, describe, expect, it } from 'vitest';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import App from './App';
import { fallbackDashboardSnapshot } from './data/mockDashboard';
import { MockWebSocket } from './test/setup';
@@ -115,6 +115,19 @@ describe('App login gate', () => {
expect(screen.getAllByText(/^idle$/i).length).toBeGreaterThan(0);
});
it('shows online data in the users table and keeps proxy copy inside actions', async () => {
const user = userEvent.setup();
render(<App />);
await loginIntoPanel(user);
await user.click(screen.getByRole('button', { name: /users/i }));
expect(screen.getByRole('columnheader', { name: /online/i })).toBeInTheDocument();
expect(screen.queryByRole('columnheader', { name: /^proxy$/i })).not.toBeInTheDocument();
expect(screen.getAllByRole('button', { name: /copy proxy link/i }).length).toBeGreaterThan(0);
expect(screen.getAllByText(/^now$/i).length).toBeGreaterThan(0);
});
it('opens add-user flow in a modal and closes it on escape', async () => {
const user = userEvent.setup();
render(<App />);
@@ -249,6 +262,27 @@ describe('App login gate', () => {
expect(screen.getByLabelText(/proxy endpoint/i)).toHaveValue('draft.example.net');
});
it('shows a connection notice and exits the panel after websocket and api retries are exhausted', async () => {
vi.useFakeTimers();
MockWebSocket.connectMode = 'close';
window.sessionStorage.setItem(
'3proxy-ui-panel-session',
JSON.stringify({
token: 'local-ui-fallback',
expiresAt: new Date(Date.now() + 60_000).toISOString(),
}),
);
render(<App />);
await vi.advanceTimersByTimeAsync(2_100);
expect(screen.getByText(/reconnecting websocket|переподключаем websocket/i)).toBeInTheDocument();
await vi.advanceTimersByTimeAsync(25_000);
expect(screen.getByRole('button', { name: /open panel/i })).toBeInTheDocument();
}, 10_000);
it('warns before deleting a service and removes linked users after confirmation', async () => {
const user = userEvent.setup();
render(<App />);