import pytest from unittest.mock import MagicMock, patch from datetime import datetime from dataclasses import dataclass from src.application.services.pdf_service import PDFService, ConsultorWrapper, DictWrapper class TestFormatDate: def test_format_date_vazio(self): service = PDFService.__new__(PDFService) resultado = service._format_date("") assert resultado == "-" def test_format_date_none(self): service = PDFService.__new__(PDFService) resultado = service._format_date(None) assert resultado == "-" def test_format_date_formato_brasileiro(self): service = PDFService.__new__(PDFService) resultado = service._format_date("25/12/2023") assert resultado == "25/12/2023" def test_format_date_iso(self): service = PDFService.__new__(PDFService) resultado = service._format_date("2023-12-25T10:30:00") assert resultado == "25/12/2023" def test_format_date_iso_com_z(self): service = PDFService.__new__(PDFService) resultado = service._format_date("2023-12-25T10:30:00Z") assert resultado == "25/12/2023" def test_format_date_invalido(self): service = PDFService.__new__(PDFService) resultado = service._format_date("data-invalida") assert resultado == "data-invalida" class TestFormatDateShort: def test_format_date_short_vazio(self): service = PDFService.__new__(PDFService) resultado = service._format_date_short("") assert resultado == "-" def test_format_date_short_none(self): service = PDFService.__new__(PDFService) resultado = service._format_date_short(None) assert resultado == "-" def test_format_date_short_brasileiro_3_partes(self): service = PDFService.__new__(PDFService) resultado = service._format_date_short("25/12/2023") assert resultado == "Dez/2023" def test_format_date_short_brasileiro_2_partes(self): service = PDFService.__new__(PDFService) resultado = service._format_date_short("12/2023") assert resultado == "Dez/2023" def test_format_date_short_iso(self): service = PDFService.__new__(PDFService) resultado = service._format_date_short("2023-06-15T10:30:00") assert resultado == "Jun/2023" def test_format_date_short_janeiro(self): service = PDFService.__new__(PDFService) resultado = service._format_date_short("15/01/2024") assert resultado == "Jan/2024" class TestSortByDate: def test_sort_by_date_lista_vazia(self): service = PDFService.__new__(PDFService) resultado = service._sort_by_date([], "data") assert resultado == [] def test_sort_by_date_sem_campo(self): service = PDFService.__new__(PDFService) items = [{"nome": "A"}, {"nome": "B"}] resultado = service._sort_by_date(items) assert resultado == items def test_sort_by_date_ordena_desc(self): service = PDFService.__new__(PDFService) items = [ {"nome": "A", "data": "2020-01-01"}, {"nome": "B", "data": "2023-01-01"}, {"nome": "C", "data": "2021-01-01"}, ] resultado = service._sort_by_date(items, "data") assert resultado[0]["nome"] == "B" assert resultado[1]["nome"] == "C" assert resultado[2]["nome"] == "A" def test_sort_by_date_formato_brasileiro(self): service = PDFService.__new__(PDFService) items = [ {"nome": "A", "data": "01/01/2020"}, {"nome": "B", "data": "01/01/2023"}, ] resultado = service._sort_by_date(items, "data") assert resultado[0]["nome"] == "B" def test_sort_by_date_com_ano_numerico(self): service = PDFService.__new__(PDFService) items = [ {"nome": "A", "ano": 2020}, {"nome": "B", "ano": 2023}, ] resultado = service._sort_by_date(items, "ano") assert resultado[0]["nome"] == "B" def test_sort_by_date_com_ano_string(self): service = PDFService.__new__(PDFService) items = [ {"nome": "A", "ano": "2020"}, {"nome": "B", "ano": "2023"}, ] resultado = service._sort_by_date(items, "ano") assert resultado[0]["nome"] == "B" def test_sort_by_date_valores_nulos_no_final(self): service = PDFService.__new__(PDFService) items = [ {"nome": "A", "data": None}, {"nome": "B", "data": "2023-01-01"}, {"nome": "C", "data": ""}, ] resultado = service._sort_by_date(items, "data") assert resultado[0]["nome"] == "B" def test_sort_by_date_fallback_campos(self): service = PDFService.__new__(PDFService) items = [ {"nome": "A", "inicio": "2020-01-01"}, {"nome": "B", "data": "2023-01-01"}, ] resultado = service._sort_by_date(items, "data", "inicio") assert resultado[0]["nome"] == "B" assert resultado[1]["nome"] == "A" class TestConsultorToDict: def test_consultor_to_dict_dict(self): service = PDFService.__new__(PDFService) dados = {"nome": "Teste", "id": 123} resultado = service._consultor_to_dict(dados) assert resultado == dados def test_consultor_to_dict_dataclass(self): @dataclass class ConsultorTest: nome: str id: int service = PDFService.__new__(PDFService) consultor = ConsultorTest(nome="Teste", id=123) resultado = service._consultor_to_dict(consultor) assert resultado == {"nome": "Teste", "id": 123} def test_consultor_to_dict_pydantic_model_dump(self): service = PDFService.__new__(PDFService) mock_obj = MagicMock() mock_obj.model_dump.return_value = {"nome": "Teste"} del mock_obj.dict resultado = service._consultor_to_dict(mock_obj) assert resultado == {"nome": "Teste"} def test_consultor_to_dict_pydantic_dict(self): service = PDFService.__new__(PDFService) mock_obj = MagicMock(spec=['dict']) mock_obj.dict.return_value = {"nome": "Teste"} resultado = service._consultor_to_dict(mock_obj) assert resultado == {"nome": "Teste"} class TestExtrairPontuacaoCoord: def test_extrair_pontuacao_coord_vazio(self): service = PDFService.__new__(PDFService) resultado = service._extrair_pontuacao_coord({}) assert resultado == {} def test_extrair_pontuacao_coord_sem_pontuacao(self): service = PDFService.__new__(PDFService) resultado = service._extrair_pontuacao_coord({"nome": "Teste"}) assert resultado == {} def test_extrair_pontuacao_coord_com_atuacoes(self): service = PDFService.__new__(PDFService) dados = { "pontuacao": { "bloco_a": { "atuacoes": [ {"codigo": "CA", "base": 200, "tempo": 50, "bonus": 30, "total": 280}, {"codigo": "CAJ", "base": 150, "tempo": 40, "bonus": 20, "total": 210}, ] } } } resultado = service._extrair_pontuacao_coord(dados) assert "CA" in resultado assert resultado["CA"]["base"] == 200 assert resultado["CA"]["tempo"] == 50 assert resultado["CA"]["total"] == 280 assert "CAJ" in resultado class TestConsultorWrapper: def test_wrapper_acesso_atributo_simples(self): wrapper = ConsultorWrapper({"nome": "Teste", "id": 123}) assert wrapper.nome == "Teste" assert wrapper.id == 123 def test_wrapper_atributo_inexistente(self): wrapper = ConsultorWrapper({"nome": "Teste"}) assert wrapper.id is None def test_wrapper_atributo_dict_retorna_dictwrapper(self): wrapper = ConsultorWrapper({ "dados": {"campo": "valor"} }) assert isinstance(wrapper.dados, DictWrapper) assert wrapper.dados.campo == "valor" def test_wrapper_atributo_lista_de_dicts(self): wrapper = ConsultorWrapper({ "itens": [{"nome": "A"}, {"nome": "B"}] }) assert len(wrapper.itens) == 2 assert isinstance(wrapper.itens[0], DictWrapper) assert wrapper.itens[0].nome == "A" def test_wrapper_bool_true(self): wrapper = ConsultorWrapper({"nome": "Teste"}) assert bool(wrapper) is True def test_wrapper_bool_false(self): wrapper = ConsultorWrapper({}) assert bool(wrapper) is False class TestDictWrapper: def test_dictwrapper_acesso_atributo(self): wrapper = DictWrapper({"campo": "valor"}) assert wrapper.campo == "valor" def test_dictwrapper_atributo_inexistente(self): wrapper = DictWrapper({"campo": "valor"}) assert wrapper.outro is None def test_dictwrapper_aninhado(self): wrapper = DictWrapper({ "nivel1": {"nivel2": {"nivel3": "valor"}} }) assert wrapper.nivel1.nivel2.nivel3 == "valor" def test_dictwrapper_lista(self): wrapper = DictWrapper({ "itens": [{"a": 1}, {"b": 2}] }) assert len(wrapper.itens) == 2 assert wrapper.itens[0].a == 1 def test_dictwrapper_get(self): wrapper = DictWrapper({"campo": "valor"}) assert wrapper.get("campo") == "valor" assert wrapper.get("inexistente", "default") == "default" def test_dictwrapper_str(self): wrapper = DictWrapper({"campo": "valor"}) assert "campo" in str(wrapper) def test_dictwrapper_bool_true(self): wrapper = DictWrapper({"campo": "valor"}) assert bool(wrapper) is True def test_dictwrapper_bool_false(self): wrapper = DictWrapper({}) assert bool(wrapper) is False class TestGerarFichaConsultor: def test_gerar_ficha_consultor_mock(self): import sys mock_weasyprint = MagicMock() mock_weasyprint.HTML.return_value.write_pdf.return_value = b"PDF_CONTENT" mock_weasyprint.CSS.return_value = MagicMock() sys.modules['weasyprint'] = mock_weasyprint try: with patch.object(PDFService, '__init__', lambda self: None): service = PDFService() service.template = MagicMock() service.template.render.return_value = "" from pathlib import Path service.template_dir = Path("/tmp") consultor = {"nome": "Teste", "id": 123} resultado = service.gerar_ficha_consultor(consultor) assert resultado == b"PDF_CONTENT" service.template.render.assert_called_once() finally: del sys.modules['weasyprint'] class TestGerarPdfEquipe: def test_gerar_pdf_equipe_mock(self): import sys mock_weasyprint = MagicMock() mock_weasyprint.HTML.return_value.write_pdf.return_value = b"PDF_EQUIPE" mock_weasyprint.CSS.return_value = MagicMock() sys.modules['weasyprint'] = mock_weasyprint try: with patch.object(PDFService, '__init__', lambda self: None): service = PDFService() service.env = MagicMock() mock_template = MagicMock() mock_template.render.return_value = "" service.env.get_template.return_value = mock_template from pathlib import Path service.template_dir = Path("/tmp") consultores = [ {"nome": "A", "ies": "USP", "areas_avaliacao": ["FÍSICA"], "situacao": "Atividade Contínua", "foi_coordenador": True, "foi_premiado": False}, {"nome": "B", "ies": "UNICAMP", "areas_avaliacao": ["QUÍMICA"], "situacao": "Inativo", "foi_coordenador": False, "foi_premiado": True}, ] resultado = service.gerar_pdf_equipe("Tema X", "FÍSICA", consultores) assert resultado == b"PDF_EQUIPE" mock_template.render.assert_called_once() call_kwargs = mock_template.render.call_args[1] assert call_kwargs["tema"] == "Tema X" assert call_kwargs["area_avaliacao"] == "FÍSICA" assert call_kwargs["estatisticas"]["total"] == 2 assert call_kwargs["estatisticas"]["coordenadores"] == 1 assert call_kwargs["estatisticas"]["premiados"] == 1 assert call_kwargs["estatisticas"]["ies_distintas"] == 2 finally: del sys.modules['weasyprint'] def test_estatisticas_equipe_ativos(self): import sys mock_weasyprint = MagicMock() mock_weasyprint.HTML.return_value.write_pdf.return_value = b"PDF" mock_weasyprint.CSS.return_value = MagicMock() sys.modules['weasyprint'] = mock_weasyprint try: with patch.object(PDFService, '__init__', lambda self: None): service = PDFService() service.env = MagicMock() mock_template = MagicMock() mock_template.render.return_value = "" service.env.get_template.return_value = mock_template from pathlib import Path service.template_dir = Path("/tmp") consultores = [ {"nome": "A", "situacao": "Atividade Contínua"}, {"nome": "B", "situacao": "Atividade Contínua"}, {"nome": "C", "situacao": "Inativo"}, ] service.gerar_pdf_equipe("Tema", "ÁREA", consultores) call_kwargs = mock_template.render.call_args[1] assert call_kwargs["estatisticas"]["ativos"] == 2 finally: del sys.modules['weasyprint']