|
|
|
@ -2,6 +2,7 @@ import pytest |
|
|
|
from datetime import date |
|
|
|
from django.contrib.auth import get_user_model |
|
|
|
from django.contrib.auth.models import AnonymousUser |
|
|
|
from django.db import IntegrityError, transaction |
|
|
|
from django.urls import reverse |
|
|
|
from django.utils.translation import ugettext_lazy as _ |
|
|
|
from model_bakery import baker |
|
|
|
@ -9,6 +10,7 @@ from model_bakery import baker |
|
|
|
from sapl.parlamentares.models import Legislatura, SessaoLegislativa |
|
|
|
from sapl.sessao.models import (SessaoPlenaria, TipoSessaoPlenaria, |
|
|
|
IntegranteMesa, SessaoPlenariaPresenca, |
|
|
|
PresencaOrdemDia, |
|
|
|
JustificativaAusencia, ExpedienteSessao, |
|
|
|
TipoExpediente, ExpedienteMateria, |
|
|
|
Orador, OcorrenciaSessao, |
|
|
|
@ -235,3 +237,103 @@ def test_pauta_nao_publicada_indisponivel_para_anonimo(client): |
|
|
|
kwargs={'pk': sem_pauta.pk})) |
|
|
|
|
|
|
|
assert response.status_code == 404 |
|
|
|
|
|
|
|
|
|
|
|
def cria_sessao_com_parlamentares(): |
|
|
|
legislatura = baker.make(Legislatura) |
|
|
|
sessao_legislativa = baker.make(SessaoLegislativa) |
|
|
|
tipo = baker.make(TipoSessaoPlenaria) |
|
|
|
sessao = baker.make(SessaoPlenaria, |
|
|
|
legislatura=legislatura, |
|
|
|
sessao_legislativa=sessao_legislativa, |
|
|
|
tipo=tipo) |
|
|
|
parlamentares = [baker.make(Parlamentar, ativo=True) for _i in range(3)] |
|
|
|
return sessao, parlamentares |
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False) |
|
|
|
def test_presenca_sessao_preserva_registros_ao_salvar_novamente(admin_client): |
|
|
|
# Cada salvamento apagava todas as presenças da sessão e as recriava, |
|
|
|
# trocando os ids. Além do desperdício, é essa janela entre apagar e |
|
|
|
# recriar que permite a duplicação quando o formulário é submetido duas |
|
|
|
# vezes em paralelo. Salvar de novo deve ser inócuo. |
|
|
|
sessao, parlamentares = cria_sessao_com_parlamentares() |
|
|
|
url = reverse('sapl.sessao:presenca', kwargs={'pk': sessao.pk}) |
|
|
|
dados = {'presenca_ativos': [str(p.pk) for p in parlamentares]} |
|
|
|
|
|
|
|
admin_client.post(url, dados, follow=True) |
|
|
|
presencas = SessaoPlenariaPresenca.objects.filter(sessao_plenaria=sessao) |
|
|
|
ids_iniciais = sorted(presencas.values_list('id', flat=True)) |
|
|
|
|
|
|
|
admin_client.post(url, dados, follow=True) |
|
|
|
admin_client.post(url, dados, follow=True) |
|
|
|
|
|
|
|
assert presencas.count() == len(parlamentares) |
|
|
|
assert sorted(presencas.values_list('parlamentar_id', flat=True)) == \ |
|
|
|
sorted(p.pk for p in parlamentares) |
|
|
|
assert sorted(presencas.values_list('id', flat=True)) == ids_iniciais |
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False) |
|
|
|
def test_presenca_sessao_ignora_registro_ja_existente(admin_client): |
|
|
|
# Reproduz o efeito da submissão concorrente: a linha já existe quando a |
|
|
|
# view vai gravar. Deve terminar com uma única presença, sem erro. |
|
|
|
sessao, parlamentares = cria_sessao_com_parlamentares() |
|
|
|
parlamentar = parlamentares[0] |
|
|
|
SessaoPlenariaPresenca.objects.create(sessao_plenaria=sessao, |
|
|
|
parlamentar=parlamentar) |
|
|
|
|
|
|
|
url = reverse('sapl.sessao:presenca', kwargs={'pk': sessao.pk}) |
|
|
|
response = admin_client.post( |
|
|
|
url, {'presenca_ativos': [str(parlamentar.pk)]}, follow=True) |
|
|
|
|
|
|
|
assert response.status_code == 200 |
|
|
|
assert SessaoPlenariaPresenca.objects.filter( |
|
|
|
sessao_plenaria=sessao, parlamentar=parlamentar).count() == 1 |
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False) |
|
|
|
def test_presenca_sessao_remove_desmarcados(admin_client): |
|
|
|
sessao, parlamentares = cria_sessao_com_parlamentares() |
|
|
|
url = reverse('sapl.sessao:presenca', kwargs={'pk': sessao.pk}) |
|
|
|
|
|
|
|
admin_client.post(url, {'presenca_ativos': [str(p.pk) |
|
|
|
for p in parlamentares]}, |
|
|
|
follow=True) |
|
|
|
admin_client.post(url, {'presenca_ativos': [str(parlamentares[0].pk)]}, |
|
|
|
follow=True) |
|
|
|
|
|
|
|
presencas = SessaoPlenariaPresenca.objects.filter(sessao_plenaria=sessao) |
|
|
|
assert list(presencas.values_list('parlamentar_id', flat=True)) == \ |
|
|
|
[parlamentares[0].pk] |
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False) |
|
|
|
def test_presenca_ordem_dia_preserva_registros_ao_resalvar(admin_client): |
|
|
|
sessao, parlamentares = cria_sessao_com_parlamentares() |
|
|
|
url = reverse('sapl.sessao:presencaordemdia', kwargs={'pk': sessao.pk}) |
|
|
|
dados = {'presenca_ativos': [str(p.pk) for p in parlamentares]} |
|
|
|
|
|
|
|
admin_client.post(url, dados, follow=True) |
|
|
|
presencas = PresencaOrdemDia.objects.filter(sessao_plenaria=sessao) |
|
|
|
ids_iniciais = sorted(presencas.values_list('id', flat=True)) |
|
|
|
|
|
|
|
admin_client.post(url, dados, follow=True) |
|
|
|
|
|
|
|
assert presencas.count() == len(parlamentares) |
|
|
|
assert sorted(presencas.values_list('id', flat=True)) == ids_iniciais |
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.django_db(transaction=False) |
|
|
|
def test_presenca_unica_por_sessao_e_parlamentar(): |
|
|
|
# A restrição de unicidade é a proteção contra submissões concorrentes, |
|
|
|
# que a lógica da view sozinha não cobre. |
|
|
|
sessao, parlamentares = cria_sessao_com_parlamentares() |
|
|
|
parlamentar = parlamentares[0] |
|
|
|
|
|
|
|
for model in (SessaoPlenariaPresenca, PresencaOrdemDia): |
|
|
|
model.objects.create(sessao_plenaria=sessao, parlamentar=parlamentar) |
|
|
|
with pytest.raises(IntegrityError): |
|
|
|
with transaction.atomic(): |
|
|
|
model.objects.create(sessao_plenaria=sessao, |
|
|
|
parlamentar=parlamentar) |
|
|
|
|