"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const vitest_1 = require("vitest");
const reference_pipeline_js_1 = require("./reference-pipeline.js");
const index_js_1 = require("../queue-system/index.js");
vitest_1.vi.mock('../queue-system/index.js', () => ({
    queue: {
        add: vitest_1.vi.fn(),
    },
}));
const mockAdd = vitest_1.vi.mocked(index_js_1.queue.add);
function makeDNA(overrides) {
    return {
        id: 'test-char-1',
        createdAt: '2025-01-01T00:00:00Z',
        updatedAt: '2025-01-01T00:00:00Z',
        status: 'active',
        identity: { name: 'Aylin', age: 24, nationality: 'Turkish', city: 'Istanbul', occupation: 'model', personality_tags: ['fun'], mbti: 'ENFP', backstory: 'A model' },
        physicalMeasurements: { height_cm: 172, weight_kg: 56, body_type: 'slim', measurements: { bust: 88, waist: 62, hips: 90 } },
        skinMap: { base: '#F5D0A9', shadow: '#D4A574', highlight: '#FFE4C4' },
        faceAnatomy: { eye_shape: 'almond', eye_color: '#8B4513', eyebrow_shape: 'arched', nose_type: 'straight', lip_shape: 'full', cheekbones: 'high', jawline: 'soft', distinctive_marks: [] },
        hairDNA: { style: 'wavy', length: 'long', texture: 'silky', root_color: '#3B2F2F', mid_color: '#5C4033', highlight_color: '#8B6914' },
        bodyBiometrics: { body_type_detail: 'hourglass', posture: 'upright', skin_texture: 'smooth' },
        profileView: { best_angle: 'left-45', signature_pose: 'hand-on-hip' },
        expressionMotion: { default_expression: 'smile', smile_type: 'warm', gaze_style: 'direct' },
        makeupStyle: { philosophy: 'natural', skin_finish: 'dewy', colors: { primary: '#C48793', secondary: '#E8B4B8', accent: '#8B0000' } },
        fashionStyle: { aesthetic: 'casual-chic', main_colors: ['#000000', '#FFFFFF'], signature_pieces: ['jeans', 'crop top'] },
        technicalSettings: { camera_body: 'Canon R5', portrait_lens: '85mm f/1.4', full_body_lens: '35mm f/1.4', film_stock: 'Portra 400' },
        ...overrides,
    };
}
(0, vitest_1.describe)('REFERENCE_ANGLES', () => {
    (0, vitest_1.it)('should define exactly 7 angles', () => {
        (0, vitest_1.expect)(reference_pipeline_js_1.REFERENCE_ANGLES).toHaveLength(7);
    });
    (0, vitest_1.it)('should have unique filenames', () => {
        const filenames = reference_pipeline_js_1.REFERENCE_ANGLES.map(a => a.filename);
        (0, vitest_1.expect)(new Set(filenames).size).toBe(7);
    });
    (0, vitest_1.it)('should have the correct filenames in order', () => {
        const filenames = reference_pipeline_js_1.REFERENCE_ANGLES.map(a => a.filename);
        (0, vitest_1.expect)(filenames).toEqual([
            'master.jpg',
            'right-45.jpg',
            'left-45.jpg',
            'full-profile.jpg',
            'bird-eye.jpg',
            'full-body.jpg',
            'back-view.jpg',
        ]);
    });
    (0, vitest_1.it)('should have non-empty name and promptModifier for each angle', () => {
        for (const angle of reference_pipeline_js_1.REFERENCE_ANGLES) {
            (0, vitest_1.expect)(angle.name.length).toBeGreaterThan(0);
            (0, vitest_1.expect)(angle.promptModifier.length).toBeGreaterThan(0);
        }
    });
});
(0, vitest_1.describe)('buildAnglePrompt', () => {
    (0, vitest_1.it)('should include subject description from DNA', () => {
        const dna = makeDNA();
        const prompt = (0, reference_pipeline_js_1.buildAnglePrompt)(dna, reference_pipeline_js_1.REFERENCE_ANGLES[0]);
        (0, vitest_1.expect)(prompt).toContain('24 year old');
        (0, vitest_1.expect)(prompt).toContain('Turkish');
        (0, vitest_1.expect)(prompt).toContain('#F5D0A9');
    });
    (0, vitest_1.it)('should include camera settings from DNA', () => {
        const dna = makeDNA();
        const prompt = (0, reference_pipeline_js_1.buildAnglePrompt)(dna, reference_pipeline_js_1.REFERENCE_ANGLES[0]);
        (0, vitest_1.expect)(prompt).toContain('Canon R5');
        (0, vitest_1.expect)(prompt).toContain('Portra 400');
    });
    (0, vitest_1.it)('should include the angle-specific prompt modifier', () => {
        const dna = makeDNA();
        for (const angle of reference_pipeline_js_1.REFERENCE_ANGLES) {
            const prompt = (0, reference_pipeline_js_1.buildAnglePrompt)(dna, angle);
            (0, vitest_1.expect)(prompt).toContain(angle.promptModifier);
        }
    });
    (0, vitest_1.it)('should produce different prompts for different angles', () => {
        const dna = makeDNA();
        const prompts = reference_pipeline_js_1.REFERENCE_ANGLES.map(a => (0, reference_pipeline_js_1.buildAnglePrompt)(dna, a));
        (0, vitest_1.expect)(new Set(prompts).size).toBe(7);
    });
});
(0, vitest_1.describe)('generateReferenceImages', () => {
    (0, vitest_1.beforeEach)(() => {
        let callCount = 0;
        mockAdd.mockReset();
        mockAdd.mockImplementation(async () => {
            callCount++;
            return { id: `task-${callCount}`, type: 'image_generation', priority: 3, status: 'pending', characterId: '', payload: {}, retryCount: 0, maxRetries: 3, createdAt: '', updatedAt: '' };
        });
    });
    (0, vitest_1.it)('should queue exactly 7 image generation tasks', async () => {
        const dna = makeDNA();
        await (0, reference_pipeline_js_1.generateReferenceImages)('char-1', dna);
        (0, vitest_1.expect)(mockAdd).toHaveBeenCalledTimes(7);
    });
    (0, vitest_1.it)('should return 7 task IDs', async () => {
        const dna = makeDNA();
        const ids = await (0, reference_pipeline_js_1.generateReferenceImages)('char-1', dna);
        (0, vitest_1.expect)(ids).toHaveLength(7);
        ids.forEach(id => (0, vitest_1.expect)(id).toBeTruthy());
    });
    (0, vitest_1.it)('should use image_generation queue type for all tasks', async () => {
        const dna = makeDNA();
        await (0, reference_pipeline_js_1.generateReferenceImages)('char-1', dna);
        for (const call of mockAdd.mock.calls) {
            (0, vitest_1.expect)(call[0]).toBe('image_generation');
        }
    });
    (0, vitest_1.it)('should pass correct characterId to queue', async () => {
        const dna = makeDNA();
        await (0, reference_pipeline_js_1.generateReferenceImages)('my-char-id', dna);
        for (const call of mockAdd.mock.calls) {
            (0, vitest_1.expect)(call[1]).toBe('my-char-id');
        }
    });
    (0, vitest_1.it)('should include correct output paths in payload', async () => {
        const dna = makeDNA();
        await (0, reference_pipeline_js_1.generateReferenceImages)('char-1', dna);
        for (let i = 0; i < 7; i++) {
            const payload = mockAdd.mock.calls[i][2];
            (0, vitest_1.expect)(payload.outputPath).toBe(`data/characters/char-1/reference-images/${reference_pipeline_js_1.REFERENCE_ANGLES[i].filename}`);
        }
    });
    (0, vitest_1.it)('should mark all tasks as reference images', async () => {
        const dna = makeDNA();
        await (0, reference_pipeline_js_1.generateReferenceImages)('char-1', dna);
        for (const call of mockAdd.mock.calls) {
            (0, vitest_1.expect)(call[2].isReferenceImage).toBe(true);
        }
    });
    (0, vitest_1.it)('should include prompt and angle name in payload', async () => {
        const dna = makeDNA();
        await (0, reference_pipeline_js_1.generateReferenceImages)('char-1', dna);
        for (let i = 0; i < 7; i++) {
            const payload = mockAdd.mock.calls[i][2];
            (0, vitest_1.expect)(payload.prompt).toBeTruthy();
            (0, vitest_1.expect)(payload.angleName).toBe(reference_pipeline_js_1.REFERENCE_ANGLES[i].name);
            (0, vitest_1.expect)(payload.aspectRatio).toBe('1:1');
        }
    });
});
//# sourceMappingURL=reference-pipeline.test.js.map