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%
384 lines
14 KiB
Python
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']
|