diff --git a/sapl/test_general.py b/sapl/test_general.py
index 15b589a80..baaaf18d6 100644
--- a/sapl/test_general.py
+++ b/sapl/test_general.py
@@ -1,81 +1,12 @@
from django.apps import apps
-from django.contrib.auth import get_user_model
-from django.contrib.auth.management import _get_all_permissions
-from django.contrib.auth.models import Permission, User
-from django.contrib.contenttypes.models import ContentType
-from django.core.exceptions import ObjectDoesNotExist
-from django.core.urlresolvers import reverse
from django.db.models import CharField, TextField
-from django.http.response import HttpResponseNotFound
-from django.utils.translation import string_concat
-from django.utils.translation import ugettext_lazy as _
from model_mommy import mommy
import pytest
-
-from sapl.crud.base import PermissionRequiredForAppCrudMixin, CrudAux
-from scripts.inicializa_grupos_autorizacoes import cria_grupos_permissoes
-from scripts.lista_urls import lista_urls
-
from .settings import SAPL_APPS
-
pytestmark = pytest.mark.django_db
sapl_appconfs = [apps.get_app_config(n[5:]) for n in SAPL_APPS]
-_lista_urls = lista_urls()
-
-
-def create_perms_post_migrate(app):
-
- searched_perms = list()
- # The codenames and ctypes that should exist.
- ctypes = set()
-
- for klass in list(app.get_models()):
- opts = klass._meta
- permissions = (
- ("list_" + opts.model_name,
- string_concat(
- _('Visualizaçao da lista de'), ' ',
- opts.verbose_name_plural)),
- ("detail_" + opts.model_name,
- string_concat(
- _('Visualização dos detalhes de'), ' ',
- opts.verbose_name_plural)),
- )
- opts.permissions = tuple(
- set(list(permissions) + list(opts.permissions)))
-
- if opts.proxy:
- # Force looking up the content types in the current database
- # before creating foreign keys to them.
- app_label, model = opts.app_label, opts.model_name
-
- try:
- ctype = ContentType.objects.get_by_natural_key(
- app_label, model)
- except:
- ctype = ContentType.objects.create(
- app_label=app_label, model=model)
- else:
- ctype = ContentType.objects.get_for_model(klass)
-
- ctypes.add(ctype)
- for perm in _get_all_permissions(klass._meta, ctype):
- searched_perms.append((ctype, perm))
-
- all_perms = set(Permission.objects.filter(
- content_type__in=ctypes,
- ).values_list(
- "content_type", "codename"
- ))
-
- perms = [
- Permission(codename=codename, name=name, content_type=ct)
- for ct, (codename, name) in searched_perms
- if (ct.pk, codename) not in all_perms
- ]
- Permission.objects.bulk_create(perms)
def test_charfield_textfield():
@@ -102,190 +33,3 @@ def test_str_sanity():
msg = '%s.%s.__str__ is broken.' % (
model.__module__, model.__name__)
raise AssertionError(msg, exc)
-
-btn_login = ('')
-
-
-@pytest.mark.parametrize('url_item', _lista_urls)
-def test_crudaux_formato_inicio_urls_associadas(url_item):
-
- # Verifica se um crud é do tipo CrudAux, se sim, sua url deve começar
- # com /sistema/
- key, url, var, app_name = url_item
- url = '/' + (url % {v: 1 for v in var})
-
- view_class = None
- if hasattr(key, 'view_class'):
- view_class = key.view_class
-
- # se não tem view_class, possivelmente é não é uma classed base view
- if not view_class:
- return
-
- # se não tem atributo crud, não é será nenhum tipo de crud
- if not hasattr(view_class, 'crud'):
- return
-
- # se o crud da view_class relativa a url a ser testada,
- # implementa a classe CrudAux, seu link deve iniciar com /sistema
- for string_class in list(map(str, type.mro(view_class.crud))):
-
- if 'CrudAux' in string_class:
- assert url.startswith('/sistema'), """
- A url (%s) foi gerada a partir de um CrudAux,
- o que diz que está é uma implementação de uma
- tabela auxiliar, porém a url em questão, está fora
- do padrão, que é iniciar com /sistema.
- """ % (url)
-
-
-@pytest.mark.parametrize('url_item', _lista_urls)
-def test_crudaux_list_do_crud_esta_na_pagina_sistema(url_item, admin_client):
-
- # Verifica se um crud é do tipo CrudAux, se sim, sua url deve começar
- # com /sistema/
- key, url, var, app_name = url_item
- url = '/' + (url % {v: 1 for v in var})
-
- view_class = None
- if hasattr(key, 'view_class'):
- view_class = key.view_class
-
- # se não tem view_class, possivelmente não é uma classed base view
- if not view_class:
- return
-
- # se não tem atributo crud, não é será nenhum tipo de crud
- if not hasattr(view_class, 'crud'):
- return
-
- herancas_crud = list(map(str, type.mro(view_class.crud)))
- for string_class in herancas_crud:
- if 'CrudAux' in string_class:
-
- herancas_view = list(map(str, type.mro(view_class)))
-
- for string_view_class in herancas_view:
- # verifica se o link para manutenção do crud está em /sistema
- if 'ListView' in string_view_class:
- response = admin_client.get('/sistema', {}, follow=True)
- assert url in str(response.content), """
- A url (%s) não consta nas Tabelas Auxiliares,
- porem é uma implementação de ListView de CrudAux.
- Se encontra em %s.urls
- """ % (url, app_name)
-
-
-@pytest.mark.parametrize('urls_app', _lista_urls)
-def em_construcao_crud_permissions_urls(urls_app, client):
- if not get_user_model().objects.exists():
- for app in sapl_appconfs:
- # readequa permissões dos models adicionando
- # list e detail permissions
- create_perms_post_migrate(app)
- # cria usuários de perfil do sapl
- cria_grupos_permissoes()
- users = get_user_model().objects.values_list('username', flat=True)
-
- for url_item in _lista_urls[urls_app]:
-
- key, url, var, app_name = url_item
- url = '/' + (url % {v: 1 for v in var})
-
- app_labels = app_name.split('.')[1]
-
- view_class = None
- if hasattr(key, 'view_class'):
- view_class = key.view_class
-
- """
- A classe PermissionRequiredForAppCrudMixin pode ser usada em uma
- app mas envolver permissoes para outras
- como é o caso de PainelView que está na app 'sessao'
- mas é um redirecionamento para 'painel'... aqui é feita
- a troca a urls_app a ser testada, por essas outras possíveis
- """
- if PermissionRequiredForAppCrudMixin in type.mro(view_class):
- # essa classe deve informar app_label
- assert hasattr(view_class, 'app_label')
- # app_label deve ter conteudo
- assert view_class.app_label
- app_labels = view_class.app_label
-
- if isinstance(app_labels, str):
- app_labels = app_labels,
-
- for app in app_labels:
-
- # monta o username correspondente de a app da url a ser testada
- user_for_url_atual_app = 'operador_%s'
- if app in ['base', 'parlamentares']:
- user_for_url_atual_app = user_for_url_atual_app % 'geral'
- elif app in 'protocoloadm':
- user_for_url_atual_app = user_for_url_atual_app % 'administrativo'
- elif app in ['compilacao']:
- return # TODO implementar teste para compilacao
- else:
- user_for_url_atual_app = user_for_url_atual_app % app
-
- for username in users:
- print(username, user_for_url_atual_app, url)
-
- client.login(username=username, password='interlegis')
-
- rg = None
- try:
- rg = client.get(url, {}, follow=True)
- except:
- pass
-
- rp = None
- try:
- rp = client.post(url, {}, follow=True)
- except:
- pass
-
- """
- devido às urls serem incompletas ou com pks e outras valores
- inexistentes na base, iniciar a execução da view, seja por get,
- post ou qualquer outro método pode causar o erro...
- por isso o "try ... except" acima.
- No entanto, o objetivo do teste é validar o acesso de toda url.
- Independente do erro que vá acontecer, esse erro não ocorrerá
- se o user não tiver permissão de acesso pelo fato de que "AS
- VIEWS BEM FORMADAS PARA VALIDAÇÃO DE ACESSO DEVEM SEMPRE REDIRECIONAR PARA
- LOGIN ANTES DE SUA EXECUÇÃO", desta forma nunca gerando erro
- interno dada qualquer incoerência de parâmetros nas urls
- """
- if rg:
- """
- Se o usuário a ser testado é o usuário da app da url de get
- espera-se que não tenha recebido uma tela de login
- """
- if username == user_for_url_atual_app and\
- not url.startswith('/sistema/'):
- assert btn_login not in str(rg.content)
- elif username != 'operador_geral' and\
- url.startswith('/sistema/'):
- assert btn_login in str(rg.content)
- elif username == 'operador_geral' and\
- url.startswith('/sistema/'):
- assert btn_login not in str(rg.content)
-
- if rp:
- """
- Se o usuário a ser testado é o usuário da app da url de
- post espera-se que não tenha recebido uma tela de login
- """
- if username == user_for_url_atual_app and\
- not url.startswith('/sistema/'):
- assert btn_login not in str(rp.content)
- elif username != 'operador_geral' and\
- url.startswith('/sistema/'):
- assert btn_login in str(rp.content)
- elif username == 'operador_geral' and\
- url.startswith('/sistema/'):
- assert btn_login not in str(rp.content)
-
- logout = client.get('/logout/', follow=True)
diff --git a/sapl/test_urls.py b/sapl/test_urls.py
new file mode 100644
index 000000000..e958dd6c0
--- /dev/null
+++ b/sapl/test_urls.py
@@ -0,0 +1,365 @@
+from django.apps import apps
+from django.contrib.auth import get_user_model
+from django.contrib.auth.management import _get_all_permissions
+from django.contrib.auth.models import Permission, User
+from django.contrib.contenttypes.models import ContentType
+from django.core.exceptions import ObjectDoesNotExist
+from django.core.urlresolvers import reverse
+from django.db.models import CharField, TextField
+from django.http.response import HttpResponseNotFound
+from django.utils.translation import string_concat
+from django.utils.translation import ugettext_lazy as _
+from model_mommy import mommy
+import pytest
+
+from sapl.crud.base import PermissionRequiredForAppCrudMixin, CrudAux
+from scripts.inicializa_grupos_autorizacoes import cria_grupos_permissoes
+from scripts.lista_urls import lista_urls
+
+from .settings import SAPL_APPS
+
+
+pytestmark = pytest.mark.django_db
+
+sapl_appconfs = [apps.get_app_config(n[5:]) for n in SAPL_APPS]
+_lista_urls = lista_urls()
+
+
+def create_perms_post_migrate(app):
+
+ searched_perms = list()
+ # The codenames and ctypes that should exist.
+ ctypes = set()
+
+ for klass in list(app.get_models()):
+ opts = klass._meta
+ permissions = (
+ ("list_" + opts.model_name,
+ string_concat(
+ _('Visualizaçao da lista de'), ' ',
+ opts.verbose_name_plural)),
+ ("detail_" + opts.model_name,
+ string_concat(
+ _('Visualização dos detalhes de'), ' ',
+ opts.verbose_name_plural)),
+ )
+ opts.permissions = tuple(
+ set(list(permissions) + list(opts.permissions)))
+
+ if opts.proxy:
+ # Force looking up the content types in the current database
+ # before creating foreign keys to them.
+ app_label, model = opts.app_label, opts.model_name
+
+ try:
+ ctype = ContentType.objects.get_by_natural_key(
+ app_label, model)
+ except:
+ ctype = ContentType.objects.create(
+ app_label=app_label, model=model)
+ else:
+ ctype = ContentType.objects.get_for_model(klass)
+
+ ctypes.add(ctype)
+ for perm in _get_all_permissions(klass._meta, ctype):
+ searched_perms.append((ctype, perm))
+
+ all_perms = set(Permission.objects.filter(
+ content_type__in=ctypes,
+ ).values_list(
+ "content_type", "codename"
+ ))
+
+ perms = [
+ Permission(codename=codename, name=name, content_type=ct)
+ for ct, (codename, name) in searched_perms
+ if (ct.pk, codename) not in all_perms
+ ]
+ Permission.objects.bulk_create(perms)
+
+
+def test_charfield_textfield():
+ for app in sapl_appconfs:
+ for model in app.get_models():
+ fields = model._meta.local_fields
+ for field in fields:
+ if isinstance(field, (CharField, TextField)):
+ assert not field.null, 'This %s is null: %s.%s' % (
+ type(field).__name__,
+ model.__name__,
+ field.attname)
+
+
+def test_str_sanity():
+ # this simply a sanity check
+ # __str__ semantics is not considered and should be tested separetely
+ for app in sapl_appconfs:
+ for model in app.get_models():
+ obj = mommy.prepare(model)
+ try:
+ str(obj)
+ except Exception as exc:
+ msg = '%s.%s.__str__ is broken.' % (
+ model.__module__, model.__name__)
+ raise AssertionError(msg, exc)
+
+btn_login = ('')
+
+
+@pytest.mark.parametrize('url_item', _lista_urls)
+def test_crudaux_formato_inicio_urls_associadas(url_item):
+
+ # Verifica se um crud é do tipo CrudAux, se sim, sua url deve começar
+ # com /sistema/
+ key, url, var, app_name = url_item
+ url = '/' + (url % {v: 1 for v in var})
+
+ view_class = None
+ if hasattr(key, 'view_class'):
+ view_class = key.view_class
+
+ # se não tem view_class, possivelmente é não é uma classed base view
+ if not view_class:
+ return
+
+ # se não tem atributo crud, não é será nenhum tipo de crud
+ if not hasattr(view_class, 'crud'):
+ return
+
+ # se o crud da view_class relativa a url a ser testada,
+ # implementa a classe CrudAux, seu link deve iniciar com /sistema
+ for string_class in list(map(str, type.mro(view_class.crud))):
+
+ if 'CrudAux' in string_class:
+ assert url.startswith('/sistema'), """
+ A url (%s) foi gerada a partir de um CrudAux,
+ o que diz que está é uma implementação de uma
+ tabela auxiliar, porém a url em questão, está fora
+ do padrão, que é iniciar com /sistema.
+ """ % (url)
+
+
+@pytest.mark.parametrize('url_item', _lista_urls)
+def test_crudaux_list_do_crud_esta_na_pagina_sistema(url_item, admin_client):
+
+ # Verifica se um crud é do tipo CrudAux, se sim, sua url deve começar
+ # com /sistema/
+ key, url, var, app_name = url_item
+ url = '/' + (url % {v: 1 for v in var})
+
+ view_class = None
+ if hasattr(key, 'view_class'):
+ view_class = key.view_class
+
+ # se não tem view_class, possivelmente não é uma classed base view
+ if not view_class:
+ return
+
+ # se não tem atributo crud, não é será nenhum tipo de crud
+ if not hasattr(view_class, 'crud'):
+ return
+
+ herancas_crud = list(map(str, type.mro(view_class.crud)))
+ for string_class in herancas_crud:
+ if 'CrudAux' in string_class:
+
+ herancas_view = list(map(str, type.mro(view_class)))
+
+ for string_view_class in herancas_view:
+ # verifica se o link para manutenção do crud está em /sistema
+ if 'ListView' in string_view_class:
+ response = admin_client.get('/sistema', {}, follow=True)
+ assert url in str(response.content), """
+ A url (%s) não consta nas Tabelas Auxiliares,
+ porem é uma implementação de ListView de CrudAux.
+ Se encontra em %s.urls
+ """ % (url, app_name)
+
+
+@pytest.mark.parametrize('url_item', _lista_urls)
+def test_urlpatterns(url_item, admin_client):
+
+ key, url, var, app_name = url_item
+ url = '/' + (url % {v: 1 for v in var})
+ app_name = app_name[5:]
+
+ apps_url_patterns_prefixs = {
+ 'base': [
+ '/sistema',
+ '/login',
+ '/logout'
+ ],
+ 'comissoes': [
+ '/comissao',
+ '/sistema'
+ ],
+ 'compilacao': [
+ '/ta',
+ ],
+ 'lexml': [
+ '/lexml',
+ '/sistema'
+ ],
+ 'materia': [
+ '/materia',
+ '/proposicao',
+ '/sistema'
+ ],
+ 'norma': [
+ '/norma',
+ '/sistema'
+ ],
+ 'painel': [
+ '/painel',
+ '/sistema'
+ ],
+ 'parlamentares': [
+ '/parlamentar',
+ '/mesa-diretora',
+ '/sistema'
+ ],
+ 'protocoloadm': [
+ '/protocoloadm',
+ '/sistema'
+ ],
+ 'relatorios': [
+ '/relatorios',
+ ],
+ 'sessao': [
+ '/sessao',
+ '/sistema',
+ ],
+ }
+ assert app_name in apps_url_patterns_prefixs, """
+ A app (%s) da url (%s) não consta na lista de prefixos do teste
+ """ % (app_name, url)
+
+ if app_name in apps_url_patterns_prefixs:
+ prefixs = apps_url_patterns_prefixs[app_name]
+
+ isvalid = False
+ for prefix in prefixs:
+ if url.startswith(prefix):
+ isvalid = True
+ break
+
+ assert isvalid, """
+ A url (%s) não está no padrão de sua app (%s).
+ Os prefixos permitidos são:
+ %s
+ """ % (url, app_name, prefixs)
+
+
+@pytest.mark.parametrize('urls_app', _lista_urls)
+def em_construcao_crud_permissions_urls(urls_app, client):
+ if not get_user_model().objects.exists():
+ for app in sapl_appconfs:
+ # readequa permissões dos models adicionando
+ # list e detail permissions
+ create_perms_post_migrate(app)
+ # cria usuários de perfil do sapl
+ cria_grupos_permissoes()
+ users = get_user_model().objects.values_list('username', flat=True)
+
+ for url_item in _lista_urls[urls_app]:
+
+ key, url, var, app_name = url_item
+ url = '/' + (url % {v: 1 for v in var})
+
+ app_labels = app_name.split('.')[1]
+
+ view_class = None
+ if hasattr(key, 'view_class'):
+ view_class = key.view_class
+
+ """
+ A classe PermissionRequiredForAppCrudMixin pode ser usada em uma
+ app mas envolver permissoes para outras
+ como é o caso de PainelView que está na app 'sessao'
+ mas é um redirecionamento para 'painel'... aqui é feita
+ a troca a urls_app a ser testada, por essas outras possíveis
+ """
+ if PermissionRequiredForAppCrudMixin in type.mro(view_class):
+ # essa classe deve informar app_label
+ assert hasattr(view_class, 'app_label')
+ # app_label deve ter conteudo
+ assert view_class.app_label
+ app_labels = view_class.app_label
+
+ if isinstance(app_labels, str):
+ app_labels = app_labels,
+
+ for app in app_labels:
+
+ # monta o username correspondente de a app da url a ser testada
+ user_for_url_atual_app = 'operador_%s'
+ if app in ['base', 'parlamentares']:
+ user_for_url_atual_app = user_for_url_atual_app % 'geral'
+ elif app in 'protocoloadm':
+ user_for_url_atual_app = user_for_url_atual_app % 'administrativo'
+ elif app in ['compilacao']:
+ return # TODO implementar teste para compilacao
+ else:
+ user_for_url_atual_app = user_for_url_atual_app % app
+
+ for username in users:
+ print(username, user_for_url_atual_app, url)
+
+ client.login(username=username, password='interlegis')
+
+ rg = None
+ try:
+ rg = client.get(url, {}, follow=True)
+ except:
+ pass
+
+ rp = None
+ try:
+ rp = client.post(url, {}, follow=True)
+ except:
+ pass
+
+ """
+ devido às urls serem incompletas ou com pks e outras valores
+ inexistentes na base, iniciar a execução da view, seja por get,
+ post ou qualquer outro método pode causar o erro...
+ por isso o "try ... except" acima.
+ No entanto, o objetivo do teste é validar o acesso de toda url.
+ Independente do erro que vá acontecer, esse erro não ocorrerá
+ se o user não tiver permissão de acesso pelo fato de que "AS
+ VIEWS BEM FORMADAS PARA VALIDAÇÃO DE ACESSO DEVEM SEMPRE REDIRECIONAR PARA
+ LOGIN ANTES DE SUA EXECUÇÃO", desta forma nunca gerando erro
+ interno dada qualquer incoerência de parâmetros nas urls
+ """
+ if rg:
+ """
+ Se o usuário a ser testado é o usuário da app da url de get
+ espera-se que não tenha recebido uma tela de login
+ """
+ if username == user_for_url_atual_app and\
+ not url.startswith('/sistema/'):
+ assert btn_login not in str(rg.content)
+ elif username != 'operador_geral' and\
+ url.startswith('/sistema/'):
+ assert btn_login in str(rg.content)
+ elif username == 'operador_geral' and\
+ url.startswith('/sistema/'):
+ assert btn_login not in str(rg.content)
+
+ if rp:
+ """
+ Se o usuário a ser testado é o usuário da app da url de
+ post espera-se que não tenha recebido uma tela de login
+ """
+ if username == user_for_url_atual_app and\
+ not url.startswith('/sistema/'):
+ assert btn_login not in str(rp.content)
+ elif username != 'operador_geral' and\
+ url.startswith('/sistema/'):
+ assert btn_login in str(rp.content)
+ elif username == 'operador_geral' and\
+ url.startswith('/sistema/'):
+ assert btn_login not in str(rp.content)
+
+ logout = client.get('/logout/', follow=True)