$dimensions) copy($root . '/1/' . $name, $fixture . '/1/' . $name); $config = ['utm' => ['indpic' => ['default' => '1', 'weights' => ['1' => 1]]]]; // Замена изображения корректным новым изображением не требует Git SHA. $image = new Imagick($fixture . '/1/01_desk_1-source.jpg'); $image->setImageProperty('comment', 'runtime replacement preland#22'); $image->writeImage($fixture . '/1/01_desk_1-source.jpg'); $image->clear(); if (hash_file('sha256', $fixture . '/1/01_desk_1-source.jpg') === hash_file('sha256', $root . '/1/01_desk_1-source.jpg')) throw new LogicException('Fixture не изменён'); checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture); $requests = []; checkRuntimeSets($config, static function (string $path) use ($fixture, &$requests): string { $requests[] = $path; return runtimeLocalReader($fixture)($path); }); if (count($requests) !== 90) throw new LogicException('HTTP-путь обязан прочитать все 90 файлов'); $bytes = file_get_contents($fixture . '/1/01_desk_1-source.jpg'); file_put_contents($fixture . '/1/01_desk_1-source.jpg', 'HTTP 200'); $assertFails(fn() => checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture)); file_put_contents($fixture . '/1/01_desk_1-source.jpg', $bytes); $wrong = new Imagick(); $wrong->newImage(1, 1, 'red', 'jpeg'); $wrong->writeImage($fixture . '/1/01_desk_1-source.jpg'); $wrong->clear(); $assertFails(fn() => checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture)); file_put_contents($fixture . '/1/01_desk_1-source.jpg', $bytes); file_put_contents($fixture . '/1/extra.txt', 'extra'); $assertFails(fn() => checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture)); unlink($fixture . '/1/extra.txt'); unlink($fixture . '/1/05_mob_3-thumb.avif'); $assertFails(fn() => checkRuntimeSets($config, runtimeLocalReader($fixture), $fixture)); copy($root . '/1/05_mob_3-thumb.avif', $fixture . '/1/05_mob_3-thumb.avif'); foreach (['0', '10', '../1', false, null] as $default) { $bad = $config; $bad['utm']['indpic']['default'] = $default; $assertFails(fn() => checkRuntimeSets($bad, runtimeLocalReader($fixture), $fixture)); } $bad = $config; $bad['utm']['indpic']['weights']['2'] = 1; $assertFails(fn() => checkRuntimeSets($bad, runtimeLocalReader($fixture), $fixture)); $bad = $config; $bad['utm']['indpic']['default'] = '2'; $assertFails(fn() => checkRuntimeSets($bad, runtimeLocalReader($fixture), $fixture)); checkRuntimeSets([], runtimeLocalReader($fixture), $fixture); // штатный fallback /1/ foreach (releaseFiles($root) as $file) if (preg_match('~^(admin/|config\.json$|[0-9]+/)~', $file)) throw new LogicException('Приватный/runtime файл в поставке'); echo "OK: runtime replacement, decode, dimensions, missing/extra files, default, active links, release isolation\n"; } finally { foreach (glob($fixture . '/1/*') as $file) unlink($file); rmdir($fixture . '/1'); rmdir($fixture); }