Files
RedditBot/tests/image-utils.test.ts

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');
});
});