diff --git a/.gitignore b/.gitignore index 5f1ace6..d5c9d8e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .*.swp *.pyc .ropeproject/ +coverage-report/ +.coverage diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..647e39b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +# This file is here because many Platforms as a Service look for +# requirements.txt in the root directory of a project. +-r requirements/base.txt diff --git a/requirements/base.txt b/requirements/base.txt new file mode 100644 index 0000000..8d8259d --- /dev/null +++ b/requirements/base.txt @@ -0,0 +1,2 @@ +Django>=1.9.1,<2 +django-braces>=1.8.1,<2 diff --git a/requirements/test.txt b/requirements/test.txt new file mode 100644 index 0000000..67a8663 --- /dev/null +++ b/requirements/test.txt @@ -0,0 +1,4 @@ +# Test dependencies go here. +-r base.txt +coverage==4.0.3 +mock==1.3.0 diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..f52b83e --- /dev/null +++ b/setup.cfg @@ -0,0 +1,16 @@ +[pep8] +exclude = migrations + +[flake8] +exclude = migrations,.ropeproject/* + +[coverage:run] +source = . +branch = True + +[coverage:report] +omit = tests.py +show_missing = True + +[coverage:html] +directory = coverage-report diff --git a/tests.py b/tests.py new file mode 100644 index 0000000..9077d1a --- /dev/null +++ b/tests.py @@ -0,0 +1,145 @@ +""" +Tests for gvacommon code. + +""" +from __future__ import absolute_import, unicode_literals +import unittest + +try: + from unittest.Mock import MagicMock +except ImportError: + from mock import MagicMock + +import django +from django.db import connection +from django.http import HttpResponseForbidden +from django.conf import settings +from django.views.generic import View + +from django.contrib.auth import get_user_model +from celeryrouters import GvaRouter + +if not settings.configured: + settings.configure( + DEBUG=True, + ROOT_URLCONF='tests', + TEMPLATE_DIRS=['.'], + DATABASES={ + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': 'test', + } + }, + INSTALLED_APPS=( + 'django.contrib.contenttypes', + 'django.contrib.auth',), + ) + +urlpatterns = [] + + +class GvaRouteTest(unittest.TestCase): + + def test_route_for_task_ldap(self): + router = GvaRouter() + route = router.route_for_task('ldap') + self.assertEqual( + route, + {'exchange': 'ldap', 'exchange_type': 'direct', 'queue': 'ldap'}) + + def test_route_for_task_file(self): + router = GvaRouter() + route = router.route_for_task('file') + self.assertEqual( + route, + {'exchange': 'file', 'exchange_type': 'direct', 'queue': 'file'}) + + def test_route_for_task_mysql(self): + router = GvaRouter() + route = router.route_for_task('mysql') + self.assertEqual( + route, + {'exchange': 'mysql', 'exchange_type': 'direct', 'queue': 'mysql'}) + + def test_route_for_task_pgsql(self): + router = GvaRouter() + route = router.route_for_task('pgsql') + self.assertEqual( + route, + {'exchange': 'pgsql', 'exchange_type': 'direct', 'queue': 'pgsql'}) + + def test_route_for_task_web(self): + router = GvaRouter() + route = router.route_for_task('web') + self.assertEqual( + route, + {'exchange': 'web', 'exchange_type': 'direct', 'queue': 'web'}) + + def test_route_for_task_other(self): + router = GvaRouter() + route = router.route_for_task('unknown') + self.assertIsNone(route) + + +class StaffOrSelfLoginRequiredMixinTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + User = get_user_model() + User.objects.create_superuser( + username='admin', password='admin', email='test@example.org') + User.objects.create_user(username='test') + + def setUp(self): + from viewmixins import StaffOrSelfLoginRequiredMixin + + class SubjectView(StaffOrSelfLoginRequiredMixin, View): + + def get(self, request, *args, **kwargs): + return "success" + + def get_customer_object(self): + return get_user_model().objects.get(username='test') + + self.subject = SubjectView.as_view() + + def test_dispatch_anonymous(self): + from django.contrib.auth.models import AnonymousUser + request = MagicMock(method='GET') + request.user = AnonymousUser() + result = self.subject(request) + self.assertIsInstance(result, HttpResponseForbidden) + + def test_dispatch_staff_user(self): + request = MagicMock(method='GET') + request.user = get_user_model().objects.get(username='admin') + result = self.subject(request) + self.assertEqual(result, "success") + + def test_dispatch_customer_user(self): + request = MagicMock(method='GET') + request.user = get_user_model().objects.get(username='test') + result = self.subject(request) + self.assertEqual(result, "success") + + def test_dispatch_other_user(self): + request = MagicMock(method='GET') + request.user = get_user_model().objects.create_user('other') + result = self.subject(request) + self.assertIsInstance(result, HttpResponseForbidden) + + def test_get_customer_object_not_implemented(self): + from viewmixins import StaffOrSelfLoginRequiredMixin + + class IncompleteView(StaffOrSelfLoginRequiredMixin, View): + pass + + view = IncompleteView() + with self.assertRaises(NotImplementedError): + view.get_customer_object() + + +if __name__ == '__main__': + django.setup() + connection.creation.create_test_db() + unittest.main() + connection.creation.destroy_test_db() diff --git a/viewmixins.py b/viewmixins.py index fc7f106..89c36b8 100644 --- a/viewmixins.py +++ b/viewmixins.py @@ -39,4 +39,5 @@ class StaffOrSelfLoginRequiredMixin(LoginRequiredMixin): :rtype: settings.AUTH_USER_MODEL """ - raise NotImplemented("subclass has to implement get_customer_object") + raise NotImplementedError( + "subclass has to implement get_customer_object")