Files
3dp-manager/client/test/components/SecurityWarning.spec.tsx
T
2026-03-30 01:29:04 +03:00

176 lines
6.2 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import SecurityWarning from '../../src/components/SecurityWarning'
// Мок для navigator.clipboard
const mockWriteText = vi.fn()
Object.assign(navigator, {
clipboard: {
writeText: mockWriteText,
},
})
// Мок для document.execCommand (fallback для старых браузеров)
const mockExecCommand = vi.fn()
beforeEach(() => {
vi.clearAllMocks()
document.execCommand = mockExecCommand
})
describe('SecurityWarning', () => {
const INSTALL_COMMAND = 'bash <(curl -fsSL https://raw.githubusercontent.com/denpiligrim/3dp-manager/main/install.sh)'
const renderWarning = () => {
return render(<SecurityWarning />)
}
describe('рендеринг', () => {
it('должен рендериться с заголовком предупреждения', () => {
renderWarning()
expect(
screen.getByText(/3DP-MANAGER работает в небезопасном режиме/i)
).toBeInTheDocument()
})
it('должен отображать предупреждение о паролях', () => {
renderWarning()
expect(
screen.getByText(/Не вводите реальные пароли от 3x-ui панели/i)
).toBeInTheDocument()
})
it('должен отображать инструкцию по переустановке', () => {
renderWarning()
expect(
screen.getByText(/Для безопасной работы переустановите 3DP-MANAGER с SSL-сертификатами/i)
).toBeInTheDocument()
})
it('должен отображать команду установки', () => {
renderWarning()
expect(screen.getByText(INSTALL_COMMAND)).toBeInTheDocument()
})
it('должен отображать кнопку копирования команды', () => {
renderWarning()
expect(screen.getByText('Копировать')).toBeInTheDocument()
})
it('должен отображать иконку копирования', () => {
renderWarning()
expect(screen.getByTestId('icon-ContentCopy')).toBeInTheDocument()
})
it('должен иметь семантически правильный Alert', () => {
renderWarning()
const alert = screen.getByRole('alert')
expect(alert).toBeInTheDocument()
})
})
describe('копирование команды', () => {
it('должен копировать команду в буфер обмена при клике', async () => {
mockWriteText.mockResolvedValue(undefined)
renderWarning()
const copyButton = screen.getByText('Копировать')
fireEvent.click(copyButton)
await waitFor(() => {
expect(mockWriteText).toHaveBeenCalledWith(INSTALL_COMMAND)
})
})
it('должен показывать уведомление "Скопировано" после копирования', async () => {
mockWriteText.mockResolvedValue(undefined)
renderWarning()
const copyButton = screen.getByText('Копировать')
fireEvent.click(copyButton)
await waitFor(() => {
expect(screen.getByText('Скопировано')).toBeInTheDocument()
})
})
it('должен использовать fallback при отсутствии navigator.clipboard', async () => {
// Мок ошибки clipboard API
mockWriteText.mockRejectedValue(new Error('Not supported'))
renderWarning()
const copyButton = screen.getByText('Копировать')
fireEvent.click(copyButton)
await waitFor(() => {
expect(mockExecCommand).toHaveBeenCalledWith('copy')
})
})
it('должен показывать уведомление "Скопировано" при использовании fallback', async () => {
mockWriteText.mockRejectedValue(new Error('Not supported'))
mockExecCommand.mockReturnValue(true)
renderWarning()
const copyButton = screen.getByText('Копировать')
fireEvent.click(copyButton)
await waitFor(() => {
expect(screen.getByText('Скопировано')).toBeInTheDocument()
})
})
})
describe('Snackbar уведомление', () => {
it('должен показывать уведомление после копирования', async () => {
mockWriteText.mockResolvedValue(undefined)
renderWarning()
const copyButton = screen.getByText('Копировать')
fireEvent.click(copyButton)
await waitFor(() => {
expect(screen.getByText('Скопировано')).toBeInTheDocument()
})
})
it('должен закрывать уведомление при клике на кнопку закрытия', async () => {
mockWriteText.mockResolvedValue(undefined)
renderWarning()
const copyButton = screen.getByText('Копировать')
fireEvent.click(copyButton)
// Ждём появления уведомления
await waitFor(() => {
expect(screen.getByText('Скопировано')).toBeInTheDocument()
})
// Находим кнопку закрытия по иконке Close
const closeButton = screen.getByTestId('icon-Close').closest('button')
if (closeButton) {
fireEvent.click(closeButton)
}
// Уведомление закрыто
await waitFor(() => {
expect(screen.queryByText('Скопировано')).not.toBeInTheDocument()
})
})
})
describe('стили компонента', () => {
it('должен иметь variant="filled"', () => {
renderWarning()
const alert = screen.getByRole('alert')
// Проверяем что Alert имеет filled стиль (проверка через классы MUI)
expect(alert).toHaveClass('MuiAlert-filledWarning')
})
it('должен отображать код в monospace шрифте', () => {
renderWarning()
const codeBlock = screen.getByText(INSTALL_COMMAND)
expect(codeBlock.tagName).toBe('CODE')
})
})
})