import '@testing-library/jest-dom' import { render, screen } from '@testing-library/react' import { vi } from 'vitest' import { FileItem, TFileItemList, TFileTransfer } from './types' import { PktFileUpload } from './FileUpload' // Polyfill for ResizeObserver if (!global.ResizeObserver) { class ResizeObserverPolyfill { observe() {} unobserve() {} disconnect() {} } global.ResizeObserver = ResizeObserverPolyfill as any } const NOOP = () => {} const createMockFile = (name: string, type = 'text/plain'): File => new File(['content'], name, { type }) const createFileItem = (name: string, fileId?: string) => new FileItem(createMockFile(name), fileId) const expectVisibleFilename = (filename: string) => { // Truncate renders a hidden measuring element with the same text. // We assert against the visible "first" part to avoid duplicate matches. expect( screen.getByText( (content, element) => content === filename && element?.getAttribute('data-pkt-truncate-part') === 'first', ), ).toBeInTheDocument() } describe('QueueDisplay', () => { describe('Progress states', () => { it.each([ { state: 'queued', progress: 'queued' as TFileTransfer['progress'], filename: 'queued-file.pdf', description: 'when no transfer exists', }, { state: 'done', progress: 'done' as TFileTransfer['progress'], filename: 'completed-file.pdf', description: 'after successful upload', }, { state: 'error', progress: 'error' as TFileTransfer['progress'], filename: 'failed-file.pdf', description: 'after failed upload', }, { state: 'canceled', progress: 'canceled' as TFileTransfer['progress'], filename: 'canceled-file.pdf', description: 'when canceled', }, // { state: 'in-progress', progress: 10 as FileTransfer['progress'], filename: 'in-progress-file.pdf', description: 'when canceled' }, ])('should display file with $state state $description', ({ progress, filename, state }) => { const initialValue: TFileItemList = [createFileItem(filename, 'file-1')] const transfers = progress !== undefined ? [{ fileId: 'file-1', progress }] : [] const { container } = render( , ) // File should be displayed expectVisibleFilename(filename) // Should have proper class when not in progress const queueItem = container.querySelector('.pkt-fileupload__queue-display__item') expect(queueItem).toHaveClass('pkt-fileupload__queue-display__item--' + state) expect(queueItem).not.toHaveClass('pkt-fileupload__queue-display__item--in-progress') // Should not show progress bar or cancel button expect(container.querySelector('.pkt-fileupload__queue-display__item__progress')).not.toBeInTheDocument() expect(screen.queryByText('Avbryt')).not.toBeInTheDocument() }) it('should display file with in-progress state and progress bar', () => { const initialValue: TFileItemList = [createFileItem('uploading-file.pdf', 'file-1')] const { container } = render( , ) // File should be displayed expectVisibleFilename('uploading-file.pdf') // Should have the 'in-progress' class const queueItem = container.querySelector('.pkt-fileupload__queue-display__item') expect(queueItem).toHaveClass('pkt-fileupload__queue-display__item--in-progress') expect(queueItem).not.toHaveClass('pkt-fileupload__queue-display__item--done') // Should show progress bar expect(container.querySelector('.pkt-fileupload__queue-display__item__progress')).toBeInTheDocument() // Should show percentage expect(screen.getByText('45%')).toBeInTheDocument() // Should show cancel button expect(screen.getByText('Avbryt')).toBeInTheDocument() }) it('should display multiple files with different progress states', () => { const initialValue: TFileItemList = [ createFileItem('queued-file.pdf', 'file-1'), createFileItem('uploading-file.pdf', 'file-2'), createFileItem('completed-file.pdf', 'file-3'), createFileItem('failed-file.pdf', 'file-4'), ] const { container } = render( , ) // All files should be displayed expectVisibleFilename('queued-file.pdf') expectVisibleFilename('uploading-file.pdf') expectVisibleFilename('completed-file.pdf') expectVisibleFilename('failed-file.pdf') // Should have 4 queue items const queueItems = container.querySelectorAll('.pkt-fileupload__queue-display__item') expect(queueItems).toHaveLength(4) // Only the uploading file should have in-progress class const inProgressItems = container.querySelectorAll('.pkt-fileupload__queue-display__item--in-progress') expect(inProgressItems).toHaveLength(1) // Only the uploading file should show progress bar and percentage expect(screen.getByText('75%')).toBeInTheDocument() expect(container.querySelectorAll('.pkt-fileupload__queue-display__item__progress')).toHaveLength(1) }) it('should update progress percentage when transfer progresses', () => { const initialValue: TFileItemList = [createFileItem('uploading-file.pdf', 'file-1')] const { container, rerender } = render( , ) // Initially at 25% expect(screen.getByText('25%')).toBeInTheDocument() // Update to 50% rerender( , ) expect(screen.queryByText('25%')).not.toBeInTheDocument() expect(screen.getByText('50%')).toBeInTheDocument() // Update to done rerender( , ) // Progress percentage should no longer be visible expect(screen.queryByText('50%')).not.toBeInTheDocument() expect(container.querySelector('.pkt-fileupload__queue-display__item__progress')).not.toBeInTheDocument() }) }) })