107 lines
3.8 KiB
JavaScript
107 lines
3.8 KiB
JavaScript
import { describe, it, expect } from 'vitest';
|
|
import path from 'node:path';
|
|
import fs from 'node:fs/promises';
|
|
import { detectInputMime, outputMimeType, resolveInputFormat } from '../src/mime.js';
|
|
|
|
describe('detectInputMime', () => {
|
|
it('detects PNG from magic bytes regardless of file extension', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.png');
|
|
|
|
const result = await detectInputMime(fixturePath);
|
|
|
|
expect(result).toEqual({ ext: 'png', mime: 'image/png' });
|
|
});
|
|
});
|
|
|
|
describe('outputMimeType', () => {
|
|
it('returns the MIME type for a known target format', () => {
|
|
expect(outputMimeType('pdf')).toBe('application/pdf');
|
|
expect(outputMimeType('png')).toBe('image/png');
|
|
expect(outputMimeType('docx')).toBe(
|
|
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
|
|
);
|
|
expect(outputMimeType('md')).toBe('text/markdown');
|
|
});
|
|
|
|
it('throws for an unknown target format', () => {
|
|
expect(() => outputMimeType('made-up-format')).toThrowError(/made-up-format/);
|
|
});
|
|
});
|
|
|
|
describe('outputMimeType — ico', () => {
|
|
it('returns image/x-icon for ico', () => {
|
|
expect(outputMimeType('ico')).toBe('image/x-icon');
|
|
});
|
|
});
|
|
|
|
describe('resolveInputFormat', () => {
|
|
it('accepts a PNG file declared as png', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.png');
|
|
|
|
const result = await resolveInputFormat(fixturePath, 'png');
|
|
|
|
expect(result).toEqual({ mime: 'image/png', valid: true });
|
|
});
|
|
|
|
it('rejects a PNG file declared as a different format', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.png');
|
|
|
|
const result = await resolveInputFormat(fixturePath, 'pdf');
|
|
|
|
expect(result.valid).toBe(false);
|
|
});
|
|
|
|
it('treats jpg and jpeg as equivalent declared formats', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.png');
|
|
const result = await resolveInputFormat(fixturePath, 'png');
|
|
expect(result.valid).toBe(true);
|
|
});
|
|
|
|
it('trusts the declared format for undetectable txt files', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.txt');
|
|
await fs.writeFile(fixturePath, 'plain text, no magic bytes');
|
|
|
|
const result = await resolveInputFormat(fixturePath, 'txt');
|
|
|
|
expect(result).toEqual({ mime: 'text/plain', valid: true });
|
|
|
|
await fs.unlink(fixturePath);
|
|
});
|
|
|
|
it('trusts the declared format for undetectable md files', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.md');
|
|
await fs.writeFile(fixturePath, '# plain markdown, no magic bytes');
|
|
|
|
const result = await resolveInputFormat(fixturePath, 'md');
|
|
|
|
expect(result).toEqual({ mime: 'text/markdown', valid: true });
|
|
|
|
await fs.unlink(fixturePath);
|
|
});
|
|
|
|
it('rejects an undetectable file declared as a binary format', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample-fake.png');
|
|
await fs.writeFile(fixturePath, 'this is not really a PNG');
|
|
|
|
const result = await resolveInputFormat(fixturePath, 'png');
|
|
|
|
expect(result.valid).toBe(false);
|
|
|
|
await fs.unlink(fixturePath);
|
|
});
|
|
});
|
|
|
|
describe('resolveInputFormat — heic/heif alias', () => {
|
|
it('accepts a HEIC-family file declared as heic', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.heic');
|
|
const result = await resolveInputFormat(fixturePath, 'heic');
|
|
expect(result.valid).toBe(true);
|
|
});
|
|
|
|
it('accepts the same HEIC-family content declared as heif', async () => {
|
|
const fixturePath = path.join(import.meta.dirname, 'fixtures', 'sample.heif');
|
|
const result = await resolveInputFormat(fixturePath, 'heif');
|
|
expect(result.valid).toBe(true);
|
|
});
|
|
});
|