85 lines
3.0 KiB
TypeScript
85 lines
3.0 KiB
TypeScript
import { describe, it, expect } from 'vitest';
|
|
import { isValidImageMimeType, bufferToBase64, normalizeContentType } from '../src/utils/image.js';
|
|
|
|
describe('isValidImageMimeType', () => {
|
|
it('accepts valid image MIME types', () => {
|
|
expect(isValidImageMimeType('image/jpeg')).toBe(true);
|
|
expect(isValidImageMimeType('image/png')).toBe(true);
|
|
expect(isValidImageMimeType('image/gif')).toBe(true);
|
|
expect(isValidImageMimeType('image/webp')).toBe(true);
|
|
});
|
|
|
|
it('rejects invalid MIME types', () => {
|
|
expect(isValidImageMimeType('text/plain')).toBe(false);
|
|
expect(isValidImageMimeType('application/pdf')).toBe(false);
|
|
expect(isValidImageMimeType('video/mp4')).toBe(false);
|
|
expect(isValidImageMimeType('application/json')).toBe(false);
|
|
expect(isValidImageMimeType('text/html')).toBe(false);
|
|
});
|
|
|
|
it('rejects empty string', () => {
|
|
expect(isValidImageMimeType('')).toBe(false);
|
|
});
|
|
|
|
it('rejects null-like values', () => {
|
|
expect(isValidImageMimeType('null' as unknown as string)).toBe(false);
|
|
expect(isValidImageMimeType('undefined' as unknown as string)).toBe(false);
|
|
});
|
|
|
|
it('is case-sensitive (lowercase required)', () => {
|
|
// The function checks exact matches against lowercase values
|
|
expect(isValidImageMimeType('IMAGE/JPEG')).toBe(false);
|
|
expect(isValidImageMimeType('Image/Png')).toBe(false);
|
|
});
|
|
|
|
it('rejects MIME types with parameters', () => {
|
|
expect(isValidImageMimeType('image/jpeg; charset=utf-8')).toBe(false);
|
|
expect(isValidImageMimeType('image/png; alpha')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('bufferToBase64', () => {
|
|
it('converts buffer to base64 string', () => {
|
|
const buffer = Buffer.from('hello world');
|
|
const result = bufferToBase64(buffer);
|
|
expect(result).toBe(btoa('hello world'));
|
|
});
|
|
|
|
it('handles empty buffer', () => {
|
|
const buffer = Buffer.from('');
|
|
const result = bufferToBase64(buffer);
|
|
expect(result).toBe('');
|
|
});
|
|
|
|
it('handles binary data', () => {
|
|
const buffer = Buffer.from([0x00, 0x01, 0x02, 0xff, 0xfe, 0xfd]);
|
|
const result = bufferToBase64(buffer);
|
|
expect(result).toBe(btoa('\x00\x01\x02\xff\xfe\xfd'));
|
|
});
|
|
|
|
it('handles large buffer', () => {
|
|
const buffer = Buffer.alloc(1024 * 1024); // 1MB
|
|
buffer.fill(0x41); // 'A'
|
|
const result = bufferToBase64(buffer);
|
|
expect(result.length).toBeGreaterThan(0);
|
|
// Base64 encodes each 3 bytes as 4 chars, rounding up.
|
|
expect(result.length).toBe(Math.ceil((1024 * 1024) / 3) * 4);
|
|
});
|
|
|
|
it('produces valid base64 (only valid chars)', () => {
|
|
const buffer = Buffer.from(Math.random().toString(36).repeat(100));
|
|
const result = bufferToBase64(buffer);
|
|
expect(result).toMatch(/^[A-Za-z0-9+/]+=*$/);
|
|
});
|
|
});
|
|
|
|
describe('normalizeContentType', () => {
|
|
it('uses the fallback when Axios exposes a non-string header value', () => {
|
|
expect(normalizeContentType(['image/png'])).toBe('image/jpeg');
|
|
});
|
|
|
|
it('removes header parameters from a string content type', () => {
|
|
expect(normalizeContentType('image/webp; charset=binary')).toBe('image/webp');
|
|
});
|
|
});
|