33, 'post_type' => 'attachment', 'post_title' => 'Foto', 'post_mime_type' => 'image/jpeg', 'post_excerpt' => 'Bildunterschrift', 'post_content' => 'Beschreibung', 'post_parent' => 5, ]); } private function stubCommon(array $meta): void { Functions\when('wp_get_attachment_metadata')->justReturn($meta); Functions\when('get_attached_file')->justReturn('/var/www/html/wp-content/uploads/2026/09/foto.jpg'); Functions\when('wp_basename')->alias('basename'); Functions\when('wp_get_attachment_url')->justReturn('https://kunde.de/wp-content/uploads/2026/09/foto.jpg'); Functions\when('get_post_meta')->justReturn('Porträt'); Functions\when('get_edit_post_link')->justReturn('https://kunde.de/wp-admin/post.php?post=33&action=edit'); } public function testSummaryHasFileDataAndAlt(): void { $this->stubCommon(['width' => 1600, 'height' => 900, 'filesize' => 123456]); $summary = (new MediaPresenter())->summary($this->attachment()); self::assertSame('foto.jpg', $summary['filename']); self::assertSame('Porträt', $summary['alt']); self::assertSame(1600, $summary['width']); self::assertSame(123456, $summary['filesize']); } public function testFullListsSizesAndUsagesAndCopesWithMissingMetadata(): void { $this->stubCommon(['sizes' => ['medium' => ['width' => 300, 'height' => 169]]]); Functions\when('wp_get_attachment_image_src')->justReturn(['https://kunde.de/foto-300x169.jpg', 300, 169, true]); $usages = [['post_id' => 5, 'title' => 'Team', 'post_type' => 'page', 'where' => 'featured', 'certainty' => 'sicher']]; $full = (new MediaPresenter())->full($this->attachment(), $usages); self::assertSame(['medium' => ['url' => 'https://kunde.de/foto-300x169.jpg', 'width' => 300, 'height' => 169]], $full['sizes']); self::assertSame($usages, $full['usages']); self::assertSame('Bildunterschrift', $full['caption']); self::assertSame(5, $full['parent']); self::assertSame('https://kunde.de/wp-admin/post.php?post=33&action=edit', $full['edit_url']); self::assertNull($full['width']); Functions\when('wp_get_attachment_metadata')->justReturn(false); self::assertInstanceOf(stdClass::class, (new MediaPresenter())->full($this->attachment(), [])['sizes']); } public function testFullSchemaRequiresSizesAndUsagesAndDescribesUsages(): void { $schema = MediaPresenter::fullSchema(); self::assertContains('sizes', $schema['required']); self::assertContains('usages', $schema['required']); self::assertSame(['sicher', 'möglicherweise'], $schema['properties']['usages']['items']['properties']['certainty']['enum']); } }