dify/web/app/components/base/qrcode/__tests__/index.spec.tsx
2026-03-12 15:09:10 +08:00

135 lines
4.2 KiB
TypeScript

import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { downloadUrl } from '@/utils/download'
import ShareQRCode from '..'
vi.mock('@/utils/download', () => ({
downloadUrl: vi.fn(),
}))
describe('ShareQRCode', () => {
const content = 'https://example.com'
beforeEach(() => {
vi.clearAllMocks()
})
describe('Rendering', () => {
it('renders correctly', () => {
render(<ShareQRCode content={content} />)
expect(screen.getByRole('button').firstElementChild).toBeInTheDocument()
})
})
describe('Interaction', () => {
it('toggles QR code panel when clicking the icon', async () => {
const user = userEvent.setup()
render(<ShareQRCode content={content} />)
expect(screen.queryByRole('img')).not.toBeInTheDocument()
const trigger = screen.getByTestId('qrcode-container')
await user.click(trigger)
expect(screen.getByRole('img')).toBeInTheDocument()
await user.click(trigger)
expect(screen.queryByRole('img')).not.toBeInTheDocument()
})
it('closes panel when clicking outside', async () => {
const user = userEvent.setup()
render(
<div>
<div data-testid="outside">Outside</div>
<ShareQRCode content={content} />
</div>,
)
const trigger = screen.getByTestId('qrcode-container')
await user.click(trigger)
expect(screen.getByRole('img')).toBeInTheDocument()
await user.click(screen.getByTestId('outside'))
expect(screen.queryByRole('img')).not.toBeInTheDocument()
})
it('does not close panel when clicking inside the panel', async () => {
const user = userEvent.setup()
render(<ShareQRCode content={content} />)
const trigger = screen.getByTestId('qrcode-container')
await user.click(trigger)
const canvas = screen.getByRole('img')
const panel = canvas.parentElement
await user.click(panel!)
expect(canvas).toBeInTheDocument()
})
it('calls downloadUrl when clicking download', async () => {
const user = userEvent.setup()
const originalToDataURL = HTMLCanvasElement.prototype.toDataURL
HTMLCanvasElement.prototype.toDataURL = vi.fn(() => 'data:image/png;base64,test')
try {
render(<ShareQRCode content={content} />)
const trigger = screen.getByTestId('qrcode-container')
await user.click(trigger!)
const downloadBtn = screen.getByText('appOverview.overview.appInfo.qrcode.download')
await user.click(downloadBtn)
expect(downloadUrl).toHaveBeenCalledWith({
url: 'data:image/png;base64,test',
fileName: 'qrcode.png',
})
}
finally {
HTMLCanvasElement.prototype.toDataURL = originalToDataURL
}
})
it('does not call downloadUrl when canvas is not found', async () => {
const user = userEvent.setup()
render(<ShareQRCode content={content} />)
const trigger = screen.getByTestId('qrcode-container')
await user.click(trigger)
// Override querySelector on the panel to simulate canvas not being found
const panel = screen.getByRole('img').parentElement!
const origQuerySelector = panel.querySelector.bind(panel)
panel.querySelector = ((sel: string) => {
if (sel === 'canvas')
return null
return origQuerySelector(sel)
}) as typeof panel.querySelector
try {
const downloadBtn = screen.getByText('appOverview.overview.appInfo.qrcode.download')
await user.click(downloadBtn)
expect(downloadUrl).not.toHaveBeenCalled()
}
finally {
panel.querySelector = origQuerySelector
}
})
it('does not close when clicking inside the qrcode ref area', async () => {
const user = userEvent.setup()
render(<ShareQRCode content={content} />)
const trigger = screen.getByTestId('qrcode-container')
await user.click(trigger)
// Click on the scan text inside the panel — panel should remain open
const scanText = screen.getByText('appOverview.overview.appInfo.qrcode.scan')
await user.click(scanText)
expect(screen.getByRole('img')).toBeInTheDocument()
})
})
})