UNPKG

@julesl23/s5js

Version:

Enhanced TypeScript SDK for S5 decentralized storage with path-based API, media processing, and directory utilities

172 lines 7.62 kB
import { describe, it, expect } from 'vitest'; import { CanvasMetadataExtractor } from '../../src/media/fallback/canvas.js'; // Mock canvas implementation for Node.js testing class MockImage { width = 0; height = 0; src = ''; onload; onerror; constructor() { // Simulate async image loading setTimeout(() => { if (this.src.startsWith('data:image/')) { // Simulate successful load this.width = 800; this.height = 600; this.onload?.(); } else { // Simulate error this.onerror?.(new Error('Invalid image')); } }, 10); } } // Mock global Image for testing globalThis.Image = MockImage; // Mock URL.createObjectURL and revokeObjectURL for Node.js globalThis.URL = { ...URL, createObjectURL: (blob) => `data:${blob.type};base64,mock`, revokeObjectURL: () => { } }; describe('CanvasMetadataExtractor', () => { describe('extract method', () => { it('should extract metadata from JPEG blob', async () => { const blob = new Blob(['fake-jpeg-data'], { type: 'image/jpeg' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata).toBeDefined(); expect(metadata?.format).toBe('jpeg'); expect(metadata?.width).toBe(800); expect(metadata?.height).toBe(600); expect(metadata?.source).toBe('canvas'); }); it('should extract metadata from PNG blob', async () => { const blob = new Blob(['fake-png-data'], { type: 'image/png' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata).toBeDefined(); expect(metadata?.format).toBe('png'); expect(metadata?.hasAlpha).toBe(true); }); it('should extract metadata from WebP blob', async () => { const blob = new Blob(['fake-webp-data'], { type: 'image/webp' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata).toBeDefined(); expect(metadata?.format).toBe('webp'); }); it('should extract metadata from GIF blob', async () => { const blob = new Blob(['fake-gif-data'], { type: 'image/gif' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata).toBeDefined(); expect(metadata?.format).toBe('gif'); }); it('should extract metadata from BMP blob', async () => { const blob = new Blob(['fake-bmp-data'], { type: 'image/bmp' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata).toBeDefined(); expect(metadata?.format).toBe('bmp'); }); it('should return undefined for non-image blobs', async () => { const blob = new Blob(['text content'], { type: 'text/plain' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata).toBeUndefined(); }); it('should include file size in metadata', async () => { const content = 'x'.repeat(1234); const blob = new Blob([content], { type: 'image/png' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata?.size).toBe(1234); }); it('should handle blob without explicit type', async () => { const blob = new Blob(['image-data']); const metadata = await CanvasMetadataExtractor.extract(blob); // Should try to detect or return unknown if (metadata) { expect(metadata.format).toBeDefined(); } }); }); describe('format detection', () => { it('should detect format from MIME type', () => { expect(CanvasMetadataExtractor.detectFormat('image/jpeg')).toBe('jpeg'); expect(CanvasMetadataExtractor.detectFormat('image/png')).toBe('png'); expect(CanvasMetadataExtractor.detectFormat('image/webp')).toBe('webp'); expect(CanvasMetadataExtractor.detectFormat('image/gif')).toBe('gif'); expect(CanvasMetadataExtractor.detectFormat('image/bmp')).toBe('bmp'); expect(CanvasMetadataExtractor.detectFormat('text/plain')).toBe('unknown'); }); it('should handle image/jpg alias for JPEG', () => { expect(CanvasMetadataExtractor.detectFormat('image/jpg')).toBe('jpeg'); }); }); describe('transparency detection', () => { it('should detect transparency for PNG', () => { expect(CanvasMetadataExtractor.hasTransparency('png')).toBe(true); }); it('should detect transparency for WebP', () => { expect(CanvasMetadataExtractor.hasTransparency('webp')).toBe(true); }); it('should detect transparency for GIF', () => { expect(CanvasMetadataExtractor.hasTransparency('gif')).toBe(true); }); it('should detect no transparency for JPEG', () => { expect(CanvasMetadataExtractor.hasTransparency('jpeg')).toBe(false); }); it('should detect no transparency for BMP', () => { expect(CanvasMetadataExtractor.hasTransparency('bmp')).toBe(false); }); }); describe('error handling', () => { it('should handle corrupt image data gracefully', async () => { // Override MockImage to simulate error const originalImage = globalThis.Image; class ErrorImage extends MockImage { constructor() { super(); setTimeout(() => { this.onerror?.(new Error('Corrupt image')); }, 10); } } globalThis.Image = ErrorImage; const blob = new Blob(['corrupt'], { type: 'image/jpeg' }); const metadata = await CanvasMetadataExtractor.extract(blob); // Should still return basic metadata from blob expect(metadata).toBeDefined(); expect(metadata?.format).toBe('jpeg'); expect(metadata?.size).toBe(7); // 'corrupt'.length // Restore original globalThis.Image = originalImage; }); it('should handle empty blob', async () => { const blob = new Blob([], { type: 'image/png' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata).toBeDefined(); expect(metadata?.size).toBe(0); }); it('should handle very large images', async () => { // Override MockImage to simulate large image const originalImage = globalThis.Image; globalThis.Image = class LargeImage { width = 10000; height = 10000; src = ''; onload; onerror; constructor() { setTimeout(() => { this.onload?.(); }, 10); } }; const blob = new Blob(['large'], { type: 'image/jpeg' }); const metadata = await CanvasMetadataExtractor.extract(blob); expect(metadata?.width).toBe(10000); expect(metadata?.height).toBe(10000); // Restore original globalThis.Image = originalImage; }); }); }); //# sourceMappingURL=canvas-fallback.test.js.map