diff --git a/CHANGELOG b/CHANGELOG
index e7b621d..e5cf7e3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,4 +1,4 @@
-2.1.0: Add support for django 4.0, 4.1. Add support for Python 3.10, 3.11.
+2.1.0: Add support for django 4.0, 4.1. Add support for Python 3.10, 3.11, 3.12
2.0.3: remove upper bound on django requirement
2.0.2: Bump py, flake8 and other dependencies for security.
2.0.0: Support for django 2.0, 2.1, 2.2. Add support for Python3.7. Drop support for Python 2.7
diff --git a/Makefile b/Makefile
index c653827..6364c92 100644
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ WITH_VENV=. $(VENV_ACTIVATE);
ifdef TRAVIS_PYTHON_VERSION
PYTHON=python$(TRAVIS_PYTHON_VERSION)
else
- PYTHON=python3.9
+ PYTHON=python3.10
endif
ifdef TOX_ENV
@@ -23,7 +23,8 @@ default:
venv: $(VENV_ACTIVATE)
$(VENV_ACTIVATE): requirements*.txt setup.py
- test -f $@ || virtualenv --python=$(PYTHON) $(VENV_DIR)
+ pip install virtualenv==20.8.1
+ test -f $@ || python3 -m venv $(VENV_DIR) || virtualenv --python=$(PYTHON) $(VENV_DIR)
$(WITH_VENV) pip install --no-deps -r requirements-setup.txt
$(WITH_VENV) pip install -e .
$(WITH_VENV) pip install --no-deps -r requirements-dev.txt
@@ -83,3 +84,25 @@ dist: venv
.PHONY: sdist
sdist: dist
@echo "runs dist"
+
+### Infastructure for Github Actions
+.PHONY: ci-libs
+ci-libs:
+ sudo apt-get update -y
+ sudo apt-get install -y libldap2-dev libssl-dev libsasl2-dev
+
+.PHONY: ci-install
+ci-install: ci-libs venv
+
+.PHONY: ci-lint
+ci-lint: lint
+
+.PHONY: ci-test
+ci-test: test
+
+.PHONY: ci-version
+ci-version: version
+
+.PHONY: ci-publish
+ci-publish:
+ $(WITH_VENV) python setup.py sdist
\ No newline at end of file
diff --git a/baya/backend.py b/baya/backend.py
index bc6c30d..278a310 100644
--- a/baya/backend.py
+++ b/baya/backend.py
@@ -1,5 +1,4 @@
from functools import partial
-import six
from django.conf import settings
from django.contrib.auth import get_permission_codename
@@ -34,7 +33,7 @@ def get_all_permissions(self, user, obj=None):
user, obj)
from baya.admin.sites import _admin_registry
for admin_site in _admin_registry:
- for model, opts in six.iteritems(admin_site._registry):
+ for model, opts in admin_site._registry.items():
app = model._meta.app_label
perm_name = partial(get_permission_codename, opts=model._meta)
if (hasattr(opts, 'user_has_add_permission') and
diff --git a/baya/mock_ldap_helpers.py b/baya/mock_ldap_helpers.py
index ffeaf4a..d2af892 100644
--- a/baya/mock_ldap_helpers.py
+++ b/baya/mock_ldap_helpers.py
@@ -149,8 +149,8 @@ def mock_ldap_setup(
`.start()` on the returned value.
"""
from django.conf import settings
- import mock
import mockldap
+ from unittest import mock
class MockLDAP(mockldap.MockLdap):
def start(self, *args, **kwargs):
diff --git a/baya/permissions.py b/baya/permissions.py
index 38501f5..6284656 100644
--- a/baya/permissions.py
+++ b/baya/permissions.py
@@ -1,9 +1,10 @@
-import collections
import functools
-import sys
-if sys.version_info[:2] >= (3, 10):
- collections.Callable = collections.abc.Callable
+try:
+ from collections.abc import Callable
+except Exception:
+ from collections import Callable
+
import django
from django.conf import settings
@@ -16,7 +17,6 @@
elif django.VERSION[0] >= 2:
from django.urls.resolvers import URLPattern
from django.urls.resolvers import URLResolver
-import six
from .membership import BaseNode
from .membership import ValueNode
@@ -87,7 +87,7 @@ def _ensure_permission_node(self, groups):
if groups is None:
groups = []
- elif isinstance(groups, six.string_types):
+ elif isinstance(groups, str):
groups = [group.strip() for group in groups.split(',')]
return self.DEFAULT_PERMISSION_NODE(*groups)
@@ -184,10 +184,10 @@ def __iadd__(self, other):
self.get_requires &= other.get_requires
self.post_requires &= other.post_requires
# Prefer other's login_url, if set
- login_text_type = six.text_type(settings.BAYA_LOGIN_URL)
+ login_text_type = str(settings.BAYA_LOGIN_URL)
if (
other.login_url is not None and
- six.text_type(other.login_url) != login_text_type
+ str(other.login_url) != login_text_type
):
self.login_url = other.login_url
return self
@@ -362,7 +362,7 @@ def __call__(self, fn, *args, **kwargs):
'Cannot decorate a bare functools.partial view. '
'You must invoke functools.update_wrapper(partial_view, '
'full_view) first.')
- if not isinstance(fn, type) and isinstance(fn, collections.Callable):
+ if not isinstance(fn, type) and isinstance(fn, Callable):
return self.decorate_method(fn, *args, **kwargs)
elif isinstance(fn, tuple):
# Must be an include('my_app.urls') we're decorating
@@ -374,7 +374,7 @@ def __call__(self, fn, *args, **kwargs):
raise TypeError("Cannot decorate Inlines. See "
"baya.admin.options.BayaInline instead.")
return self.decorate_admin(fn, *args, **kwargs)
- elif isinstance(fn, six.string_types):
+ elif isinstance(fn, str):
raise TypeError("Cannot decorate string-path to view: %s." % fn)
else:
# You'll probably only get here if you're trying to decorate
diff --git a/baya/tests/settings.py b/baya/tests/settings.py
index 7b29ea1..654f042 100644
--- a/baya/tests/settings.py
+++ b/baya/tests/settings.py
@@ -21,7 +21,6 @@
'django.contrib.auth',
'django.contrib.sessions',
'django.contrib.contenttypes',
- 'django_nose',
'baya',
'baya.tests',
'baya.tests.submod',
@@ -82,8 +81,6 @@
STATIC_URL = '/static/'
-TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
-
CSRF_USE_SESSIONS = False
MIDDLEWARE = (
@@ -129,3 +126,5 @@
ldap.SCOPE_SUBTREE,
"(objectClass=groupOfNames)"
)
+
+USE_TZ = False
diff --git a/baya/tests/test_admin.py b/baya/tests/test_admin.py
index c12cbc9..3a4a510 100644
--- a/baya/tests/test_admin.py
+++ b/baya/tests/test_admin.py
@@ -1,5 +1,5 @@
-import six
from django.contrib.admin.options import InlineModelAdmin
+import pytest
from baya import RolesNode as g
from baya.admin.sites import NestedGroupsAdminSite
@@ -12,19 +12,20 @@
from baya.tests.models import BlagEntry
from baya.tests.submod.models import Comment
from baya.tests.test_base import LDAPGroupAuthTestBase
-import mock
-from mock import MagicMock
+from unittest import mock
+from unittest.mock import MagicMock
+@pytest.mark.django_db
class TestAdminSite(LDAPGroupAuthTestBase):
def test_module_perms(self):
app_label = Blag._meta.app_label
for user in ['has_all', 'has_a', 'has_aa', 'has_aaa']:
request = self.mock_get_request(self.login(user))
- self.assertTrue(request.user.has_module_perms(app_label))
+ assert request.user.has_module_perms(app_label)
request = self.mock_get_request(self.login('has_b'))
- self.assertFalse(request.user.has_module_perms(app_label))
+ assert not request.user.has_module_perms(app_label)
def test_required_baya_groups(self):
# The required groups for an admin site is the `or`-union of all
@@ -33,7 +34,7 @@ def test_required_baya_groups(self):
exp = ((g('AAA') & ALLOW_ALL) |
(g('AA') & ALLOW_ALL) |
(g('AA') | g('B')))
- self.assertEqual(required_groups, exp)
+ assert required_groups == exp
def test_required_baya_groups_repeats(self):
"""Repeated roles should only be shown once."""
@@ -53,81 +54,80 @@ def test_required_baya_groups_repeats(self):
site = NestedGroupsAdminSite()
required_groups = site._get_required_baya_groups()
exp = g('A')
- self.assertEqual(required_groups, exp)
+ assert required_groups == exp
def test_index(self):
"""Only display those apps which the user can access."""
request = self.mock_get_request(self.login('has_all'))
index = site.index(request)
app_list = index.context_data['app_list']
- self.assertEqual(len(app_list), 2)
+ assert len(app_list) == 2
for app in app_list:
- models = {six.text_type(model['name']) for model in app['models']}
+ models = {str(model['name']) for model in app['models']}
if len(models) == 2:
- self.assertEqual({"Blags", "Entries"}, models)
+ assert {"Blags", "Entries"} == models
for model in app['models']:
for permission in ['add', 'change', 'delete']:
- self.assertTrue(model['perms'][permission])
+ assert model['perms'][permission]
else:
- self.assertEqual({"Comments"}, models)
+ assert {"Comments"} == models
model = app['models'][0]
- self.assertTrue(model['perms']['add'])
- self.assertTrue(model['perms']['change'])
- self.assertFalse(model['perms']['delete'])
+ assert model['perms']['add']
+ assert model['perms']['change']
+ assert not model['perms']['delete']
def test_read_only(self):
# has_aaa can only access the read-only Blag changelist
request = self.mock_get_request(self.login('has_aaa'))
index = site.index(request)
app_list = index.context_data['app_list']
- self.assertEqual(len(app_list), 1)
+ assert len(app_list) == 1
app_list = app_list[0]
- self.assertEqual(
- {"Blags"},
- {six.text_type(model['name']) for model in app_list['models']})
+ assert {"Blags"} == {str(model['name']) for model in app_list['models']}
perms = app_list['models'][0]['perms']
- self.assertFalse(perms['add'])
- self.assertTrue(perms['change'])
- self.assertFalse(perms['delete'])
+ assert not perms['add']
+ assert perms['change']
+ assert not perms['delete']
+@pytest.mark.django_db
class TestOptions(LDAPGroupAuthTestBase):
def _get_options(self):
return site._registry[Blag]
def test_add_permissions(self):
options = self._get_options()
- self.assertTrue(
+ assert (
options.has_add_permission(
self.mock_get_request(self.login('has_all'))))
- self.assertTrue(
+ assert (
options.has_add_permission(
self.mock_get_request(self.login('has_a'))))
- self.assertFalse(
+ assert not (
options.has_add_permission(
self.mock_get_request(self.login('has_aaa'))))
def test_change_view_permission(self):
options = self._get_options()
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_all'))))
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_a'))))
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_aaa'))))
def test_delete_permission(self):
options = self._get_options()
- self.assertTrue(
+ assert (
options.has_delete_permission(
self.mock_post_request(self.login('has_all'))))
- self.assertTrue(
+ assert (
options.has_delete_permission(
self.mock_post_request(self.login('has_a'))))
- self.assertFalse(
+ assert not (
options.has_delete_permission(
self.mock_post_request(self.login('has_aaa'))))
@@ -138,19 +138,19 @@ def _get_options(self):
def test_create_permissions(self):
options = self._get_options()
- self.assertTrue(
+ assert (
options.has_add_permission(
self.mock_get_request(self.login('has_all'))))
- self.assertTrue(
+ assert (
options.has_add_permission(
self.mock_get_request(self.login('has_a'))))
- self.assertFalse(
+ assert not (
options.has_add_permission(
self.mock_get_request(self.login('has_aa'))))
- self.assertFalse(
+ assert not (
options.has_add_permission(
self.mock_get_request(self.login('has_aaa'))))
- self.assertFalse(
+ assert not (
options.has_add_permission(
self.mock_get_request(self.login('has_b'))))
@@ -159,62 +159,63 @@ def test_read_permissions(self):
# Note - django admin doesn't distinguish between read and update, so
# baya blocks read-only access from writing, but it still looks to
# the admin like they have change permissions.
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_all'))))
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_a'))))
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_aa'))))
- self.assertFalse(
+ assert not (
options.has_change_permission(
self.mock_get_request(self.login('has_aaa'))))
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_b'))))
def test_update_permissions(self):
options = self._get_options()
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_all'))))
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_a'))))
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_aa'))))
- self.assertFalse(
+ assert not (
options.has_change_permission(
self.mock_get_request(self.login('has_aaa'))))
- self.assertTrue(
+ assert (
options.has_change_permission(
self.mock_get_request(self.login('has_b'))))
def test_delete_permissions(self):
options = self._get_options()
- self.assertFalse(
+ assert not (
options.has_delete_permission(
self.mock_get_request(self.login('has_all'))))
- self.assertFalse(
+ assert not (
options.has_delete_permission(
self.mock_get_request(self.login('has_a'))))
- self.assertFalse(
+ assert not (
options.has_delete_permission(
self.mock_get_request(self.login('has_aa'))))
- self.assertFalse(
+ assert not (
options.has_delete_permission(
self.mock_get_request(self.login('has_aaa'))))
- self.assertFalse(
+ assert not (
options.has_delete_permission(
self.mock_get_request(self.login('has_b'))))
+@pytest.mark.django_db
class TestInlines(LDAPGroupAuthTestBase):
- def setUp(self):
- super(TestInlines, self).setUp()
+ def setup_method(self):
+ super().setup_method()
Blag.objects.all().delete()
self.blag = Blag.objects.create(name="My Blag")
self.entries = [
@@ -231,19 +232,16 @@ def _get_inlines(self):
def test_entries_displayed(self):
inline_formsets = self._get_inlines()
- self.assertEqual(len(inline_formsets), 2)
+ assert len(inline_formsets) == 2
# The UnprotectedPhotoBlagEntryInline should not be here
inline_opts = {type(inf.opts) for inf in inline_formsets}
- self.assertEqual(
- inline_opts, {BlagEntryInline, ProtectedPhotoBlagEntryInline})
+ assert inline_opts == {BlagEntryInline, ProtectedPhotoBlagEntryInline}
def test_perms_correct(self):
def _check(inline, request, add, change, delete):
- self.assertEqual(inline.opts.has_add_permission(request, obj=None), add)
- self.assertEqual(
- inline.opts.has_change_permission(request), change)
- self.assertEqual(
- inline.opts.has_delete_permission(request), delete)
+ assert inline.opts.has_add_permission(request, obj=None) == add
+ assert inline.opts.has_change_permission(request) == change
+ assert inline.opts.has_delete_permission(request) == delete
inline_formsets = self._get_inlines()
while inline_formsets:
@@ -262,7 +260,7 @@ def _check(inline, request, add, change, delete):
def test_inline_decoration(self):
# This should fail because inlines don't have any {add,change,delete}
# views to protect.
- with self.assertRaises(TypeError):
+ with pytest.raises(TypeError):
@requires(g('A'))
class MyInline(InlineModelAdmin):
pass
diff --git a/baya/tests/test_backend.py b/baya/tests/test_backend.py
index f621081..d8a78a5 100644
--- a/baya/tests/test_backend.py
+++ b/baya/tests/test_backend.py
@@ -1,7 +1,7 @@
import ldap
from django.test import TestCase
-from mock import Mock
-from mock import sentinel
+from unittest.mock import Mock
+from unittest.mock import sentinel
from baya.backend import NestedLDAPGroupsBackend
from baya.backend import ReconnectingLDAP
@@ -12,7 +12,7 @@ class TestReconnectingLDAP(TestCase):
def test_getattr_not_initialize(self):
ldap = Mock()
reconnecting_ldap = ReconnectingLDAP(ldap)
- self.assertIs(reconnecting_ldap.not_initialize, ldap.not_initialize)
+ assert reconnecting_ldap.not_initialize is ldap.not_initialize
def test_initialize(self):
ldap = Mock()
@@ -30,8 +30,8 @@ class TestBackend(NestedLDAPGroupsBackend):
def test_reconnecting_backend(self):
backend = self.TestBackend()
ldap_module = backend.ldap
- self.assertTrue(isinstance(ldap_module, ReconnectingLDAP))
- self.assertIs(ldap_module.SERVER_DOWN, ldap.SERVER_DOWN)
+ assert isinstance(ldap_module, ReconnectingLDAP)
+ assert ldap_module.SERVER_DOWN is ldap.SERVER_DOWN
class TestNonReconnectingLDAPBackend(TestCase):
@@ -42,5 +42,5 @@ class TestBackend(NestedLDAPGroupsBackend):
def test_non_reconnecting_backend(self):
backend = self.TestBackend()
ldap_module = backend.ldap
- self.assertFalse(isinstance(ldap_module, ReconnectingLDAP))
- self.assertIs(ldap_module.SERVER_DOWN, ldap.SERVER_DOWN)
+ assert not isinstance(ldap_module, ReconnectingLDAP)
+ assert ldap_module.SERVER_DOWN is ldap.SERVER_DOWN
diff --git a/baya/tests/test_base.py b/baya/tests/test_base.py
index 04763bd..4010981 100644
--- a/baya/tests/test_base.py
+++ b/baya/tests/test_base.py
@@ -1,4 +1,5 @@
-from mock import MagicMock
+from unittest.mock import MagicMock
+import pytest
import django
from django_auth_ldap import backend
@@ -7,7 +8,7 @@
from django.contrib.auth.models import AnonymousUser
from django.core.exceptions import PermissionDenied
from django.middleware.csrf import _get_new_csrf_string
-from django.test import TestCase
+
if django.VERSION[:2] <= (2, 2):
from django.middleware.csrf import _salt_cipher_secret
@@ -20,26 +21,27 @@
from ..mock_ldap_helpers import mock_ldap_setup
-class LDAPGroupAuthTestBase(TestCase):
+@pytest.mark.django_db
+class LDAPGroupAuthTestBase():
@classmethod
- def setUpClass(cls):
+ def setup_class(cls):
cls.mockldap = mock_ldap_setup(
ldap_dc='dc=test',
extra_users=directory.test_users,
group_lineage=directory.group_lineage)
@classmethod
- def tearDownClass(cls):
+ def teardown_class(cls):
del cls.mockldap
- def setUp(self):
+ def setup_method(self):
self.mockldap.start()
self.ldapobj = self.mockldap['ldap://localhost']
self.backend = backend.LDAPBackend()
self.backend.ldap # Force global configuration
- def tearDown(self):
+ def teardown_method(self):
self.mockldap.stop()
del self.ldapobj
@@ -88,11 +90,13 @@ def mock_post_request(self, *args, **kwargs):
def assert_no_get_permission(self, user, view, get=None):
request = self.mock_get_request(user, get=get)
- self.assertRaises(PermissionDenied, view, request)
+ with pytest.raises(PermissionDenied):
+ view(request)
def assert_no_post_permission(self, user, view, get=None, post=None):
request = self.mock_post_request(user, get=get, post=post)
- self.assertRaises(PermissionDenied, view, request)
+ with pytest.raises(PermissionDenied):
+ view(request)
def assert_no_permission(self, user, view, get=None, post=None):
self.assert_no_get_permission(user, view, get)
@@ -101,18 +105,19 @@ def assert_no_permission(self, user, view, get=None, post=None):
def assert_has_get_permission(self, user, view, get=None):
request = self.mock_get_request(user, get=get)
response = view(request)
- self.assertEqual(response.status_code, 200)
+ assert response.status_code == 200
def assert_has_post_permission(self, user, view, get=None, post=None):
request = self.mock_post_request(user, get=get, post=post)
response = view(request)
- self.assertEqual(response.status_code, 200)
+ assert response.status_code == 200
def assert_has_permission(self, user, view, get=None, post=None):
self.assert_has_get_permission(user, view, get)
self.assert_has_post_permission(user, view, get, post)
+@pytest.mark.django_db
class TestSetup(LDAPGroupAuthTestBase):
def test_has_all_groups(self):
"""Verify that mockldap & django-auth-ldap are both working.
@@ -123,5 +128,5 @@ def test_has_all_groups(self):
group_count = Group.objects.count()
self.login('has_all')
group_count_2 = Group.objects.count()
- self.assertGreater(group_count_2, group_count)
- self.assertEqual(group_count_2 - group_count, 6)
+ assert group_count_2 > group_count
+ assert group_count_2 - group_count == 6
diff --git a/baya/tests/test_dynamic_roles.py b/baya/tests/test_dynamic_roles.py
index 88f7525..8684013 100644
--- a/baya/tests/test_dynamic_roles.py
+++ b/baya/tests/test_dynamic_roles.py
@@ -1,5 +1,5 @@
-from mock import MagicMock
-from mock import patch
+from unittest.mock import MagicMock
+from unittest.mock import patch
from unittest import TestCase
@@ -26,21 +26,21 @@ def build_mock_request(self, request_group):
def test_returns_set(self):
"""The formatter should return a set of groups."""
roles = self.formatter(self.build_mock_request('mygroup'))
- self.assertEqual(type(roles), set)
- self.assertEqual(len(roles), 1)
- self.assertEqual(roles.pop(), "mygroup_admin")
+ assert type(roles) == set
+ assert len(roles) == 1
+ assert roles.pop() == "mygroup_admin"
def test_query_param(self):
request = self.build_mock_request('mygroup')
roles = self.formatter(request)
- self.assertEqual(roles, {'mygroup_admin'})
+ assert roles == {'mygroup_admin'}
def test_reverse_kwarg(self):
request = self.build_mock_request('mygroup')
request.GET = {}
request.resolver_match.kwargs = {'group': 'mygroup'}
roles = self.formatter(request)
- self.assertEqual(roles, {'mygroup_admin'})
+ assert roles == {'mygroup_admin'}
def test_query_param_collision(self):
"""The URL kwarg should take precedence over the query parameter."""
@@ -48,14 +48,14 @@ def test_query_param_collision(self):
request.resolver_match.kwargs = {'group': 'kwarg_group'}
with patch('baya.dynamic_roles.logger') as mock_logger:
roles = self.formatter(request)
- self.assertEqual(mock_logger.warning.call_count, 1)
- self.assertEqual(roles, {'kwarg_group_admin'})
+ assert mock_logger.warning.call_count == 1
+ assert roles == {'kwarg_group_admin'}
def test_str(self):
st = str(self.formatter)
- self.assertIn("%s_admin", st)
- self.assertIn("group", st)
+ assert "%s_admin" in st
+ assert "group" in st
def test_repr(self):
re = repr(self.formatter)
- self.assertIn(self.formatter.__class__.__name__, re)
+ assert self.formatter.__class__.__name__ in re
diff --git a/baya/tests/test_integration.py b/baya/tests/test_integration.py
index d2220cc..a2367b9 100644
--- a/baya/tests/test_integration.py
+++ b/baya/tests/test_integration.py
@@ -1,8 +1,9 @@
-from distutils.version import StrictVersion
+import pytest
-from django import get_version as get_django_version
+from pytest_django.asserts import assertRedirects, assertContains, assertNotContains
from django.urls import reverse
from django.test.utils import override_settings
+from django.test import client as dj_client
from baya.tests.test_base import LDAPGroupAuthTestBase
from baya.tests.models import Blag
@@ -23,10 +24,9 @@ class _IntegrationBase(LDAPGroupAuthTestBase):
URL level, and the RF doesn't go through that.
"""
def get_client(self, username=None, password='password'):
- client = self.client
+ client = dj_client.Client()
if username:
- self.assertTrue(
- client.login(username=username, password=password))
+ assert client.login(username=username, password=password)
return client
def _get_and_assert_access(
@@ -35,26 +35,24 @@ def _get_and_assert_access(
client = self.get_client(username)
url = reverse(url_name, args=reverse_args, kwargs=reverse_kwargs)
response = client.get(url)
- self.assertEqual(
- response.status_code,
- target_status_code,
- '%s != %s, %s' % (response.status_code, target_status_code,
- message))
+ assert response.status_code == target_status_code,\
+ f"{response.status_code} != {target_status_code}, {message}"
return response
+@pytest.mark.django_db
class TestIntegration(_IntegrationBase):
def _test_login_redirect(
self, url_name, username, target_status_code, login_url='login'):
client = self.get_client()
url = reverse(url_name)
response = client.get(url)
- self.assertRedirects(
+ assertRedirects(
response, "%s?next=%s" % (reverse(login_url), url))
login_response = client.post(
response['Location'],
{'username': username, 'password': 'password'})
- self.assertRedirects(
+ assertRedirects(
login_response, url, target_status_code=target_status_code)
client.logout()
@@ -73,16 +71,14 @@ def test_verbs(self):
def _has_method(client, method):
verb = getattr(client, method)
response = verb(url)
- self.assertEqual(
- response.status_code, OK,
- "Error %s: %s not allowed" % (response.status_code, method))
+ assert response.status_code == OK,\
+ "Error %s: %s not allowed" % (response.status_code, method)
def _has_not_method(client, method):
verb = getattr(client, method)
response = verb(url)
- self.assertEqual(
- response.status_code, DENIED,
- "Error %s: %s allowed" % (response.status_code, method))
+ assert response.status_code == DENIED,\
+ "Error %s: %s allowed" % (response.status_code, method)
url = reverse('my_view')
@@ -105,7 +101,7 @@ def _has_not_method(client, method):
def test_index(self):
blag = Blag.objects.create(name="my blag")
response = self._get_and_assert_access('index', 'has_all', OK)
- self.assertContains(response, blag.name)
+ assertContains(response, blag.name)
def test_my_view_str(self):
"""Test a decorated view method works when resolved by string path."""
@@ -199,19 +195,19 @@ def test_query_param(self):
'query_param_view', 'has_aa', OK, reverse_kwargs={'name': 'aa'})
+@pytest.mark.django_db
class TestAdminIntegration(_IntegrationBase):
def test_admin_view_uses_baya(self):
# Default django admin_view returns a 200, not a 403
client = self.get_client('has_nothing')
url = reverse('admin:index')
response = client.get(url)
- self.assertEqual(response.status_code, 403)
+ assert response.status_code == 403
# Ensure that baya_requires was set on the request
- self.assertTrue(hasattr(response.context['request'], 'baya_requires'))
+ assert hasattr(response.context['request'], 'baya_requires')
# And that it's in the 403 template
- self.assertIn(
- "{aaa} & True | {aa} & True | {aa} | {b}",
- response.content.decode('utf-8'))
+ assert ("{aaa} & True | {aa} & True | {aa} | {b}"
+ in response.content.decode('utf-8'))
def test_index(self):
for url, reverse_kwargs in [
@@ -219,18 +215,18 @@ def test_index(self):
('admin:app_list', {'app_label': 'tests'})]:
response = self._get_and_assert_access(
url, 'has_all', OK, reverse_kwargs=reverse_kwargs)
- self.assertContains(response, 'Blags')
- self.assertContains(response, 'Entries')
+ assertContains(response, 'Blags')
+ assertContains(response, 'Entries')
if 'index' in url:
- self.assertContains(response, 'Comments')
+ assertContains(response, 'Comments')
else:
- self.assertNotContains(response, 'Comments')
+ assertNotContains(response, 'Comments')
response = self._get_and_assert_access(
url, 'has_aaa', OK, reverse_kwargs=reverse_kwargs)
- self.assertContains(response, 'Blags')
- self.assertNotContains(response, 'Entries')
- self.assertNotContains(response, 'Comments')
+ assertContains(response, 'Blags')
+ assertNotContains(response, 'Entries')
+ assertNotContains(response, 'Comments')
if 'index' in url:
# B just sees an empty admin page, following the normal
@@ -238,20 +234,12 @@ def test_index(self):
response = self._get_and_assert_access(
url, 'has_b', OK, reverse_kwargs=reverse_kwargs,
message=url)
- self.assertNotContains(response, 'Blags')
- self.assertNotContains(response, 'Entries')
- self.assertContains(response, 'Comments')
+ assertNotContains(response, 'Blags')
+ assertNotContains(response, 'Entries')
+ assertContains(response, 'Comments')
else:
- # In django <1.7 >1.10 B gets a 404 for app_list.
- # In django >=1.7 <=1.10 B get sa 403, like you'd expect.
- django_version = StrictVersion(get_django_version())
- if (django_version >= StrictVersion('1.7.0') and
- django_version < StrictVersion('1.11.0')):
- expected_status = DENIED
- else:
- expected_status = NOT_FOUND
response = self._get_and_assert_access(
- url, 'has_b', expected_status,
+ url, 'has_b', NOT_FOUND,
reverse_kwargs=reverse_kwargs,
message=url)
@@ -280,13 +268,13 @@ def test_add(self):
data = self._get_form_data()
data.update({'name': 'has_all blag'})
response = client.post(add_url, data)
- self.assertRedirects(response, changelist_url)
- self.assertEqual(Blag.objects.count(), blag_count + 1)
+ assertRedirects(response, changelist_url)
+ assert Blag.objects.count() == blag_count + 1
# And the POST is rejected too
client = self.get_client('has_aaa')
response = client.post(add_url, {'name': 'has_aaa blag'})
- self.assertEqual(response.status_code, DENIED)
- self.assertEqual(Blag.objects.count(), blag_count + 1)
+ assert response.status_code == DENIED
+ assert Blag.objects.count() == blag_count + 1
def test_changelist_view(self):
self._get_and_assert_access(
@@ -309,7 +297,7 @@ def test_read_not_update(self):
client = self.get_client('has_b')
response = client.post(
change_url, {'id': '%s' % comment.id, 'body': 'syke'})
- self.assertEqual(response.status_code, DENIED)
+ assert response.status_code == DENIED
def test_changelist_post(self):
changelist_url = reverse('admin:tests_blag_changelist')
@@ -326,13 +314,13 @@ def test_changelist_post(self):
# But AAA can't actually change anything
client = self.get_client('has_aaa')
response = client.post(changelist_url, delete_kwargs)
- self.assertEqual(response.status_code, DENIED)
- self.assertEqual(Blag.objects.count(), blag_count)
+ assert response.status_code == DENIED
+ assert Blag.objects.count() == blag_count
client = self.get_client('has_all')
response = client.post(changelist_url, delete_kwargs)
- self.assertRedirects(response, changelist_url)
- self.assertEqual(Blag.objects.count(), blag_count - 1)
+ assertRedirects(response, changelist_url)
+ assert Blag.objects.count() == blag_count - 1
def test_change_view(self):
blag = Blag.objects.create(name="blagonet")
@@ -358,14 +346,14 @@ def test_change_post(self):
'name': 'new name',
})
response = client.post(change_url, data)
- self.assertRedirects(response, changelist_url)
- self.assertEqual(Blag.objects.get(id=blag.id).name, 'new name')
+ assertRedirects(response, changelist_url)
+ assert Blag.objects.get(id=blag.id).name == 'new name'
# ...but AAA Cannot actually change anything
client = self.get_client('has_aaa')
response = client.post(
change_url, {'id': '%s' % blag.id, 'name': 'newer name'})
- self.assertEqual(response.status_code, DENIED)
+ assert response.status_code == DENIED
def test_delete_view(self):
blag = Blag.objects.create(name="blagonet")
@@ -391,24 +379,25 @@ def test_delete_post(self):
# ...but AAA Cannot actually change anything
client = self.get_client('has_aaa')
response = client.post(delete_url, data)
- self.assertEqual(response.status_code, DENIED)
+ assert response.status_code == DENIED
client = self.get_client('has_all')
response = client.post(delete_url, data)
- self.assertRedirects(response, changelist_url)
- self.assertEqual(Blag.objects.count(), 0)
+ assertRedirects(response, changelist_url)
+ assert Blag.objects.count() == 0
def test_inner_url(self):
"""Should be able to decorate urls in ModelAdmin.get_urls()."""
blag1 = Blag.objects.create(name='blag one')
blag2 = Blag.objects.create(name='blag two')
response = self._get_and_assert_access('admin:list', 'has_all', OK)
- self.assertContains(response, blag1.name)
- self.assertContains(response, blag2.name)
+ assertContains(response, blag1.name)
+ assertContains(response, blag2.name)
self._get_and_assert_access('admin:list', 'has_aaa', DENIED)
self._get_and_assert_access('admin:list', 'has_b', DENIED)
+@pytest.mark.django_db
class TestAdminInlineIntegration(_IntegrationBase):
def _get_form_data(self):
return {
@@ -423,7 +412,7 @@ def _get_form_data(self):
def test_add(self):
blag = Blag.objects.create(name="blagonet")
PhotoBlagEntry.objects.all().delete()
- self.assertEqual(PhotoBlagEntry.objects.all().count(), 0)
+ assert PhotoBlagEntry.objects.all().count() == 0
change_url = reverse('admin:tests_blag_change', args=[blag.id])
changelist_url = reverse('admin:tests_blag_changelist')
@@ -436,15 +425,14 @@ def test_add(self):
# B has no permissions
client = self.get_client('has_b')
response = client.post(change_url, data)
- self.assertEqual(response.status_code, 403)
+ assert response.status_code == 403
# A succeedes
client = self.get_client('has_a')
response = client.post(change_url, data)
- self.assertRedirects(response, changelist_url)
- self.assertEqual(
- Blag.objects.get(id=blag.id).photoblagentry_set.count(), 1)
- self.assertEqual(PhotoBlagEntry.objects.all().count(), 1)
+ assertRedirects(response, changelist_url)
+ assert Blag.objects.get(id=blag.id).photoblagentry_set.count() == 1
+ assert PhotoBlagEntry.objects.all().count() == 1
def test_change(self):
blag = Blag.objects.create(name="blagonet")
@@ -453,8 +441,7 @@ def test_change(self):
change_url = reverse('admin:tests_blag_change', args=[blag.id])
changelist_url = reverse('admin:tests_blag_changelist')
- self.assertEqual(
- Blag.objects.get(id=blag.id).photoblagentry_set.count(), 1)
+ assert Blag.objects.get(id=blag.id).photoblagentry_set.count() == 1
data = self._get_form_data()
data.update({
@@ -468,17 +455,16 @@ def test_change(self):
# B has no permissions
client = self.get_client('has_b')
response = client.post(change_url, data)
- self.assertEqual(response.status_code, 403)
+ assert response.status_code == 403
# A successfully alters the entry
client = self.get_client('has_a')
- self.assertContains(client.get(change_url), entry.title)
+ assertContains(client.get(change_url), entry.title)
response = client.post(change_url, data)
- self.assertRedirects(response, changelist_url)
- self.assertEqual(
- Blag.objects.get(id=blag.id).photoblagentry_set.count(), 1)
- self.assertEqual(PhotoBlagEntry.objects.all().count(), 1)
- self.assertEqual(PhotoBlagEntry.objects.get().title, 'my new title')
+ assertRedirects(response, changelist_url)
+ assert Blag.objects.get(id=blag.id).photoblagentry_set.count() == 1
+ assert PhotoBlagEntry.objects.all().count() == 1
+ assert PhotoBlagEntry.objects.get().title == 'my new title'
def test_delete(self):
blag = Blag.objects.create(name="blagonet")
@@ -502,12 +488,11 @@ def test_delete(self):
# B has no permissions
client = self.get_client('has_b')
response = client.post(change_url, data)
- self.assertEqual(response.status_code, 403)
+ assert response.status_code == 403
# A successfully deletes the entry
client = self.get_client('has_a')
response = client.post(change_url, data)
- self.assertRedirects(response, changelist_url)
- self.assertEqual(
- Blag.objects.get(id=blag.id).photoblagentry_set.count(), 0)
- self.assertEqual(PhotoBlagEntry.objects.all().count(), 0)
+ assertRedirects(response, changelist_url)
+ assert Blag.objects.get(id=blag.id).photoblagentry_set.count() == 0
+ assert PhotoBlagEntry.objects.all().count() == 0
diff --git a/baya/tests/test_mock_ldap_helpers.py b/baya/tests/test_mock_ldap_helpers.py
index 0dc7f63..b6450da 100644
--- a/baya/tests/test_mock_ldap_helpers.py
+++ b/baya/tests/test_mock_ldap_helpers.py
@@ -12,28 +12,25 @@ class TestPerson(TestCase):
def test_attrs(self):
name = "bigfoot"
person_attrs = person(name)
- self.assertEqual(person_attrs[0],
- "cn=%s,ou=people,%s" % (name, DEFAULT_DC))
- self.assertEqual(person_attrs[1]['uid'], [name])
- self.assertEqual(person_attrs[1]['cn'], [name])
- self.assertEqual(person_attrs[1]['sn'], [name])
- self.assertEqual(person_attrs[1]['mail'], ["%s@test" % name])
+ assert person_attrs[0] == "cn=%s,ou=people,%s" % (name, DEFAULT_DC)
+ assert person_attrs[1]['uid'] == [name]
+ assert person_attrs[1]['cn'] == [name]
+ assert person_attrs[1]['sn'] == [name]
+ assert person_attrs[1]['mail'] == ["%s@test" % name]
def test_password(self):
name = "yeti"
person_attrs = person(name)
- self.assertEqual(person_attrs[1]['userPassword'], ['password'])
+ assert person_attrs[1]['userPassword'] == ['password']
person_attrs = person(name, password='snowstorm')
- self.assertEqual(person_attrs[1]['userPassword'], ['snowstorm'])
+ assert person_attrs[1]['userPassword'] == ['snowstorm']
def test_email(self):
name = "sasquatch"
dc = "dc=test,dc=example,dc=com"
person_attrs = person(name, dc=dc)
- self.assertEqual(person_attrs[0],
- "cn=%s,ou=people,%s" % (name, dc))
- self.assertEqual(person_attrs[1]['mail'],
- ["%s@test.example.com" % name])
+ assert person_attrs[0] == "cn=%s,ou=people,%s" % (name, dc)
+ assert person_attrs[1]['mail'] == ["%s@test.example.com" % name]
class TestGroup(TestCase):
@@ -41,7 +38,7 @@ def test_attrs(self):
member = person('bigfoot')
name = "north-american-great-apes"
group_attrs = group(name, member)
- self.assertEqual(group_attrs[1]['cn'], [name])
+ assert group_attrs[1]['cn'] == [name]
class TestMockLdapDirectory(TestCase):
@@ -60,68 +57,65 @@ def test_child_group_no_user(self):
],
ldap_dc="",
)
- self.assertEqual(len(directory), 12)
- self.assertIn(group_dn('child_1', ""), directory)
- self.assertEqual(directory[group_dn('child_1', '')]['memberOf'],
- [group_dn('child_1_1', '')])
- self.assertEqual(directory[group_dn('child_1', "")]['member'],
- [group_dn('the_parent', '')])
- self.assertIn(group_dn('child_2', ""), directory)
- self.assertEqual(
- directory[group_dn('child_2', '')]['memberOf'],
- [group_dn('child_2_1', ''), group_dn('child_2_2', '')])
- self.assertEqual(directory[group_dn('child_2', "")]['member'],
- [group_dn('the_parent', '')])
- self.assertIn(group_dn('child_1_1', ""), directory)
- self.assertEqual(directory[group_dn('child_1_1', "")]['memberOf'], [])
- self.assertEqual(directory[group_dn('child_1_1', "")]['member'],
- [group_dn('child_1', '')])
- self.assertIn(group_dn('child_2_1', ""), directory)
- self.assertEqual(directory[group_dn('child_2_1', "")]['memberOf'], [])
- self.assertEqual(directory[group_dn('child_2_1', "")]['member'],
- [group_dn('child_2', '')])
- self.assertIn(group_dn('child_2_2', ""), directory)
- self.assertEqual(directory[group_dn('child_2_2', "")]['memberOf'], [])
- self.assertEqual(directory[group_dn('child_2_2', "")]['member'],
- [group_dn('child_2', '')])
+ assert len(directory) == 12
+ assert group_dn('child_1', "") in directory
+ assert (directory[group_dn('child_1', '')]['memberOf'] ==
+ [group_dn('child_1_1', '')])
+ assert (directory[group_dn('child_1', "")]['member'] ==
+ [group_dn('the_parent', '')])
+ assert group_dn('child_2', "") in directory
+ assert (directory[group_dn('child_2', '')]['memberOf'] ==
+ [group_dn('child_2_1', ''), group_dn('child_2_2', '')])
+ assert (directory[group_dn('child_2', "")]['member'] ==
+ [group_dn('the_parent', '')])
+ assert group_dn('child_1_1', "") in directory
+ assert directory[group_dn('child_1_1', "")]['memberOf'] == []
+ assert (directory[group_dn('child_1_1', "")]['member'] ==
+ [group_dn('child_1', '')])
+ assert group_dn('child_2_1', "") in directory
+ assert directory[group_dn('child_2_1', "")]['memberOf'] == []
+ assert (directory[group_dn('child_2_1', "")]['member'] ==
+ [group_dn('child_2', '')])
+ assert group_dn('child_2_2', "") in directory
+ assert directory[group_dn('child_2_2', "")]['memberOf'] == []
+ assert (directory[group_dn('child_2_2', "")]['member'] ==
+ [group_dn('child_2', '')])
def test_no_args(self):
directory = mock_ldap_directory()
- self.assertEqual(len(directory), 5)
- self.assertSetEqual(
- set(directory.keys()),
- {
- 'ou=Access,dc=example,dc=com',
- 'dc=example,dc=com',
- 'ou=Service-Accounts,dc=example,dc=com',
- 'cn=auth,ou=people,dc=example,dc=com',
- 'ou=People,dc=example,dc=com'
- })
+ assert len(directory) == 5
+ assert (set(directory.keys()) == {
+ 'ou=Access,dc=example,dc=com',
+ 'dc=example,dc=com',
+ 'ou=Service-Accounts,dc=example,dc=com',
+ 'cn=auth,ou=people,dc=example,dc=com',
+ 'ou=People,dc=example,dc=com'
+ })
def test_bind_user(self):
directory = mock_ldap_directory(ldap_dc="")
dn = person_dn('auth', "")
- self.assertIn(dn, directory)
- self.assertEqual(directory[dn]['userPassword'], ['password'])
+ assert dn in directory
+ assert directory[dn]['userPassword'] == ['password']
def test_bind_password(self):
directory = mock_ldap_directory(
bind_user='ned', default_password='mancy', ldap_dc="")
dn = person_dn('ned', "")
- self.assertEqual(directory[dn]['userPassword'], ['password'])
+ assert directory[dn]['userPassword'] == ['password']
directory = mock_ldap_directory(
bind_user='ned', bind_password='flanders',
default_password='mancy', ldap_dc="")
- self.assertEqual(directory[dn]['userPassword'], ['flanders'])
+ assert directory[dn]['userPassword'] == ['flanders']
def test_default_password(self):
dn = person_dn('somebody', "")
directory = mock_ldap_directory(
ldap_dc="",
extra_users=[('somebody', 'agroup')])
- self.assertEqual(directory[dn]['userPassword'], ['password'])
+ assert directory[dn]['userPassword'] == ['password']
directory = mock_ldap_directory(
ldap_dc="",
extra_users=[('somebody', 'agroup')],
default_password='swordfish')
- self.assertEqual(directory[dn]['userPassword'], ['swordfish'])
+ assert directory[dn]['userPassword'] == ['swordfish']
diff --git a/baya/tests/test_nodes.py b/baya/tests/test_nodes.py
index 0e09900..3d1faea 100644
--- a/baya/tests/test_nodes.py
+++ b/baya/tests/test_nodes.py
@@ -1,8 +1,9 @@
-from mock import Mock
+from unittest.mock import Mock
from operator import and_
from operator import or_
from operator import xor
+import pytest
from unittest import TestCase
from ..membership import AndNode
@@ -15,30 +16,34 @@ def test_equality(self):
a = g('A')
b = g('B')
c = g('C')
- self.assertNotEqual(a, b)
- self.assertEqual(a & b, a & b)
- self.assertNotEqual(a & b, a | b)
- self.assertEqual((a & b) | c, (a & b | c))
- self.assertNotEqual(a & b, a | b)
- self.assertNotEqual(a & b, a & b & c)
+ assert not a == b
+ assert a & b == a & b
+ assert not (a & b == a | b)
+ assert (a & b) | c == (a & b | c)
+ assert not (a & b == a | b)
+ assert not (a & b == a & b & c)
def test_or_raises(self):
"""The or keyword is going to screw people up."""
- with self.assertRaises(TypeError):
+ with pytest.raises(TypeError):
g('A') or g('B')
def test_and_raises(self):
"""The and keyword is going to screw people up."""
- with self.assertRaises(TypeError):
+ with pytest.raises(TypeError):
g('A') and g('B')
def test_coercion(self):
"""Throw a TypeError when trying to combine nodes with non-nodes."""
for op in [and_, or_, xor]:
- self.assertRaises(TypeError, op, g('A'), 'b')
- self.assertRaises(TypeError, op, 'b', g('A'))
- self.assertRaises(TypeError, op, g('A'), 1234)
- self.assertRaises(TypeError, op, 1234, g('A'))
+ with pytest.raises(TypeError):
+ op(g('A'), 'b')
+ with pytest.raises(TypeError):
+ op('b', g('A'))
+ with pytest.raises(TypeError):
+ op(g('A'), 1234)
+ with pytest.raises(TypeError):
+ op(1234, g('A'))
class TestDynamicRolesNode(TestCase):
@@ -47,7 +52,7 @@ def test_get_roles_set(self):
node = dg(roles_callable1)
kwargs = {'a': 123}
node.get_roles_set(**kwargs)
- self.assertTrue(roles_callable1.called_with(**kwargs))
+ assert roles_callable1.called_with(**kwargs)
def test_get_roles_set_multiple_callables(self):
roles_callable1 = Mock(return_value=set())
@@ -55,35 +60,35 @@ def test_get_roles_set_multiple_callables(self):
node = dg(roles_callable1, roles_callable2)
kwargs = {'b': 123}
node.get_roles_set(**kwargs)
- self.assertTrue(roles_callable1.called_with(**kwargs))
- self.assertTrue(roles_callable2.called_with(**kwargs))
+ assert roles_callable1.called_with(**kwargs)
+ assert roles_callable2.called_with(**kwargs)
def test_get_roles_set_or(self):
c1 = lambda: {True}
c2 = lambda: {True}
c3 = lambda: {False}
node = dg(c1, c2, c3)
- self.assertEqual(node.get_roles_set(), {True, False})
+ assert node.get_roles_set() == {True, False}
def test_invalid_callable_return(self):
c1 = lambda x: x
node = dg(c1)
- self.assertRaises(RuntimeError, node.get_roles_set, x='abc')
+ with pytest.raises(RuntimeError):
+ node.get_roles_set(x='abc')
def test_combine_roles(self):
"""Combining roles into a simpler node when AND-ing."""
role1 = dg(lambda x: x)
role2 = dg(lambda y: y)
combined = role1 & role2
- self.assertTrue(isinstance(combined, dg))
- self.assertLess(role1._roles_set, combined._roles_set)
- self.assertLess(role2._roles_set, combined._roles_set)
- self.assertEqual(role1._roles_set | role2._roles_set,
- combined._roles_set)
+ assert isinstance(combined, dg)
+ assert role1._roles_set < combined._roles_set
+ assert role2._roles_set < combined._roles_set
+ assert role1._roles_set | role2._roles_set == combined._roles_set
def test_combine_regular_role(self):
"""Combining with a regular node should just give an AndNode."""
role1 = g('abc')
role2 = dg(lambda y: y)
combined = role1 & role2
- self.assertTrue(isinstance(combined, AndNode))
+ assert isinstance(combined, AndNode)
diff --git a/baya/tests/test_permissions.py b/baya/tests/test_permissions.py
index d66cc98..9a24910 100644
--- a/baya/tests/test_permissions.py
+++ b/baya/tests/test_permissions.py
@@ -1,9 +1,9 @@
import functools
-from mock import patch
-from mock import sentinel
+from unittest.mock import patch
+from unittest.mock import sentinel
from types import FunctionType
+import pytest
-import six
import django
from django.conf import settings
if django.VERSION[:2] < (4, 0):
@@ -32,9 +32,10 @@
B = g('b')
+@pytest.mark.django_db
class TestGate(LDAPGroupAuthTestBase):
- def setUp(self):
- super(TestGate, self).setUp()
+ def setup_method(self):
+ super(TestGate, self).setup_method()
self.has_all = self.login('has_all')
self.request_has_all = self.mock_get_request(self.has_all)
self.has_aaa = self.login('has_aaa')
@@ -45,11 +46,11 @@ def _has_permissions(self, node, roles):
def test_case_insensitive(self):
"""Groups should be case insensitive."""
- self.assertEqual(g('A'), g('a'))
- self.assertTrue(self._has_permissions(g('A'), ['A']))
- self.assertTrue(self._has_permissions(g('A'), ['a']))
- self.assertTrue(self._has_permissions(g('a'), ['A']))
- self.assertTrue(self._has_permissions(g('a'), ['a']))
+ assert g('A') == g('a')
+ assert self._has_permissions(g('A'), ['A'])
+ assert self._has_permissions(g('A'), ['a'])
+ assert self._has_permissions(g('a'), ['A'])
+ assert self._has_permissions(g('a'), ['a'])
def _test_perms(self, gate, has_all_perm, has_aaa_perm, method=None):
if method == 'get':
@@ -58,10 +59,8 @@ def _test_perms(self, gate, has_all_perm, has_aaa_perm, method=None):
perm = 'has_post_permission'
else:
perm = 'has_any_permission'
- self.assertEqual(getattr(gate, perm)(self.request_has_all),
- has_all_perm)
- self.assertEqual(getattr(gate, perm)(self.request_has_aaa),
- has_aaa_perm)
+ assert getattr(gate, perm)(self.request_has_all) == has_all_perm
+ assert getattr(gate, perm)(self.request_has_aaa) == has_aaa_perm
def test_no_permissions(self):
"""If no permissions declared, always allow."""
@@ -149,31 +148,30 @@ def test_all_and_get_and_post_requires(self):
self._test_perms(gate, True, True, 'get')
self._test_perms(gate, True, False, 'post')
self._test_perms(gate, True, True)
- self.assertFalse(gate.get_requires is gate.post_requires)
+ assert gate.get_requires is not gate.post_requires
def test_redirect(self):
g1 = Gate()
- self.assertEqual(g1.login_url, settings.BAYA_LOGIN_URL)
+ assert g1.login_url == settings.BAYA_LOGIN_URL
g2 = Gate(login_url=None)
- self.assertEqual(g2.login_url, settings.BAYA_LOGIN_URL)
+ assert g2.login_url == settings.BAYA_LOGIN_URL
custom_login = "/testlogin/"
g3 = Gate(login_url=custom_login)
- self.assertEqual(g3.login_url, custom_login)
- self.assertEqual(six.text_type((g3 + g2).login_url),
- six.text_type(custom_login))
- self.assertEqual((g2 + g3).login_url, custom_login)
+ assert g3.login_url == custom_login
+ assert str((g3 + g2).login_url) == str(custom_login)
+ assert (g2 + g3).login_url == custom_login
with override_settings(BAYA_LOGIN_URL="/testlogin/"):
g4 = Gate()
- self.assertEqual(g4.login_url, "/testlogin/")
+ assert g4.login_url == "/testlogin/"
with override_settings(BAYA_LOGIN_URL=None):
g5 = Gate()
- self.assertEqual(g5.login_url, "/login/")
+ assert g5.login_url == "/login/"
def test_lazy_login_url(self):
lazy_login_url = reverse_lazy('lazy_login')
gate = Gate(login_url=lazy_login_url)
- self.assertEqual(gate.login_url, lazy_login_url)
- self.assertEqual(str(gate.login_url), '/lazy_login/')
+ assert gate.login_url == lazy_login_url
+ assert str(gate.login_url) == '/lazy_login/'
def test_non_existent_group(self):
"""If you require a non-existent group, then nobody can authorize."""
@@ -183,24 +181,25 @@ def test_non_existent_group(self):
self._test_perms(gate, False, False)
+@pytest.mark.django_db
class TestDeniedReason(LDAPGroupAuthTestBase):
def test_not_logged_in(self):
gate = Gate()
request = self.mock_get_request()
data = gate.get_permissions_required_data(request)
- self.assertEqual(data['requires_groups'], g())
- self.assertEqual(data['requires_groups_str'], "{}")
- self.assertEqual(data['user_groups'], [])
- self.assertEqual(data['user_groups_str'], "{}")
+ assert data['requires_groups'] == g()
+ assert data['requires_groups_str'] == "{}"
+ assert data['user_groups'] == []
+ assert data['user_groups_str'] == "{}"
def test_insufficient_permissions(self):
gate = Gate(AA | A)
request = self.mock_get_request(self.login('has_aaa'))
data = gate.get_permissions_required_data(request)
- self.assertEqual(data['requires_groups'], AA | A)
- self.assertEqual(data['requires_groups_str'], "{aa} | {a}")
- self.assertEqual(data['user_groups'], ['aaa'])
- self.assertEqual(data['user_groups_str'], "{aaa}")
+ assert data['requires_groups'] == AA | A
+ assert data['requires_groups_str'] == "{aa} | {a}"
+ assert data['user_groups'] == ['aaa']
+ assert data['user_groups_str'] == "{aaa}"
class MyListView(ListView):
@@ -220,11 +219,11 @@ class TestRequires(LDAPGroupAuthTestBase):
def test_str(self):
"""If given a string, convert to a PermissionNode."""
req = requires('a')
- self.assertEqual(req.gate.get_requires, A)
+ assert req.gate.get_requires == A
req = requires(['a', 'b'])
- self.assertEqual(req.gate.get_requires, A & B)
+ assert req.gate.get_requires == A & B
req = requires('a, b')
- self.assertEqual(req.gate.get_requires, A & B)
+ assert req.gate.get_requires == A & B
def test_no_denied_not_logged_in(self):
"""A user can access unprotected views when not logged in."""
@@ -240,8 +239,8 @@ def test_no_collision(self):
"""Multiple requires calls in different URLs shouldn't interact."""
call1 = requires(AA)(undecorated_view)
call2 = requires(B)(undecorated_view)
- self.assertFalse(hasattr(undecorated_view, '_gate'))
- self.assertNotEqual(call1._gate, call2._gate)
+ assert not hasattr(undecorated_view, '_gate')
+ assert not call1._gate == call2._gate
self.assert_no_permission(self.login('has_aaa'), call1)
self.assert_no_permission(self.login('has_b'), call1)
@@ -256,10 +255,10 @@ def test_no_collision(self):
def test_url_wrapping_syntax(self):
"""Test the syntax for decorating a url pattern."""
decorated = requires(get=AA, post=g('nobody'))(undecorated_view)
- self.assertTrue(hasattr(decorated, '_gate'))
- self.assertTrue(isinstance(decorated._gate, Gate))
- self.assertEqual(type(decorated), FunctionType)
- self.assertEqual(decorated._gate.get_requires, AA)
+ assert hasattr(decorated, '_gate')
+ assert isinstance(decorated._gate, Gate)
+ assert type(decorated) == FunctionType
+ assert decorated._gate.get_requires == AA
self.assert_has_get_permission(self.login('has_aa'), decorated)
self.assert_has_get_permission(self.login('has_all'), decorated)
self.assert_no_get_permission(self.login('has_aaa'), decorated)
@@ -269,9 +268,9 @@ def test_url_wrapping_syntax(self):
def test_method_view_has_gate(self):
"""Test decorating a regular method view."""
- self.assertTrue(hasattr(my_view, '_gate'))
- self.assertTrue(isinstance(my_view._gate, Gate))
- self.assertEqual(type(my_view), FunctionType)
+ assert hasattr(my_view, '_gate')
+ assert isinstance(my_view._gate, Gate)
+ assert type(my_view) == FunctionType
exclude = requires(g('nobody'))(my_view)
self.assert_has_get_permission(self.login('has_all'), my_view)
self.assert_no_get_permission(self.login('has_all'), exclude)
@@ -290,16 +289,17 @@ def test_method_view_has_gate(self):
def test_class_view_fails(self):
"""Test decorating a CBV."""
- self.assertRaises(TypeError, requires(A), MyListView)
+ with pytest.raises(TypeError):
+ requires(A)(MyListView)
def test_class_view_as_view_method(self):
"""Ensure that the as_view() method can be decorated."""
view = MyListView.as_view()
decorated1 = requires(g('one'))(view)
decorated2 = requires(g('two'))(view)
- self.assertFalse(decorated1 is view)
- self.assertTrue(hasattr(decorated1, '_gate'))
- self.assertNotEqual(decorated1._gate, decorated2._gate)
+ assert decorated1 is not view
+ assert hasattr(decorated1, '_gate')
+ assert not decorated1._gate == decorated2._gate
def test_functools_partial(self):
"""Test that a functools.partial is able to be decorated."""
@@ -311,14 +311,14 @@ def pseudoview(request, foo):
decorated1 = requires(g('one'))(view)
decorated2 = requires(g('two'))(view)
- self.assertFalse(decorated1 is view)
- self.assertTrue(hasattr(decorated1, '_gate'))
- self.assertNotEqual(decorated1._gate, decorated2._gate)
+ assert decorated1 is not view
+ assert hasattr(decorated1, '_gate')
+ assert not decorated1._gate == decorated2._gate
def test_multiple(self):
# B is anded with the others
decorated1 = requires(B, get=AAA, post=AA)(undecorated_view)
- self.assertEqual(decorated1._gate.post_requires, B & AA)
+ assert decorated1._gate.post_requires == B & AA
self.assert_no_get_permission(self.login('has_b'), decorated1)
self.assert_no_post_permission(self.login('has_b'), decorated1)
self.assert_no_get_permission(self.login('has_aaa'), decorated1)
@@ -328,18 +328,18 @@ def test_multiple(self):
decorated2 = requires(get=(AAA | B), post=(AA | B))(
undecorated_view)
- self.assertEqual(decorated2._gate.get_requires, AAA | B)
- self.assertEqual(decorated2._gate.post_requires, AA | B)
+ assert decorated2._gate.get_requires == AAA | B
+ assert decorated2._gate.post_requires == AA | B
decorated2 = requires(A, get=(AAA | B), post=(AA | B))(
undecorated_view)
- self.assertEqual(decorated2._gate.get_requires, A & (AAA | B))
- self.assertEqual(decorated2._gate.post_requires, A & (AA | B))
+ assert decorated2._gate.get_requires == A & (AAA | B)
+ assert decorated2._gate.post_requires == A & (AA | B)
def test_chaining(self):
decorated1 = requires(A)(undecorated_view)
decorated2 = requires(B)(decorated1)
- self.assertNotEqual(decorated1._gate, decorated2._gate)
+ assert not decorated1._gate == decorated2._gate
self.assert_has_permission(self.login('has_a'), decorated1)
self.assert_no_permission(self.login('has_a'), decorated2)
# B doesn't have access to either, because decorated1 still requires A
@@ -352,38 +352,32 @@ def test_chain_user_has_permission(self):
decorated1 = requires(A)(undecorated_view)
decorated2 = requires(B)(decorated1)
for perm in ['get', 'post', 'any']:
- self.assertTrue(
- has_permission(decorated1, self.login('has_a'), perm))
- self.assertFalse(
- has_permission(decorated2, self.login('has_a'), perm))
- self.assertFalse(
- has_permission(decorated1, self.login('has_b'), perm))
- self.assertFalse(
- has_permission(decorated2, self.login('has_b'), perm))
- self.assertTrue(
- has_permission(decorated1, self.login('has_a_b'), perm))
- self.assertTrue(
- has_permission(decorated2, self.login('has_a_b'), perm))
+ assert has_permission(decorated1, self.login('has_a'), perm)
+ assert not has_permission(decorated2, self.login('has_a'), perm)
+ assert not has_permission(decorated1, self.login('has_b'), perm)
+ assert not has_permission(decorated2, self.login('has_b'), perm)
+ assert has_permission(decorated1, self.login('has_a_b'), perm)
+ assert has_permission(decorated2, self.login('has_a_b'), perm)
def test_redirect(self):
url = "url"
decorated = requires(B, get=AAA, post=AA)(undecorated_view)
- self.assertEqual(decorated._gate.login_url, settings.LOGIN_URL)
+ assert decorated._gate.login_url == settings.LOGIN_URL
decorated = requires(B, login_url=url, get=AAA, post=AA)(
undecorated_view)
- self.assertEqual(decorated._gate.login_url, url)
+ assert decorated._gate.login_url == url
with patch('django.contrib.auth.views.redirect_to_login',
return_value=sentinel) as do_redirect:
request = self.mock_get_request()
redirect = decorated(request)
do_redirect.assert_called_once_with(request.get_full_path(), url)
- self.assertIs(redirect, sentinel)
+ assert redirect is sentinel
def test_str_view_path(self):
"""Test decorating a string path to a view throws an exception."""
- self.assertRaises(
- TypeError, requires(A), 'baya.tests.views.my_view')
+ with pytest.raises(TypeError):
+ requires(A)('baya.tests.views.my_view')
def test_include(self):
"""Make sure requires(A)(include(my_app.urls)) works."""
@@ -392,10 +386,8 @@ def test_include(self):
[cell] = [cell for cell in pattern.resolve.__closure__
if isinstance(cell.cell_contents, requires)]
requirer = cell.cell_contents
- self.assertTrue(
- PermissionChecker(['a']).visit(requirer.gate.get_requires))
- self.assertTrue(
- PermissionChecker(['a']).visit(requirer.gate.post_requires))
+ assert PermissionChecker(['a']).visit(requirer.gate.get_requires)
+ assert PermissionChecker(['a']).visit(requirer.gate.post_requires)
def test_deny_all(self):
def _no_perms(method):
diff --git a/baya/tests/test_templatetags.py b/baya/tests/test_templatetags.py
index ffed95a..7c25970 100644
--- a/baya/tests/test_templatetags.py
+++ b/baya/tests/test_templatetags.py
@@ -1,9 +1,11 @@
+import pytest
from django.template import Context
from django.template import Template
from .test_base import LDAPGroupAuthTestBase
from django.contrib.auth.models import AnonymousUser
+@pytest.mark.django_db
class CanUserPerformActionTagTest(LDAPGroupAuthTestBase):
BASIC_TEMPLATE = Template(
@@ -22,7 +24,7 @@ def test_anonymous_user_has_permission_false(self):
'user': AnonymousUser(),
})
rendered = self.BASIC_TEMPLATE.render(context)
- self.assertIn('False', rendered)
+ assert 'False' in rendered
def test_has_permission_false(self):
context = Context({
@@ -30,7 +32,7 @@ def test_has_permission_false(self):
'user': self.login('has_nothing'),
})
rendered = self.BASIC_TEMPLATE.render(context)
- self.assertIn('False', rendered)
+ assert 'False' == rendered
def test_has_permission_true(self):
context = Context({
@@ -38,4 +40,4 @@ def test_has_permission_true(self):
'user': self.login('has_all'),
})
rendered = self.BASIC_TEMPLATE.render(context)
- self.assertIn('True', rendered)
+ assert 'True' in rendered
diff --git a/baya/tests/test_visitors.py b/baya/tests/test_visitors.py
index 9a5be02..82258a6 100644
--- a/baya/tests/test_visitors.py
+++ b/baya/tests/test_visitors.py
@@ -1,5 +1,5 @@
-from mock import MagicMock
-from unittest import TestCase
+from unittest.mock import MagicMock
+import pytest
from ..dynamic_roles import DjangoRequestGroupFormatter
from ..membership import DynamicRolesNode as dg
@@ -9,8 +9,9 @@
from ..visitors import PermissionChecker
-class TestPermissionChecker(TestCase):
- def setUp(self):
+@pytest.mark.django_db
+class TestPermissionChecker():
+ def setup_method(self):
self.a = g('A')
self.b = g('B')
self.c = g('C')
@@ -32,139 +33,130 @@ def _has_permissions(self, node, roles, **kwargs):
return PermissionChecker(roles).visit(node, **kwargs)
def test_set_membership_single(self):
- self.assertTrue(self._has_permissions(self.a, ['A']))
- self.assertFalse(self._has_permissions(self.a, ['B']))
+ assert self._has_permissions(self.a, ['A'])
+ assert not self._has_permissions(self.a, ['B'])
def test_and(self):
and_node = self.a & self.b
- self.assertTrue(self._has_permissions(and_node, ['A', 'B']))
- self.assertFalse(self._has_permissions(and_node, ['A']))
- self.assertFalse(self._has_permissions(and_node, ['B']))
+ assert self._has_permissions(and_node, ['A', 'B'])
+ assert not self._has_permissions(and_node, ['A'])
+ assert not self._has_permissions(and_node, ['B'])
def test_and_dynamic(self):
"""Ensure the group permissions are using the requested group."""
and_node = self.a & self.s_admin
- self.assertTrue(self._has_permissions(
- and_node, ['A', 'a_admin'], request=self.mock_request('A')))
- self.assertFalse(self._has_permissions(
- and_node, ['A', 'a_admin'], request=self.mock_request('B')))
+ assert self._has_permissions(
+ and_node, ['A', 'a_admin'], request=self.mock_request('A'))
+ assert not self._has_permissions(
+ and_node, ['A', 'a_admin'], request=self.mock_request('B'))
def test_or(self):
or_node = self.a | self.b
- self.assertTrue(self._has_permissions(or_node, ['A', 'B']))
- self.assertTrue(self._has_permissions(or_node, ['A']))
- self.assertTrue(self._has_permissions(or_node, ['B']))
- self.assertTrue(self._has_permissions(or_node, ['A', 'B', 'C']))
+ assert self._has_permissions(or_node, ['A', 'B'])
+ assert self._has_permissions(or_node, ['A'])
+ assert self._has_permissions(or_node, ['B'])
+ assert self._has_permissions(or_node, ['A', 'B', 'C'])
def test_xor(self):
xor_node = self.a ^ self.b
- self.assertFalse(self._has_permissions(xor_node, ['A', 'B']))
- self.assertTrue(self._has_permissions(xor_node, ['A']))
- self.assertTrue(self._has_permissions(xor_node, ['B']))
+ assert not self._has_permissions(xor_node, ['A', 'B'])
+ assert self._has_permissions(xor_node, ['A'])
+ assert self._has_permissions(xor_node, ['B'])
def test_not(self):
not_node = ~self.a
- self.assertFalse(self._has_permissions(not_node, ['A', 'B']))
- self.assertFalse(self._has_permissions(not_node, ['A']))
- self.assertTrue(self._has_permissions(not_node, ['B']))
- self.assertFalse(self._has_permissions(not_node, ['A', 'B', 'C']))
- self.assertTrue(self._has_permissions(not_node, ['B', 'C']))
+ assert not self._has_permissions(not_node, ['A', 'B'])
+ assert not self._has_permissions(not_node, ['A'])
+ assert self._has_permissions(not_node, ['B'])
+ assert not self._has_permissions(not_node, ['A', 'B', 'C'])
+ assert self._has_permissions(not_node, ['B', 'C'])
def test_and_or_and(self):
node = (self.a & self.b) | (self.c & self.s_admin)
req = self.mock_request('a')
- self.assertFalse(self._has_permissions(node, ['A'], request=req))
- self.assertFalse(self._has_permissions(node, ['B'], request=req))
- self.assertFalse(self._has_permissions(node, ['C'], request=req))
- self.assertFalse(
- self._has_permissions(node, ['a_admin'], request=req))
- self.assertTrue(self._has_permissions(node, ['A', 'B'], request=req))
- self.assertTrue(
- self._has_permissions(node, ['a_admin', 'C'], request=req))
- self.assertFalse(self._has_permissions(node, ['A', 'C'], request=req))
- self.assertFalse(
- self._has_permissions(node, ['B', 'a_admin'], request=req))
+ assert not self._has_permissions(node, ['A'], request=req)
+ assert not self._has_permissions(node, ['B'], request=req)
+ assert not self._has_permissions(node, ['C'], request=req)
+ assert not self._has_permissions(node, ['a_admin'], request=req)
+ assert self._has_permissions(node, ['A', 'B'], request=req)
+ assert self._has_permissions(node, ['a_admin', 'C'], request=req)
+ assert not self._has_permissions(node, ['A', 'C'], request=req)
+ assert not self._has_permissions(node, ['B', 'a_admin'], request=req)
def test_and_xor_not_and(self):
"""What a ridiculous membership requirement."""
node = (self.a & self.b) ^ ~(self.c | self.s_admin)
req = self.mock_request('A')
- self.assertTrue(self._has_permissions(node, ['A'], request=req))
- self.assertTrue(self._has_permissions(node, ['B'], request=req))
- self.assertFalse(self._has_permissions(node, ['C'], request=req))
- self.assertFalse(self._has_permissions(node, ['a_admin'], request=req))
- self.assertFalse(self._has_permissions(node, ['A', 'B'], request=req))
- self.assertFalse(
- self._has_permissions(node, ['a_admin', 'C'], request=req))
- self.assertFalse(self._has_permissions(node, ['A', 'C'], request=req))
- self.assertFalse(
- self._has_permissions(node, ['B', 'a_admin'], request=req))
- self.assertTrue(self._has_permissions(
- node, ['A', 'B', 'a_admin'], request=req))
- self.assertTrue(self._has_permissions(
- node, ['A', 'B', 'C'], request=req))
- self.assertTrue(self._has_permissions(
- node, ['A', 'B', 'C', 'a_admin'], request=req))
+ assert self._has_permissions(node, ['A'], request=req)
+ assert self._has_permissions(node, ['B'], request=req)
+ assert not self._has_permissions(node, ['C'], request=req)
+ assert not self._has_permissions(node, ['a_admin'], request=req)
+ assert not self._has_permissions(node, ['A', 'B'], request=req)
+ assert not self._has_permissions(node, ['a_admin', 'C'], request=req)
+ assert not self._has_permissions(node, ['A', 'C'], request=req)
+ assert not self._has_permissions(node, ['B', 'a_admin'], request=req)
+ assert self._has_permissions(node, ['A', 'B', 'a_admin'], request=req)
+ assert self._has_permissions(node, ['A', 'B', 'C'], request=req)
+ assert self._has_permissions(node, ['A', 'B', 'C', 'a_admin'], request=req)
def test_value_node(self):
node1 = ValueNode(True)
node2 = ~ValueNode(False)
- self.assertTrue(self._has_permissions(node1, ['A']))
- self.assertTrue(self._has_permissions(node2, ['A']))
- self.assertTrue(self._has_permissions(node1, ['']))
- self.assertTrue(self._has_permissions(node2, ['']))
- self.assertTrue(self._has_permissions(node1, ['A', 'F']))
- self.assertTrue(self._has_permissions(node2, ['A', 'F']))
+ assert self._has_permissions(node1, ['A'])
+ assert self._has_permissions(node2, ['A'])
+ assert self._has_permissions(node1, [''])
+ assert self._has_permissions(node2, [''])
+ assert self._has_permissions(node1, ['A', 'F'])
+ assert self._has_permissions(node2, ['A', 'F'])
node1 = ValueNode(False)
node2 = ~ValueNode(True)
- self.assertFalse(self._has_permissions(node1, ['A']))
- self.assertFalse(self._has_permissions(node2, ['A']))
- self.assertFalse(self._has_permissions(node1, ['']))
- self.assertFalse(self._has_permissions(node2, ['']))
- self.assertFalse(self._has_permissions(node1, ['A', 'F']))
- self.assertFalse(self._has_permissions(node2, ['A', 'F']))
+ assert not self._has_permissions(node1, ['A'])
+ assert not self._has_permissions(node2, ['A'])
+ assert not self._has_permissions(node1, [''])
+ assert not self._has_permissions(node2, [''])
+ assert not self._has_permissions(node1, ['A', 'F'])
+ assert not self._has_permissions(node2, ['A', 'F'])
def test_member_and_value_node(self):
node = ValueNode(True) | g('A')
- self.assertTrue(self._has_permissions(node, ['A']))
- self.assertTrue(self._has_permissions(node, ['']))
- self.assertTrue(self._has_permissions(node, ['A', 'F']))
+ assert self._has_permissions(node, ['A'])
+ assert self._has_permissions(node, [''])
+ assert self._has_permissions(node, ['A', 'F'])
node = ValueNode(True) & g('A')
- self.assertTrue(self._has_permissions(node, ['A']))
- self.assertFalse(self._has_permissions(node, ['']))
- self.assertTrue(self._has_permissions(node, ['A', 'F']))
+ assert self._has_permissions(node, ['A'])
+ assert not self._has_permissions(node, [''])
+ assert self._has_permissions(node, ['A', 'F'])
node = ValueNode(False) | g('A')
- self.assertTrue(self._has_permissions(node, ['A']))
- self.assertFalse(self._has_permissions(node, ['']))
- self.assertTrue(self._has_permissions(node, ['A', 'F']))
+ assert self._has_permissions(node, ['A'])
+ assert not self._has_permissions(node, [''])
+ assert self._has_permissions(node, ['A', 'F'])
node = ValueNode(False) & g('A')
- self.assertFalse(self._has_permissions(node, ['A']))
- self.assertFalse(self._has_permissions(node, ['']))
- self.assertFalse(self._has_permissions(node, ['A', 'F']))
+ assert not self._has_permissions(node, ['A'])
+ assert not self._has_permissions(node, [''])
+ assert not self._has_permissions(node, ['A', 'F'])
-class TestExpressionWriter(TestCase):
- def setUp(self):
+@pytest.mark.django_db
+class TestExpressionWriter():
+ def setup_method(self):
self.writer = ExpressionWriter()
def test_operator_precedence(self):
node = g('A') ^ g('B') | g('C') ^ g('D')
- self.assertEqual('{a} ^ {b} | {c} ^ {d}', self.writer.visit(node),
- repr(node))
+ assert '{a} ^ {b} | {c} ^ {d}', self.writer.visit(node) == repr(node)
node = ~(g('A') & g('B')) ^ (g('C') | g('D') & g('E'))
- self.assertEqual('~{a, b} ^ ({c} | {d, e})', self.writer.visit(node),
- repr(node))
+ assert '~{a, b} ^ ({c} | {d, e})', self.writer.visit(node) == repr(node)
def test_unary(self):
node = ~~g('A')
- self.assertEqual('~~{a}', self.writer.visit(node), repr(node))
+ assert '~~{a}', self.writer.visit(node) == repr(node)
node = ~(g('A') ^ g('B'))
- self.assertEqual('~({a} ^ {b})', self.writer.visit(node), repr(node))
+ assert '~({a} ^ {b})', self.writer.visit(node) == repr(node)
def test_value_node(self):
node = ~ValueNode(True)
- self.assertEqual('~True', self.writer.visit(node))
+ assert '~True' == self.writer.visit(node)
node = g('A') & ValueNode(False)
- self.assertEqual('{a} & False', self.writer.visit(node))
+ assert '{a} & False' == self.writer.visit(node)
node = ~node
- self.assertEqual('~({a} & False)', self.writer.visit(node))
+ assert '~({a} & False)' == self.writer.visit(node)
diff --git a/baya/utils.py b/baya/utils.py
index 2e48398..a10a361 100644
--- a/baya/utils.py
+++ b/baya/utils.py
@@ -1,4 +1,3 @@
-import six
from ldap.dn import str2dn
from .membership import RolesNode as g
@@ -22,7 +21,7 @@ def user_in_group(user, group, **kwargs):
user_groups = set()
if hasattr(user, 'ldap_user'):
user_groups = group_names(user.ldap_user.group_dns)
- if isinstance(group, six.string_types):
+ if isinstance(group, str):
group = g(group)
return PermissionChecker(user_groups).visit(group, **kwargs)
diff --git a/requirements-dev.txt b/requirements-dev.txt
index 63dad64..b1bebc0 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,9 +1,11 @@
-coverage==5.1
-django-nose==1.4.6
+coverage
funcparserlib==0.3.6
-mock==1.0.1
mockldap==0.2.6
-nose==1.3.7
pycodestyle==2.9.1
pyflakes==2.5.0
flake8==5.0.4
+
+pytest==7.0.1
+py==1.11.0
+pytest-cov==3.0.0
+pytest-django==4.5.2
\ No newline at end of file
diff --git a/requirements-setup.txt b/requirements-setup.txt
index b0c2dda..eb1815f 100644
--- a/requirements-setup.txt
+++ b/requirements-setup.txt
@@ -1,6 +1,6 @@
# Requirements needed for the setup make target and the test target
# outside of the individual tox environments.
-
+setuptools<58.0
pluggy==1.0.0
py==1.11.0
tox==3.27.1
diff --git a/setup.py b/setup.py
index 8d93da9..e4e4384 100644
--- a/setup.py
+++ b/setup.py
@@ -40,8 +40,6 @@ def load_version():
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
- "Programming Language :: Python :: 2",
- "Programming Language :: Python :: 2.7",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.5",
"Programming Language :: Python :: 3.6",
diff --git a/tox.ini b/tox.ini
index 4dd6293..3fd4554 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,7 @@
[tox]
install_command = pip install {opts} {packages}
downloadcache = {toxworkdir}/_download/
-envlist = {py37}-django{3.1,3.2},{py38,py39,py310,py311}-django{3.1,3.2,4.0,4.1}
+envlist = {py37}-django{3.1,3.2},{py38,py39,py310,py311}-django{3.1,3.2,4.0,4.1},p312-django{3.2,4.0,4.1}
indexserver =
default = https://pypi.python.org/simple
@@ -9,9 +9,10 @@ indexserver =
[testenv]
setuptools_version = setuptools<58.0
usedevelop = True
+setenv =
+ DJANGO_SETTINGS_MODULE=baya.tests.settings
commands =
- coverage run --omit="*tests*" --source=baya --branch \
- ./baya/tests/manage.py test {posargs:baya}
+ py.test {posargs:baya}
deps =
-r{toxinidir}/requirements-dev.txt
django3.1: Django>=3.1,<3.2
@@ -25,11 +26,18 @@ whitelist_externals = flake8
commands =
flake8 -v baya/
+[testenv:py311-django3.2]
+commands =
+ rm -f .coverage
+ py.test --cov=baya {posargs:baya}
[flake8]
max-line-length = 99
ignore = E731,E402,W504
+[pytest]
+DJANGO_SETTINGS_MODULE = baya.tests.settings
+python_files = tests.py test_*.py *_tests.py
[gh-actions]
python =
@@ -37,4 +45,5 @@ python =
3.8: py38
3.9: py39
3.10: py310
- 3.11: py311
\ No newline at end of file
+ 3.11: py311
+ 3.12: py312
\ No newline at end of file