registry = new BlockTypeRegistry(); $this->validator = new BlockValidator($this->registry); }); it('validates hero block with required title', function () { $block = ContentBlock::create( type: BlockType::hero(), blockId: BlockId::fromString('hero-1'), data: BlockData::fromArray(['title' => 'Hero Title']) ); $this->validator->validate($block); expect(true)->toBeTrue(); // Test passes if no exception is thrown }); it('throws exception for hero block without title', function () { $block = ContentBlock::create( type: BlockType::hero(), blockId: BlockId::fromString('hero-1'), data: BlockData::fromArray([]) ); expect(fn () => $this->validator->validate($block)) ->toThrow(InvalidBlockException::class); }); it('validates text block with required content', function () { $block = ContentBlock::create( type: BlockType::text(), blockId: BlockId::fromString('text-1'), data: BlockData::fromArray(['content' => 'Text content']) ); $this->validator->validate($block); expect(true)->toBeTrue(); // Test passes if no exception is thrown }); it('throws exception for text block without content', function () { $block = ContentBlock::create( type: BlockType::text(), blockId: BlockId::fromString('text-1'), data: BlockData::fromArray([]) ); expect(fn () => $this->validator->validate($block)) ->toThrow(InvalidBlockException::class); }); it('validates image block with imageId', function () { $block = ContentBlock::create( type: BlockType::image(), blockId: BlockId::fromString('image-1'), data: BlockData::fromArray(['imageId' => 'img-123']) ); $this->validator->validate($block); expect(true)->toBeTrue(); // Test passes if no exception is thrown }); it('validates image block with image_url', function () { $block = ContentBlock::create( type: BlockType::image(), blockId: BlockId::fromString('image-1'), data: BlockData::fromArray(['image_url' => 'https://example.com/image.jpg']) ); $this->validator->validate($block); expect(true)->toBeTrue(); // Test passes if no exception is thrown }); it('throws exception for image block without imageId or image_url', function () { $block = ContentBlock::create( type: BlockType::image(), blockId: BlockId::fromString('image-1'), data: BlockData::fromArray([]) ); expect(fn () => $this->validator->validate($block)) ->toThrow(InvalidBlockException::class); }); it('validates gallery block with images array', function () { $block = ContentBlock::create( type: BlockType::gallery(), blockId: BlockId::fromString('gallery-1'), data: BlockData::fromArray(['images' => ['img1', 'img2']]) ); $this->validator->validate($block); expect(true)->toBeTrue(); // Test passes if no exception is thrown }); it('throws exception for gallery block without images', function () { $block = ContentBlock::create( type: BlockType::gallery(), blockId: BlockId::fromString('gallery-1'), data: BlockData::fromArray([]) ); expect(fn () => $this->validator->validate($block)) ->toThrow(InvalidBlockException::class); }); it('validates cta block with buttonText and buttonLink', function () { $block = ContentBlock::create( type: BlockType::cta(), blockId: BlockId::fromString('cta-1'), data: BlockData::fromArray([ 'buttonText' => 'Click Me', 'buttonLink' => '/signup', ]) ); $this->validator->validate($block); expect(true)->toBeTrue(); // Test passes if no exception is thrown }); it('validates cta block with button_text and button_link', function () { $block = ContentBlock::create( type: BlockType::cta(), blockId: BlockId::fromString('cta-1'), data: BlockData::fromArray([ 'button_text' => 'Click Me', 'button_link' => '/signup', ]) ); $this->validator->validate($block); expect(true)->toBeTrue(); // Test passes if no exception is thrown }); it('validates separator block without required data', function () { $block = ContentBlock::create( type: BlockType::separator(), blockId: BlockId::fromString('sep-1'), data: BlockData::empty() ); $this->validator->validate($block); expect(true)->toBeTrue(); // Test passes if no exception is thrown }); it('throws exception for unregistered block type', function () { $customType = BlockType::fromString('custom-block', false); $block = ContentBlock::create( type: $customType, blockId: BlockId::fromString('custom-1'), data: BlockData::empty() ); expect(fn () => $this->validator->validate($block)) ->toThrow(InvalidArgumentException::class, 'not registered'); }); });