__copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
__license__ = "AGPL v3"
import re
from django.core import mail
from django.core.exceptions import PermissionDenied
from django.test import TestCase, RequestFactory
from django.test.client import Client
from django.contrib.auth.models import Group
from django.urls import reverse, reverse_lazy
from django.contrib.messages.storage.fallback import FallbackStorage
from scipost.factories import UserFactory, ContributorFactory
from comments.factories import CommentFactory
from comments.forms import CommentForm
from comments.models import Comment
from ..views import RequestThesisLink, VetThesisLink, thesis_detail
from ..factories import ThesisLinkFactory, ThesisLinkFactory, VetThesisLinkFormFactory
from ..models import ThesisLink
from ..forms import VetThesisLinkForm
from common.helpers import model_form_data
from common.helpers.test import add_groups_and_permissions
[docs]class TestThesisDetail(TestCase):
[docs] def setUp(self):
add_groups_and_permissions()
[docs] def test_visits_valid_thesis_detail(self):
""" A visitor does not have to be logged in to view a thesis link. """
thesis_link = ThesisLinkFactory()
client = Client()
target = reverse('theses:thesis', kwargs={'thesislink_id': thesis_link.id})
response = client.post(target)
self.assertEqual(response.status_code, 200)
[docs]class TestRequestThesisLink(TestCase):
[docs] def setUp(self):
add_groups_and_permissions()
self.client = Client()
self.target = reverse('theses:request_thesislink')
[docs] def test_response_when_not_logged_in(self):
'''
A visitor that is not logged in cannot view this page and is redirected to login.
'''
response = self.client.get(self.target)
self.assertRedirects(
response,
expected_url='%s?next=%s' % (
reverse('scipost:login'), reverse('theses:request_thesislink')))
[docs] def test_response_when_logged_in(self):
request = RequestFactory().get(self.target)
request.user = UserFactory()
response = RequestThesisLink.as_view()(request)
self.assertEqual(response.status_code, 200)
[docs]class TestVetThesisLinkRequests(TestCase):
[docs] def setUp(self):
add_groups_and_permissions()
ContributorFactory.create_batch(5)
self.client = Client()
self.thesislink = ThesisLinkFactory()
self.target = reverse('theses:vet_thesislink', kwargs={'pk': self.thesislink.id})
[docs] def test_response_when_not_logged_in(self):
response = self.client.get(self.target)
self.assertEqual(response.status_code, 403)
[docs] def test_response_regular_contributor(self):
'''
A Contributor needs to be in the Vetting Editors group to be able to
vet submitted thesis links.
'''
request = RequestFactory().get(self.target)
user = UserFactory()
request.user = user
self.assertRaises(
PermissionDenied, VetThesisLink.as_view(), request, pk=self.thesislink.id)
[docs] def test_response_vetting_editor(self):
request = RequestFactory().get(self.target)
user = UserFactory()
user.groups.add(Group.objects.get(name="Vetting Editors"))
request.user = user
response = VetThesisLink.as_view()(request, pk=self.thesislink.id)
self.assertEqual(response.status_code, 200)
[docs] def test_thesislink_is_vetted_by_correct_contributor_and_mail_is_sent(self):
contributor = ContributorFactory()
contributor.user.groups.add(Group.objects.get(name="Vetting Editors"))
request = RequestFactory().get(self.target)
request.user = contributor.user
post_data = model_form_data(ThesisLinkFactory(), VetThesisLinkForm)
post_data["action_option"] = VetThesisLinkForm.ACCEPT
target = reverse('theses:vet_thesislink', kwargs={'pk': self.thesislink.id})
request = RequestFactory().post(target, post_data)
request.user = contributor.user
# I don't know what the following three lines do, but they help make a RequestFactory
# work with the messages middleware
setattr(request, 'session', 'session')
messages = FallbackStorage(request)
setattr(request, '_messages', messages)
response = VetThesisLink.as_view()(request, pk=self.thesislink.id)
self.thesislink.refresh_from_db()
self.assertEqual(self.thesislink.vetted_by, contributor)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'SciPost Thesis Link activated')
[docs] def test_thesislink_that_is_refused_is_deleted_and_mail_is_sent(self):
contributor = ContributorFactory()
contributor.user.groups.add(Group.objects.get(name="Vetting Editors"))
request = RequestFactory().get(self.target)
request.user = contributor.user
post_data = model_form_data(ThesisLinkFactory(), VetThesisLinkForm)
post_data["action_option"] = VetThesisLinkForm.REFUSE
post_data["refusal_reason"] = VetThesisLinkForm.ALREADY_EXISTS
post_data["justification"] = "This thesis already exists."
target = reverse('theses:vet_thesislink', kwargs={'pk': self.thesislink.id})
request = RequestFactory().post(target, post_data)
request.user = contributor.user
# I don't know what the following three lines do, but they help make a RequestFactory
# work with the messages middleware
setattr(request, 'session', 'session')
messages = FallbackStorage(request)
setattr(request, '_messages', messages)
response = VetThesisLink.as_view()(request, pk=self.thesislink.id)
self.assertEqual(ThesisLink.objects.filter(id=self.thesislink.id).count(), 0)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'SciPost Thesis Link')
[docs] def test_thesislink_is_vetted_by_correct_contributor_and_mail_is_sent_when_modified(self):
contributor = ContributorFactory()
contributor.user.groups.add(Group.objects.get(name="Vetting Editors"))
request = RequestFactory().get(self.target)
request.user = contributor.user
post_data = model_form_data(ThesisLinkFactory(), VetThesisLinkForm)
post_data["action_option"] = VetThesisLinkForm.MODIFY
target = reverse('theses:vet_thesislink', kwargs={'pk': self.thesislink.id})
request = RequestFactory().post(target, post_data)
request.user = contributor.user
# I don't know what the following three lines do, but they help make a RequestFactory
# work with the messages middleware
setattr(request, 'session', 'session')
messages = FallbackStorage(request)
setattr(request, '_messages', messages)
response = VetThesisLink.as_view()(request, pk=self.thesislink.id)
self.thesislink.refresh_from_db()
self.assertEqual(self.thesislink.vetted_by, contributor)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, 'SciPost Thesis Link activated')
[docs]class TestTheses(TestCase):
[docs] def setUp(self):
add_groups_and_permissions()
self.client = Client()
self.target = reverse('theses:theses')
[docs] def test_empty_search_query(self):
thesislink = ThesisLinkFactory()
response = self.client.get(self.target)
search_results = response.context["object_list"]
self.assertTrue(thesislink in search_results)
[docs] def test_search_query_on_author(self):
thesislink = ThesisLinkFactory()
other_thesislink = ThesisLinkFactory()
form_data = {'author': thesislink.author}
response = self.client.get(self.target, form_data)
search_results = response.context['object_list']
self.assertTrue(thesislink in search_results)
self.assertTrue(other_thesislink not in search_results)
self.assertEqual(len(search_results), 1)