splitJuryByRole($jury); } public function exposedCollectCaptionPaths(array $files): array { return $this->collectCaptionPaths($files); } }; } private function getThesisCreateController(): ThesisCreateController { $db = TestDatabase::getInstance(); return new class($db) extends ThesisCreateController { public function exposedDetectFileType(string $mimeType, string $ext): string { return $this->detectFileType($mimeType, $ext); } }; } // ── splitJuryByRole ────────────────────────────────────────────────────── public function testSplitJuryByRoleAllRoles(): void { $ctrl = $this->getTfeController(); $jury = [ ['name' => 'Alice', 'role' => 'president', 'is_external' => 0, 'is_ulb' => 0], ['name' => 'Bob', 'role' => 'promoteur', 'is_external' => 0, 'is_ulb' => 0], ['name' => 'Carol', 'role' => 'promoteur', 'is_external' => 1, 'is_ulb' => 1], ['name' => 'Dave', 'role' => 'promoteur', 'is_external' => 1, 'is_ulb' => 0], ['name' => 'Eve', 'role' => 'lecteur', 'is_external' => 0, 'is_ulb' => 0], ['name' => 'Frank', 'role' => 'lecteur', 'is_external' => 1, 'is_ulb' => 0], ]; $split = $ctrl->exposedSplitJuryByRole($jury); $this->assertSame(['Alice'], $split['presidents']); $this->assertSame(['Bob'], $split['internes']); $this->assertSame(['Carol'], $split['ulb']); $this->assertSame(['Dave'], $split['externes']); $this->assertSame(['Eve'], $split['lecteurs_internes']); $this->assertSame(['Frank'], $split['lecteurs_externes']); } public function testSplitJuryByRoleEmptyNameSkipped(): void { $ctrl = $this->getTfeController(); $jury = [['name' => '', 'role' => 'president', 'is_external' => 0, 'is_ulb' => 0]]; $split = $ctrl->exposedSplitJuryByRole($jury); $this->assertEmpty($split['presidents']); } public function testSplitJuryByRoleEmptyJury(): void { $ctrl = $this->getTfeController(); $split = $ctrl->exposedSplitJuryByRole([]); $this->assertEmpty($split['presidents']); $this->assertEmpty($split['internes']); $this->assertEmpty($split['ulb']); $this->assertEmpty($split['externes']); $this->assertEmpty($split['lecteurs_internes']); $this->assertEmpty($split['lecteurs_externes']); } // ── collectCaptionPaths ────────────────────────────────────────────────── public function testCollectCaptionPathsVttByMime(): void { $ctrl = $this->getTfeController(); $files = [ ['mime_type' => 'application/pdf', 'file_path' => 'main.pdf'], ['mime_type' => 'text/vtt', 'file_path' => 'captions1.vtt'], ['mime_type' => 'video/mp4', 'file_path' => 'video.mp4'], ['mime_type' => 'text/plain', 'file_path' => 'captions2.vtt'], ]; $captions = $ctrl->exposedCollectCaptionPaths($files); // Only the VTT files, in order $this->assertCount(2, $captions); $this->assertSame('captions1.vtt', $captions[0]); $this->assertSame('captions2.vtt', $captions[1]); } public function testCollectCaptionPathsVttByExtension(): void { $ctrl = $this->getTfeController(); $files = [ ['mime_type' => 'application/octet-stream', 'file_path' => 'sub.vtt'], ['mime_type' => 'video/mp4', 'file_path' => 'video.mp4'], ]; $captions = $ctrl->exposedCollectCaptionPaths($files); $this->assertCount(1, $captions); $this->assertSame('sub.vtt', $captions[0]); } public function testCollectCaptionPathsNoVttReturnsEmpty(): void { $ctrl = $this->getTfeController(); $files = [['mime_type' => 'video/mp4', 'file_path' => 'video.mp4']]; $this->assertEmpty($ctrl->exposedCollectCaptionPaths($files)); } // ── detectFileType ─────────────────────────────────────────────────────── public function testDetectFileTypeByMime(): void { $ctrl = $this->getThesisCreateController(); $this->assertSame('caption', $ctrl->exposedDetectFileType('text/vtt', 'vtt')); $this->assertSame('audio', $ctrl->exposedDetectFileType('audio/mpeg', 'mp3')); $this->assertSame('audio', $ctrl->exposedDetectFileType('audio/ogg', 'ogg')); $this->assertSame('video', $ctrl->exposedDetectFileType('video/mp4', 'mp4')); $this->assertSame('video', $ctrl->exposedDetectFileType('video/webm', 'webm')); $this->assertSame('main', $ctrl->exposedDetectFileType('application/pdf', 'pdf')); $this->assertSame('image', $ctrl->exposedDetectFileType('image/jpeg', 'jpg')); $this->assertSame('image', $ctrl->exposedDetectFileType('image/png', 'png')); $this->assertSame('other', $ctrl->exposedDetectFileType('application/zip', 'zip')); } public function testDetectFileTypeByExtensionFallback(): void { $ctrl = $this->getThesisCreateController(); $this->assertSame('audio', $ctrl->exposedDetectFileType('application/octet-stream', 'mp3')); $this->assertSame('video', $ctrl->exposedDetectFileType('application/octet-stream', 'mp4')); $this->assertSame('main', $ctrl->exposedDetectFileType('application/octet-stream', 'pdf')); $this->assertSame('image', $ctrl->exposedDetectFileType('application/octet-stream', 'webp')); $this->assertSame('caption', $ctrl->exposedDetectFileType('application/octet-stream', 'vtt')); } }