import { describe, expect, it } from 'vitest';
import { calculateMediaSeoScore, gradeForScore, isGenericFilename, mediaKind, MEDIA_SEO_WEIGHTS, } from '../../media/seo.js';
describe('media SEO weights', () => {
    it('sum to 100', () => {
        const total = Object.values(MEDIA_SEO_WEIGHTS).reduce((a, b) => a + b, 0);
        expect(total).toBe(100);
    });
});
describe('mediaKind', () => {
    it.each([
        ['image/jpeg', 'image'],
        ['image/png', 'image'],
        ['image/webp', 'image'],
        ['image/svg+xml', 'svg'],
        ['video/mp4', 'video'],
        ['audio/mpeg', 'audio'],
        ['application/pdf', 'pdf'],
        ['application/zip', 'other'],
        ['', 'other'],
    ])('maps %s -> %s', (mime, expected) => {
        expect(mediaKind(mime)).toBe(expected);
    });
    it('treats undefined as other', () => {
        expect(mediaKind(undefined)).toBe('other');
        expect(mediaKind(null)).toBe('other');
    });
});
describe('isGenericFilename', () => {
    it.each([
        'IMG_4892.jpg',
        'img4892.png',
        'DSC_0001.jpg',
        'DSCF1234.jpg',
        'P1010101.jpg',
        'image.png',
        'image1.png',
        'photo-2.jpg',
        'Untitled.png',
        'Screen Shot 2024-01-01 at 10.00.00.png',
        'screenshot.png',
        'download.pdf',
        '12345.jpg',
        'a1b2c3d4e5f6.jpg',
        '',
        '   ',
    ])('flags %s as generic', (name) => {
        expect(isGenericFilename(name)).toBe(true);
    });
    it.each([
        'hero-banner.jpg',
        'team-photo.png',
        'product-screenshot.webp',
        'logo-dark.svg',
        'annual-report-2025.pdf',
        'case-study-fintech.pdf',
    ])('accepts %s as descriptive', (name) => {
        expect(isGenericFilename(name)).toBe(false);
    });
    it('treats null/undefined as generic', () => {
        expect(isGenericFilename(null)).toBe(true);
        expect(isGenericFilename(undefined)).toBe(true);
    });
});
describe('gradeForScore', () => {
    it.each([
        [100, 'good'],
        [80, 'good'],
        [79, 'needs-work'],
        [60, 'needs-work'],
        [59, 'poor'],
        [1, 'poor'],
        [0, 'critical'],
    ])('score %d -> %s', (score, grade) => {
        expect(gradeForScore(score)).toBe(grade);
    });
});
describe('calculateMediaSeoScore', () => {
    it('awards a perfect 100 when every field is set and the name is descriptive', () => {
        const input = {
            fileName: 'product-screenshot.webp',
            mimeType: 'image/webp',
            altText: 'A product dashboard screenshot',
            title: 'Product Dashboard',
            caption: 'The analytics view',
            description: 'A detailed look at the analytics dashboard',
            focusKeyword: 'product dashboard',
        };
        const result = calculateMediaSeoScore(input);
        expect(result.score).toBe(100);
        expect(result.grade).toBe('good');
        expect(result.issues).toHaveLength(0);
    });
    it('scores hero-banner.jpg at 80 (alt+title+caption+filename+focus, no description)', () => {
        const result = calculateMediaSeoScore({
            fileName: 'hero-banner.jpg',
            mimeType: 'image/jpeg',
            altText: 'Actuate Media team collaborating in a modern open office space',
            title: 'Actuate Media Hero Banner',
            caption: 'Our talented team at work',
            description: '',
            focusKeyword: 'actuate media',
        });
        expect(result.score).toBe(MEDIA_SEO_WEIGHTS.altText +
            MEDIA_SEO_WEIGHTS.title +
            MEDIA_SEO_WEIGHTS.caption +
            MEDIA_SEO_WEIGHTS.descriptiveFileName +
            MEDIA_SEO_WEIGHTS.focusKeyword);
        expect(result.score).toBe(80);
        expect(result.grade).toBe('good');
        expect(result.issues.map((i) => i.type)).toContain('missing-description');
        expect(result.issues.map((i) => i.type)).not.toContain('missing-alt');
    });
    it('scores a bare generic image at 0 / critical with the expected issues', () => {
        const result = calculateMediaSeoScore({
            fileName: 'IMG_4892.jpg',
            mimeType: 'image/jpeg',
        });
        expect(result.score).toBe(0);
        expect(result.grade).toBe('critical');
        const types = result.issues.map((i) => i.type);
        expect(types).toContain('missing-alt');
        expect(types).toContain('missing-title');
        expect(types).toContain('missing-description');
        expect(types).toContain('generic-filename');
        expect(types).toContain('critical-score');
    });
    it('does not raise missing-alt for non-visual assets like PDFs', () => {
        const result = calculateMediaSeoScore({
            fileName: 'annual-report-2025.pdf',
            mimeType: 'application/pdf',
            title: 'Annual Report 2025',
            description: 'Our full-year results',
        });
        const types = result.issues.map((i) => i.type);
        expect(types).not.toContain('missing-alt');
    });
    it('flags oversized images above the configured threshold', () => {
        const result = calculateMediaSeoScore({
            fileName: 'team-photo.png',
            mimeType: 'image/png',
            sizeBytes: 4 * 1024 * 1024,
        }, { maxImageBytes: 2 * 1024 * 1024 });
        expect(result.issues.map((i) => i.type)).toContain('oversized-image');
    });
    it('does not flag oversized for a small image', () => {
        const result = calculateMediaSeoScore({
            fileName: 'bg-gradient.png',
            mimeType: 'image/png',
            sizeBytes: 45 * 1024,
        });
        expect(result.issues.map((i) => i.type)).not.toContain('oversized-image');
    });
    it('flags missing video caption', () => {
        const result = calculateMediaSeoScore({
            fileName: 'product-demo.mp4',
            mimeType: 'video/mp4',
            title: 'Product Demo',
        });
        expect(result.issues.map((i) => i.type)).toContain('missing-video-caption');
    });
    it('clamps and rounds the score into 0..100', () => {
        const result = calculateMediaSeoScore({
            fileName: 'x.jpg',
            mimeType: 'image/jpeg',
            altText: 'a',
            title: 't',
            description: 'd',
            caption: 'c',
            focusKeyword: 'k',
        });
        expect(result.score).toBeGreaterThanOrEqual(0);
        expect(result.score).toBeLessThanOrEqual(100);
        expect(Number.isInteger(result.score)).toBe(true);
    });
    it('treats whitespace-only metadata as missing', () => {
        const result = calculateMediaSeoScore({
            fileName: 'hero-banner.jpg',
            mimeType: 'image/jpeg',
            altText: '   ',
            title: '\n\t',
        });
        expect(result.issues.map((i) => i.type)).toContain('missing-alt');
        expect(result.issues.map((i) => i.type)).toContain('missing-title');
    });
});
//# sourceMappingURL=seo.test.js.map