]> gitweb.erp-flowers.ru Git - erp24_rep/yii-erp24/.git/commitdiff
auto-claude: subtask-1-1 - Создать FileServiceVideoTest.php с тестами для convertToMp4()
authorAleksey Filippov <Aleksey.Filippov@erp-flowers.ru>
Thu, 19 Feb 2026 16:38:42 +0000 (19:38 +0300)
committerAleksey Filippov <Aleksey.Filippov@erp-flowers.ru>
Thu, 19 Feb 2026 16:38:42 +0000 (19:38 +0300)
TDD RED phase: тесты написаны ДО реализации метода convertToMp4().

Добавлены тесты:
- testConvertToMp4MethodExists: проверка наличия метода
- testConvertToMp4MethodSignature: проверка сигнатуры метода
- testConvertToMp4ChecksFfmpegAvailability: проверка FFmpeg через which
- testConvertToMp4UsesEscapeshellarg: проверка безопасности shell-команд
- testConvertToMp4UsesFfmpegOverwriteFlag: проверка флага -y
- testConvertToMp4UsesFaststartFlag: проверка movflags +faststart
- testConvertToMp4LogsWhenFfmpegNotInstalled: проверка логирования
- testAviFileTypeIsVideo: проверка типа AVI файлов
- testSaveUploadedFileAutoConvertsMovAvi: проверка авто-конвертации
- testOriginalFileDeletedOnlyAfterSuccessfulConversion: проверка удаления
- testConvertToMp4UsesH264Codec: проверка h264 кодека
- testConvertToMp4UsesAacCodec: проверка aac кодека

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
erp24/tests/unit/services/FileServiceVideoTest.php [new file with mode: 0644]

diff --git a/erp24/tests/unit/services/FileServiceVideoTest.php b/erp24/tests/unit/services/FileServiceVideoTest.php
new file mode 100644 (file)
index 0000000..67e7879
--- /dev/null
@@ -0,0 +1,311 @@
+<?php
+
+declare(strict_types=1);
+
+namespace tests\unit\services;
+
+use Codeception\Test\Unit;
+
+/**
+ * Тесты FileService для видео-конвертации
+ *
+ * Тестируют метод convertToMp4() и обработку AVI файлов.
+ * TDD RED phase: тесты написаны ДО реализации метода.
+ *
+ * @group services
+ * @group file
+ * @group video
+ */
+class FileServiceVideoTest extends Unit
+{
+    /**
+     * Путь к FileService
+     */
+    private string $fileServicePath;
+
+    protected function _before(): void
+    {
+        $this->fileServicePath = dirname(__DIR__, 3) . '/services/FileService.php';
+    }
+
+    /**
+     * Проверяет наличие метода convertToMp4 в FileService
+     *
+     * TDD RED: Этот тест должен ПРОВАЛИТЬСЯ пока метод не реализован.
+     */
+    public function testConvertToMp4MethodExists(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем наличие метода convertToMp4
+        $hasMethod = preg_match(
+            '/public\s+static\s+function\s+convertToMp4\s*\(/s',
+            $content
+        );
+
+        $this->assertEquals(
+            1,
+            $hasMethod,
+            'FileService should have public static method convertToMp4()'
+        );
+    }
+
+    /**
+     * Проверяет сигнатуру метода convertToMp4
+     *
+     * Ожидаемая сигнатура:
+     * public static function convertToMp4(string $sourcePath, string $targetPath): ?string
+     */
+    public function testConvertToMp4MethodSignature(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем сигнатуру метода с типами параметров и возвращаемым типом
+        $hasCorrectSignature = preg_match(
+            '/public\s+static\s+function\s+convertToMp4\s*\(\s*string\s+\$\w+\s*,\s*string\s+\$\w+\s*\)\s*:\s*\?string/s',
+            $content
+        );
+
+        $this->assertEquals(
+            1,
+            $hasCorrectSignature,
+            'convertToMp4 should have signature: (string $sourcePath, string $targetPath): ?string'
+        );
+    }
+
+    /**
+     * Проверяет что convertToMp4 проверяет наличие FFmpeg
+     *
+     * Метод должен использовать `which ffmpeg` для проверки.
+     */
+    public function testConvertToMp4ChecksFfmpegAvailability(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем что метод проверяет наличие FFmpeg
+        $this->assertStringContainsString(
+            'which ffmpeg',
+            $content,
+            'convertToMp4 should check FFmpeg availability using "which ffmpeg"'
+        );
+    }
+
+    /**
+     * Проверяет что convertToMp4 использует escapeshellarg для безопасности
+     */
+    public function testConvertToMp4UsesEscapeshellarg(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем использование escapeshellarg для безопасности shell-команд
+        $this->assertStringContainsString(
+            'escapeshellarg',
+            $content,
+            'convertToMp4 should use escapeshellarg() for security'
+        );
+    }
+
+    /**
+     * Проверяет что convertToMp4 использует флаг -y для перезаписи
+     */
+    public function testConvertToMp4UsesFfmpegOverwriteFlag(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем использование флага -y для перезаписи без подтверждения
+        $hasFfmpegCommand = preg_match(
+            '/ffmpeg\s+-y\s+-i/s',
+            $content
+        );
+
+        $this->assertEquals(
+            1,
+            $hasFfmpegCommand,
+            'convertToMp4 should use ffmpeg -y flag for overwrite without confirmation'
+        );
+    }
+
+    /**
+     * Проверяет что convertToMp4 использует movflags для быстрого старта
+     */
+    public function testConvertToMp4UsesFaststartFlag(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем использование -movflags +faststart для быстрого старта воспроизведения
+        $this->assertStringContainsString(
+            'faststart',
+            $content,
+            'convertToMp4 should use -movflags +faststart for quick playback start'
+        );
+    }
+
+    /**
+     * Проверяет что convertToMp4 логирует при отсутствии FFmpeg
+     */
+    public function testConvertToMp4LogsWhenFfmpegNotInstalled(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем что есть логирование при отсутствии FFmpeg
+        $hasWarningLog = preg_match(
+            '/Yii::warning\s*\([^)]*FFmpeg[^)]*\)/si',
+            $content
+        );
+
+        $this->assertEquals(
+            1,
+            $hasWarningLog,
+            'convertToMp4 should log warning when FFmpeg is not installed'
+        );
+    }
+
+    /**
+     * Проверяет что AVI файлы определяются как video тип
+     *
+     * TDD RED: AVI должен быть добавлен в switch-case.
+     */
+    public function testAviFileTypeIsVideo(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем наличие avi в типах
+        $this->assertStringContainsString(
+            "'avi'",
+            $content,
+            'FileService should support .avi file type'
+        );
+
+        // Проверяем, что avi определяется как video
+        // Паттерн: case 'avi': ... $type = 'video'
+        $hasAviAsVideo = preg_match(
+            "/case\s+'avi'.*?'video'/s",
+            $content
+        );
+
+        $this->assertEquals(
+            1,
+            $hasAviAsVideo,
+            '.avi files should be classified as video type'
+        );
+    }
+
+    /**
+     * Проверяет авто-конвертацию MOV/AVI после saveAs
+     */
+    public function testSaveUploadedFileAutoConvertsMovAvi(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем что saveUploadedFile вызывает convertToMp4 для mov/avi
+        $hasAutoConvert = preg_match(
+            "/in_array\s*\([^)]*\['mov',\s*'avi'\]|in_array\s*\([^)]*\['avi',\s*'mov'\]/s",
+            $content
+        );
+
+        $this->assertEquals(
+            1,
+            $hasAutoConvert,
+            'saveUploadedFile should auto-convert mov/avi files using convertToMp4'
+        );
+    }
+
+    /**
+     * Проверяет что оригинальный файл удаляется только после успешной конвертации
+     */
+    public function testOriginalFileDeletedOnlyAfterSuccessfulConversion(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем паттерн: if ($converted !== null) { @unlink(...) }
+        // Это означает что удаление происходит только при успешной конвертации
+        $hasCorrectDeleteLogic = preg_match(
+            '/if\s*\(\s*\$\w+\s*!==\s*null\s*\)\s*\{[^}]*@?unlink/s',
+            $content
+        );
+
+        $this->assertEquals(
+            1,
+            $hasCorrectDeleteLogic,
+            'Original file should only be deleted after successful conversion (when result !== null)'
+        );
+    }
+
+    /**
+     * Проверяет что convertToMp4 использует h264 видеокодек
+     */
+    public function testConvertToMp4UsesH264Codec(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем использование h264 кодека
+        $this->assertStringContainsString(
+            'h264',
+            $content,
+            'convertToMp4 should use h264 video codec for browser compatibility'
+        );
+    }
+
+    /**
+     * Проверяет что convertToMp4 использует aac аудиокодек
+     */
+    public function testConvertToMp4UsesAacCodec(): void
+    {
+        if (!file_exists($this->fileServicePath)) {
+            $this->markTestSkipped('FileService.php not found');
+        }
+
+        $content = file_get_contents($this->fileServicePath);
+
+        // Проверяем использование aac кодека
+        $this->assertStringContainsString(
+            'aac',
+            $content,
+            'convertToMp4 should use aac audio codec for browser compatibility'
+        );
+    }
+}