Files
portal/app/tests/Support/MtsMediaFixture.php
T

69 lines
3.7 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace Tests\Support;
use Illuminate\Http\UploadedFile;
/**
* Синтетические файлы медиа под требования кабинета МТС.
*
* 🪤 Почему классом, а не функциями в тесте: в Pest помощники из разных файлов живут
* в ОДНОМ пространстве имён, и одноимённые функции в двух наборах роняют прогон
* «Cannot redeclare» — на этом уже спотыкались при сведении веток 01.08.2026.
* Класс автозагружается (Tests\ → tests/) и столкнуться не может.
*
* Настоящих пикселей внутри нет — только те поля заголовка, которые читает
* App\Support\Mp4Probe: длительность (mvhd) и размер кадра (tkhd).
*/
final class MtsMediaFixture
{
/** Один бокс контейнера ISO-BMFF: длина (4 байта) + тип (4 байта) + содержимое. */
private static function box(string $type, string $payload): string
{
return pack('N', 8 + strlen($payload)).$type.$payload;
}
/** Байты mp4 с настоящими mvhd (длительность) и tkhd (размер кадра). */
public static function mp4Bytes(float $seconds = 10.0, int $width = 1280, int $height = 720): string
{
$timescale = 1000;
$duration = (int) round($seconds * $timescale);
$mvhd = "\x00\x00\x00\x00" // version 0 + flags
.pack('N', 0).pack('N', 0) // создан / изменён
.pack('N', $timescale).pack('N', $duration) // масштаб времени и длительность
.pack('N', 0x00010000) // rate
.pack('n', 0x0100) // volume
.str_repeat("\x00", 2 + 8 + 36 + 24) // reserved + matrix + pre_defined
.pack('N', 2); // next_track_ID
$tkhd = "\x00\x00\x00\x07" // version 0 + флаги «дорожка включена»
.pack('N', 0).pack('N', 0) // создан / изменён
.pack('N', 1) // track_ID
.pack('N', 0) // reserved
.pack('N', $duration) // длительность дорожки
.str_repeat("\x00", 8) // reserved
.pack('n', 0).pack('n', 0) // layer, alternate_group
.pack('n', 0).pack('n', 0) // volume, reserved
.str_repeat("\x00", 36) // matrix
.pack('N', $width << 16).pack('N', $height << 16); // ширина/высота 16.16
return self::box('ftyp', 'isom'.pack('N', 512).'isomiso2mp41')
.self::box('moov', self::box('mvhd', $mvhd).self::box('trak', self::box('tkhd', $tkhd)));
}
/** Годное видео файлом — ровно то, что кабинет принимает. */
public static function video(float $seconds = 10.0, int $width = 1280, int $height = 720): UploadedFile
{
return UploadedFile::fake()->createWithContent('ad.mp4', self::mp4Bytes($seconds, $width, $height));
}
/** Годная картинка файлом. */
public static function kartinka(int $width = 1280, int $height = 720): UploadedFile
{
return UploadedFile::fake()->image('ad.jpg', $width, $height);
}
}