Browse Source

Atualiza com o master

pull/506/head
Eduardo Calil 8 years ago
parent
commit
17f841723a
  1. 36
      .travis.yml
  2. 13
      README.rst
  3. 4
      requirements/requirements.txt
  4. 0
      sapl/.env_test
  5. 5
      sapl/base/templatetags/common_tags.py
  6. 34
      sapl/comissoes/tests/test_comissoes.py
  7. 19
      sapl/crispy_layout_mixin.py
  8. 220
      sapl/materia/tests/test_materia.py
  9. 28
      sapl/norma/tests/test_norma.py
  10. 105
      sapl/parlamentares/tests/test_parlamentares.py
  11. 18
      sapl/protocoloadm/tests/test_protocoloadm.py
  12. 1
      sapl/settings.py
  13. 4
      sapl/static/styles/app.scss
  14. 8
      sapl/utils.py
  15. 262
      scripts/inicializa_grupos_autorizacoes.py
  16. 47
      scripts/test_inicializa_grupos_autorizacoes.py

36
.travis.yml

@ -1,45 +1,23 @@
language: python
sudo: required
python:
- "3.4.3"
- 3.4.3
services:
- postgresql
addons:
postgresql: "9.3"
install:
- sudo apt-get install git nginx python3-dev libpq-dev graphviz-dev graphviz pkg-config python-psycopg2 nodejs npm
- sudo ln -s /usr/bin/node
- pip install -r requirements/test-requirements.txt
- pip install --upgrade setuptools
# Line 24 to 35 is a hack found in this link below
# It was used to fix an error in database building
# https://dockyard.com/blog/ruby/2013/03/29/running-postgresql-9-2-on-travis-ci
before_script:
- sudo /etc/init.d/postgresql stop
- sudo cp /etc/postgresql/9.2/main/pg_hba.conf ./
- sudo apt-get remove postgresql postgresql-9.2 -qq --purge
- source /etc/lsb-release
- echo "deb http://apt.postgresql.org/pub/repos/apt/ $DISTRIB_CODENAME-pgdg main" > pgdg.list
- sudo mv pgdg.list /etc/apt/sources.list.d/
- wget --quiet -O - http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc | sudo apt-key add -
- sudo apt-get update
- sudo apt-get -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confnew" install postgresql-9.3 postgresql-contrib-9.3 -qq
- sudo /etc/init.d/postgresql stop
- sudo cp ./pg_hba.conf /etc/postgresql/9.3/main
- sudo /etc/init.d/postgresql start
- npm install -g bower
- cp .env_dev .env
- sed -i -e 's/getpass.getuser()/"postgres"/g' sapl/settings.py
- psql -c 'create database sapl;' -U postgres
- cp sapl/.env_test sapl/.env
- psql -c "CREATE USER sapl WITH PASSWORD 'sapl'" -U postgres;
- psql -c "CREATE DATABASE sapl OWNER sapl;" -U postgres
script:
- ./manage.py migrate
- ./manage.py bower install
- pip freeze
- ./test_and_check_qa.sh
- py.test
# - ./test_and_check_qa.sh

13
README.rst

@ -1,6 +1,5 @@
.. image:: https://badge.waffle.io/interlegis/sapl.png?label=ready&title=Ready
:target: https://waffle.io/interlegis/sapl
:alt: 'Stories in Ready'
.. image:: https://travis-ci.org/interlegis/sapl.svg?branch=master
:target: https://travis-ci.org/interlegis/sapl
***********************************************
SAPL - Sistema de Apoio ao Processo Legislativo
@ -246,18 +245,18 @@ Boas Práticas
* Em caso de Implementação de modelo que envolva a classe ``django.contrib.auth.models.User``, não a use diretamente, use para isso a função ``get_settings_auth_user_model()`` de ``sapl.utils``. Exemplo:
- no lugar de ``owner = models.ForeignKey(User, ... )``
- use ``owner = models.ForeignKey(get_settings_auth_user_model(), ... )``
- no lugar de ``owner = models.ForeignKey(User, ... )``
- use ``owner = models.ForeignKey(get_settings_auth_user_model(), ... )``
- Não use em qualquer modelagem futura, ``ForeignKey`` com ``User`` ou mesmo ``settings.AUTH_USER_MODEL`` sem o import correto que não é o do projeto e sim o que está em ``sapl.utils``, ou seja (``from django.conf import settings``)
- em https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#referencing-the-user-model é explicado por que ser dessa forma!
- em https://docs.djangoproject.com/en/1.9/topics/auth/customizing/#referencing-the-user-model é explicado por que ser dessa forma!
- Já em qualquer uso em implementação de execução, ao fazer uma query, por exemplo:
- não use ``django.contrib.auth.models.User`` para utilizar as caracteristicas do model, para isso, use esta função: django.contrib.auth.get_user_model()
- Seguir esses passos simplificará qualquer customização futura que venha a ser feita na autenticação do usuários ao evitar correções de inúmeros import's e ainda, desta forma, torna a funcionalidade de autenticação reimplementável por qualquer outro projeto que venha usar partes ou o todo do SAPL.
- Seguir esses passos simplificará qualquer customização futura que venha a ser feita na autenticação do usuários ao evitar correções de inúmeros import's e ainda, desta forma, torna a funcionalidade de autenticação reimplementável por qualquer outro projeto que venha usar partes ou o todo do SAPL.
Atenção:

4
requirements/requirements.txt

@ -1,4 +1,5 @@
dj-database-url==0.4.1
django==1.9.7
django-admin-bootstrapped==2.5.7
django-bootstrap3==7.0.1
django-bower==5.1.0
@ -10,8 +11,7 @@ django-extra-views==0.8.0
django-filter==0.13.0
django-floppyforms==1.6.2
django-model-utils==2.5
django-sass-processor==0.4.0
django==1.9.7
django-sass-processor==0.4.6
djangorestframework
easy-thumbnails==2.3
git+git://github.com/interlegis/trml2pdf.git

0
.env_dev → sapl/.env_test

5
sapl/base/templatetags/common_tags.py

@ -38,11 +38,6 @@ def isinst(value, class_str):
return classe == class_str
@register.filter
def to_class_name(value):
return value.__class__.__name__.lower()
@register.filter
def get_add_perm(value, arg):
perm = value

34
sapl/comissoes/tests/test_comissoes.py

@ -44,14 +44,14 @@ def make_filiacao():
@pytest.mark.django_db(transaction=False)
def test_incluir_parlamentar_errors(client):
def test_incluir_parlamentar_errors(admin_client):
comissao = make_comissao()
composicao = make_composicao(comissao)
response = client.post(reverse('sapl.comissoes:participacao_create',
kwargs={'pk': composicao.pk}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.comissoes:participacao_create',
kwargs={'pk': composicao.pk}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['parlamentar'] ==
['Este campo é obrigatório.'])
@ -62,18 +62,18 @@ def test_incluir_parlamentar_errors(client):
@pytest.mark.django_db(transaction=False)
def test_incluir_comissao_submit(client):
def test_incluir_comissao_submit(admin_client):
tipo = mommy.make(TipoComissao,
sigla='T',
nome='Teste')
response = client.post(reverse('sapl.comissoes:comissao_create'),
{'tipo': tipo.pk,
'nome': 'Comissão Teste',
'sigla': 'CT',
'data_criacao': '2016-03-22',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.comissoes:comissao_create'),
{'tipo': tipo.pk,
'nome': 'Comissão Teste',
'sigla': 'CT',
'data_criacao': '2016-03-22',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
comissao = Comissao.objects.first()
@ -82,11 +82,11 @@ def test_incluir_comissao_submit(client):
@pytest.mark.django_db(transaction=False)
def test_incluir_comissao_errors(client):
def test_incluir_comissao_errors(admin_client):
response = client.post(reverse('sapl.comissoes:comissao_create'),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.comissoes:comissao_create'),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo'] ==
['Este campo é obrigatório.'])

19
sapl/crispy_layout_mixin.py

@ -1,12 +1,12 @@
from math import ceil
import rtyaml
from crispy_forms.bootstrap import FormActions
from crispy_forms.helper import FormHelper
from crispy_forms.layout import HTML, Div, Fieldset, Layout, Submit
from django import template
from django.utils import formats
from django.utils.translation import ugettext as _
import rtyaml
def heads_and_tails(list_of_lists):
@ -50,8 +50,9 @@ class SaplFormLayout(Layout):
def get_field_display(obj, fieldname):
field = obj._meta.get_field(fieldname)
verbose_name = str(field.verbose_name)
if field.choices:
verbose_name = str(field.verbose_name)\
if hasattr(field, 'verbose_name') else ''
if hasattr(field, 'choices') and field.choices:
value = getattr(obj, 'get_%s_display' % fieldname)()
else:
value = getattr(obj, fieldname)
@ -74,6 +75,14 @@ def get_field_display(obj, fieldname):
value.name.split('/')[-1:][0])
else:
display = ''
elif 'ManyRelatedManager' in str(type(value))\
or 'RelatedManager' in str(type(value)):
display = '<ul>'
for v in value.all():
display += '<li>%s</li>' % str(v)
display += '</ul>'
if not verbose_name:
verbose_name = str(field.related_model._meta.verbose_name_plural)
else:
display = str(value)
return verbose_name, display
@ -147,7 +156,9 @@ class CrispyLayoutFormMixin:
def read_yaml_from_file(yaml_layout):
# TODO cache this at application level
t = template.loader.get_template(yaml_layout)
rendered = t.render()
# aqui é importante converter para str pois, dependendo do ambiente,
# o rtyaml pode usar yaml.CSafeLoader, que exige str ou stream
rendered = str(t.render())
return rtyaml.load(rendered)

220
sapl/materia/tests/test_materia.py

@ -80,7 +80,7 @@ def make_materia_principal():
@pytest.mark.django_db(transaction=False)
def test_materia_anexada_submit(client):
def test_materia_anexada_submit(admin_client):
materia_principal = make_materia_principal()
# Cria a matéria que será anexada
@ -99,14 +99,14 @@ def test_materia_anexada_submit(client):
materia_anexada = MateriaLegislativa.objects.get(numero=32, ano=2004)
# Testa POST
response = client.post(reverse('sapl.materia:anexada_create',
kwargs={'pk': materia_principal.pk}),
{'tipo': materia_anexada.tipo.pk,
'numero': materia_anexada.numero,
'ano': materia_anexada.ano,
'data_anexacao': '2016-03-18',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:anexada_create',
kwargs={'pk': materia_principal.pk}),
{'tipo': materia_anexada.tipo.pk,
'numero': materia_anexada.numero,
'ano': materia_anexada.ano,
'data_anexacao': '2016-03-18',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
# Verifica se a matéria foi anexada corretamente
@ -116,7 +116,7 @@ def test_materia_anexada_submit(client):
@pytest.mark.django_db(transaction=False)
def test_autoria_submit(client):
def test_autoria_submit(admin_client):
materia_principal = make_materia_principal()
# Cria um tipo de Autor
@ -126,14 +126,14 @@ def test_autoria_submit(client):
autor = mommy.make(Autor, tipo=tipo_autor, nome='Autor Teste')
# Testa POST
response = client.post(reverse('sapl.materia:autoria_create',
kwargs={'pk': materia_principal.pk}),
{'autor': autor.pk,
'primeiro_autor': True,
'materia_id': materia_principal.pk,
'partido': '',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:autoria_create',
kwargs={'pk': materia_principal.pk}),
{'autor': autor.pk,
'primeiro_autor': True,
'materia_id': materia_principal.pk,
'partido': '',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
# Verifica se o autor foi realmente criado
@ -144,7 +144,7 @@ def test_autoria_submit(client):
@pytest.mark.django_db(transaction=False)
def test_despacho_inicial_submit(client):
def test_despacho_inicial_submit(admin_client):
materia_principal = make_materia_principal()
# Cria uma comissão
@ -156,11 +156,11 @@ def test_despacho_inicial_submit(client):
data_criacao='2016-03-18')
# Testa POST
response = client.post(reverse('sapl.materia:despachoinicial_create',
kwargs={'pk': materia_principal.pk}),
{'comissao': comissao.pk,
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:despachoinicial_create',
kwargs={'pk': materia_principal.pk}),
{'comissao': comissao.pk,
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
# Verifica se o despacho foi criado
@ -170,19 +170,19 @@ def test_despacho_inicial_submit(client):
@pytest.mark.django_db(transaction=False)
def test_numeracao_submit(client):
def test_numeracao_submit(admin_client):
materia_principal = make_materia_principal()
materia = make_materia_principal()
# Testa POST
response = client.post(reverse('sapl.materia:numeracao_create',
kwargs={'pk': materia_principal.pk}),
{'tipo_materia': materia.tipo.pk,
'numero_materia': materia.numero,
'ano_materia': materia.ano,
'data_materia': '2016-03-21',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:numeracao_create',
kwargs={'pk': materia_principal.pk}),
{'tipo_materia': materia.tipo.pk,
'numero_materia': materia.numero,
'ano_materia': materia.ano,
'data_materia': '2016-03-21',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
@ -193,7 +193,7 @@ def test_numeracao_submit(client):
@pytest.mark.django_db(transaction=False)
def test_documento_acessorio_submit(client):
def test_documento_acessorio_submit(admin_client):
materia_principal = make_materia_principal()
# Cria um tipo de Autor
@ -207,15 +207,16 @@ def test_documento_acessorio_submit(client):
descricao='Teste')
# Testa POST
response = client.post(reverse('sapl.materia:documentoacessorio_create',
kwargs={'pk': materia_principal.pk}),
{'tipo': tipo.pk,
'nome': 'teste_nome',
'data_materia': '2016-03-21',
'autor': autor,
'ementa': 'teste_ementa',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse(
'sapl.materia:documentoacessorio_create',
kwargs={'pk': materia_principal.pk}),
{'tipo': tipo.pk,
'nome': 'teste_nome',
'data_materia': '2016-03-21',
'autor': autor,
'ementa': 'teste_ementa',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
@ -227,19 +228,20 @@ def test_documento_acessorio_submit(client):
@pytest.mark.django_db(transaction=False)
def test_legislacao_citada_submit(client):
def test_legislacao_citada_submit(admin_client):
materia_principal = make_materia_principal()
norma = make_norma()
# Testa POST
response = client.post(reverse('sapl.materia:legislacaocitada_create',
kwargs={'pk': materia_principal.pk}),
{'tipo': norma.tipo.pk,
'numero': norma.numero,
'ano': norma.ano,
'disposicao': 'disposicao',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(
reverse('sapl.materia:legislacaocitada_create',
kwargs={'pk': materia_principal.pk}),
{'tipo': norma.tipo.pk,
'numero': norma.numero,
'ano': norma.ano,
'disposicao': 'disposicao',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
@ -249,7 +251,7 @@ def test_legislacao_citada_submit(client):
@pytest.mark.django_db(transaction=False)
def test_tramitacao_submit(client):
def test_tramitacao_submit(admin_client):
materia_principal = make_materia_principal()
# Cria status para tramitação
status_tramitacao = mommy.make(StatusTramitacao,
@ -257,7 +259,7 @@ def test_tramitacao_submit(client):
sigla='ST',
descricao='Status_Teste')
# Testa POST
response = client.post(
response = admin_client.post(
reverse('sapl.materia:tramitacao_create',
kwargs={'pk': materia_principal.pk}),
{'unidade_tramitacao_local': make_unidade_tramitacao(
@ -283,12 +285,12 @@ def test_tramitacao_submit(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_anexada(client):
def test_form_errors_anexada(admin_client):
materia_principal = make_materia_principal()
response = client.post(reverse('sapl.materia:anexada_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:anexada_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo'] ==
['Este campo é obrigatório.'])
@ -301,42 +303,43 @@ def test_form_errors_anexada(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_autoria(client):
def test_form_errors_autoria(admin_client):
materia_principal = make_materia_principal()
response = client.post(reverse('sapl.materia:autoria_create',
kwargs={'pk': materia_principal.pk}),
{'materia_id': materia_principal.pk,
'partido': '',
'autor': '',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:autoria_create',
kwargs={'pk': materia_principal.pk}),
{'materia_id': materia_principal.pk,
'partido': '',
'autor': '',
'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['autor'] ==
['Este campo é obrigatório.'])
@pytest.mark.django_db(transaction=False)
def test_form_errors_despacho_inicial(client):
def test_form_errors_despacho_inicial(admin_client):
materia_principal = make_materia_principal()
response = client.post(reverse('sapl.materia:despachoinicial_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:despachoinicial_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['comissao'] ==
['Este campo é obrigatório.'])
@pytest.mark.django_db(transaction=False)
def test_form_errors_documento_acessorio(client):
def test_form_errors_documento_acessorio(admin_client):
materia_principal = make_materia_principal()
response = client.post(reverse('sapl.materia:documentoacessorio_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(
reverse('sapl.materia:documentoacessorio_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo'] ==
['Este campo é obrigatório.'])
@ -345,13 +348,14 @@ def test_form_errors_documento_acessorio(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_legislacao_citada(client):
def test_form_errors_legislacao_citada(admin_client):
materia_principal = make_materia_principal()
response = client.post(reverse('sapl.materia:legislacaocitada_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(
reverse('sapl.materia:legislacaocitada_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo'] ==
['Este campo é obrigatório.'])
@ -362,13 +366,13 @@ def test_form_errors_legislacao_citada(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_numeracao(client):
def test_form_errors_numeracao(admin_client):
materia_principal = make_materia_principal()
response = client.post(reverse('sapl.materia:numeracao_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:numeracao_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo_materia'] ==
['Este campo é obrigatório.'])
@ -381,13 +385,14 @@ def test_form_errors_numeracao(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_tramitacao(client):
def test_form_errors_tramitacao(admin_client):
materia_principal = make_materia_principal()
response = client.post(reverse('sapl.materia:tramitacao_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(
reverse('sapl.materia:tramitacao_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['data_tramitacao'] ==
['Este campo é obrigatório.'])
@ -402,13 +407,14 @@ def test_form_errors_tramitacao(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_relatoria(client):
def test_form_errors_relatoria(admin_client):
materia_principal = make_materia_principal()
response = client.post(reverse('sapl.materia:relatoria_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(
reverse('sapl.materia:relatoria_create',
kwargs={'pk': materia_principal.pk}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['data_designacao_relator'] ==
['Este campo é obrigatório.'])
@ -417,12 +423,12 @@ def test_form_errors_relatoria(client):
@pytest.mark.django_db(transaction=False)
def test_proposicao_submit(client):
response = client.post(reverse('sapl.materia:proposicao_create'),
{'tipo': mommy.make(TipoProposicao, pk=3).pk,
'descricao': 'Teste proposição',
'salvar': 'salvar'},
follow=True)
def test_proposicao_submit(admin_client):
response = admin_client.post(reverse('sapl.materia:proposicao_create'),
{'tipo': mommy.make(TipoProposicao, pk=3).pk,
'descricao': 'Teste proposição',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
@ -432,11 +438,11 @@ def test_proposicao_submit(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_proposicao(client):
def test_form_errors_proposicao(admin_client):
response = client.post(reverse('sapl.materia:proposicao_create'),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.materia:proposicao_create'),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo'] ==
['Este campo é obrigatório.'])
assert (response.context_data['form'].errors['descricao'] ==

28
sapl/norma/tests/test_norma.py

@ -6,22 +6,22 @@ from sapl.norma.models import NormaJuridica, TipoNormaJuridica
@pytest.mark.django_db(transaction=False)
def test_incluir_norma_submit(client):
def test_incluir_norma_submit(admin_client):
# Cria um tipo de norma
tipo = mommy.make(TipoNormaJuridica,
sigla='T',
descricao='Teste')
# Testa POST
response = client.post(reverse('sapl.norma:normajuridica_create'),
{'tipo': tipo.pk,
'numero': '1',
'ano': '2016',
'data': '2016-03-22',
'esfera_federacao': 'E',
'ementa': 'Teste_Ementa',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.norma:normajuridica_create'),
{'tipo': tipo.pk,
'numero': '1',
'ano': '2016',
'data': '2016-03-22',
'esfera_federacao': 'E',
'ementa': 'Teste_Ementa',
'salvar': 'salvar'},
follow=True)
assert response.status_code == 200
norma = NormaJuridica.objects.first()
@ -31,11 +31,11 @@ def test_incluir_norma_submit(client):
@pytest.mark.django_db(transaction=False)
def test_incluir_norma_errors(client):
def test_incluir_norma_errors(admin_client):
response = client.post(reverse('sapl.norma:normajuridica_create'),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.norma:normajuridica_create'),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['tipo'] ==
['Este campo é obrigatório.'])

105
sapl/parlamentares/tests/test_parlamentares.py

@ -8,20 +8,20 @@ from sapl.parlamentares.models import (Dependente, Filiacao, Legislatura,
@pytest.mark.django_db(transaction=False)
def test_cadastro_parlamentar(client):
def test_cadastro_parlamentar(admin_client):
legislatura = mommy.make(Legislatura)
url = reverse('sapl.parlamentares:parlamentar_create')
response = client.get(url)
response = admin_client.get(url)
assert response.status_code == 200
response = client.post(url, {'nome_completo': 'Teresa Barbosa',
'nome_parlamentar': 'Terezinha',
'sexo': 'F',
'ativo': 'True',
'legislatura': legislatura.id,
'data_expedicao_diploma': '2001-01-01'},
follow=True)
response = admin_client.post(url, {'nome_completo': 'Teresa Barbosa',
'nome_parlamentar': 'Terezinha',
'sexo': 'F',
'ativo': 'True',
'legislatura': legislatura.id,
'data_expedicao_diploma': '2001-01-01'},
follow=True)
[parlamentar] = Parlamentar.objects.all()
assert parlamentar.nome_parlamentar == 'Terezinha'
@ -36,9 +36,9 @@ def test_cadastro_parlamentar(client):
@pytest.mark.django_db(transaction=False)
def test_incluir_parlamentar_errors(client):
def test_incluir_parlamentar_errors(admin_client):
url = reverse('sapl.parlamentares:parlamentar_create')
response = client.post(url)
response = admin_client.post(url)
erros_esperados = {campo: ['Este campo é obrigatório.']
for campo in ['legislatura',
'data_expedicao_diploma',
@ -50,34 +50,34 @@ def test_incluir_parlamentar_errors(client):
@pytest.mark.django_db(transaction=False)
def test_filiacao_submit(client):
def test_filiacao_submit(admin_client):
mommy.make(Parlamentar, pk=14)
mommy.make(Partido, pk=32)
client.post(reverse('sapl.parlamentares:filiacao_create',
kwargs={'pk': 14}),
{'partido': 32,
'data': '2016-03-22',
'salvar': 'salvar'},
follow=True)
admin_client.post(reverse('sapl.parlamentares:filiacao_create',
kwargs={'pk': 14}),
{'partido': 32,
'data': '2016-03-22',
'salvar': 'salvar'},
follow=True)
filiacao = Filiacao.objects.first()
assert 32 == filiacao.partido.pk
@pytest.mark.django_db(transaction=False)
def test_dependente_submit(client):
def test_dependente_submit(admin_client):
mommy.make(Parlamentar, pk=14)
mommy.make(Partido, pk=32)
mommy.make(TipoDependente, pk=3)
client.post(reverse('sapl.parlamentares:dependente_create',
kwargs={'pk': 14}),
{'nome': 'Eduardo',
'tipo': 3,
'sexo': 'M',
'salvar': 'salvar'},
follow=True)
admin_client.post(reverse('sapl.parlamentares:dependente_create',
kwargs={'pk': 14}),
{'nome': 'Eduardo',
'tipo': 3,
'sexo': 'M',
'salvar': 'salvar'},
follow=True)
dependente = Dependente.objects.first()
assert 3 == dependente.tipo.pk
@ -85,12 +85,13 @@ def test_dependente_submit(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_dependente(client):
def test_form_errors_dependente(admin_client):
mommy.make(Parlamentar, pk=14)
response = client.post(reverse('sapl.parlamentares:dependente_create',
kwargs={'pk': 14}),
{'salvar': 'salvar'},
follow=True)
response = admin_client.post(
reverse('sapl.parlamentares:dependente_create',
kwargs={'pk': 14}),
{'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['nome'] ==
['Este campo é obrigatório.'])
@ -101,14 +102,14 @@ def test_form_errors_dependente(client):
@pytest.mark.django_db(transaction=False)
def test_form_errors_filiacao(client):
def test_form_errors_filiacao(admin_client):
mommy.make(Parlamentar, pk=14)
response = client.post(reverse('sapl.parlamentares:filiacao_create',
kwargs={'pk': 14}),
{'partido': '',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.parlamentares:filiacao_create',
kwargs={'pk': 14}),
{'partido': '',
'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['partido'] ==
['Este campo é obrigatório.'])
@ -117,31 +118,31 @@ def test_form_errors_filiacao(client):
@pytest.mark.django_db(transaction=False)
def test_mandato_submit(client):
def test_mandato_submit(admin_client):
mommy.make(Parlamentar, pk=14)
mommy.make(Legislatura, pk=5)
client.post(reverse('sapl.parlamentares:mandato_create',
kwargs={'pk': 14}),
{'legislatura': 5,
'data_fim_mandato': '2016-01-01',
'data_expedicao_diploma': '2016-03-22',
'observacao': 'Observação do mandato',
'salvar': 'salvar'},
follow=True)
admin_client.post(reverse('sapl.parlamentares:mandato_create',
kwargs={'pk': 14}),
{'legislatura': 5,
'data_fim_mandato': '2016-01-01',
'data_expedicao_diploma': '2016-03-22',
'observacao': 'Observação do mandato',
'salvar': 'salvar'},
follow=True)
mandato = Mandato.objects.first()
assert 'Observação do mandato' == mandato.observacao
@pytest.mark.django_db(transaction=False)
def test_form_errors_mandato(client):
def test_form_errors_mandato(admin_client):
mommy.make(Parlamentar, pk=14)
response = client.post(reverse('sapl.parlamentares:mandato_create',
kwargs={'pk': 14}),
{'legislatura': '',
'salvar': 'salvar'},
follow=True)
response = admin_client.post(reverse('sapl.parlamentares:mandato_create',
kwargs={'pk': 14}),
{'legislatura': '',
'salvar': 'salvar'},
follow=True)
assert (response.context_data['form'].errors['legislatura'] ==
['Este campo é obrigatório.'])

18
sapl/protocoloadm/tests/test_protocoloadm.py

@ -8,22 +8,22 @@ from sapl.protocoloadm.models import Protocolo
@pytest.mark.django_db(transaction=False)
def test_anular_protocolo_acessivel(client):
response = client.get(reverse('sapl.protocoloadm:anular_protocolo'))
def test_anular_protocolo_acessivel(admin_client):
response = admin_client.get(reverse('sapl.protocoloadm:anular_protocolo'))
assert response.status_code == 200
@pytest.mark.django_db(transaction=False)
def test_anular_protocolo_submit(client):
def test_anular_protocolo_submit(admin_client):
mommy.make(Protocolo, numero='76', ano='2016', anulado=False)
# TODO: setar usuario e IP
response = client.post(reverse('sapl.protocoloadm:anular_protocolo'),
{'numero': '76',
'ano': '2016',
'justificativa_anulacao': 'TESTE',
'salvar': 'Anular'},
follow=True)
response = admin_client.post(reverse('sapl.protocoloadm:anular_protocolo'),
{'numero': '76',
'ano': '2016',
'justificativa_anulacao': 'TESTE',
'salvar': 'Anular'},
follow=True)
assert response.status_code == 200

1
sapl/settings.py

@ -38,6 +38,7 @@ LOGIN_URL = '/login/?next='
# SAPL business apps in dependency order
SAPL_APPS = (
'sapl.base',
'sapl.crud',
'sapl.parlamentares',
'sapl.comissoes',
'sapl.materia',

4
sapl/static/styles/app.scss

@ -131,13 +131,11 @@ body {
}
}
fieldset {
fieldset {
font-size: 95%;
legend {
font-size: 18px;
}
}
}
}

8
sapl/utils.py

@ -261,7 +261,7 @@ def permissoes_parlamentares():
def permissoes_protocoloadm():
lista_permissoes = []
perms_protocolo = Permission.objects.filter(
group__name='Operador de Protocolo')
group__name='Operador de Protocolo Administrativo')
for p in perms_protocolo:
lista_permissoes.append('protocoloadm.' + p.codename)
return set(lista_permissoes)
@ -270,7 +270,7 @@ def permissoes_protocoloadm():
def permissoes_adm():
lista_permissoes = []
perms_adm = Permission.objects.filter(
group__name='Operador de Administração')
group__name='Operador Administrativo')
for p in perms_adm:
lista_permissoes.append('protocoloadm.' + p.codename)
return set(lista_permissoes)
@ -279,7 +279,7 @@ def permissoes_adm():
def permissoes_sessao():
lista_permissoes = []
perms_sessao = list(Permission.objects.filter(
group__name='Operador de Sessão'))
group__name='Operador de Sessão Plenária'))
for p in perms_sessao:
lista_permissoes.append('sessao.' + p.codename)
return set(lista_permissoes)
@ -288,7 +288,7 @@ def permissoes_sessao():
def permissoes_painel():
lista_permissoes = []
perms_painel = list(Permission.objects.filter(
group__name='Operador de Painel'))
group__name='Operador de Painel Eletrônico'))
for p in perms_painel:
lista_permissoes.append('painel.' + p.codename)
return set(lista_permissoes)

262
scripts/inicializa_grupos_autorizacoes.py

@ -1,188 +1,114 @@
from django.apps import apps
from django.contrib.auth.models import Group, Permission, User
from django.contrib.contenttypes.models import ContentType
def cria_grupos_permissoes():
if not Group.objects.filter("Teste"):
pass
# Cria todos os grupos necessários para a aplicação
op_geral = Group.objects.get_or_create(name="Operador Geral")
op_prot = Group.objects.get_or_create(name="Operador de Protocolo")
op_sessao = Group.objects.get_or_create(name="Operador de Sessão")
op_comissao = Group.objects.get_or_create(name="Operador de Comissão")
op_adm = Group.objects.get_or_create(name="Operador de Administração")
op_norma = Group.objects.get_or_create(name="Operador de Norma Jurídica")
op_materia = Group.objects.get_or_create(
name="Operador de Matéria Legislativa")
op_painel = Group.objects.get_or_create(name="Operador de Painel")
op_autor = Group.objects.get_or_create(name="Autor")
op_geral = op_geral[0]
op_prot = op_prot[0]
op_sessao = op_sessao[0]
op_comissao = op_comissao[0]
op_adm = op_adm[0]
op_norma = op_norma[0]
op_materia = op_materia[0]
op_painel = op_painel[0]
op_autor = op_autor[0]
# Base
permissao_add_cl = Permission.objects.get(
name="Can add Casa Legislativa")
permissao_edit_cl = Permission.objects.get(
name="Can change Casa Legislativa")
permissao_remove_cl = Permission.objects.get(
name="Can delete Casa Legislativa")
permissoes_base = [permissao_add_cl,
permissao_edit_cl,
permissao_remove_cl]
def cria_ou_reseta_grupo(nome):
grupo = Group.objects.get_or_create(name=nome)[0]
for p in list(grupo.permissions.all()):
grupo.permissions.remove(p)
return grupo
# Comissao
cts = ContentType.objects.filter(app_label='comissoes')
perms_comissoes = list(Permission.objects.filter(content_type__in=cts))
def cria_usuario(nome, grupo):
nome_usuario = nome
usuario = User.objects.get_or_create(username=nome_usuario)[0]
usuario.set_password('interlegis')
usuario.save()
grupo.user_set.add(usuario)
# Materia
cts = ContentType.objects.filter(app_label='materia')
perms_materia = list(Permission.objects.filter(content_type__in=cts))
# Norma
cts = ContentType.objects.filter(app_label='norma')
perms_norma = list(Permission.objects.filter(content_type__in=cts))
# Painel
cts = ContentType.objects.filter(app_label='painel')
perms_painel = list(Permission.objects.filter(content_type__in=cts))
# Parlamentares
def cria_grupos_permissoes():
cts = ContentType.objects.filter(app_label='parlamentares')
perms_parlamentares = list(Permission.objects.filter(content_type__in=cts))
nomes_apps = ['base', 'parlamentares', 'comissoes',
'materia', 'norma', 'sessao', 'painel']
# ProtocoloADM e DOCADM
permissoes = {app: list(Permission.objects.filter(
content_type__in=ContentType.objects.filter(app_label=app)))
for app in nomes_apps}
# permissoes específicas para protocolo e documento administrativo
cts = ContentType.objects.filter(app_label='protocoloadm')
perms_docadm = list(Permission.objects.filter(content_type__in=cts))
cts_exc1 = cts.filter(model__icontains='tramitacao')
cts_exc2 = cts.filter(model__icontains='documentoadministrativo')
cts = cts.exclude(id__in=[o.id for o in cts_exc1])
cts = cts.exclude(id__in=[o.id for o in cts_exc2])
perms_protocoloadm = list(Permission.objects.filter(content_type__in=cts))
# Sessao
cts = ContentType.objects.filter(app_label='sessao')
perms_sessao = list(Permission.objects.filter(content_type__in=cts))
# Painel
cts = ContentType.objects.filter(app_label='painel')
perms_painel = list(Permission.objects.filter(content_type__in=cts))
# documento administrativo
permissoes['documento_administrativo'] = list(
Permission.objects.filter(content_type__in=cts))
nome_grupo = 'Operador Administrativo'
grupo = cria_ou_reseta_grupo(nome_grupo)
for p in permissoes['documento_administrativo']:
grupo.permissions.add(p)
nome_usuario = 'operador_administrativo'
cria_usuario(nome_usuario, grupo)
# prolocolo administrativo
cts = cts.exclude(model__icontains='tramitacao').exclude(
model__icontains='documentoadministrativo')
permissoes['protocoloadm'] = list(
Permission.objects.filter(content_type__in=cts))
nome_grupo = 'Operador de Protocolo Administrativo'
grupo = cria_ou_reseta_grupo(nome_grupo)
for p in permissoes['protocoloadm']:
grupo.permissions.add(p)
nome_usuario = 'operador_protocoloadm'
cria_usuario(nome_usuario, grupo)
# permissoes do base
cts = ContentType.objects.filter(app_label='base')
permissoes['base'] = list(
Permission.objects.filter(content_type__in=cts))
for nome_app in nomes_apps:
if nome_app not in {'base', 'parlamentares'}:
# Elimina casos especificos
# Cria Grupo
nome_grupo = 'Operador de %s' % apps.get_app_config(
nome_app).verbose_name
grupo = cria_ou_reseta_grupo(nome_grupo)
# Elimina o acesso a proposicoes pelo Operador de Matérias
if nome_app == 'materia':
cts = ContentType.objects.filter(
app_label='materia').exclude(model='proposicao')
permissoes['materia'] = list(
Permission.objects.filter(content_type__in=cts))
# Configura as permissoes
for p in permissoes[nome_app]:
grupo.permissions.add(p)
# Cria o Usuario
nome_usuario = 'operador_%s' % nome_app
usuario = User.objects.get_or_create(username=nome_usuario)[0]
usuario.set_password('interlegis')
usuario.save()
grupo.user_set.add(usuario)
# Operador Geral
grupo_geral = cria_ou_reseta_grupo('Operador Geral')
for lista in permissoes.values():
for p in lista:
grupo_geral.permissions.add(p)
nome_usuario = 'operador_geral'
cria_usuario(nome_usuario, grupo_geral)
# Autor
perms_autor = Permission.objects.get(name="Can add Proposição")
# Configura Permissoes Operador de Protocolo
for p in perms_protocoloadm:
op_prot.permissions.add(p)
# Configura Permissoes Operador de Sessao
for p in perms_sessao:
op_sessao.permissions.add(p)
# Configura Permissoes Operador de Comissao
for p in perms_comissoes:
op_comissao.permissions.add(p)
# Configura Permissoes Operador de Administracao
for p in perms_docadm:
op_adm.permissions.add(p)
# Configura Permissoes Operador de Norma
for p in perms_norma:
op_norma.permissions.add(p)
# Configura Permissoes Operador de Materia
for p in perms_materia:
op_materia.permissions.add(p)
# Configura Permissoes Operador de Painel
for p in perms_painel:
op_painel.permissions.add(p)
perms_autor = []
perms_autor.append(Permission.objects.get(name='Can add Proposição'))
perms_autor.append(Permission.objects.get(name='Can change Proposição'))
perms_autor.append(Permission.objects.get(name='Can delete Proposição'))
# Configura Permissoes Autor
op_autor.permissions.add(perms_autor)
# Configura Permissoes Operador Geral
perms_op_geral = perms_protocoloadm + perms_sessao + perms_comissoes
perms_op_geral = perms_op_geral + perms_docadm + perms_norma
perms_op_geral = perms_op_geral + perms_materia
perms_op_geral = perms_op_geral + perms_parlamentares + perms_painel
perms_op_geral = perms_op_geral + permissoes_base
for p in perms_op_geral:
op_geral.permissions.add(p)
op_geral.permissions.add(perms_autor)
# Cria usuarios
op_geral_user = User.objects.get_or_create(username='op_geral')[0]
op_geral_user.set_password('interlegis')
op_geral_user.save()
op_geral.user_set.add(op_geral_user)
op_materia_user = User.objects.get_or_create(username='op_materia')[0]
op_materia_user.set_password('interlegis')
op_materia_user.save()
op_materia.user_set.add(op_materia_user)
op_prot_user = User.objects.get_or_create(username='op_protocolo')[0]
op_prot_user.set_password('interlegis')
op_prot_user.save()
op_prot.user_set.add(op_prot_user)
op_sessao_user = User.objects.get_or_create(username='op_sessao')[0]
op_sessao_user.set_password('interlegis')
op_sessao_user.save()
op_sessao.user_set.add(op_sessao_user)
op_comissao_user = User.objects.get_or_create(username='op_comissao')[0]
op_comissao_user.set_password('interlegis')
op_comissao_user.save()
op_comissao.user_set.add(op_comissao_user)
op_adm_user = User.objects.get_or_create(username='op_adm')[0]
op_adm_user.set_password('interlegis')
op_adm_user.save()
op_adm.user_set.add(op_adm_user)
op_norma_user = User.objects.get_or_create(username='op_norma')[0]
op_norma_user.set_password('interlegis')
op_norma_user.save()
op_norma.user_set.add(op_norma_user)
op_painel_user = User.objects.get_or_create(username='op_painel')[0]
op_painel_user.set_password('interlegis')
op_painel_user.save()
op_painel.user_set.add(op_norma_user)
op_autor_user = User.objects.get_or_create(username='op_autor')[0]
op_autor_user.set_password('interlegis')
op_autor_user.save()
op_autor.user_set.add(op_autor_user)
grupo = cria_ou_reseta_grupo('Autor')
for p in perms_autor:
grupo.permissions.add(p)
nome_usuario = 'operador_autor'
cria_usuario(nome_usuario, grupo_geral)
if __name__ == '__main__':
cria_grupos_permissoes()

47
scripts/test_inicializa_grupos_autorizacoes.py

@ -0,0 +1,47 @@
import pytest
from django.apps import apps
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from inicializa_grupos_autorizacoes import cria_grupos_permissoes
pytestmark = pytest.mark.django_db
apps_com_permissao_padrao = [
'comissoes', 'norma', 'sessao', 'painel']
@pytest.mark.parametrize('app_label', apps_com_permissao_padrao)
def test_grupo_padrao_tem_permissoes_sobre_todo_o_app(app_label):
app = apps.get_app_config(app_label)
# código testado
cria_grupos_permissoes()
def gerar_permissoes(app):
for model in app.get_models():
for op in ['add', 'change', 'delete']:
yield model, 'Can %s %s' % (op, model._meta.verbose_name)
grupo = Group.objects.get(name='Operador de %s' % app.verbose_name)
esperado = set(gerar_permissoes(app))
real = set((p.content_type.model_class(), p.name)
for p in grupo.permissions.all())
assert real == esperado
@pytest.mark.parametrize('app_label', apps_com_permissao_padrao)
def test_permissoes_extras_sao_apagadas(app_label):
app = apps.get_app_config(app_label)
grupo = Group.objects.create(name='Operador de %s' % app.verbose_name)
permissao_errada = Permission.objects.create(
name='STUB', content_type=ContentType.objects.first())
grupo.permissions.add(permissao_errada)
# código testado
cria_grupos_permissoes()
assert not grupo.permissions.filter(id=permissao_errada.id).exists()
Loading…
Cancel
Save