Skip to content

Commit

Permalink
* Add tests for the documents settings views.
Browse files Browse the repository at this point in the history
* Fixed authentication bugs found by the tests.
  • Loading branch information
bgroff committed Oct 11, 2018
1 parent 063e877 commit ec7e3e7
Show file tree
Hide file tree
Showing 8 changed files with 322 additions and 16 deletions.
10 changes: 5 additions & 5 deletions django_kala/projects/views/documents/settings/archive.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.views.generic.base import TemplateView

from documents.models import Document


class ArchiveView(LoginRequiredMixin, TemplateView):
class ArchiveView(TemplateView):
template_name = 'documents/settings/archive.html'

def get_context_data(self, **kwargs):
return {
'document': self.document,
'project': self.project,
'organization': self.project.organization,
'can_create': self.document.can_create(self.request.user),
'can_invite': self.document.can_invite(self.request.user)
'organization': self.project.organization
}

@method_decorator(login_required)
def dispatch(self, request, project_pk, document_pk, *args, **kwargs):
self.document = get_object_or_404(
Document.objects.active().select_related(
Expand Down
13 changes: 7 additions & 6 deletions django_kala/projects/views/documents/settings/details.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.views.generic.base import TemplateView

Expand All @@ -11,28 +12,28 @@
from projects.forms.documents.settings.details import DetailsForm


class DocumentDetailsView(LoginRequiredMixin, TemplateView):
class DocumentDetailsView(TemplateView):
template_name = 'documents/settings/details.html'

def get_context_data(self, **kwargs):
return {
'form': self.form,
'document': self.document,
'project': self.project,
'organization': self.project.organization,
'can_create': self.document.can_create(self.request.user),
'can_invite': self.document.can_invite(self.request.user)
'organization': self.project.organization
}

@method_decorator(login_required)
def dispatch(self, request, project_pk, document_pk, *args, **kwargs):
view = super(DocumentDetailsView, self)
self.project = get_object_or_404(Project.objects.active(), pk=project_pk)
self.document = get_object_or_404(Document.objects.active(), pk=document_pk)

if not self.document.can_manage(request.user):
raise PermissionDenied(_('You do not have permission to edit this project'))

self.form = DetailsForm(request.POST or None, instance=self.document, project=self.project)
return super(DocumentDetailsView, self).dispatch(request, *args, **kwargs)
return view.dispatch(request, *args, **kwargs)

def post(self, request, *args, **kwargs):
if self.form.is_valid():
Expand Down
10 changes: 5 additions & 5 deletions django_kala/projects/views/documents/settings/manage_access.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.decorators import login_required
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect
from django.urls import reverse
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext as _
from django.views.generic import TemplateView

from auth.forms.manage_access import manage_access_forms
from documents.models import Document, DocumentPermission


class ManageAccessView(LoginRequiredMixin, TemplateView):
class ManageAccessView(TemplateView):
template_name = 'documents/settings/manage_access.html'

def get_context_data(self, **kwargs):
return {
'forms': self.forms,
'document': self.document,
'project': self.project,
'organization': self.project.organization,
'can_create': self.document.can_create(self.request.user),
'can_invite': self.document.can_invite(self.request.user)
'organization': self.project.organization
}

@method_decorator(login_required)
def dispatch(self, request, project_pk, document_pk, *args, **kwargs):
self.document = get_object_or_404(
Document.objects.active().select_related(
Expand Down
85 changes: 85 additions & 0 deletions django_kala/projects/views/documents/settings/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from django.test import Client
from django.urls import reverse
from rest_framework.status import HTTP_403_FORBIDDEN, HTTP_200_OK, HTTP_302_FOUND

from auth.tests.factories import UserFactory
from documents.tests.factories import DocumentFactory
from organizations.tests.factories import OrganizationFactory
from projects.tests.factories import ProjectFactory


def setup():
user = UserFactory.create()
organization = OrganizationFactory.create()
project = ProjectFactory.create(organization=organization)
document = DocumentFactory.create(project=project)

return user, organization, project, document, Client()


def login(client, user):
user.set_password('test')
user.save()
return client.login(username=user.email, password='test')


def user_permissions_test(view, client, user, organization, project, document, args):
# Not logged in should redirect to the login page
response = client.get(reverse(view, args=args), follow=True)
assert response.redirect_chain[0][0] == '{0}?next={1}'.format(
reverse('users:login'),
reverse(view, args=args)
)
assert response.redirect_chain[0][1] == HTTP_302_FOUND

assert login(client, user)

response = client.get(reverse(view, args=args))
assert response.status_code == HTTP_403_FORBIDDEN

# Test correct permissions
organization.add_manage(user)
response = client.get(reverse(view, args=args))
assert response.status_code == HTTP_200_OK
organization.delete_manage(user)

project.add_manage(user)
response = client.get(reverse(view, args=args))
assert response.status_code == HTTP_200_OK
project.delete_manage(user)

document.add_manage(user)
response = client.get(reverse(view, args=args))
assert response.status_code == HTTP_200_OK
document.delete_manage(user)

# Super user does what they want
user.is_superuser = True
user.save()
response = client.get(reverse(view, args=args))
assert response.status_code == HTTP_200_OK
user.is_superuser = False
user.save()

# Test that other permissions do not work
organization.add_create(user)
organization.add_invite(user)
response = client.get(reverse(view, args=args))
assert response.status_code == HTTP_403_FORBIDDEN
organization.delete_create(user)
organization.delete_invite(user)

project.add_create(user)
project.add_invite(user)
response = client.get(reverse(view, args=args))
assert response.status_code == HTTP_403_FORBIDDEN
project.delete_create(user)
project.delete_invite(user)

document.add_create(user)
document.add_invite(user)
response = client.get(reverse(view, args=args))
assert response.status_code == HTTP_403_FORBIDDEN
document.delete_create(user)
document.delete_invite(user)

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import pytest
from django.urls import reverse
from rest_framework.status import HTTP_302_FOUND

from . import setup, login, user_permissions_test


@pytest.mark.django_db
def test_user_permissions_for_document_archive():
user, organization, project, document, client = setup()
user_permissions_test(
view='projects:document_archive',
client=client,
user=user,
organization=organization,
project=project,
document=document,
args=[project.pk, document.pk]
)


@pytest.mark.django_db
def test_archive():
user, organization, project, document, client = setup()
document.add_manage(user)
assert login(client, user)

# Valid case
response = client.post(
path=reverse('projects:document_archive', args=[project.pk, document.pk]),
data={
'archive': 'Test Project',
},
follow=True
)
assert response.redirect_chain[0][0] == reverse('projects:document_archive', args=[project.pk, document.pk])
assert response.redirect_chain[0][1] == HTTP_302_FOUND

document.refresh_from_db()
assert document.is_active == False
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import pytest
from django.urls import reverse
from rest_framework.status import HTTP_200_OK, HTTP_302_FOUND

from projects.models import Category
from . import setup, login, user_permissions_test


@pytest.mark.django_db
def test_user_permissions_for_document_details():
user, organization, project, document, client = setup()
user_permissions_test(
view='projects:document_details',
client=client,
user=user,
organization=organization,
project=project,
document=document,
args=[project.pk, document.pk]
)


@pytest.mark.django_db
def test_updated_details():
user, organization, project, document, client = setup()
document.add_manage(user)
assert login(client, user)

# Valid case
category = Category.objects.create(name='Test Category', project=project, type='test')
response = client.post(
path=reverse('projects:document_details', args=[project.pk, document.pk]),
data={
'name': 'Test Project',
'category': category.pk,
'tags': ['test, tags']
},
follow=True
)
assert response.redirect_chain[0][0] == reverse('projects:document_details', args=[project.pk, document.pk])
assert response.redirect_chain[0][1] == HTTP_302_FOUND

document.refresh_from_db()
assert document.name == 'Test Project'
assert document.category.name == category.name
assert len(document.tags.all()) == 2

# Invalid form
response = client.post(
path=reverse('projects:document_details', args=[project.pk, document.pk]),
data={
'foo': 'bar',
}
)
assert response.status_code == HTTP_200_OK

0 comments on commit ec7e3e7

Please sign in to comment.