mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-08-22 20:29:23 +00:00
365 lines
12 KiB
TypeScript
365 lines
12 KiB
TypeScript
![]() |
/**
|
||
|
* Tests for auto-detection and smart conversion features in useConvertParameters
|
||
|
* This covers the analyzeFileTypes function and related smart detection logic
|
||
|
*/
|
||
|
|
||
|
import { describe, test, expect } from 'vitest';
|
||
|
import { renderHook, act, waitFor } from '@testing-library/react';
|
||
|
import { useConvertParameters } from './useConvertParameters';
|
||
|
|
||
|
describe('useConvertParameters - Auto Detection & Smart Conversion', () => {
|
||
|
|
||
|
describe('Single File Detection', () => {
|
||
|
|
||
|
test('should detect single file extension and set auto-target', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const pdfFile = [{ name: 'document.pdf' }];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(pdfFile);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('pdf');
|
||
|
expect(result.current.parameters.toExtension).toBe(''); // No auto-selection for multiple targets
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(false);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('none');
|
||
|
});
|
||
|
|
||
|
test('should handle unknown file types with file-to-pdf fallback', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const unknownFile = [{ name: 'document.xyz' }, { name: 'image.jpggg' }];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(unknownFile);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('any');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf'); // Fallback to file-to-pdf
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
});
|
||
|
|
||
|
test('should handle files without extensions', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const noExtFile = [{ name: 'document' }];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(noExtFile);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('any');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf'); // Fallback to file-to-pdf
|
||
|
});
|
||
|
|
||
|
|
||
|
});
|
||
|
|
||
|
describe('Multiple Identical Files', () => {
|
||
|
|
||
|
test('should detect multiple PDF files and set auto-target', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const pdfFiles = [
|
||
|
{ name: 'doc1.pdf' },
|
||
|
{ name: 'doc2.pdf' },
|
||
|
{ name: 'doc3.pdf' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(pdfFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('pdf');
|
||
|
expect(result.current.parameters.toExtension).toBe(''); // Auto-selected
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(false);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('none');
|
||
|
});
|
||
|
|
||
|
test('should handle multiple unknown file types with fallback', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const unknownFiles = [
|
||
|
{ name: 'file1.xyz' },
|
||
|
{ name: 'file2.xyz' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(unknownFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('any');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf');
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(false);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Smart Detection - All Images', () => {
|
||
|
|
||
|
test('should detect all image files and enable smart detection', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const imageFiles = [
|
||
|
{ name: 'photo1.jpg' },
|
||
|
{ name: 'photo2.png' },
|
||
|
{ name: 'photo3.gif' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(imageFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('image');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf');
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('images');
|
||
|
});
|
||
|
|
||
|
test('should handle mixed case image extensions', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const imageFiles = [
|
||
|
{ name: 'photo1.JPG' },
|
||
|
{ name: 'photo2.PNG' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(imageFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('images');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Smart Detection - All Web Files', () => {
|
||
|
|
||
|
test('should detect all web files and enable web smart detection', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const webFiles = [
|
||
|
{ name: 'page1.html' },
|
||
|
{ name: 'archive.zip' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(webFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('html');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf');
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('web');
|
||
|
});
|
||
|
|
||
|
test('should handle mixed case web extensions', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const webFiles = [
|
||
|
{ name: 'page1.HTML' },
|
||
|
{ name: 'archive.ZIP' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(webFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('web');
|
||
|
});
|
||
|
|
||
|
test('should detect multiple web files and enable web smart detection', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const zipFiles = [
|
||
|
{ name: 'site1.zip' },
|
||
|
{ name: 'site2.html' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(zipFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('html');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf');
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('web');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Smart Detection - Mixed File Types', () => {
|
||
|
|
||
|
test('should detect mixed file types and enable smart detection', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const mixedFiles = [
|
||
|
{ name: 'document.pdf' },
|
||
|
{ name: 'spreadsheet.xlsx' },
|
||
|
{ name: 'presentation.pptx' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(mixedFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('any');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf');
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('mixed');
|
||
|
});
|
||
|
|
||
|
test('should detect mixed images and documents as mixed type', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const mixedFiles = [
|
||
|
{ name: 'photo.jpg' },
|
||
|
{ name: 'document.pdf' },
|
||
|
{ name: 'text.txt' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(mixedFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('mixed');
|
||
|
});
|
||
|
|
||
|
test('should handle mixed with unknown file types', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const mixedFiles = [
|
||
|
{ name: 'document.pdf' },
|
||
|
{ name: 'unknown.xyz' },
|
||
|
{ name: 'noextension' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(mixedFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('mixed');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Smart Detection Endpoint Resolution', () => {
|
||
|
|
||
|
test('should return correct endpoint for image smart detection', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const imageFiles = [
|
||
|
{ name: 'photo1.jpg' },
|
||
|
{ name: 'photo2.png' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(imageFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.getEndpointName()).toBe('img-to-pdf');
|
||
|
expect(result.current.getEndpoint()).toBe('/api/v1/convert/img/pdf');
|
||
|
});
|
||
|
|
||
|
test('should return correct endpoint for web smart detection', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const webFiles = [
|
||
|
{ name: 'page1.html' },
|
||
|
{ name: 'archive.zip' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(webFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.getEndpointName()).toBe('html-to-pdf');
|
||
|
expect(result.current.getEndpoint()).toBe('/api/v1/convert/html/pdf');
|
||
|
});
|
||
|
|
||
|
test('should return correct endpoint for mixed smart detection', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const mixedFiles = [
|
||
|
{ name: 'document.pdf' },
|
||
|
{ name: 'spreadsheet.xlsx' }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(mixedFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.getEndpointName()).toBe('file-to-pdf');
|
||
|
expect(result.current.getEndpoint()).toBe('/api/v1/convert/file/pdf');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Auto-Target Selection Logic', () => {
|
||
|
|
||
|
test('should select single available target automatically', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
// Markdown has only one conversion target (PDF)
|
||
|
const mdFile = [{ name: 'readme.md' }];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(mdFile);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('md');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf'); // Only available target
|
||
|
});
|
||
|
|
||
|
test('should not auto-select when multiple targets available', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
// PDF has multiple conversion targets, so no auto-selection
|
||
|
const pdfFile = [{ name: 'document.pdf' }];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(pdfFile);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('pdf');
|
||
|
// Should NOT auto-select when multiple targets available
|
||
|
expect(result.current.parameters.toExtension).toBe('');
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('Edge Cases', () => {
|
||
|
|
||
|
test('should handle empty file names', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const emptyFiles = [{ name: '' }];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(emptyFiles);
|
||
|
});
|
||
|
|
||
|
expect(result.current.parameters.fromExtension).toBe('any');
|
||
|
expect(result.current.parameters.toExtension).toBe('pdf');
|
||
|
});
|
||
|
|
||
|
test('should handle malformed file objects', () => {
|
||
|
const { result } = renderHook(() => useConvertParameters());
|
||
|
|
||
|
const malformedFiles = [
|
||
|
{ name: 'valid.pdf' },
|
||
|
// @ts-ignore - Testing runtime resilience
|
||
|
{ name: null },
|
||
|
// @ts-ignore
|
||
|
{ name: undefined }
|
||
|
];
|
||
|
|
||
|
act(() => {
|
||
|
result.current.analyzeFileTypes(malformedFiles);
|
||
|
});
|
||
|
|
||
|
// Should still process the valid file and handle gracefully
|
||
|
expect(result.current.parameters.isSmartDetection).toBe(true);
|
||
|
expect(result.current.parameters.smartDetectionType).toBe('mixed');
|
||
|
});
|
||
|
});
|
||
|
});
|