1<?php 2 3namespace dokuwiki\plugin\dw2pdf\test; 4 5use dokuwiki\plugin\dw2pdf\src\MediaLinkResolver; 6use DokuWikiTest; 7 8/** 9 * Tests for translating Dokuwiki media references into local cached files. 10 * 11 * @group plugin_dw2pdf 12 * @group plugins 13 */ 14class MediaLinkResolverTest extends DokuWikiTest 15{ 16 private $resolver; 17 18 public function setUp(): void 19 { 20 parent::setUp(); 21 $this->resolver = new MediaLinkResolver(); 22 } 23 24 /** 25 * @return array<string, array{0:string,1:string,2:string}> 26 */ 27 public static function resolveProvider(): array 28 { 29 global $conf; 30 31 return [ 32 'internal fetch url' => [ 33 DOKU_URL . 'lib/exe/fetch.php?media=wiki:dokuwiki-128.png', 34 $conf['mediadir'] . '/wiki/dokuwiki-128.png', 35 'image/png', 36 ], 37 'static local file' => [ 38 DOKU_URL . 'lib/images/throbber.gif', 39 DOKU_INC . 'lib/images/throbber.gif', 40 'image/gif', 41 ], 42 ]; 43 } 44 45 /** 46 * @dataProvider resolveProvider 47 */ 48 public function testResolveReturnsLocalPathAndMime(string $input, string $expectedPath, string $expectedMime): void 49 { 50 $resolved = $this->resolver->resolve($input); 51 52 $this->assertNotNull($resolved); 53 $this->assertSame($expectedPath, $resolved['path']); 54 $this->assertSame($expectedMime, $resolved['mime']); 55 $this->assertFileExists($resolved['path']); 56 } 57 58 /** 59 * The resolver must support our dw2pdf:// pseudo scheme for temporary files. 60 */ 61 public function testResolveDw2pdfScheme(): void 62 { 63 $temp = tempnam(sys_get_temp_dir(), 'dw2pdf'); 64 if ($temp === false) { 65 $this->fail('Unable to create temp file for dw2pdf:// test'); 66 } 67 68 $image = $temp . '.png'; 69 if (!rename($temp, $image)) { 70 $this->fail('Unable to rename temp file for dw2pdf:// test'); 71 } 72 73 $resolved = $this->resolver->resolve('dw2pdf://' . $image); 74 75 $this->assertNotNull($resolved); 76 $this->assertSame($image, $resolved['path']); 77 $this->assertSame('image/png', $resolved['mime']); 78 79 @unlink($image); 80 } 81 82 /** 83 * @group internet 84 */ 85 public function testResolveFetchesExternalMedia(): void 86 { 87 global $conf; 88 $conf['fetchsize'] = 512 * 1024; // 512 KB 89 90 $external = 'https://php.net/images/php.gif'; 91 $input = DOKU_URL . 'lib/exe/fetch.php?media=' . rawurlencode($external); 92 $resolved = $this->resolver->resolve($input); 93 94 if ($resolved === null) { 95 $this->markTestSkipped('External media fetching is not available in this environment.'); 96 } 97 98 $this->assertNotNull($resolved); 99 $this->assertFileExists($resolved['path']); 100 $this->assertSame('image/gif', $resolved['mime']); 101 $this->assertSame(2523, filesize($resolved['path'])); 102 } 103 104 /** 105 * Non-image payloads should never be returned to the PDF generator. 106 */ 107 public function testResolveRejectsNonImages(): void 108 { 109 $resolved = $this->resolver->resolve(DOKU_URL . 'README'); 110 111 $this->assertNull($resolved); 112 } 113 114 /** 115 * Resizing parameters from fetch.php should trigger scaled copies in cache. 116 */ 117 public function testResolveAppliesResizeParameter(): void 118 { 119 global $conf; 120 121 $input = DOKU_URL . 'lib/exe/fetch.php?w=32&media=wiki:dokuwiki-128.png'; 122 $original = $conf['mediadir'] . '/wiki/dokuwiki-128.png'; 123 $resolved = $this->resolver->resolve($input); 124 125 $this->assertNotNull($resolved); 126 $this->assertNotSame($original, $resolved['path']); 127 $this->assertSame('image/png', $resolved['mime']); 128 $this->assertFileExists($resolved['path']); 129 } 130} 131