diff --git a/mayan/apps/acls/tests/mixins.py b/mayan/apps/acls/tests/mixins.py new file mode 100644 index 0000000000..8eac0d80d6 --- /dev/null +++ b/mayan/apps/acls/tests/mixins.py @@ -0,0 +1,37 @@ +from __future__ import unicode_literals + +from django.contrib.auth import get_user_model +from django.contrib.auth.models import Group + +from acls.models import AccessControlList +from permissions.models import Role +from permissions.tests.literals import TEST_ROLE_LABEL +from permissions.tests.mixins import RoleTestCaseMixin +from user_management.tests.literals import ( + TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME, TEST_ADMIN_EMAIL, + TEST_GROUP_NAME, TEST_USER_EMAIL, TEST_USER_USERNAME, TEST_USER_PASSWORD +) + + +class ACLTestCaseMixin(RoleTestCaseMixin): + def setUp(self): + super(ACLTestCaseMixin, self).setUp() + self.admin_user = get_user_model().objects.create_superuser( + username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL, + password=TEST_ADMIN_PASSWORD + ) + + self.user = get_user_model().objects.create_user( + username=TEST_USER_USERNAME, email=TEST_USER_EMAIL, + password=TEST_USER_PASSWORD + ) + + self.group = Group.objects.create(name=TEST_GROUP_NAME) + self.role = Role.objects.create(label=TEST_ROLE_LABEL) + self.group.user_set.add(self.user) + self.role.groups.add(self.group) + + def grant_access(self, permission, obj): + AccessControlList.objects.grant( + permission=permission, role=self.role, obj=obj + ) diff --git a/mayan/apps/acls/tests/test_api.py b/mayan/apps/acls/tests/test_api.py index 359530fcf0..9e086277dd 100644 --- a/mayan/apps/acls/tests/test_api.py +++ b/mayan/apps/acls/tests/test_api.py @@ -53,6 +53,7 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase): ) def test_object_acl_delete_view(self): + self.expected_content_type = None self._create_acl() response = self.delete( @@ -87,6 +88,7 @@ class ACLAPITestCase(DocumentTestMixin, BaseAPITestCase): ) def test_object_acl_permission_delete_view(self): + self.expected_content_type = None self._create_acl() permission = self.acl.permissions.first() diff --git a/mayan/apps/checkouts/tests/test_models.py b/mayan/apps/checkouts/tests/test_models.py index 071709d167..f3c08675f2 100644 --- a/mayan/apps/checkouts/tests/test_models.py +++ b/mayan/apps/checkouts/tests/test_models.py @@ -35,21 +35,6 @@ class DocumentCheckoutTestCase(DocumentTestMixin, BaseTestCase): ) ) - def test_version_creation_blocking(self): - # Silence unrelated logging - logging.getLogger('documents.models').setLevel(logging.CRITICAL) - - expiration_datetime = now() + datetime.timedelta(days=1) - - DocumentCheckout.objects.checkout_document( - document=self.document, expiration_datetime=expiration_datetime, - user=self.admin_user, block_new_version=True - ) - - with self.assertRaises(NewDocumentVersionNotAllowed): - with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object: - self.document.new_version(file_object=file_object) - def test_checkin_in(self): expiration_datetime = now() + datetime.timedelta(days=1) @@ -100,16 +85,6 @@ class DocumentCheckoutTestCase(DocumentTestMixin, BaseTestCase): self.assertFalse(self.document.is_checked_out()) - def test_blocking_new_versions(self): - # Silence unrelated logging - logging.getLogger('documents.models').setLevel(logging.CRITICAL) - - NewVersionBlock.objects.block(document=self.document) - - with self.assertRaises(NewDocumentVersionNotAllowed): - with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object: - self.document.new_version(file_object=file_object) - @override_settings(OCR_AUTO_OCR=False) class NewVersionBlockTestCase(DocumentTestMixin, BaseTestCase): @@ -121,6 +96,16 @@ class NewVersionBlockTestCase(DocumentTestMixin, BaseTestCase): NewVersionBlock.objects.first().document, self.document ) + def test_blocking_new_versions(self): + # Silence unrelated logging + logging.getLogger('documents.models').setLevel(logging.CRITICAL) + + NewVersionBlock.objects.block(document=self.document) + + with self.assertRaises(NewDocumentVersionNotAllowed): + with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object: + self.document.new_version(file_object=file_object) + def test_unblocking(self): NewVersionBlock.objects.create(document=self.document) @@ -140,3 +125,18 @@ class NewVersionBlockTestCase(DocumentTestMixin, BaseTestCase): self.assertFalse( NewVersionBlock.objects.is_blocked(document=self.document) ) + + def test_version_creation_blocking(self): + # Silence unrelated logging + logging.getLogger('documents.models').setLevel(logging.CRITICAL) + + expiration_datetime = now() + datetime.timedelta(days=1) + + DocumentCheckout.objects.checkout_document( + document=self.document, expiration_datetime=expiration_datetime, + user=self.admin_user, block_new_version=True + ) + + with self.assertRaises(NewDocumentVersionNotAllowed): + with open(TEST_SMALL_DOCUMENT_PATH, mode='rb') as file_object: + self.document.new_version(file_object=file_object) diff --git a/mayan/apps/checkouts/tests/test_views.py b/mayan/apps/checkouts/tests/test_views.py index b1eb783da3..8f6b74b843 100644 --- a/mayan/apps/checkouts/tests/test_views.py +++ b/mayan/apps/checkouts/tests/test_views.py @@ -8,7 +8,7 @@ from django.utils.timezone import now from common.literals import TIME_DELTA_UNIT_DAYS from documents.tests import GenericDocumentViewTestCase from sources.links import link_upload_version -from user_management.tests import ( +from user_management.tests.literals import ( TEST_USER_PASSWORD, TEST_USER_USERNAME, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME, ) diff --git a/mayan/apps/common/tests/base.py b/mayan/apps/common/tests/base.py index cf67bf5ec7..91a2b611b9 100644 --- a/mayan/apps/common/tests/base.py +++ b/mayan/apps/common/tests/base.py @@ -1,30 +1,23 @@ from __future__ import absolute_import, unicode_literals -from django.conf.urls import url -from django.contrib.auth import get_user_model -from django.http import HttpResponse -from django.template import Context, Template from django.test import TestCase -from django.test.utils import ContextList -from django.urls import clear_url_caches, reverse from django_downloadview import assert_download_response +from acls.tests.mixins import ACLTestCaseMixin from permissions.classes import Permission from smart_settings.classes import Namespace -from user_management.tests import ( - TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME, TEST_USER_USERNAME, - TEST_USER_PASSWORD -) +from user_management.tests.mixins import UserTestCaseMixin -from .literals import TEST_VIEW_NAME, TEST_VIEW_URL from .mixins import ( - ContentTypeCheckMixin, DatabaseConversionMixin, OpenFileCheckMixin, - TempfileCheckMixin, UserMixin + ClientMethodsTestCaseMixin, ContentTypeCheckTestCaseMixin, + DatabaseConversionMixin, OpenFileCheckTestCaseMixin, + RandomPrimaryKeyModelMonkeyPatchMixin, TempfileCheckTestCasekMixin, + TestViewTestCaseMixin ) -class BaseTestCase(DatabaseConversionMixin, UserMixin, ContentTypeCheckMixin, OpenFileCheckMixin, TempfileCheckMixin, TestCase): +class BaseTestCase(RandomPrimaryKeyModelMonkeyPatchMixin, DatabaseConversionMixin, ACLTestCaseMixin, OpenFileCheckTestCaseMixin, TempfileCheckTestCasekMixin, TestCase): """ This is the most basic test case class any test in the project should use. """ @@ -36,81 +29,9 @@ class BaseTestCase(DatabaseConversionMixin, UserMixin, ContentTypeCheckMixin, Op Permission.invalidate_cache() -class GenericViewTestCase(BaseTestCase): - def setUp(self): - super(GenericViewTestCase, self).setUp() - self.has_test_view = False - - def tearDown(self): - from mayan.urls import urlpatterns - - self.client.logout() - if self.has_test_view: - urlpatterns.pop(0) - super(GenericViewTestCase, self).tearDown() - - def add_test_view(self, test_object): - from mayan.urls import urlpatterns - - def test_view(request): - template = Template('{{ object }}') - context = Context( - {'object': test_object, 'resolved_object': test_object} - ) - return HttpResponse(template.render(context=context)) - - urlpatterns.insert(0, url(TEST_VIEW_URL, test_view, name=TEST_VIEW_NAME)) - clear_url_caches() - self.has_test_view = True - - def get_test_view(self): - response = self.get(TEST_VIEW_NAME) - if isinstance(response.context, ContextList): - # template widget rendering causes test client response to be - # ContextList rather than RequestContext. Typecast to dictionary - # before updating. - result = dict(response.context).copy() - result.update({'request': response.wsgi_request}) - return Context(result) - else: - response.context.update({'request': response.wsgi_request}) - return Context(response.context) - - def get(self, viewname=None, path=None, *args, **kwargs): - data = kwargs.pop('data', {}) - follow = kwargs.pop('follow', False) - - if viewname: - path = reverse(viewname=viewname, *args, **kwargs) - - return self.client.get( - path=path, data=data, follow=follow - ) - - def login(self, username, password): - logged_in = self.client.login(username=username, password=password) - - user = get_user_model().objects.get(username=username) - - self.assertTrue(logged_in) - self.assertTrue(user.is_authenticated) - - def login_user(self): - self.login(username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD) - - def login_admin_user(self): - self.login(username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD) - - def logout(self): - self.client.logout() - - def post(self, viewname=None, path=None, *args, **kwargs): - data = kwargs.pop('data', {}) - follow = kwargs.pop('follow', False) - - if viewname: - path = reverse(viewname=viewname, *args, **kwargs) - - return self.client.post( - path=path, data=data, follow=follow - ) +class GenericViewTestCase(ClientMethodsTestCaseMixin, ContentTypeCheckTestCaseMixin, TestViewTestCaseMixin, UserTestCaseMixin, BaseTestCase): + """ + A generic view test case built on top of the base test case providing + a single, user customizable view to test object resolution and shorthand + HTTP method functions. + """ diff --git a/mayan/apps/common/tests/mixins.py b/mayan/apps/common/tests/mixins.py index 85006a73bc..5838ba6fb2 100644 --- a/mayan/apps/common/tests/mixins.py +++ b/mayan/apps/common/tests/mixins.py @@ -2,19 +2,21 @@ from __future__ import unicode_literals import glob import os +import random + +from furl import furl from django.conf import settings -from django.contrib.auth import get_user_model -from django.contrib.auth.models import Group +from django.conf.urls import url from django.core import management +from django.db import models +from django.db.models.signals import post_save, pre_save +from django.http import HttpResponse +from django.template import Context, Template +from django.test.utils import ContextList +from django.urls import clear_url_caches, reverse -from acls.models import AccessControlList -from permissions.models import Role -from permissions.tests.literals import TEST_ROLE_LABEL -from user_management.tests import ( - TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME, TEST_ADMIN_EMAIL, - TEST_GROUP_NAME, TEST_USER_EMAIL, TEST_USER_USERNAME, TEST_USER_PASSWORD -) +from .literals import TEST_VIEW_NAME, TEST_VIEW_URL from ..settings import setting_temporary_directory @@ -22,24 +24,75 @@ if getattr(settings, 'COMMON_TEST_FILE_HANDLES', False): import psutil -class ContentTypeCheckMixin(object): +class ClientMethodsTestCaseMixin(object): + def _build_verb_kwargs(self, viewname=None, path=None, *args, **kwargs): + data = kwargs.pop('data', {}) + follow = kwargs.pop('follow', False) + query = kwargs.pop('query', {}) + + if viewname: + path = reverse(viewname=viewname, *args, **kwargs) + + path = furl(url=path) + path.args.update(query) + + return {'follow': follow, 'data': data, 'path': path.tostr()} + + def delete(self, viewname=None, path=None, *args, **kwargs): + return self.client.delete( + **self._build_verb_kwargs( + path=path, viewname=viewname, *args, **kwargs + ) + ) + + def get(self, viewname=None, path=None, *args, **kwargs): + return self.client.get( + **self._build_verb_kwargs( + path=path, viewname=viewname, *args, **kwargs + ) + ) + + def patch(self, viewname=None, path=None, *args, **kwargs): + return self.client.patch( + **self._build_verb_kwargs( + path=path, viewname=viewname, *args, **kwargs + ) + ) + + def post(self, viewname=None, path=None, *args, **kwargs): + return self.client.post( + **self._build_verb_kwargs( + path=path, viewname=viewname, *args, **kwargs + ) + ) + + def put(self, viewname=None, path=None, *args, **kwargs): + return self.client.put( + **self._build_verb_kwargs( + path=path, viewname=viewname, *args, **kwargs + ) + ) + + +class ContentTypeCheckTestCaseMixin(object): expected_content_type = 'text/html; charset=utf-8' def _pre_setup(self): - super(ContentTypeCheckMixin, self)._pre_setup() + super(ContentTypeCheckTestCaseMixin, self)._pre_setup() test_instance = self class CustomClient(self.client_class): def request(self, *args, **kwargs): response = super(CustomClient, self).request(*args, **kwargs) - content_type = response._headers['content-type'][1] - test_instance.assertEqual( - content_type, test_instance.expected_content_type, - msg='Unexpected response content type: {}, expected: {}.'.format( - content_type, test_instance.expected_content_type + content_type = response._headers.get('content-type', [None, ''])[1] + if test_instance.expected_content_type: + test_instance.assertEqual( + content_type, test_instance.expected_content_type, + msg='Unexpected response content type: {}, expected: {}.'.format( + content_type, test_instance.expected_content_type + ) ) - ) return response @@ -53,7 +106,7 @@ class DatabaseConversionMixin(object): ) -class OpenFileCheckMixin(object): +class OpenFileCheckTestCaseMixin(object): def _get_descriptor_count(self): process = psutil.Process() return process.num_fds() @@ -63,7 +116,7 @@ class OpenFileCheckMixin(object): return process.open_files() def setUp(self): - super(OpenFileCheckMixin, self).setUp() + super(OpenFileCheckTestCaseMixin, self).setUp() if getattr(settings, 'COMMON_TEST_FILE_HANDLES', False): self._open_files = self._get_open_files() @@ -78,10 +131,84 @@ class OpenFileCheckMixin(object): self._skip_file_descriptor_test = False - super(OpenFileCheckMixin, self).tearDown() + super(OpenFileCheckTestCaseMixin, self).tearDown() -class TempfileCheckMixin(object): +class RandomPrimaryKeyModelMonkeyPatchMixin(object): + random_primary_key_random_floor = 100 + random_primary_key_random_ceiling = 10000 + random_primary_key_maximum_attempts = 100 + + @staticmethod + def get_unique_primary_key(model): + pk_list = model._meta.default_manager.values_list('pk', flat=True) + + attempts = 0 + while True: + primary_key = random.randint( + RandomPrimaryKeyModelMonkeyPatchMixin.random_primary_key_random_floor, + RandomPrimaryKeyModelMonkeyPatchMixin.random_primary_key_random_ceiling + ) + + if primary_key not in pk_list: + break + + attempts = attempts + 1 + + if attempts > RandomPrimaryKeyModelMonkeyPatchMixin.random_primary_key_maximum_attempts: + raise Exception( + 'Maximum number of retries for an unique random primary ' + 'key reached.' + ) + + return primary_key + + def setUp(self): + self.method_save_original = models.Model.save + + def method_save_new(instance, *args, **kwargs): + if instance.pk: + return self.method_save_original(instance, *args, **kwargs) + else: + # Set meta.auto_created to True to have the original save_base + # not send the pre_save signal which would normally send + # the instance without a primary key. Since we assign a random + # primary key any pre_save signal handler that relies on an + # empty primary key will fail. + # The meta.auto_created and manual pre_save sending emulates + # the original behavior. Since meta.auto_created also disables + # the post_save signal we must also send it ourselves. + # This hack work with Django 1.11 .save_base() but can break + # in future versions if that method is updated. + pre_save.send( + sender=instance.__class__, instance=instance, raw=False, + update_fields=None, + ) + instance._meta.auto_created = True + instance.pk = RandomPrimaryKeyModelMonkeyPatchMixin.get_unique_primary_key( + model=instance._meta.model + ) + instance.id = instance.pk + + result = instance.save_base(force_insert=True) + instance._meta.auto_created = False + + post_save.send( + sender=instance.__class__, instance=instance, created=True, + update_fields=None, raw=False + ) + + return result + + setattr(models.Model, 'save', method_save_new) + super(RandomPrimaryKeyModelMonkeyPatchMixin, self).setUp() + + def tearDown(self): + models.Model.save = self.method_save_original + super(RandomPrimaryKeyModelMonkeyPatchMixin, self).tearDown() + + +class TempfileCheckTestCasekMixin(object): # Ignore the jvmstat instrumentation and GitLab's CI .config files # Ignore LibreOffice fontconfig cache dir ignore_globs = ('hsperfdata_*', '.config', '.cache') @@ -106,7 +233,7 @@ class TempfileCheckMixin(object): ) - set(ignored_result) def setUp(self): - super(TempfileCheckMixin, self).setUp() + super(TempfileCheckTestCasekMixin, self).setUp() if getattr(settings, 'COMMON_TEST_TEMP_FILES', False): self._temporary_items = self._get_temporary_entries() @@ -121,33 +248,43 @@ class TempfileCheckMixin(object): ','.join(final_temporary_items - self._temporary_items) ) ) - super(TempfileCheckMixin, self).tearDown() + super(TempfileCheckTestCasekMixin, self).tearDown() -class UserMixin(object): - def setUp(self): - super(UserMixin, self).setUp() - self.admin_user = get_user_model().objects.create_superuser( - username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL, - password=TEST_ADMIN_PASSWORD - ) +class TestViewTestCaseMixin(object): + has_test_view = False - self.user = get_user_model().objects.create_user( - username=TEST_USER_USERNAME, email=TEST_USER_EMAIL, - password=TEST_USER_PASSWORD - ) + def tearDown(self): + from mayan.urls import urlpatterns - self.group = Group.objects.create(name=TEST_GROUP_NAME) - self.role = Role.objects.create(label=TEST_ROLE_LABEL) - self.group.user_set.add(self.user) - self.role.groups.add(self.group) + self.client.logout() + if self.has_test_view: + urlpatterns.pop(0) + super(TestViewTestCaseMixin, self).tearDown() - def grant_access(self, permission, obj): - AccessControlList.objects.grant( - permission=permission, role=self.role, obj=obj - ) + def add_test_view(self, test_object): + from mayan.urls import urlpatterns - def grant_permission(self, permission): - self.role.permissions.add( - permission.stored_permission - ) + def test_view(request): + template = Template('{{ object }}') + context = Context( + {'object': test_object, 'resolved_object': test_object} + ) + return HttpResponse(template.render(context=context)) + + urlpatterns.insert(0, url(TEST_VIEW_URL, test_view, name=TEST_VIEW_NAME)) + clear_url_caches() + self.has_test_view = True + + def get_test_view(self): + response = self.get(TEST_VIEW_NAME) + if isinstance(response.context, ContextList): + # template widget rendering causes test client response to be + # ContextList rather than RequestContext. Typecast to dictionary + # before updating. + result = dict(response.context).copy() + result.update({'request': response.wsgi_request}) + return Context(result) + else: + response.context.update({'request': response.wsgi_request}) + return Context(response.context) diff --git a/mayan/apps/documents/tests/test_api.py b/mayan/apps/documents/tests/test_api.py index f80e74dac0..ab64ddf6e6 100644 --- a/mayan/apps/documents/tests/test_api.py +++ b/mayan/apps/documents/tests/test_api.py @@ -135,6 +135,7 @@ class DocumentTypeAPITestCase(BaseAPITestCase): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_document_type_delete_with_access(self): + self.expected_content_type = None self.document_type = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_LABEL ) @@ -522,6 +523,8 @@ class TrashedDocumentAPITestCase(DocumentTestMixin, BaseAPITestCase): self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_document_move_to_trash_with_access(self): + self.expected_content_type = None + self.document = self.upload_document() self.grant_access( permission=permission_document_trash, obj=self.document @@ -546,6 +549,8 @@ class TrashedDocumentAPITestCase(DocumentTestMixin, BaseAPITestCase): self.assertEqual(Document.trash.count(), 1) def test_trashed_document_delete_from_trash_with_access(self): + self.expected_content_type = None + self.document = self.upload_document() self.document.delete() self.grant_access(permission=permission_document_delete, obj=self.document) diff --git a/mayan/apps/permissions/tests/mixins.py b/mayan/apps/permissions/tests/mixins.py new file mode 100644 index 0000000000..90ab95e14d --- /dev/null +++ b/mayan/apps/permissions/tests/mixins.py @@ -0,0 +1,8 @@ +from __future__ import unicode_literals + + +class RoleTestCaseMixin(object): + def grant_permission(self, permission): + self.role.permissions.add( + permission.stored_permission + ) diff --git a/mayan/apps/rest_api/tests/base.py b/mayan/apps/rest_api/tests/base.py index 8fbe927250..5db1e4c84f 100644 --- a/mayan/apps/rest_api/tests/base.py +++ b/mayan/apps/rest_api/tests/base.py @@ -1,101 +1,19 @@ from __future__ import absolute_import, unicode_literals -from django.contrib.auth import get_user_model -from django.urls import reverse - from rest_framework.test import APITestCase -from common.tests.mixins import UserMixin +from common.tests import GenericViewTestCase from permissions.classes import Permission from smart_settings.classes import Namespace -from user_management.tests import ( - TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME, TEST_USER_USERNAME, - TEST_USER_PASSWORD -) -class BaseAPITestCase(UserMixin, APITestCase): +class BaseAPITestCase(APITestCase, GenericViewTestCase): """ API test case class that invalidates permissions and smart settings """ + expected_content_type = None + def setUp(self): super(BaseAPITestCase, self).setUp() Namespace.invalidate_cache_all() Permission.invalidate_cache() - - def tearDown(self): - self.client.logout() - super(BaseAPITestCase, self).tearDown() - - def delete(self, viewname=None, path=None, *args, **kwargs): - data = kwargs.pop('data', {}) - follow = kwargs.pop('follow', False) - - if viewname: - path = reverse(viewname=viewname, *args, **kwargs) - - return self.client.delete( - path=path, data=data, follow=follow - ) - - def get(self, viewname=None, path=None, *args, **kwargs): - data = kwargs.pop('data', {}) - follow = kwargs.pop('follow', False) - - if viewname: - path = reverse(viewname=viewname, *args, **kwargs) - - return self.client.get( - path=path, data=data, follow=follow - ) - - def login(self, username, password): - logged_in = self.client.login(username=username, password=password) - - user = get_user_model().objects.get(username=username) - - self.assertTrue(logged_in) - self.assertTrue(user.is_authenticated) - return user.is_authenticated - - def login_user(self): - self.login(username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD) - - def login_admin_user(self): - self.login(username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD) - - def logout(self): - self.client.logout() - - def patch(self, viewname=None, path=None, *args, **kwargs): - data = kwargs.pop('data', {}) - follow = kwargs.pop('follow', False) - - if viewname: - path = reverse(viewname=viewname, *args, **kwargs) - - return self.client.patch( - path=path, data=data, follow=follow - ) - - def post(self, viewname=None, path=None, *args, **kwargs): - data = kwargs.pop('data', {}) - follow = kwargs.pop('follow', False) - - if viewname: - path = reverse(viewname=viewname, *args, **kwargs) - - return self.client.post( - path=path, data=data, follow=follow - ) - - def put(self, viewname=None, path=None, *args, **kwargs): - data = kwargs.pop('data', {}) - follow = kwargs.pop('follow', False) - - if viewname: - path = reverse(viewname=viewname, *args, **kwargs) - - return self.client.put( - path=path, data=data, follow=follow - ) diff --git a/mayan/apps/user_management/tests/__init__.py b/mayan/apps/user_management/tests/__init__.py index 124ec460a6..e69de29bb2 100644 --- a/mayan/apps/user_management/tests/__init__.py +++ b/mayan/apps/user_management/tests/__init__.py @@ -1 +0,0 @@ -from .literals import * # NOQA diff --git a/mayan/apps/user_management/tests/literals.py b/mayan/apps/user_management/tests/literals.py index 17577445a3..740d950127 100644 --- a/mayan/apps/user_management/tests/literals.py +++ b/mayan/apps/user_management/tests/literals.py @@ -1,11 +1,5 @@ from __future__ import unicode_literals -__all__ = ( - 'TEST_ADMIN_EMAIL', 'TEST_ADMIN_PASSWORD', 'TEST_ADMIN_USERNAME', - 'TEST_GROUP_NAME', 'TEST_GROUP_NAME_EDITED', 'TEST_USER_EMAIL', - 'TEST_USER_PASSWORD', 'TEST_USER_PASSWORD_EDITED', 'TEST_USER_USERNAME' -) - TEST_ADMIN_EMAIL = 'admin@example.com' TEST_ADMIN_PASSWORD = 'test admin password' TEST_ADMIN_USERNAME = 'test_admin' diff --git a/mayan/apps/user_management/tests/mixins.py b/mayan/apps/user_management/tests/mixins.py index ed3c0cd77b..068586ba6c 100644 --- a/mayan/apps/user_management/tests/mixins.py +++ b/mayan/apps/user_management/tests/mixins.py @@ -3,7 +3,9 @@ from __future__ import unicode_literals from django.contrib.auth import get_user_model from .literals import ( - TEST_USER_2_EMAIL, TEST_USER_2_PASSWORD, TEST_USER_2_USERNAME + TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME, TEST_USER_PASSWORD, + TEST_USER_USERNAME, TEST_USER_2_EMAIL, TEST_USER_2_PASSWORD, + TEST_USER_2_USERNAME ) @@ -18,3 +20,22 @@ class UserTestMixin(object): self.user_2 = get_user_model().objects.create( username=TEST_USER_2_USERNAME ) + + +class UserTestCaseMixin(object): + def tearDown(self): + self.client.logout() + super(UserTestCaseMixin, self).tearDown() + + def login(self, username, password): + logged_in = self.client.login(username=username, password=password) + return logged_in + + def login_user(self): + self.login(username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD) + + def login_admin_user(self): + self.login(username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD) + + def logout(self): + self.client.logout() diff --git a/mayan/apps/user_management/tests/test_views.py b/mayan/apps/user_management/tests/test_views.py index 5c2487caca..f6b6bd9df8 100644 --- a/mayan/apps/user_management/tests/test_views.py +++ b/mayan/apps/user_management/tests/test_views.py @@ -87,10 +87,11 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase): self.logout() - with self.assertRaises(AssertionError): - self.login( - username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED - ) + result = self.login( + username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED + ) + + self.assertFalse(result) response = self.get('common:current_user_details') @@ -134,10 +135,11 @@ class UserManagementViewTestCase(UserTestMixin, GenericViewTestCase): self.logout() - with self.assertRaises(AssertionError): - self.login( - username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED - ) + result = self.login( + username=TEST_USER_2_USERNAME, password=TEST_USER_PASSWORD_EDITED + ) + + self.assertFalse(result) response = self.get('common:current_user_details') self.assertEqual(response.status_code, 302)