75+ fronttest

This commit is contained in:
iqubik
2026-03-29 23:49:43 +03:00
parent f6908cd890
commit 6afa8f268e
3 changed files with 300 additions and 0 deletions
+175
View File
@@ -444,5 +444,180 @@ describe('DomainsPage', () => {
}))
})
})
it('должен очищать результаты сканирования', async () => {
setupMockGet({
capabilities: { scannerAvailable: true },
settings: { xui_ip: '1.2.3.4' }
})
mockPost.mockResolvedValue({ data: { runId: '123', foundCount: 2, domains: ['a.com', 'b.com'] } })
renderDomainsPage()
const scanButton = await screen.findByText('Сканировать')
fireEvent.click(scanButton)
const clearButton = await screen.findByText('Очистить предварительный')
fireEvent.click(clearButton)
await waitFor(() => {
expect(mockGet).toHaveBeenCalled()
})
})
it('должен изменять настройки сканирования', async () => {
setupMockGet({
capabilities: { scannerAvailable: true },
settings: { xui_ip: '1.2.3.4' }
})
renderDomainsPage()
const secondsInput = await screen.findByLabelText('Секунд скана')
fireEvent.change(secondsInput, { target: { value: '120' } })
expect(secondsInput).toHaveValue(120)
const threadInput = screen.getByLabelText('Потоков')
fireEvent.change(threadInput, { target: { value: '8' } })
expect(threadInput).toHaveValue(8)
const timeoutInput = screen.getByLabelText('Таймаут, сек')
fireEvent.change(timeoutInput, { target: { value: '10' } })
expect(timeoutInput).toHaveValue(10)
})
it('должен разворачивать/сворачивать аккордеон сканера', async () => {
setupMockGet({
capabilities: { scannerAvailable: true }
})
renderDomainsPage()
const accordionSummary = await screen.findByText('Автопоиск SNI (backend scanner)')
fireEvent.click(accordionSummary)
await waitFor(() => {
const secondsInput = screen.getByLabelText('Секунд скана')
expect(secondsInput).toBeInTheDocument()
})
})
it('должен показывать сообщение при пустом списке кандидатов после сканирования', async () => {
setupMockGet({
capabilities: { scannerAvailable: true },
settings: { xui_ip: '1.2.3.4' }
})
mockPost.mockResolvedValue({ data: { runId: '123', foundCount: 0, domains: [] } })
renderDomainsPage()
const scanButton = await screen.findByText('Сканировать')
fireEvent.click(scanButton)
await waitFor(() => {
expect(screen.getByText('Домены не найдены')).toBeInTheDocument()
})
})
it('должен сохранять состояние сканера в localStorage', async () => {
const mockSetItem = vi.fn()
const mockLocalStorage = {
getItem: vi.fn().mockReturnValue(null),
setItem: mockSetItem,
removeItem: vi.fn(),
clear: vi.fn(),
}
Object.defineProperty(window, 'localStorage', { value: mockLocalStorage, writable: true })
setupMockGet({
capabilities: { scannerAvailable: true },
settings: { xui_ip: '1.2.3.4' }
})
renderDomainsPage()
const addrInput = await screen.findByLabelText('IP/домен VPS')
fireEvent.change(addrInput, { target: { value: 'new-addr.com' } })
await waitFor(() => {
expect(mockSetItem).toHaveBeenCalledWith(
'domains_scan_state_v1',
expect.any(String)
)
})
})
it('должен показывать кнопку удаления для домена в основном списке', async () => {
setupMockGet({
domains: { data: [{ id: 1, name: 'test.com' }], total: 1 }
})
renderDomainsPage()
const deleteButtons = await screen.findAllByTestId('icon-Delete')
expect(deleteButtons.length).toBeGreaterThan(0)
})
it('должен подтверждать удаление всех доменов', async () => {
setupMockGet({
domains: { data: [{ id: 1, name: 'test.com' }], total: 1 }
})
mockDelete.mockResolvedValue({})
renderDomainsPage()
const deleteAllButton = await screen.findByText('Удалить все')
fireEvent.click(deleteAllButton)
const confirmButton = await screen.findByText('Удалить')
fireEvent.click(confirmButton)
await waitFor(() => {
expect(mockDelete).toHaveBeenCalledWith('/domains/all')
})
})
it('должен показывать успех после удаления всех доменов', async () => {
setupMockGet({
domains: { data: [{ id: 1, name: 'test.com' }], total: 1 }
})
mockDelete.mockResolvedValue({})
renderDomainsPage()
const deleteAllButton = await screen.findByText('Удалить все')
fireEvent.click(deleteAllButton)
const confirmButton = await screen.findByText('Удалить')
fireEvent.click(confirmButton)
await waitFor(() => {
const alerts = screen.getAllByRole('alert')
const successAlert = alerts.find(alert => alert.textContent?.includes('Все домены удалены'))
expect(successAlert).toBeInTheDocument()
})
})
it('должен показывать ошибку при неудачном удалении всех доменов', async () => {
setupMockGet({
domains: { data: [{ id: 1, name: 'test.com' }], total: 1 }
})
mockDelete.mockRejectedValue({ response: { status: 500 } })
renderDomainsPage()
const deleteAllButton = await screen.findByText('Удалить все')
fireEvent.click(deleteAllButton)
const confirmButton = await screen.findByText('Удалить')
fireEvent.click(confirmButton)
await waitFor(() => {
const alerts = screen.getAllByRole('alert')
const errorAlert = alerts.find(alert => alert.textContent?.includes('Ошибка удаления'))
expect(errorAlert).toBeInTheDocument()
})
})
})
})
@@ -697,4 +697,128 @@ describe('SubscriptionsPage', () => {
})
})
})
describe('Утилитные функции', () => {
it('должен генерировать уникальный ID', async () => {
setupMockGet()
renderSubscriptionsPage()
const createButton = await screen.findByText('Создать')
fireEvent.click(createButton)
// Проверяем что ID генерируется (просто что форма открывается)
await waitFor(() => {
expect(screen.getByText('Новая подписка')).toBeInTheDocument()
})
})
})
describe('Просмотр ссылок', () => {
it('должен открывать диалог ссылок при клике на опцию меню', async () => {
const mockSubs = [
{ id: '1', name: 'Test Sub', uuid: 'abc-123', inbounds: [{ type: 'vless', port: 443, sni: 'example.com', link: 'vless://test' }], isAutoRotationEnabled: true }
]
setupMockGet({ subscriptions: mockSubs })
renderSubscriptionsPage()
const menuButton = await screen.findByTestId('icon-MoreVert')
fireEvent.click(menuButton)
const linksOption = await screen.findByText('Показать конфиги')
fireEvent.click(linksOption)
await waitFor(() => {
expect(screen.getByText('Активные ссылки')).toBeInTheDocument()
})
})
it('должен закрывать диалог ссылок при клике на "Закрыть"', async () => {
const mockSubs = [
{ id: '1', name: 'Test Sub', uuid: 'abc-123', inbounds: [{ type: 'vless', port: 443, sni: 'example.com', link: 'vless://test' }], isAutoRotationEnabled: true }
]
setupMockGet({ subscriptions: mockSubs })
renderSubscriptionsPage()
const menuButton = await screen.findByTestId('icon-MoreVert')
fireEvent.click(menuButton)
const linksOption = await screen.findByText('Показать конфиги')
fireEvent.click(linksOption)
const closeButton = await screen.findByText('Закрыть')
fireEvent.click(closeButton)
await waitFor(() => {
expect(screen.queryByText('Активные ссылки')).not.toBeInTheDocument()
})
})
it('должен копировать ссылку при клике на кнопку копирования', async () => {
const mockSubs = [
{ id: '1', name: 'Test Sub', uuid: 'abc-123', inbounds: [{ type: 'vless', port: 443, sni: 'example.com', link: 'vless://test' }], isAutoRotationEnabled: true }
]
setupMockGet({ subscriptions: mockSubs })
mockClipboardWriteText.mockResolvedValue(undefined)
renderSubscriptionsPage()
const menuButton = await screen.findByTestId('icon-MoreVert')
fireEvent.click(menuButton)
const linksOption = await screen.findByText('Показать конфиги')
fireEvent.click(linksOption)
const copyButton = await screen.findByText('Копировать все')
fireEvent.click(copyButton)
await waitFor(() => {
expect(mockClipboardWriteText).toHaveBeenCalled()
})
})
it('должен открывать ссылку в новой вкладке при клике на иконку открытия', async () => {
const mockSubs = [
{ id: '1', name: 'Test Sub', uuid: 'abc-123', inbounds: [{ type: 'vless', port: 443, sni: 'example.com', link: 'vless://test' }], isAutoRotationEnabled: true }
]
setupMockGet({ subscriptions: mockSubs })
renderSubscriptionsPage()
const menuButton = await screen.findByTestId('icon-MoreVert')
fireEvent.click(menuButton)
const linksOption = await screen.findByText('Показать конфиги')
fireEvent.click(linksOption)
const openButtons = await screen.findAllByTestId('icon-OpenInNew')
if (openButtons.length > 0) {
fireEvent.click(openButtons[0])
}
await waitFor(() => {
expect(mockWindowOpen).toHaveBeenCalled()
})
})
it('должен показывать сообщение при отсутствии ссылок', async () => {
const mockSubs = [
{ id: '1', name: 'Test Sub', uuid: 'abc-123', inbounds: [], isAutoRotationEnabled: true }
]
setupMockGet({ subscriptions: mockSubs })
renderSubscriptionsPage()
const menuButton = await screen.findByTestId('icon-MoreVert')
fireEvent.click(menuButton)
const linksOption = await screen.findByText('Показать конфиги')
fireEvent.click(linksOption)
await waitFor(() => {
expect(screen.getByText('Нет активных ссылок (ждите ротации)')).toBeInTheDocument()
})
})
})
})