preview(); self::assertTrue($preview->enabled()); self::assertSame('previews', $preview->store()); self::assertSame(26214400, $preview->maxSourceSize()); self::assertSame(640, $preview->variants()->variant('popover')?->width); self::assertSame(440, $preview->variants()->variant('popover')?->height); self::assertSame('image/webp', $preview->variants()->variant('popover')?->format); self::assertSame(80, $preview->variants()->variant('popover')?->quality); self::assertSame(256, $preview->variants()->variant('thumbnail')?->width); } #[Test] public function loadsAndSerializesTenantPreviewConfiguration(): void { $data = [ 'enabled' => true, 'store' => 'generated-content', 'maxSourceSize' => 1024, 'variants' => [ 'popover' => [ 'width' => 800, 'height' => 600, 'format' => 'IMAGE/PNG', 'quality' => 90, ], ], ]; $configuration = (new TenantConfiguration())->jsonDeserialize(['preview' => $data]); self::assertSame('generated-content', $configuration->preview()->store()); self::assertSame(1024, $configuration->preview()->maxSourceSize()); self::assertSame(['popover'], array_keys($configuration->preview()->variants()->all())); self::assertSame('image/png', $configuration->preview()->variants()->variant('popover')?->format); $data['variants']['popover']['format'] = 'image/png'; self::assertSame($data, $configuration->jsonSerialize()['preview']); } #[Test] public function mergesKnownVariantDefaultsForPartialOverrides(): void { $configuration = (new TenantConfiguration())->jsonDeserialize([ 'preview' => [ 'variants' => [ 'popover' => ['width' => 900], ], ], ]); $variant = $configuration->preview()->variants()->variant('popover'); self::assertSame(900, $variant?->width); self::assertSame(440, $variant?->height); self::assertSame('image/webp', $variant?->format); self::assertSame(80, $variant?->quality); self::assertNull($configuration->preview()->variants()->variant('thumbnail')); } #[Test] public function allowsNoVariantsWhenPreviewsAreDisabled(): void { $configuration = (new TenantConfiguration())->jsonDeserialize([ 'preview' => ['enabled' => false, 'variants' => []], ]); self::assertFalse($configuration->preview()->enabled()); self::assertSame([], $configuration->preview()->variants()->all()); } /** @return iterable}> */ public static function invalidConfigurations(): iterable { yield 'invalid store' => [['store' => '../previews']]; yield 'zero source limit' => [['maxSourceSize' => 0]]; yield 'invalid variant name' => [['variants' => ['../popover' => []]]]; yield 'invalid dimensions' => [['variants' => ['popover' => ['width' => 0]]]]; yield 'invalid output MIME' => [['variants' => ['popover' => ['format' => 'webp']]]]; yield 'invalid quality' => [['variants' => ['popover' => ['quality' => 101]]]]; yield 'enabled without variants' => [['enabled' => true, 'variants' => []]]; } #[Test] #[\PHPUnit\Framework\Attributes\DataProvider('invalidConfigurations')] public function rejectsInvalidConfiguration(array $data): void { $this->expectException(InvalidArgumentException::class); (new TenantConfiguration())->jsonDeserialize(['preview' => $data]); } }