diff --git a/mayan/apps/document_states/tests/test_api.py b/mayan/apps/document_states/tests/test_api.py index a00d5cd1ae..be3de75497 100644 --- a/mayan/apps/document_states/tests/test_api.py +++ b/mayan/apps/document_states/tests/test_api.py @@ -1,28 +1,22 @@ from __future__ import absolute_import, unicode_literals -from django.contrib.auth import get_user_model -from django.contrib.auth.models import Group from django.test import override_settings -from django.urls import reverse -from rest_framework.test import APITestCase +from rest_framework import status -from acls.models import AccessControlList from documents.models import DocumentType +from documents.permissions import permission_document_type_view from documents.tests.literals import ( TEST_DOCUMENT_TYPE_LABEL, TEST_SMALL_DOCUMENT_PATH ) -from permissions import Permission -from permissions.models import Role -from permissions.tests.literals import TEST_ROLE_LABEL from rest_api.tests import BaseAPITestCase -from user_management.tests import ( - TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME, - TEST_GROUP_NAME, TEST_USER_EMAIL, TEST_USER_USERNAME, TEST_USER_PASSWORD -) from ..models import Workflow -from ..permissions import permission_workflow_transition +from ..permissions import ( + permission_workflow_create, permission_workflow_delete, + permission_workflow_edit, permission_workflow_transition, + permission_workflow_view +) from .literals import ( TEST_WORKFLOW_INTERNAL_NAME, TEST_WORKFLOW_INITIAL_STATE_COMPLETION, @@ -38,14 +32,7 @@ from .literals import ( class WorkflowAPITestCase(BaseAPITestCase): def setUp(self): super(WorkflowAPITestCase, self).setUp() - self.admin_user = get_user_model().objects.create_superuser( - username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL, - password=TEST_ADMIN_PASSWORD - ) - - self.client.login( - username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD - ) + self.login_user() self.document_type = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_LABEL @@ -67,166 +54,319 @@ class WorkflowAPITestCase(BaseAPITestCase): internal_name=TEST_WORKFLOW_INTERNAL_NAME ) - def test_workflow_create_view(self): - response = self.client.post( - reverse('rest_api:workflow-list'), { + def _request_workflow_create_view(self): + return self.post( + viewname='rest_api:workflow-list', data={ 'label': TEST_WORKFLOW_LABEL } ) - workflow = Workflow.objects.first() - self.assertEqual(Workflow.objects.count(), 1) - self.assertEqual(response.data['id'], workflow.pk) + def test_workflow_create_view_no_permission(self): + response = self._request_workflow_create_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertEqual(Workflow.objects.count(), 0) - def test_workflow_create_with_document_type_view(self): - response = self.client.post( - reverse('rest_api:workflow-list'), { + def test_workflow_create_view_with_permission(self): + self.grant_permission(permission=permission_workflow_create) + response = self._request_workflow_create_view() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + self.assertEqual(Workflow.objects.count(), 1) + self.assertEqual( + response.data['label'], TEST_WORKFLOW_LABEL + ) + + def _request_workflow_create_view_with_document_type(self): + return self.post( + viewname='rest_api:workflow-list', data={ 'label': TEST_WORKFLOW_LABEL, 'document_types_pk_list': '{}'.format(self.document_type.pk) } ) - workflow = Workflow.objects.first() + def test_workflow_create_with_document_type_view_no_permission(self): + response = self._request_workflow_create_view_with_document_type() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertEqual(Workflow.objects.count(), 0) + + def test_workflow_create_with_document_type_view_with_permission(self): + self.grant_permission(permission=permission_workflow_create) + response = self._request_workflow_create_view_with_document_type() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Workflow.objects.count(), 1) + workflow = Workflow.objects.first() self.assertQuerysetEqual( workflow.document_types.all(), (repr(self.document_type),) ) self.assertEqual(response.data['id'], workflow.pk) - def test_workflow_delete_view(self): - workflow = self._create_workflow() - - self.client.delete( - reverse('rest_api:workflow-detail', args=(workflow.pk,)) + def _request_workflow_delete_view(self): + return self.delete( + viewname='rest_api:workflow-detail', args=(self.workflow.pk,) ) + def test_workflow_delete_view_no_permission(self): + self.workflow = self._create_workflow() + response = self._request_workflow_delete_view() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertEqual(Workflow.objects.count(), 1) + + def test_workflow_delete_view_with_permission(self): + self.workflow = self._create_workflow() + self.grant_access( + permission=permission_workflow_delete, obj=self.workflow + ) + response = self._request_workflow_delete_view() + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertEqual(Workflow.objects.count(), 0) - def test_workflow_detail_view(self): - workflow = self._create_workflow() - - response = self.client.get( - reverse('rest_api:workflow-detail', args=(workflow.pk,)) + def _request_workflow_detail_view(self): + return self.get( + viewname='rest_api:workflow-detail', args=(self.workflow.pk,) ) - self.assertEqual(response.data['label'], workflow.label) + def test_workflow_detail_view_no_access(self): + self.workflow = self._create_workflow() + response = self._request_workflow_detail_view() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertFalse('label' in response.data) - def test_workflow_document_type_create_view(self): - workflow = self._create_workflow() + def test_workflow_detail_view_with_access(self): + self.workflow = self._create_workflow() + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_detail_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['label'], self.workflow.label) - self.client.post( - reverse( - 'rest_api:workflow-document-type-list', - args=(workflow.pk,) - ), data={'document_type_pk': self.document_type.pk} + def _request_workflow_document_type_list_create_view(self): + return self.post( + viewname='rest_api:workflow-document-type-list', + args=(self.workflow.pk,), data={ + 'document_type_pk': self.document_type.pk + } ) + def test_workflow_document_type_create_view_no_access(self): + self.workflow = self._create_workflow() + response = self._request_workflow_document_type_list_create_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertEqual(self.workflow.document_types.count(), 0) + + def test_workflow_document_type_create_view_with_access(self): + self.workflow = self._create_workflow() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_document_type_list_create_view() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertQuerysetEqual( - workflow.document_types.all(), (repr(self.document_type),) + self.workflow.document_types.all(), (repr(self.document_type),) ) - def test_workflow_document_type_delete_view(self): - workflow = self._create_workflow() - workflow.document_types.add(self.document_type) - - self.client.delete( - reverse( - 'rest_api:workflow-document-type-detail', - args=(workflow.pk, self.document_type.pk) - ) + def _request_workflow_document_type_delete_view(self): + return self.delete( + viewname='rest_api:workflow-document-type-detail', + args=(self.workflow.pk, self.document_type.pk) ) - workflow.refresh_from_db() - self.assertQuerysetEqual(workflow.document_types.all(), ()) - # The workflow document type entry was deleted and not the document - # type itself. - self.assertQuerysetEqual( - DocumentType.objects.all(), (repr(self.document_type),) + def test_workflow_document_type_delete_view_no_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + response = self._request_workflow_document_type_delete_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + + self.workflow.refresh_from_db() + self.assertEqual(self.workflow.document_types.count(), 1) + + def test_workflow_document_type_delete_view_with_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_document_type_delete_view() + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + + self.workflow.refresh_from_db() + self.assertEqual(self.workflow.document_types.count(), 0) + + def _request_workflow_document_type_detail_view(self): + return self.get( + viewname='rest_api:workflow-document-type-detail', + args=(self.workflow.pk, self.document_type.pk) ) - def test_workflow_document_type_detail_view(self): - workflow = self._create_workflow() - workflow.document_types.add(self.document_type) + def test_workflow_document_type_detail_view_no_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + response = self._request_workflow_document_type_detail_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('label' in response.data) - response = self.client.get( - reverse( - 'rest_api:workflow-document-type-detail', - args=(workflow.pk, self.document_type.pk) - ) - ) + def test_workflow_document_type_detail_view_with_workflow_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_document_type_detail_view() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertFalse('label' in response.data) + def test_workflow_document_type_detail_view_with_document_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_document_type_view, obj=self.document_type) + response = self._request_workflow_document_type_detail_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('label' in response.data) + + def test_workflow_document_type_detail_view_with_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_document_type_view, obj=self.document_type) + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_document_type_detail_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.data['label'], self.document_type.label) - def test_workflow_document_type_list_view(self): - workflow = self._create_workflow() - workflow.document_types.add(self.document_type) - - response = self.client.get( - reverse( - 'rest_api:workflow-document-type-list', args=(workflow.pk,) + def _request_workflow_document_type_list_view(self): + return self.get( + viewname='rest_api:workflow-document-type-list', args=( + self.workflow.pk, ) ) - self.assertEqual( - response.data['results'][0]['label'], self.document_type.label - ) + def test_workflow_document_type_list_view_no_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + response = self._request_workflow_document_type_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - def test_workflow_list_view(self): - workflow = self._create_workflow() + def test_workflow_document_type_list_view_with_workflow_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_document_type_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['count'], 0) - response = self.client.get(reverse('rest_api:workflow-list')) + def test_workflow_document_type_list_view_with_document_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_document_type_view, obj=self.document_type) + response = self._request_workflow_document_type_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) - self.assertEqual(response.data['results'][0]['label'], workflow.label) + def test_workflow_document_type_list_view_with_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_document_type_view, obj=self.document_type) + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_document_type_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['results'][0]['label'], self.document_type.label) - def test_workflow_put_view(self): - workflow = self._create_workflow() + def _request_workflow_list_view(self): + return self.get(viewname='rest_api:workflow-list') - self.client.put( - reverse('rest_api:workflow-detail', args=(workflow.pk,)), + def test_workflow_list_view_no_access(self): + self.workflow = self._create_workflow() + response = self._request_workflow_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['count'], 0) + + def test_workflow_list_view_with_access(self): + self.workflow = self._create_workflow() + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['results'][0]['label'], self.workflow.label) + + def _request_workflow_edit_view_via_patch(self): + return self.patch( + viewname='rest_api:workflow-detail', args=(self.workflow.pk,), data={'label': TEST_WORKFLOW_LABEL_EDITED} ) - workflow.refresh_from_db() - self.assertEqual(workflow.label, TEST_WORKFLOW_LABEL_EDITED) + def test_workflow_patch_view_no_access(self): + self.workflow = self._create_workflow() + response = self._request_workflow_edit_view_via_patch() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.workflow.refresh_from_db() + self.assertEqual(self.workflow.label, TEST_WORKFLOW_LABEL) - def test_workflow_patch_view(self): - workflow = self._create_workflow() + def test_workflow_patch_view_with_access(self): + self.workflow = self._create_workflow() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_edit_view_via_patch() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.workflow.refresh_from_db() + self.assertEqual(self.workflow.label, TEST_WORKFLOW_LABEL_EDITED) - self.client.patch( - reverse('rest_api:workflow-detail', args=(workflow.pk,)), + def _request_workflow_edit_view_via_put(self): + return self.put( + viewname='rest_api:workflow-detail', args=(self.workflow.pk,), data={'label': TEST_WORKFLOW_LABEL_EDITED} ) - workflow.refresh_from_db() - self.assertEqual(workflow.label, TEST_WORKFLOW_LABEL_EDITED) + def test_workflow_put_view_no_access(self): + self.workflow = self._create_workflow() + response = self._request_workflow_edit_view_via_put() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.workflow.refresh_from_db() + self.assertEqual(self.workflow.label, TEST_WORKFLOW_LABEL) - def test_document_type_workflow_list(self): - workflow = self._create_workflow() - workflow.document_types.add(self.document_type) + def test_workflow_put_view_with_access(self): + self.workflow = self._create_workflow() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_edit_view_via_put() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.workflow.refresh_from_db() + self.assertEqual(self.workflow.label, TEST_WORKFLOW_LABEL_EDITED) - response = self.client.get( - reverse( - 'rest_api:documenttype-workflow-list', - args=(self.document_type.pk,) - ), + def _request_document_type_workflow_list_view(self): + return self.get( + viewname='rest_api:documenttype-workflow-list', + args=(self.document_type.pk,) ) - self.assertEqual(response.data['results'][0]['label'], workflow.label) + def test_document_type_workflow_list_no_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + response = self._request_document_type_workflow_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('results' in response.data) + + def test_document_type_workflow_list_with_workflow_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_document_type_workflow_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('results' in response.data) + + def test_document_type_workflow_list_with_document_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access( + permission=permission_document_type_view, obj=self.document_type + ) + response = self._request_document_type_workflow_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['count'], 0) + + def test_document_type_workflow_list_with_access(self): + self.workflow = self._create_workflow() + self.workflow.document_types.add(self.document_type) + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + self.grant_access( + permission=permission_document_type_view, obj=self.document_type + ) + response = self._request_document_type_workflow_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['results'][0]['label'], self.workflow.label) @override_settings(OCR_AUTO_OCR=False) class WorkflowStatesAPITestCase(BaseAPITestCase): def setUp(self): super(WorkflowStatesAPITestCase, self).setUp() - - self.admin_user = get_user_model().objects.create_superuser( - username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL, - password=TEST_ADMIN_PASSWORD - ) - - self.client.login( - username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD - ) + self.login_user() self.document_type = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_LABEL @@ -255,97 +395,146 @@ class WorkflowStatesAPITestCase(BaseAPITestCase): label=TEST_WORKFLOW_STATE_LABEL ) - def test_workflow_state_create_view(self): - self._create_workflow() - - self.client.post( - reverse( - 'rest_api:workflowstate-list', args=(self.workflow.pk,) - ), data={ + def _request_workflow_state_create_view(self): + return self.post( + viewname='rest_api:workflowstate-list', + args=(self.workflow.pk,), data={ 'completion': TEST_WORKFLOW_STATE_COMPLETION, 'label': TEST_WORKFLOW_STATE_LABEL } ) + def test_workflow_state_create_view_no_access(self): + self._create_workflow() + response = self._request_workflow_state_create_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.workflow.refresh_from_db() + self.assertEqual(self.workflow.states.count(), 0) + def test_workflow_state_create_view_with_access(self): + self._create_workflow() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_state_create_view() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.workflow.refresh_from_db() self.assertEqual( self.workflow.states.first().label, TEST_WORKFLOW_STATE_LABEL ) - def test_workflow_state_delete_view(self): - self._create_workflow_state() - - self.client.delete( - reverse( - 'rest_api:workflowstate-detail', - args=(self.workflow.pk, self.workflow_state.pk) - ), + def _request_workflow_state_delete_view(self): + return self.delete( + viewname='rest_api:workflowstate-detail', + args=(self.workflow.pk, self.workflow_state.pk) ) + def test_workflow_state_delete_view_no_access(self): + self._create_workflow_state() + response = self._request_workflow_state_delete_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.workflow.refresh_from_db() + self.assertEqual(self.workflow.states.count(), 1) + def test_workflow_state_delete_view_with_access(self): + self._create_workflow_state() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_state_delete_view() + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.workflow.refresh_from_db() self.assertEqual(self.workflow.states.count(), 0) - def test_workflow_state_detail_view(self): - self._create_workflow_state() - - response = self.client.get( - reverse( - 'rest_api:workflowstate-detail', - args=(self.workflow.pk, self.workflow_state.pk) - ), + def _request_workflow_state_detail_view(self): + return self.get( + viewname='rest_api:workflowstate-detail', + args=(self.workflow.pk, self.workflow_state.pk) ) + def test_workflow_state_detail_view_no_access(self): + self._create_workflow_state() + response = self._request_workflow_state_detail_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('label' in response.data) + + def test_workflow_state_detail_view_with_access(self): + self._create_workflow_state() + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_state_detail_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data['label'], TEST_WORKFLOW_STATE_LABEL ) - def test_workflow_state_list_view(self): - self._create_workflow_state() - - response = self.client.get( - reverse('rest_api:workflowstate-list', args=(self.workflow.pk,)), + def _request_workflow_state_list_view(self): + return self.get( + viewname='rest_api:workflowstate-list', args=(self.workflow.pk,), ) + def test_workflow_state_list_view_no_access(self): + self._create_workflow_state() + response = self._request_workflow_state_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('label' in response.data) + + def test_workflow_state_list_view_with_access(self): + self._create_workflow_state() + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_state_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data['results'][0]['label'], TEST_WORKFLOW_STATE_LABEL ) - def test_workflow_state_patch_view(self): + def _request_workflow_state_edit_view_via_patch(self): + return self.patch( + viewname='rest_api:workflowstate-detail', + args=(self.workflow.pk, self.workflow_state.pk), data={ + 'label': TEST_WORKFLOW_STATE_LABEL_EDITED + } + ) + + def test_workflow_state_edit_view_via_patch_no_access(self): self._create_workflow_state() - - self.client.patch( - reverse( - 'rest_api:workflowstate-detail', - args=(self.workflow.pk, self.workflow_state.pk) - ), - data={'label': TEST_WORKFLOW_STATE_LABEL_EDITED} - ) - + response = self._request_workflow_state_edit_view_via_patch() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.workflow_state.refresh_from_db() - self.assertEqual( - self.workflow_state.label, - TEST_WORKFLOW_STATE_LABEL_EDITED + self.workflow_state.label, TEST_WORKFLOW_STATE_LABEL ) - def test_workflow_state_put_view(self): + def test_workflow_state_edit_view_via_patch_with_access(self): self._create_workflow_state() - - self.client.put( - reverse( - 'rest_api:workflowstate-detail', - args=(self.workflow.pk, self.workflow_state.pk) - ), - data={'label': TEST_WORKFLOW_STATE_LABEL_EDITED} + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_state_edit_view_via_patch() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.workflow_state.refresh_from_db() + self.assertEqual( + self.workflow_state.label, TEST_WORKFLOW_STATE_LABEL_EDITED ) - self.workflow_state.refresh_from_db() + def _request_workflow_state_edit_view_via_put(self): + return self.put( + viewname='rest_api:workflowstate-detail', + args=(self.workflow.pk, self.workflow_state.pk), data={ + 'label': TEST_WORKFLOW_STATE_LABEL_EDITED + } + ) + def test_workflow_state_edit_view_via_put_no_access(self): + self._create_workflow_state() + response = self._request_workflow_state_edit_view_via_put() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.workflow_state.refresh_from_db() self.assertEqual( - self.workflow_state.label, - TEST_WORKFLOW_STATE_LABEL_EDITED + self.workflow_state.label, TEST_WORKFLOW_STATE_LABEL + ) + + def test_workflow_state_edit_view_via_put_with_access(self): + self._create_workflow_state() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_state_edit_view_via_put() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.workflow_state.refresh_from_db() + self.assertEqual( + self.workflow_state.label, TEST_WORKFLOW_STATE_LABEL_EDITED ) @@ -353,15 +542,7 @@ class WorkflowStatesAPITestCase(BaseAPITestCase): class WorkflowTransitionsAPITestCase(BaseAPITestCase): def setUp(self): super(WorkflowTransitionsAPITestCase, self).setUp() - - self.admin_user = get_user_model().objects.create_superuser( - username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL, - password=TEST_ADMIN_PASSWORD - ) - - self.client.login( - username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD - ) + self.login_user() self.document_type = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_LABEL @@ -402,85 +583,136 @@ class WorkflowTransitionsAPITestCase(BaseAPITestCase): destination_state=self.workflow_state_2, ) - def test_workflow_transition_create_view(self): - self._create_workflow_states() - - self.client.post( - reverse( - 'rest_api:workflowtransition-list', args=(self.workflow.pk,) - ), data={ + def _request_workflow_transition_create_view(self): + return self.post( + viewname='rest_api:workflowtransition-list', + args=(self.workflow.pk,), data={ 'label': TEST_WORKFLOW_TRANSITION_LABEL, 'origin_state_pk': self.workflow_state_1.pk, 'destination_state_pk': self.workflow_state_2.pk, } ) + def test_workflow_transition_create_view_no_access(self): + self._create_workflow_states() + response = self._request_workflow_transition_create_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.workflow.refresh_from_db() + self.assertEqual(self.workflow.transitions.count(), 0) + def test_workflow_transition_create_view_with_access(self): + self._create_workflow_states() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_transition_create_view() + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.workflow.refresh_from_db() self.assertEqual( self.workflow.transitions.first().label, TEST_WORKFLOW_TRANSITION_LABEL ) - def test_workflow_transition_delete_view(self): - self._create_workflow_transition() - - self.client.delete( - reverse( - 'rest_api:workflowtransition-detail', - args=(self.workflow.pk, self.workflow_transition.pk) - ), + def _request_workflow_transition_delete_view(self): + return self.delete( + viewname='rest_api:workflowtransition-detail', + args=(self.workflow.pk, self.workflow_transition.pk) ) + def test_workflow_transition_delete_view_no_access(self): + self._create_workflow_transition() + response = self._request_workflow_transition_delete_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.workflow.refresh_from_db() + self.assertEqual(self.workflow.transitions.count(), 1) + def test_workflow_transition_delete_view_with_access(self): + self._create_workflow_transition() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_transition_delete_view() + self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) + self.workflow.refresh_from_db() self.assertEqual(self.workflow.transitions.count(), 0) - def test_workflow_transition_detail_view(self): - self._create_workflow_transition() - - response = self.client.get( - reverse( - 'rest_api:workflowtransition-detail', - args=(self.workflow.pk, self.workflow_transition.pk) - ), + def _request_workflow_transition_detail_view(self): + return self.get( + viewname='rest_api:workflowtransition-detail', + args=(self.workflow.pk, self.workflow_transition.pk) ) + def test_workflow_transition_detail_view_no_access(self): + self._create_workflow_transition() + response = self._request_workflow_transition_detail_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('label' in response.data) + + def test_workflow_transition_detail_view_with_access(self): + self._create_workflow_transition() + self.grant_access( + permission=permission_workflow_view, obj=self.workflow + ) + response = self._request_workflow_transition_detail_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data['label'], TEST_WORKFLOW_TRANSITION_LABEL ) - def test_workflow_transition_list_view(self): - self._create_workflow_transition() - - response = self.client.get( - reverse( - 'rest_api:workflowtransition-list', args=(self.workflow.pk,) - ), + def _request_workflow_transition_list_view(self): + return self.get( + viewname='rest_api:workflowtransition-list', + args=(self.workflow.pk,) ) + def test_workflow_transition_list_view_no_access(self): + self._create_workflow_transition() + response = self._request_workflow_transition_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('results' in response.data) + + def test_workflow_transition_list_view_with_access(self): + self._create_workflow_transition() + self.grant_access( + permission=permission_workflow_view, obj=self.workflow + ) + response = self._request_workflow_transition_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data['results'][0]['label'], TEST_WORKFLOW_TRANSITION_LABEL ) - def test_workflow_transition_patch_view(self): - self._create_workflow_transition() - - self.client.patch( - reverse( - 'rest_api:workflowtransition-detail', - args=(self.workflow.pk, self.workflow_transition.pk) - ), - data={ + def _request_workflow_transition_edit_view_via_patch(self): + return self.patch( + viewname='rest_api:workflowtransition-detail', + args=(self.workflow.pk, self.workflow_transition.pk), data={ 'label': TEST_WORKFLOW_TRANSITION_LABEL_EDITED, 'origin_state_pk': self.workflow_state_2.pk, 'destination_state_pk': self.workflow_state_1.pk, } ) + def test_workflow_transition_edit_view_via_patch_no_access(self): + self._create_workflow_transition() + response = self._request_workflow_transition_edit_view_via_patch() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.workflow_transition.refresh_from_db() + self.assertEqual( + self.workflow_transition.label, + TEST_WORKFLOW_TRANSITION_LABEL + ) + self.assertEqual( + self.workflow_transition.origin_state, + self.workflow_state_1 + ) + self.assertEqual( + self.workflow_transition.destination_state, + self.workflow_state_2 + ) + def test_workflow_transition_edit_view_via_patch_with_access(self): + self._create_workflow_transition() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_transition_edit_view_via_patch() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.workflow_transition.refresh_from_db() self.assertEqual( self.workflow_transition.label, TEST_WORKFLOW_TRANSITION_LABEL_EDITED @@ -494,23 +726,40 @@ class WorkflowTransitionsAPITestCase(BaseAPITestCase): self.workflow_state_1 ) - def test_workflow_transition_put_view(self): - self._create_workflow_transition() - - self.client.put( - reverse( - 'rest_api:workflowtransition-detail', - args=(self.workflow.pk, self.workflow_transition.pk) - ), - data={ + def _request_workflow_transition_edit_view_via_put(self): + return self.put( + viewname='rest_api:workflowtransition-detail', + args=(self.workflow.pk, self.workflow_transition.pk), data={ 'label': TEST_WORKFLOW_TRANSITION_LABEL_EDITED, 'origin_state_pk': self.workflow_state_2.pk, 'destination_state_pk': self.workflow_state_1.pk, } ) + def test_workflow_transition_edit_view_via_put_no_access(self): + self._create_workflow_transition() + response = self._request_workflow_transition_edit_view_via_put() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.workflow_transition.refresh_from_db() + self.assertEqual( + self.workflow_transition.label, + TEST_WORKFLOW_TRANSITION_LABEL + ) + self.assertEqual( + self.workflow_transition.origin_state, + self.workflow_state_1 + ) + self.assertEqual( + self.workflow_transition.destination_state, + self.workflow_state_2 + ) + def test_workflow_transition_edit_view_via_put_with_access(self): + self._create_workflow_transition() + self.grant_access(permission=permission_workflow_edit, obj=self.workflow) + response = self._request_workflow_transition_edit_view_via_put() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.workflow_transition.refresh_from_db() self.assertEqual( self.workflow_transition.label, TEST_WORKFLOW_TRANSITION_LABEL_EDITED @@ -529,15 +778,7 @@ class WorkflowTransitionsAPITestCase(BaseAPITestCase): class DocumentWorkflowsAPITestCase(BaseAPITestCase): def setUp(self): super(DocumentWorkflowsAPITestCase, self).setUp() - - self.admin_user = get_user_model().objects.create_superuser( - username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL, - password=TEST_ADMIN_PASSWORD - ) - - self.client.login( - username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD - ) + self.login_user() self.document_type = DocumentType.objects.create( label=TEST_DOCUMENT_TYPE_LABEL @@ -583,230 +824,150 @@ class DocumentWorkflowsAPITestCase(BaseAPITestCase): def _create_workflow_instance_log_entry(self): self.document.workflows.first().log_entries.create( comment=TEST_WORKFLOW_INSTANCE_LOG_ENTRY_COMMENT, transition=self.workflow_transition, - user=self.admin_user + user=self.user ) - def test_workflow_instance_detail_view(self): - self._create_workflow_transition() - self._create_document() - - response = self.client.get( - reverse( - 'rest_api:workflowinstance-detail', args=( - self.document.pk, self.document.workflows.first().pk - ) + def _request_workflow_instance_detail_view(self): + return self.get( + viewname='rest_api:workflowinstance-detail', args=( + self.document.pk, self.document.workflows.first().pk ), ) + def test_workflow_instance_detail_view_no_access(self): + self._create_workflow_transition() + self._create_document() + response = self._request_workflow_instance_detail_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('workflow' in response.data) + + def test_workflow_instance_detail_view_with_workflow_access(self): + self._create_workflow_transition() + self._create_document() + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_instance_detail_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('workflow' in response.data) + + def test_workflow_instance_detail_view_with_document_access(self): + self._create_workflow_transition() + self._create_document() + self.grant_access(permission=permission_workflow_view, obj=self.document) + response = self._request_workflow_instance_detail_view() + self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) + self.assertFalse('workflow' in response.data) + + def test_workflow_instance_detail_view_with_access(self): + self._create_workflow_transition() + self._create_document() + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + self.grant_access(permission=permission_workflow_view, obj=self.document) + response = self._request_workflow_instance_detail_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data['workflow']['label'], TEST_WORKFLOW_LABEL ) - def test_workflow_instance_list_view(self): - self._create_workflow_transition() - self._create_document() - - response = self.client.get( - reverse( - 'rest_api:workflowinstance-list', args=(self.document.pk,) - ), + def _request_workflow_instance_list_view(self): + return self.get( + viewname='rest_api:workflowinstance-list', + args=(self.document.pk,) ) + def test_workflow_instance_list_view_no_access(self): + self._create_workflow_transition() + self._create_document() + response = self._request_workflow_instance_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('result' in response.data) + + def test_workflow_instance_list_view_with_document_access(self): + self._create_workflow_transition() + self._create_document() + self.grant_access(permission=permission_workflow_view, obj=self.document) + response = self._request_workflow_instance_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(response.data['count'], 0) + + def test_workflow_instance_list_view_with_workflow_access(self): + self._create_workflow_transition() + self._create_document() + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + response = self._request_workflow_instance_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('result' in response.data) + + def test_workflow_instance_list_view_with_access(self): + self._create_workflow_transition() + self._create_document() + self.grant_access(permission=permission_workflow_view, obj=self.workflow) + self.grant_access(permission=permission_workflow_view, obj=self.document) + response = self._request_workflow_instance_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data['results'][0]['workflow']['label'], TEST_WORKFLOW_LABEL ) - def test_workflow_instance_log_entries_create_view(self): - self._create_workflow_transition() - self._create_document() - - workflow_instance = self.document.workflows.first() - - self.client.post( - reverse( - 'rest_api:workflowinstancelogentry-list', args=( - self.document.pk, workflow_instance.pk - ), + def _request_workflow_instance_log_entry_create_view(self, workflow_instance): + return self.post( + viewname='rest_api:workflowinstancelogentry-list', args=( + self.document.pk, workflow_instance.pk ), data={'transition_pk': self.workflow_transition.pk} ) - workflow_instance.refresh_from_db() + def test_workflow_instance_log_entries_create_view_no_access(self): + self._create_workflow_transition() + self._create_document() + workflow_instance = self.document.workflows.first() + response = self._request_workflow_instance_log_entry_create_view( + workflow_instance=workflow_instance + ) + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + # We get bad request because we try to create a transition for which + # we don't have permission and therefore is not valid for this + # workflow instance current state + self.assertEqual(workflow_instance.log_entries.count(), 0) + def test_workflow_instance_log_entries_create_view_with_workflow_access(self): + self._create_workflow_transition() + self._create_document() + self.grant_access(permission=permission_workflow_transition, obj=self.workflow) + workflow_instance = self.document.workflows.first() + response = self._request_workflow_instance_log_entry_create_view( + workflow_instance=workflow_instance + ) + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + workflow_instance.refresh_from_db() self.assertEqual( workflow_instance.log_entries.first().transition.label, TEST_WORKFLOW_TRANSITION_LABEL ) - def test_workflow_instance_log_entries_list_view(self): - self._create_workflow_transition() - self._create_document() - self._create_workflow_instance_log_entry() - - response = self.client.get( - reverse( - 'rest_api:workflowinstancelogentry-list', args=( - self.document.pk, self.document.workflows.first().pk - ) + def _request_workflow_instance_log_entry_list_view(self): + return self.get( + viewname='rest_api:workflowinstancelogentry-list', args=( + self.document.pk, self.document.workflows.first().pk ), ) + def test_workflow_instance_log_entries_list_view_no_access(self): + self._create_workflow_transition() + self._create_document() + self._create_workflow_instance_log_entry() + response = self._request_workflow_instance_log_entry_list_view() + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) + self.assertFalse('results' in response.data) + + def test_workflow_instance_log_entries_list_view_with_document_access(self): + self._create_workflow_transition() + self._create_document() + self._create_workflow_instance_log_entry() + self.grant_access(permission=permission_workflow_view, obj=self.document) + response = self._request_workflow_instance_log_entry_list_view() + self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual( response.data['results'][0]['transition']['label'], TEST_WORKFLOW_TRANSITION_LABEL ) - - -@override_settings(OCR_AUTO_OCR=False) -class DocumentWorkflowsTransitionACLsAPITestCase(APITestCase): - def setUp(self): - self.user = get_user_model().objects.create_user( - username=TEST_USER_USERNAME, email=TEST_USER_EMAIL, - password=TEST_USER_PASSWORD - ) - - self.client.login( - username=TEST_USER_USERNAME, password=TEST_USER_PASSWORD - ) - - self.document_type = DocumentType.objects.create( - label=TEST_DOCUMENT_TYPE_LABEL - ) - - 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) - Permission.invalidate_cache() - - def tearDown(self): - if hasattr(self, 'document_type'): - self.document_type.delete() - - def _create_document(self): - with open(TEST_SMALL_DOCUMENT_PATH) as file_object: - self.document = self.document_type.new_document( - file_object=file_object - ) - - def _create_workflow(self): - self.workflow = Workflow.objects.create( - label=TEST_WORKFLOW_LABEL, - internal_name=TEST_WORKFLOW_INTERNAL_NAME - ) - self.workflow.document_types.add(self.document_type) - - def _create_workflow_states(self): - self._create_workflow() - self.workflow_state_1 = self.workflow.states.create( - completion=TEST_WORKFLOW_INITIAL_STATE_COMPLETION, - initial=True, label=TEST_WORKFLOW_INITIAL_STATE_LABEL - ) - self.workflow_state_2 = self.workflow.states.create( - completion=TEST_WORKFLOW_STATE_COMPLETION, - label=TEST_WORKFLOW_STATE_LABEL - ) - - def _create_workflow_transition(self): - self._create_workflow_states() - self.workflow_transition = self.workflow.transitions.create( - label=TEST_WORKFLOW_TRANSITION_LABEL, - origin_state=self.workflow_state_1, - destination_state=self.workflow_state_2, - ) - - def test_workflow_transition_view_no_permission(self): - self._create_workflow_transition() - self._create_document() - - workflow_instance = self.document.workflows.first() - - self.client.post( - reverse( - 'rest_api:workflowinstancelogentry-list', args=( - self.document.pk, workflow_instance.pk - ), - ), data={'transition_pk': self.workflow_transition.pk} - ) - - workflow_instance.refresh_from_db() - - self.assertEqual(workflow_instance.log_entries.count(), 0) - - def test_workflow_transition_view_with_permission(self): - self._create_workflow_transition() - self._create_document() - - workflow_instance = self.document.workflows.first() - - self.role.permissions.add( - permission_workflow_transition.stored_permission - ) - - self.client.post( - reverse( - 'rest_api:workflowinstancelogentry-list', args=( - self.document.pk, workflow_instance.pk - ), - ), data={'transition_pk': self.workflow_transition.pk} - ) - - workflow_instance.refresh_from_db() - - self.assertEqual( - workflow_instance.log_entries.first().transition.label, - TEST_WORKFLOW_TRANSITION_LABEL - ) - - def test_workflow_transition_view_with_workflow_acl(self): - self._create_workflow_transition() - self._create_document() - - workflow_instance = self.document.workflows.first() - - acl = AccessControlList.objects.create( - content_object=self.workflow, role=self.role - ) - acl.permissions.add(permission_workflow_transition.stored_permission) - - self.client.post( - reverse( - 'rest_api:workflowinstancelogentry-list', args=( - self.document.pk, workflow_instance.pk - ), - ), data={'transition_pk': self.workflow_transition.pk} - ) - - workflow_instance.refresh_from_db() - - self.assertEqual( - workflow_instance.log_entries.first().transition.label, - TEST_WORKFLOW_TRANSITION_LABEL - ) - - def test_workflow_transition_view_transition_acl(self): - self._create_workflow_transition() - self._create_document() - - workflow_instance = self.document.workflows.first() - - acl = AccessControlList.objects.create( - content_object=self.workflow_transition, role=self.role - ) - acl.permissions.add(permission_workflow_transition.stored_permission) - - self.client.post( - reverse( - 'rest_api:workflowinstancelogentry-list', args=( - self.document.pk, workflow_instance.pk - ), - ), data={'transition_pk': self.workflow_transition.pk} - ) - - workflow_instance.refresh_from_db() - - self.assertEqual( - workflow_instance.log_entries.first().transition.label, - TEST_WORKFLOW_TRANSITION_LABEL - )