Files
TREK/client/src/components/Files/FileManager.helpers.extra.test.ts
T

112 lines
4.0 KiB
TypeScript

// FE-W4FMH-001 to FE-W4FMH-012
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { File as FileIcon, FileText, FileImage, FileVideo, Plane, Train, Bus, Car, CarTaxiFront, Bike, Ship, Sailboat, Route } from 'lucide-react'
const downloadFile = vi.fn(async (_url: string, _name: string) => {})
vi.mock('../../utils/fileDownload', () => ({ downloadFile: (url: string, name: string) => downloadFile(url, name) }))
import {
isImage, isVideo, isMedia, isMarkdown, getFileIcon, formatSize,
triggerDownload, formatDateWithLocale, transportIcon,
} from './FileManager.helpers'
beforeEach(() => {
downloadFile.mockReset()
downloadFile.mockResolvedValue(undefined)
})
describe('mime helpers', () => {
it('FE-W4FMH-001: detects images and videos', () => {
expect(isImage('image/png')).toBe(true)
expect(isImage('application/pdf')).toBe(false)
expect(isImage(null)).toBe(false)
expect(isVideo('video/mp4')).toBe(true)
expect(isVideo(undefined)).toBe(false)
})
it('FE-W4FMH-002: treats both images and videos as lightbox media', () => {
expect(isMedia('image/jpeg')).toBe(true)
expect(isMedia('video/quicktime')).toBe(true)
expect(isMedia('application/pdf')).toBe(false)
expect(isMedia(null)).toBe(false)
})
it('FE-W4FMH-003: detects markdown by extension first', () => {
expect(isMarkdown('application/octet-stream', 'NOTES.MD')).toBe(true)
expect(isMarkdown('', 'readme.markdown')).toBe(true)
expect(isMarkdown('text/markdown', 'blob')).toBe(true)
expect(isMarkdown('text/x-markdown', null)).toBe(true)
expect(isMarkdown('text/plain', 'notes.txt')).toBe(false)
expect(isMarkdown(null, null)).toBe(false)
})
})
describe('getFileIcon', () => {
it('FE-W4FMH-004: picks the icon matching the mime family', () => {
expect(getFileIcon('application/pdf')).toBe(FileText)
expect(getFileIcon('video/mp4')).toBe(FileVideo)
expect(getFileIcon('image/png')).toBe(FileImage)
expect(getFileIcon('application/zip')).toBe(FileIcon)
expect(getFileIcon(null)).toBe(FileIcon)
})
})
describe('formatSize', () => {
it('FE-W4FMH-005: renders bytes below a kilobyte', () => {
expect(formatSize(512)).toBe('512 B')
})
it('FE-W4FMH-006: renders kilobytes and megabytes with one decimal', () => {
expect(formatSize(2048)).toBe('2.0 KB')
expect(formatSize(1024 * 1024 * 3.25)).toBe('3.3 MB')
})
it('FE-W4FMH-007: renders nothing for a missing or zero size', () => {
expect(formatSize(0)).toBe('')
expect(formatSize(null)).toBe('')
expect(formatSize(undefined)).toBe('')
})
})
describe('triggerDownload', () => {
it('FE-W4FMH-008: forwards to the download helper', () => {
triggerDownload('/uploads/files/a.pdf', 'a.pdf')
expect(downloadFile).toHaveBeenCalledWith('/uploads/files/a.pdf', 'a.pdf')
})
it('FE-W4FMH-009: swallows a rejected download', async () => {
downloadFile.mockRejectedValue(new Error('offline'))
expect(() => triggerDownload('/x', 'x')).not.toThrow()
await Promise.resolve()
})
})
describe('formatDateWithLocale', () => {
it('FE-W4FMH-010: formats an ISO date in the given locale', () => {
expect(formatDateWithLocale('2026-06-15T10:00:00Z', 'en-GB')).toBe('15/06/2026')
})
it('FE-W4FMH-011: returns an empty string for a missing or unparseable date', () => {
expect(formatDateWithLocale(null, 'en-GB')).toBe('')
expect(formatDateWithLocale('', 'en-GB')).toBe('')
expect(formatDateWithLocale('2026-06-15', 'en_US')).toBe('')
})
})
describe('transportIcon', () => {
it('FE-W4FMH-012: maps every transport type, defaulting to the plane', () => {
expect(transportIcon('train')).toBe(Train)
expect(transportIcon('bus')).toBe(Bus)
expect(transportIcon('car')).toBe(Car)
expect(transportIcon('taxi')).toBe(CarTaxiFront)
expect(transportIcon('bicycle')).toBe(Bike)
expect(transportIcon('cruise')).toBe(Ship)
expect(transportIcon('ferry')).toBe(Sailboat)
expect(transportIcon('transport_other')).toBe(Route)
expect(transportIcon('flight')).toBe(Plane)
expect(transportIcon('')).toBe(Plane)
})
})