/** * Tests for the photo_archive Macro * * This macro creates a photo gallery organized by year and month, * dynamically loading images from the media library based on their creation date. */ import { describe, it, expect, beforeEach } from 'vitest'; import { clearMacros, getMacro, registerMacro } from '../../../src/renderer/macros/registry'; import type { MacroParams, MacroRenderContext } from '../../../src/renderer/macros/types'; import photoArchiveMacro from '../../../src/renderer/macros/definitions/photo_archive'; describe('photo_archive macro', () => { beforeEach(() => { clearMacros(); // Re-register the macro for each test registerMacro(photoArchiveMacro); }); describe('validation', () => { it('should require year parameter', () => { const macro = getMacro('photo_archive'); expect(macro).toBeDefined(); const error = macro!.validate?.({}); expect(error).toBe('photo_archive macro requires a "year" parameter'); }); it('should reject non-numeric year', () => { const macro = getMacro('photo_archive'); const error = macro!.validate?.({ year: 'abc' }); expect(error).toBe('Year must be a valid 4-digit year (e.g., 2024)'); }); it('should reject year out of range', () => { const macro = getMacro('photo_archive'); const error = macro!.validate?.({ year: '999' }); expect(error).toBe('Year must be a valid 4-digit year (e.g., 2024)'); }); it('should accept valid year only', () => { const macro = getMacro('photo_archive'); const error = macro!.validate?.({ year: '2024' }); expect(error).toBeUndefined(); }); it('should reject invalid month', () => { const macro = getMacro('photo_archive'); const error = macro!.validate?.({ year: '2024', month: '13' }); expect(error).toBe('Month must be a number between 1 and 12'); }); it('should reject month of zero', () => { const macro = getMacro('photo_archive'); const error = macro!.validate?.({ year: '2024', month: '0' }); expect(error).toBe('Month must be a number between 1 and 12'); }); it('should accept valid year and month', () => { const macro = getMacro('photo_archive'); const error = macro!.validate?.({ year: '2024', month: '6' }); expect(error).toBeUndefined(); }); }); describe('editorPreview', () => { it('should show year-only preview when no month', () => { const macro = getMacro('photo_archive'); const preview = macro!.editorPreview?.({ year: '2024' }); expect(preview).toBe('📅 Photo Archive: 2024'); }); it('should show year and month in preview', () => { const macro = getMacro('photo_archive'); const preview = macro!.editorPreview?.({ year: '2024', month: '6' }); expect(preview).toBe('📅 Photo Archive: June 2024'); }); it('should handle all months correctly', () => { const macro = getMacro('photo_archive'); const months = [ { month: '1', expected: 'January' }, { month: '2', expected: 'February' }, { month: '3', expected: 'March' }, { month: '4', expected: 'April' }, { month: '5', expected: 'May' }, { month: '6', expected: 'June' }, { month: '7', expected: 'July' }, { month: '8', expected: 'August' }, { month: '9', expected: 'September' }, { month: '10', expected: 'October' }, { month: '11', expected: 'November' }, { month: '12', expected: 'December' }, ]; for (const { month, expected } of months) { const preview = macro!.editorPreview?.({ year: '2024', month }); expect(preview).toContain(expected); } }); }); describe('render - year only', () => { it('should render wrapper with year data attribute', () => { const macro = getMacro('photo_archive'); const context: MacroRenderContext = { isPreview: true, postId: 'test-post-id' }; const html = macro!.render({ year: '2024' }, context); expect(html).toContain('data-year="2024"'); expect(html).toContain('macro-photo-archive'); }); it('should not include month attribute when only year provided', () => { const macro = getMacro('photo_archive'); const context: MacroRenderContext = { isPreview: true, postId: 'test-post-id' }; const html = macro!.render({ year: '2024' }, context); expect(html).not.toContain('data-month='); }); it('should include post-id data attribute when available', () => { const macro = getMacro('photo_archive'); const context: MacroRenderContext = { isPreview: true, postId: 'post-123' }; const html = macro!.render({ year: '2024' }, context); expect(html).toContain('data-post-id="post-123"'); }); it('should include loading placeholder', () => { const macro = getMacro('photo_archive'); const context: MacroRenderContext = { isPreview: true, postId: 'test-post-id' }; const html = macro!.render({ year: '2024' }, context); expect(html).toContain('photo-archive-loading'); expect(html).toContain('Loading photo archive'); }); }); describe('render - year and month', () => { it('should render with both year and month data attributes', () => { const macro = getMacro('photo_archive'); const context: MacroRenderContext = { isPreview: true, postId: 'test-post-id' }; const html = macro!.render({ year: '2024', month: '6' }, context); expect(html).toContain('data-year="2024"'); expect(html).toContain('data-month="6"'); }); it('should have single-month class when month specified', () => { const macro = getMacro('photo_archive'); const context: MacroRenderContext = { isPreview: true, postId: 'test-post-id' }; const html = macro!.render({ year: '2024', month: '6' }, context); expect(html).toContain('photo-archive-single-month'); }); }); describe('self-registration', () => { it('should self-register on import', () => { const macro = getMacro('photo_archive'); expect(macro).toBeDefined(); expect(macro!.name).toBe('photo_archive'); }); it('should have proper description', () => { const macro = getMacro('photo_archive'); expect(macro!.description).toContain('photo'); expect(macro!.description.toLowerCase()).toContain('archive'); }); }); });