Files
ranking/backend/tests/application/services/test_pdf_service.py
Frederico Castro 3558a4b6ca feat(tests): adicionar testes para ExcelService e PDFService
ExcelService (41 testes):
- Geração de Excel com consultores
- Parse de JSON, formatação de filtros
- Extração de coordenações, consultoria, prêmios, titulação

PDFService (44 testes):
- Formatação de datas (completa e curta)
- Ordenação por data com múltiplos formatos
- Wrappers (ConsultorWrapper, DictWrapper)
- Geração de ficha e PDF de equipe (mocked)

Correções:
- Ajuste nos testes Oracle para acessar params corretamente

Cobertura: 54% → 66%
2025-12-29 09:29:33 -03:00

384 lines
14 KiB
Python

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 = "<html></html>"
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 = "<html></html>"
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 = "<html></html>"
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']