import json import tempfile import unittest from pathlib import Path from unittest.mock import patch from engine.dominio import Clipe, Faixa, IntervaloDeTempo, Timeline from engine.scanner.coordenacao import ContextoDeAnalise from engine.scanner.descoberta import ArquivoDescoberto, DescobertaDeArquivos from engine.scanner.metadados import ExtracaoDeMetadados from engine.integracoes.midia.extracao_de_metadados import ExtracaoDeMetadados as Adapter class TesteArquivosEMetadados(unittest.TestCase): def _contexto(self, *arquivos: str | None) -> ContextoDeAnalise: clipes = [Clipe(str(i), f"clipe-{i}", IntervaloDeTempo(0, 1), arquivo=arquivo) for i, arquivo in enumerate(arquivos)] timeline = Timeline("timeline", "Principal", faixas=[Faixa("v1", "V1", "video", 0, clipes)]) return ContextoDeAnalise(timeline=timeline) def test_descoberta_normaliza_caminho_e_marca_offline(self): with tempfile.TemporaryDirectory() as pasta: arquivo = Path(pasta) / "camera.mp4" arquivo.touch() contexto = self._contexto(str(arquivo), str(Path(pasta) / "ausente.mp4"), None) DescobertaDeArquivos().executar(contexto) self.assertEqual(contexto.timeline.faixas[0].clipes[0].arquivo, str(arquivo.resolve())) self.assertFalse(contexto.timeline.faixas[0].clipes[0].offline) self.assertTrue(contexto.timeline.faixas[0].clipes[1].offline) self.assertTrue(contexto.timeline.faixas[0].clipes[2].offline) self.assertEqual(len(contexto.erros), 2) def test_descoberta_identifica_arquivo_duplicado(self): with tempfile.TemporaryDirectory() as pasta: arquivo = Path(pasta) / "camera.mov" arquivo.touch() contexto = self._contexto(str(arquivo), str(arquivo)) DescobertaDeArquivos().executar(contexto) self.assertEqual(len(contexto.avisos), 1) def test_extracao_converte_ffprobe_e_usa_cache(self): dados = {"format": {"format_name": "mov,mp4,m4a", "duration": "12.5", "size": "900"}, "streams": [{"codec_type": "video", "codec_name": "h264", "width": 1920, "height": 1080, "avg_frame_rate": "30000/1001"}, {"codec_type": "audio", "codec_name": "aac", "channels": 2, "sample_rate": "48000"}]} with tempfile.TemporaryDirectory() as pasta: arquivo = Path(pasta) / "camera.mp4" arquivo.touch() adapter = Adapter(ffprobe="ffprobe-simulado") processo = type("Processo", (), {"stdout": json.dumps(dados)})() with patch("engine.integracoes.midia.extracao_de_metadados.subprocess.run", return_value=processo) as run: primeiro = adapter.extrair(arquivo) segundo = adapter.extrair(arquivo) self.assertEqual(primeiro.codec_de_video, "h264") self.assertEqual(primeiro.codec_de_audio, "aac") self.assertEqual((primeiro.largura, primeiro.altura), (1920, 1080)) self.assertAlmostEqual(primeiro.taxa_de_quadros, 29.97002997, places=5) self.assertEqual(primeiro.duracao, 12.5) self.assertIs(primeiro, segundo) run.assert_called_once() def test_etapa_de_metadados_ignora_arquivos_offline(self): class ExtratorSimulado: def extrair(self, arquivo): return "metadados" with tempfile.TemporaryDirectory() as pasta: arquivo = Path(pasta) / "camera.mp4" arquivo.touch() contexto = self._contexto(str(arquivo), str(Path(pasta) / "ausente.mp4")) DescobertaDeArquivos().executar(contexto) ExtracaoDeMetadados(ExtratorSimulado()).executar(contexto) self.assertEqual(contexto.metadados_dos_arquivos["0"], "metadados") self.assertNotIn("1", contexto.metadados_dos_arquivos) if __name__ == "__main__": unittest.main()