service = new BlockTemplateService(); }); it('loads templates from config file', function () { $templates = $this->service->getAllTemplates(); expect($templates)->toBeArray(); expect($templates)->not->toBeEmpty(); }); it('has landing-page template', function () { expect($this->service->hasTemplate('landing-page'))->toBeTrue(); }); it('has article template', function () { expect($this->service->hasTemplate('article'))->toBeTrue(); }); it('returns null for non-existent template', function () { expect($this->service->hasTemplate('non-existent'))->toBeFalse(); expect($this->service->getTemplate('non-existent'))->toBeNull(); }); it('gets template by ID', function () { $template = $this->service->getTemplate('landing-page'); expect($template)->toBeArray(); expect($template)->toHaveKeys(['name', 'description', 'blocks']); expect($template['name'])->toBe('Landing Page'); expect($template['blocks'])->toBeArray(); expect($template['blocks'])->not->toBeEmpty(); }); it('applies template and returns ContentBlocks', function () { $contentBlocks = $this->service->applyTemplate('landing-page'); expect($contentBlocks)->toBeInstanceOf(ContentBlocks::class); expect($contentBlocks->count())->toBeGreaterThan(0); }); it('throws exception when applying non-existent template', function () { expect(fn () => $this->service->applyTemplate('non-existent')) ->toThrow(\InvalidArgumentException::class); }); it('generates unique IDs for template blocks', function () { $contentBlocks1 = $this->service->applyTemplate('landing-page'); $contentBlocks2 = $this->service->applyTemplate('landing-page'); $ids1 = array_map(fn ($block) => $block->blockId->toString(), iterator_to_array($contentBlocks1)); $ids2 = array_map(fn ($block) => $block->blockId->toString(), iterator_to_array($contentBlocks2)); // IDs should be different between calls expect($ids1)->not->toBe($ids2); }); it('applies hero-only template correctly', function () { $contentBlocks = $this->service->applyTemplate('hero-only'); expect($contentBlocks->count())->toBe(1); $blocks = iterator_to_array($contentBlocks); expect($blocks[0]->type->toString())->toBe('hero'); }); it('applies article template correctly', function () { $contentBlocks = $this->service->applyTemplate('article'); expect($contentBlocks->count())->toBeGreaterThan(0); $blocks = iterator_to_array($contentBlocks); $blockTypes = array_map(fn ($block) => $block->type->toString(), $blocks); expect($blockTypes)->toContain('text'); expect($blockTypes)->toContain('image'); }); it('gets template metadata without blocks', function () { $metadata = $this->service->getTemplateMetadata('landing-page'); expect($metadata)->toBeArray(); expect($metadata)->toHaveKeys(['name', 'description']); expect($metadata['name'])->toBe('Landing Page'); expect($metadata)->not->toHaveKey('blocks'); }); it('returns null metadata for non-existent template', function () { expect($this->service->getTemplateMetadata('non-existent'))->toBeNull(); }); });