mirror of https://github.com/interlegis/sapl.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
205 lines
7.7 KiB
205 lines
7.7 KiB
from datetime import date
|
|
|
|
import pytest
|
|
from django.urls import reverse
|
|
from model_bakery import baker
|
|
|
|
from sapl.base.models import Autor, CasaLegislativa
|
|
from sapl.materia.models import Autoria, MateriaLegislativa
|
|
from sapl.norma.models import AutoriaNorma, NormaJuridica
|
|
from sapl.relatorios import views as relatorios_views
|
|
from sapl.relatorios.views import get_sessao_plenaria
|
|
from sapl.sessao.models import ExpedienteSessao, SessaoPlenaria, TipoExpediente
|
|
from sapl.sessao.views import get_expedientes
|
|
|
|
|
|
def cria_sessao_com_expedientes():
|
|
"""Cria uma sessão cujos expedientes têm `ordenacao` inversa à ordem
|
|
alfabética dos nomes -- o caso que expõe o OSTicket #125461."""
|
|
sessao = baker.make(SessaoPlenaria)
|
|
tipo_leitura = baker.make(
|
|
TipoExpediente, nome='Leitura e Aprovação da Ata', ordenacao=1)
|
|
tipo_grande = baker.make(
|
|
TipoExpediente, nome='Grande Expediente', ordenacao=2)
|
|
|
|
for tipo in (tipo_grande, tipo_leitura):
|
|
baker.make(ExpedienteSessao, sessao_plenaria=sessao, tipo=tipo,
|
|
conteudo='<p>Conteúdo de {}.</p>'.format(tipo.nome))
|
|
|
|
return sessao
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_relatorio_sessao_respeita_ordenacao_do_tipo_expediente():
|
|
"""O PDF da Sessão Plenária deve seguir o campo `ordenacao` de
|
|
TipoExpediente, e não a ordem alfabética do nome."""
|
|
sessao = cria_sessao_com_expedientes()
|
|
casa = baker.make(CasaLegislativa)
|
|
user = baker.make('auth.User')
|
|
|
|
lst_expedientes = get_sessao_plenaria(sessao, casa, user)[6]
|
|
nomes = [e['nom_expediente'] for e in lst_expedientes]
|
|
|
|
assert nomes == ['Leitura e Aprovação da Ata', 'Grande Expediente']
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_relatorio_sessao_tem_mesma_ordem_de_expedientes_do_resumo():
|
|
"""O PDF e o Resumo exibido em tela não podem divergir: foi essa
|
|
divergência que originou o OSTicket #125461."""
|
|
sessao = cria_sessao_com_expedientes()
|
|
casa = baker.make(CasaLegislativa)
|
|
user = baker.make('auth.User')
|
|
|
|
do_pdf = [e['nom_expediente']
|
|
for e in get_sessao_plenaria(sessao, casa, user)[6]]
|
|
da_tela = [e['tipo'].nome for e in get_expedientes(sessao)['expedientes']]
|
|
|
|
assert do_pdf == da_tela
|
|
|
|
|
|
MSG_AUTOR_OU_PERIODO = 'Selecione um autor ou informe o período'
|
|
|
|
|
|
def params_materias_por_autor(autor='', inicio='', fim='', **extra):
|
|
return dict(tipo='', data_apresentacao_0=inicio,
|
|
data_apresentacao_1=fim, autoria__autor=autor,
|
|
pesquisar='Pesquisar', **extra)
|
|
|
|
|
|
def params_normas_por_autor(autor='', inicio='', fim='', **extra):
|
|
return dict(tipo='', data_0=inicio, data_1=fim,
|
|
autorianorma__autor=autor, pesquisar='Pesquisar', **extra)
|
|
|
|
|
|
def cria_materia(numero, data_apresentacao, autores):
|
|
materia = baker.make(MateriaLegislativa, numero=numero,
|
|
ano=data_apresentacao.year,
|
|
data_apresentacao=data_apresentacao,
|
|
ementa='Ementa da matéria {}'.format(numero))
|
|
for i, autor in enumerate(autores):
|
|
baker.make(Autoria, materia=materia, autor=autor,
|
|
primeiro_autor=(i == 0))
|
|
return materia
|
|
|
|
|
|
def cria_norma(numero, data_norma, autores):
|
|
norma = baker.make(NormaJuridica, numero=numero, ano=data_norma.year,
|
|
data=data_norma,
|
|
ementa='Ementa da norma {}'.format(numero))
|
|
for i, autor in enumerate(autores):
|
|
baker.make(AutoriaNorma, norma=norma, autor=autor,
|
|
primeiro_autor=(i == 0))
|
|
return norma
|
|
|
|
|
|
@pytest.fixture
|
|
def pdf_html(monkeypatch):
|
|
"""Troca o WeasyPrint por uma captura do HTML que iria para o PDF."""
|
|
baker.make(CasaLegislativa, cep='')
|
|
capturado = {}
|
|
|
|
def make_pdf(base_url, main_template, header_template, **kwargs):
|
|
capturado['html'] = main_template
|
|
return b'%PDF-fake'
|
|
|
|
monkeypatch.setattr(relatorios_views, 'make_pdf', make_pdf)
|
|
return capturado
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_materias_por_autor_sem_autor_e_sem_periodo_pede_filtro(client):
|
|
response = client.get(reverse('sapl.relatorios:materia_por_autor'),
|
|
params_materias_por_autor())
|
|
|
|
assert MSG_AUTOR_OU_PERIODO in response.content.decode()
|
|
assert not response.context.get('show_results')
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_materias_por_autor_sem_autor_lista_materias_do_periodo(client):
|
|
"""OSTicket #885134: sem autor, a pesquisa por período deve listar as
|
|
matérias do período, uma vez cada, mesmo as de mais de um autor."""
|
|
ana = baker.make(Autor, nome='Ana')
|
|
bruno = baker.make(Autor, nome='Bruno')
|
|
m1 = cria_materia(1, date(2025, 3, 1), [ana, bruno])
|
|
m2 = cria_materia(2, date(2025, 6, 1), [bruno])
|
|
cria_materia(3, date(2024, 1, 1), [ana])
|
|
|
|
response = client.get(
|
|
reverse('sapl.relatorios:materia_por_autor'),
|
|
params_materias_por_autor(inicio='01/01/2025', fim='31/12/2025'))
|
|
|
|
assert list(response.context['object_list']) == [m2, m1]
|
|
content = response.content.decode()
|
|
assert 'Autor: Todos' in content
|
|
assert 'Autor(es)' in content
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_materias_por_autor_com_autor_dispensa_periodo(client):
|
|
ana = baker.make(Autor, nome='Ana')
|
|
bruno = baker.make(Autor, nome='Bruno')
|
|
m1 = cria_materia(1, date(2025, 3, 1), [ana, bruno])
|
|
cria_materia(2, date(2025, 6, 1), [bruno])
|
|
m3 = cria_materia(3, date(2024, 1, 1), [ana])
|
|
|
|
response = client.get(reverse('sapl.relatorios:materia_por_autor'),
|
|
params_materias_por_autor(autor=ana.pk))
|
|
|
|
assert list(response.context['object_list']) == [m1, m3]
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_materias_por_autor_pdf_lista_materias(client, pdf_html):
|
|
"""OSTicket #885134: o PDF saía "Nenhum documento encontrado" mesmo com
|
|
a tela listando as matérias do autor."""
|
|
ana = baker.make(Autor, nome='Ana')
|
|
cria_materia(1, date(2025, 3, 1), [ana])
|
|
|
|
response = client.get(
|
|
reverse('sapl.relatorios:materia_por_autor'),
|
|
params_materias_por_autor(autor=ana.pk, relatorio='on'))
|
|
|
|
assert response['Content-Type'].startswith('application/pdf')
|
|
assert 'Ementa da matéria 1' in pdf_html['html']
|
|
assert 'Nenhum documento encontrado' not in pdf_html['html']
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_materias_por_autor_pdf_sem_filtro_volta_ao_form(client, pdf_html):
|
|
response = client.get(
|
|
reverse('sapl.relatorios:materia_por_autor'),
|
|
params_materias_por_autor(relatorio='on'))
|
|
|
|
assert response['Content-Type'].startswith('text/html')
|
|
assert MSG_AUTOR_OU_PERIODO in response.content.decode()
|
|
assert 'html' not in pdf_html
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_normas_por_autor_sem_autor_e_sem_periodo_pede_filtro(client):
|
|
response = client.get(reverse('sapl.relatorios:normas_por_autor'),
|
|
params_normas_por_autor())
|
|
|
|
assert MSG_AUTOR_OU_PERIODO in response.content.decode()
|
|
assert not response.context.get('show_results')
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False)
|
|
def test_normas_por_autor_sem_autor_agrupa_pelo_primeiro_autor(client):
|
|
ana = baker.make(Autor, nome='Ana')
|
|
bruno = baker.make(Autor, nome='Bruno')
|
|
n1 = cria_norma('1', date(2025, 3, 1), [ana, bruno])
|
|
n2 = cria_norma('2', date(2025, 6, 1), [bruno])
|
|
cria_norma('3', date(2024, 1, 1), [ana])
|
|
|
|
response = client.get(
|
|
reverse('sapl.relatorios:normas_por_autor'),
|
|
params_normas_por_autor(inicio='01/01/2025', fim='31/12/2025'))
|
|
|
|
assert list(response.context['object_list']) == [n1, n2]
|
|
content = response.content.decode()
|
|
assert 'Autor: Todos' in content
|
|
assert 'Autor: Ana' in content
|
|
assert 'Autor: Bruno' in content
|
|
|