diff --git a/README.md b/README.md
index 0aef241e..f78febca 100644
--- a/README.md
+++ b/README.md
@@ -7,3 +7,4 @@ to store and retrieve church records online.
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![Imports: isort](https://img.shields.io/badge/%20imports-isort-%231674b1?style=flat&labelColor=ef8336)](https://pycqa.github.io/isort/)
[![Documentation Status](https://readthedocs.org/projects/church-ims/badge/?version=latest)](https://church-ims.readthedocs.io/en/latest/?badge=latest)
+[![Maintainability](https://api.codeclimate.com/v1/badges/669adf02ec70d3484662/maintainability)](https://codeclimate.com/github/harisonmg/church-ims/maintainability)
diff --git a/core/tests/test_views.py b/core/tests/test_views.py
index 73217def..8664bfb1 100644
--- a/core/tests/test_views.py
+++ b/core/tests/test_views.py
@@ -1,4 +1,6 @@
-from django.test import RequestFactory, SimpleTestCase, TestCase
+from django.contrib.auth.models import AnonymousUser
+from django.core.exceptions import PermissionDenied
+from django.test import RequestFactory, TestCase
from django.urls import reverse
from accounts.factories import UserFactory
@@ -6,73 +8,93 @@
from people.factories import AdultFactory
-class IndexViewTestCase(SimpleTestCase):
+class IndexViewTestCase(TestCase):
def setUp(self):
self.factory = RequestFactory()
self.request = self.factory.get("dummy_path/")
- self.view = views.IndexView
-
- def test_response_status_code(self):
- response = self.view.as_view()(self.request)
+ self.view_class = views.IndexView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ # TemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("core/index.html", template_names)
+
+ # View
+ def test_response(self):
+ response = self.view_func(self.request)
self.assertEqual(response.status_code, 200)
- def test_template_used(self):
- response = self.view.as_view()(self.request)
- with self.assertTemplateUsed("core/index.html"):
- response.render()
-
class LoginRedirectViewTestCase(TestCase):
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
-
- cls.url = "/login/redirect/"
- cls.fully_registered_user = UserFactory()
- cls.partially_registered_user = UserFactory()
-
- # personal details
- AdultFactory(user=cls.fully_registered_user)
-
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
-
- def test_fully_registered_user_response(self):
- self.client.force_login(self.fully_registered_user)
- response = self.client.get(self.url)
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.get("dummy_path/")
+ self.view_class = views.LoginRedirectView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ response = self.view_func(self.request)
self.assertEqual(response.status_code, 302)
- self.assertRedirects(response, reverse("core:dashboard"))
+ self.assertIn(reverse("account_login"), response.url)
- def test_partially_registered_user_response(self):
- self.client.force_login(self.partially_registered_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 302)
- self.assertRedirects(response, reverse("people:adult_self_register"))
+ # RedirectView
+ def test_redirect_url_for_user_with_person(self):
+ # setup
+ user = UserFactory()
+ AdultFactory(user=user)
+ self.request.user = user
+ self.view.setup(self.request)
+ # test
+ url = self.view.get_redirect_url()
+ self.assertEqual(url, reverse("core:dashboard"))
-class DashboardViewTestCase(TestCase):
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
+ def test_redirect_url_for_user_without_person(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ url = self.view.get_redirect_url()
+ self.assertEqual(url, reverse("people:adult_self_register"))
- cls.url = "/dashboard/"
- cls.fully_registered_user = UserFactory()
- cls.partially_registered_user = UserFactory()
- # personal details
- AdultFactory(user=cls.fully_registered_user)
+class DashboardViewTestCase(TestCase):
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.get("dummy_path/")
+ self.view_class = views.DashboardView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ # TemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("core/dashboard.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ response = self.view_func(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
+ # View
+ def test_response_for_user_with_person(self):
+ # setup
+ user = UserFactory()
+ AdultFactory(user=user)
+ self.request.user = user
- def test_fully_registered_user_response(self):
- self.client.force_login(self.fully_registered_user)
- response = self.client.get(self.url)
+ # test
+ response = self.view_func(self.request)
self.assertEqual(response.status_code, 200)
- def test_partially_registered_user_response(self):
- self.client.force_login(self.partially_registered_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ def test_response_for_user_without_person(self):
+ self.request.user = UserFactory()
+ with self.assertRaises(PermissionDenied):
+ self.view_func(self.request)
diff --git a/people/tests/test_views.py b/people/tests/test_views.py
index f2540b74..6a1dd11c 100644
--- a/people/tests/test_views.py
+++ b/people/tests/test_views.py
@@ -1,9 +1,14 @@
-from django.contrib.auth.models import Permission
-from django.test import TestCase
+from unittest.mock import call, patch
+
+from django.contrib.auth.models import AnonymousUser, Permission
+from django.core.exceptions import ImproperlyConfigured
+from django.http.response import Http404
+from django.test import RequestFactory, TestCase
from django.urls import reverse
from django.utils.module_loading import import_string
from accounts.factories import UserFactory
+from people import views
from people.factories import (
AdultFactory,
ChildFactory,
@@ -20,8 +25,26 @@ class PeopleListViewTestCase(TestCase):
def setUpClass(cls):
super().setUpClass()
- cls.url = "/people/"
- cls.table_head = """
+ cls.authorized_user = cls.get_authorized_user()
+
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.build_get_request()
+ self.view_class = views.PeopleListView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ def build_get_request(self, data=None):
+ return self.factory.get("dummy_path", data=data)
+
+ @staticmethod
+ def get_authorized_user():
+ view_person = Permission.objects.filter(name="Can view person")
+ return UserFactory(user_permissions=tuple(view_person))
+
+ @property
+ def table_head(self):
+ thead = """
# |
@@ -32,87 +55,130 @@ def setUpClass(cls):
"""
- # users
- view_person = Permission.objects.filter(name="Can view person")
- cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(view_person))
- cls.staff_user = UserFactory(is_staff=True)
-
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
-
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
-
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/people_list.html")
-
- def test_context_data_contains_people(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertIn("people", response.context)
-
- def test_is_paginated(self):
- PersonFactory.create_batch(11)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTrue(response.context.get("is_paginated"))
- self.assertEqual(len(response.context.get("people")), 10)
-
- def test_pagination_lists_all_items(self):
- PersonFactory.create_batch(12)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url + "?page=2")
- expected_people = list(Person.objects.all())[-2:]
- people = list(response.context.get("people"))
- self.assertEqual(people, expected_people)
-
+ return thead
+
+ # MultipleObjectMixin
+ def test_allow_empty(self):
+ self.view.setup(self.request)
+ allow_empty = self.view.get_allow_empty()
+ self.assertTrue(allow_empty)
+
+ def test_ordering(self):
+ self.view.setup(self.request)
+ ordering = self.view.get_ordering()
+ self.assertIsNone(ordering)
+
+ # SearchableListMixin
+ def test_search_fields(self):
+ self.view.setup(self.request)
+ search_fields = self.view.get_search_fields_with_filters()
+ expected_search_fields = [("username", "icontains"), ("full_name", "icontains")]
+ self.assertEqual(search_fields, expected_search_fields)
+
+ def test_search_query(self):
+ search_term = "search query"
+ self.request = self.build_get_request({"q": search_term})
+ self.view.setup(self.request)
+ search_query = self.view.get_search_query()
+ self.assertEqual(search_query, search_term)
+
+ def test_queryset_without_search_query(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.assertQuerysetEqual(queryset, Person.objects.all())
+
+ def test_queryset_with_search_query(self):
+ people = PersonFactory.create_batch(10)
+ search_term = people[0].full_name.split()[0]
+ self.request = self.build_get_request({"q": search_term})
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.assertQuerysetEqual(queryset, search_people(search_term))
+
+ # MultipleObjectMixin
+ def test_paginate_by(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ paginate_by = self.view.get_paginate_by(queryset)
+ self.assertEqual(paginate_by, 10)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertEqual(context_object_name, "people")
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.view.object_list = queryset
+ context_object_name = self.view.get_context_object_name(queryset)
+ context_data = self.view.get_context_data()
+ expected_context_data_keys = [
+ "paginator",
+ "page_obj",
+ "is_paginated",
+ "object_list",
+ context_object_name,
+ "view",
+ ]
+ self.assertEqual(list(context_data.keys()), expected_context_data_keys)
+
+ # MultipleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ self.view.object_list = self.view.get_queryset()
+ template_names = self.view.get_template_names()
+ self.assertIn("people/people_list.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ("people.view_person",))
+
+ # template logic
def test_response_with_no_people(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
+ # setup
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
+
+ # test
with self.assertRaises(AssertionError):
self.assertInHTML(self.table_head, response.content.decode())
self.assertInHTML("There are no people yet!", response.content.decode())
def test_response_with_people(self):
- PersonFactory.create_batch(3)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
+ # setup
+ PersonFactory()
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
+
+ # test
with self.assertRaises(AssertionError):
self.assertInHTML("There are no people yet!", response.content.decode())
self.assertInHTML(self.table_head, response.content.decode())
- def test_search_results(self):
+ def test_response_with_no_search_results(self):
# setup
- people = PersonFactory.create_batch(10)
- search_term = people[0].full_name.split()[0]
- self.client.force_login(self.authorized_user)
+ search_term = "does not exist"
+ self.request = self.build_get_request({"q": search_term})
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
# test
- response = self.client.get(f"{self.url}?q={search_term}")
- search_results = response.context.get("people")
- self.assertQuerysetEqual(search_results, search_people(search_term))
-
- def test_response_with_no_search_results(self):
- PersonFactory.create_batch(10)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url + "?q=Does not exist")
- self.assertEqual(list(response.context.get("people")), [])
with self.assertRaises(AssertionError):
self.assertInHTML(self.table_head, response.content.decode())
self.assertInHTML(
@@ -120,95 +186,241 @@ def test_response_with_no_search_results(self):
)
-class PersonCreateViewTestCase(TestCase):
+class PersonDetailViewTestCase(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- cls.url = "/people/add/"
+ cls.person = PersonFactory()
+
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.get("dummy_path")
+ self.view_class = views.PersonDetailView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [self.person])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "username")
+
+ def test_object_with_existing_person(self):
+ self.view.setup(self.request, username=self.person.username)
+ obj = self.view.get_object()
+ self.assertEqual(obj, self.person)
+
+ def test_object_with_non_existent_person(self):
+ self.view.setup(self.request, username="non-existent-person")
+ with self.assertRaises(Http404):
+ self.view.get_object()
+
+ def test_context_object_name(self):
+ self.view.setup(self.request, username=self.person.username)
+ obj = self.view.get_object()
+ context_object_name = self.view.get_context_object_name(obj)
+ self.assertEqual(context_object_name, "person")
+
+ def test_context_data(self):
+ self.view.setup(self.request, username=self.person.username)
+ obj = self.view.get_object()
+ self.view.object = obj
+ context_object_name = self.view.get_context_object_name(obj)
+ context_data = self.view.get_context_data()
+ expected_context_data_keys = ["object", context_object_name, "view"]
+ self.assertEqual(list(context_data.keys()), expected_context_data_keys)
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("people/person_detail.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ("people.view_person",))
- # users
- create_person = Permission.objects.filter(name="Can add person")
- view_person = Permission.objects.filter(name="Can view person")
- permissions = create_person | view_person
- cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(permissions))
- cls.staff_user = UserFactory(is_staff=True)
-
- # POST data
- person = PersonFactory.build()
- cls.data = {
- "username": person.username,
- "full_name": person.full_name,
- "gender": person.gender,
- "dob": person.dob,
- }
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
+class PersonCreateViewTestCase(TestCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ cls.user = UserFactory()
+ cls.person = PersonFactory.build()
+ cls.form_data = {
+ "username": cls.person.username,
+ "full_name": cls.person.full_name,
+ "gender": cls.person.gender,
+ "dob": cls.person.dob,
+ }
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.post("dummy_path", data=self.form_data)
+ self.view_class = views.PersonCreateView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ def create_duplicate(self):
+ data = self.form_data.copy()
+ data["username"] = PersonFactory.build().username
+ data["created_by"] = self.user
+ PersonFactory(**data)
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/person_form.html")
+ # FormMixin
+ def test_initial(self):
+ self.view.setup(self.request)
+ initial = self.view.get_initial()
+ self.assertEqual(initial, {})
- def test_context_data_contains_action(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("action"), "add")
+ def test_prefix(self):
+ self.view.setup(self.request)
+ prefix = self.view.get_prefix()
+ self.assertIsNone(prefix)
def test_form_class(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- form = response.context.get("form")
- self.assertEqual(form.__class__.__name__, "PersonCreationForm")
- self.assertIsInstance(form, import_string("django.forms.ModelForm"))
- self.assertIsInstance(form, import_string("people.forms.PersonCreationForm"))
+ self.view.setup(self.request)
+ form_class = self.view.get_form_class()
+ self.assertEqual(form_class, import_string("people.forms.PersonCreationForm"))
+
+ def test_form_kwargs(self):
+ self.view.setup(self.request)
+ form_kwargs = {
+ "initial": self.view.get_initial(),
+ "prefix": self.view.get_prefix(),
+ "data": self.request.POST,
+ "files": self.request.FILES,
+ }
+ self.assertEqual(self.view.get_form_kwargs(), form_kwargs)
+
+ def test_success_url(self):
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_url = self.view.get_success_url()
+ self.assertEqual(
+ success_url,
+ reverse(
+ "people:person_detail", kwargs={"username": self.form_data["username"]}
+ ),
+ )
def test_form_invalid(self):
- # setup
- data = self.data.copy()
- data["created_by"] = self.authorized_user
- PersonFactory(**data)
- data["full_name"] = data["full_name"] + " " + data["username"].title()
- data["username"] = PersonFactory.build().username
- self.client.force_login(self.authorized_user)
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_invalid(form)
+ self.assertEqual(response.status_code, 200)
- # test
- response = self.client.post(self.url, data)
- form = response.context.get("form")
- self.assertFalse(form.is_valid())
- self.assertEqual(form.errors, {"__all__": ["This person already exists"]})
+ # SuccessMessageMixin
+ def test_success_message(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_message = self.view.get_success_message(self.form_data)
+ self.assertEqual(
+ success_message, f"{self.person}'s information has been added successfully."
+ )
- def test_form_valid(self):
- self.client.force_login(self.authorized_user)
- self.client.post(self.url, self.data)
- person = Person.objects.get(username=self.data["username"])
- self.assertEqual(person.created_by, self.authorized_user)
+ @patch("django.contrib.messages.success")
+ def test_form_valid_without_duplicate(self, mock_success):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
+ person = Person.objects.get(username=self.form_data["username"])
+ self.assertEqual(person.created_by, self.user)
- def test_success_url(self):
- self.client.force_login(self.authorized_user)
- response = self.client.post(self.url, self.data)
- self.assertRedirects(
- response,
- reverse("people:person_detail", kwargs={"username": self.data["username"]}),
- )
+ # ModelFormMixin
+ def test_form_valid_with_duplicate(self):
+ # setup
+ self.create_duplicate()
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+
+ # test
+ self.assertEqual(response.status_code, 200)
+ response.render()
+ error_message = "This person already exists"
+ self.assertInHTML(error_message, str(response.content))
+
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "slug")
+
+ def test_object(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ obj = self.view.get_object()
+ self.assertIsNone(obj)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertIsNone(context_object_name)
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ self.view.object = None
+ context_data = self.view.get_context_data()
+ self.assertEqual(list(context_data.keys()), ["form", "view", "action"])
+ self.assertEqual(context_data.get("action"), "add")
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("people/person_form.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ("people.add_person",))
class AdultCreateViewTestCase(TestCase):
@@ -216,96 +428,168 @@ class AdultCreateViewTestCase(TestCase):
def setUpClass(cls):
super().setUpClass()
- cls.url = "/people/add/adult/"
-
- # users
- create_person = Permission.objects.filter(name="Can add person")
- view_person = Permission.objects.filter(name="Can view person")
- permissions = create_person | view_person
cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(permissions))
- cls.staff_user = UserFactory(is_staff=True)
-
- # POST data
- person = AdultFactory.build()
- cls.data = {
- "username": person.username,
- "full_name": person.full_name,
- "gender": person.gender,
- "dob": person.dob,
- "phone_number": person.phone_number,
+ cls.person = AdultFactory.build()
+ cls.form_data = {
+ "username": cls.person.username,
+ "full_name": cls.person.full_name,
+ "gender": cls.person.gender,
+ "dob": cls.person.dob,
+ "phone_number": cls.person.phone_number,
}
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.post("dummy_path", data=self.form_data)
+ self.view_class = views.AdultCreateView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ def create_duplicate(self):
+ data = self.form_data.copy()
+ data["username"] = AdultFactory.build().username
+ data["created_by"] = self.user
+ AdultFactory(**data)
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
+ # FormMixin
+ def test_initial(self):
+ self.view.setup(self.request)
+ initial = self.view.get_initial()
+ self.assertEqual(initial, {})
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ def test_prefix(self):
+ self.view.setup(self.request)
+ prefix = self.view.get_prefix()
+ self.assertIsNone(prefix)
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/person_form.html")
+ def test_form_class(self):
+ self.view.setup(self.request)
+ form_class = self.view.get_form_class()
+ self.assertEqual(form_class, import_string("people.forms.AdultCreationForm"))
+
+ def test_form_kwargs(self):
+ self.view.setup(self.request)
+ form_kwargs = {
+ "initial": self.view.get_initial(),
+ "prefix": self.view.get_prefix(),
+ "data": self.request.POST,
+ "files": self.request.FILES,
+ }
+ self.assertEqual(self.view.get_form_kwargs(), form_kwargs)
+
+ def test_success_url(self):
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_url = self.view.get_success_url()
+ self.assertEqual(
+ success_url,
+ reverse(
+ "people:person_detail", kwargs={"username": self.form_data["username"]}
+ ),
+ )
- def test_context_data_contains_action(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("action"), "add")
+ def test_form_invalid(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_invalid(form)
+ self.assertEqual(response.status_code, 200)
- def test_context_data_contains_age_category(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("age_category"), "an adult")
+ # SuccessMessageMixin
+ def test_success_message(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_message = self.view.get_success_message(self.form_data)
+ self.assertEqual(
+ success_message, f"{self.person}'s information has been added successfully."
+ )
- def test_form_class(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- form = response.context.get("form")
- self.assertEqual(form.__class__.__name__, "AdultCreationForm")
- self.assertIsInstance(form, import_string("django.forms.ModelForm"))
- self.assertIsInstance(form, import_string("people.forms.AdultCreationForm"))
+ @patch("django.contrib.messages.success")
+ def test_form_valid_without_duplicate(self, mock_success):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
+ person = Person.objects.get(username=self.form_data["username"])
+ self.assertEqual(person.created_by, self.user)
- def test_form_invalid(self):
+ # ModelFormMixin
+ def test_form_valid_with_duplicate(self):
# setup
- data = self.data.copy()
- data["created_by"] = self.authorized_user
- AdultFactory(**data)
- data["full_name"] = data["full_name"] + " " + data["username"].title()
- data["username"] = AdultFactory.build().username
- self.client.force_login(self.authorized_user)
+ self.create_duplicate()
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
# test
- response = self.client.post(self.url, data)
- form = response.context.get("form")
- self.assertFalse(form.is_valid())
- self.assertEqual(form.errors, {"__all__": ["This person already exists"]})
-
- def test_form_valid(self):
- self.client.force_login(self.authorized_user)
- self.client.post(self.url, self.data)
- person = Person.objects.get(username=self.data["username"])
- self.assertEqual(person.created_by, self.authorized_user)
-
- def test_success_url(self):
- self.client.force_login(self.authorized_user)
- response = self.client.post(self.url, self.data)
- self.assertRedirects(
- response,
- reverse("people:person_detail", kwargs={"username": self.data["username"]}),
+ self.assertEqual(response.status_code, 200)
+ response.render()
+ error_message = "This person already exists"
+ self.assertInHTML(error_message, str(response.content))
+
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "slug")
+
+ def test_object(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ obj = self.view.get_object()
+ self.assertIsNone(obj)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertIsNone(context_object_name)
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ self.view.object = None
+ context_data = self.view.get_context_data()
+ self.assertEqual(
+ list(context_data.keys()), ["form", "view", "action", "age_category"]
)
+ self.assertEqual(context_data.get("action"), "add")
+ self.assertEqual(context_data.get("age_category"), "an adult")
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("people/person_form.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ("people.add_person",))
class AdultSelfRegisterViewTestCase(TestCase):
@@ -313,64 +597,164 @@ class AdultSelfRegisterViewTestCase(TestCase):
def setUpClass(cls):
super().setUpClass()
- cls.url = "/people/register/self/"
-
- # users
cls.user = UserFactory()
-
- # POST data
- person = AdultFactory.build()
- cls.data = {
- "username": person.username,
- "full_name": person.full_name,
- "gender": person.gender,
- "dob": person.dob,
- "phone_number": person.phone_number,
+ cls.person = AdultFactory.build()
+ cls.form_data = {
+ "username": cls.person.username,
+ "full_name": cls.person.full_name,
+ "gender": cls.person.gender,
+ "dob": cls.person.dob,
+ "phone_number": cls.person.phone_number,
}
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.post("dummy_path", data=self.form_data)
+ self.view_class = views.AdultSelfRegisterView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
-
- def test_template_used(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/self_register_form.html")
+ def create_duplicate(self):
+ data = self.form_data.copy()
+ data["username"] = AdultFactory.build().username
+ data["created_by"] = self.user
+ AdultFactory(**data)
- def test_context_data_contains_action(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("action"), "add")
+ # FormMixin
+ def test_initial(self):
+ self.view.setup(self.request)
+ initial = self.view.get_initial()
+ self.assertEqual(initial, {})
- def test_context_data_contains_age_category(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("age_category"), "an adult")
+ def test_prefix(self):
+ self.view.setup(self.request)
+ prefix = self.view.get_prefix()
+ self.assertIsNone(prefix)
def test_form_class(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- form = response.context.get("form")
- self.assertEqual(form.__class__.__name__, "AdultCreationForm")
- self.assertIsInstance(form, import_string("django.forms.ModelForm"))
- self.assertIsInstance(form, import_string("people.forms.AdultCreationForm"))
-
- def test_form_valid(self):
- self.client.force_login(self.user)
- self.client.post(self.url, self.data)
- person = Person.objects.get(username=self.data["username"])
- self.assertEqual(person.user, self.user)
- self.assertEqual(person.created_by, self.user)
+ self.view.setup(self.request)
+ form_class = self.view.get_form_class()
+ self.assertEqual(form_class, import_string("people.forms.AdultCreationForm"))
+
+ def test_form_kwargs(self):
+ self.view.setup(self.request)
+ form_kwargs = {
+ "initial": self.view.get_initial(),
+ "prefix": self.view.get_prefix(),
+ "data": self.request.POST,
+ "files": self.request.FILES,
+ }
+ self.assertEqual(self.view.get_form_kwargs(), form_kwargs)
def test_success_url(self):
- self.client.force_login(self.user)
- response = self.client.post(self.url, self.data)
- self.assertRedirects(response, reverse("core:dashboard"))
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_url = self.view.get_success_url()
+ self.assertEqual(success_url, reverse("core:dashboard"))
+
+ def test_form_invalid(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_invalid(form)
+ self.assertEqual(response.status_code, 200)
+
+ # SuccessMessageMixin
+ def test_success_message(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_message = self.view.get_success_message(self.form_data)
+ self.assertEqual(
+ success_message, f"{self.person}'s information has been added successfully."
+ )
+
+ @patch("django.contrib.messages.success")
+ def test_form_valid_without_duplicate(self, mock_success):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
+ person = Person.objects.get(username=self.form_data["username"])
+ self.assertEqual(person.created_by, self.user)
+ self.assertEqual(person.user, self.user)
+
+ # ModelFormMixin
+ def test_form_valid_with_duplicate(self):
+ # setup
+ self.create_duplicate()
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+
+ # test
+ self.assertEqual(response.status_code, 200)
+ response.render()
+ error_message = "This person already exists"
+ self.assertInHTML(error_message, str(response.content))
+
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "slug")
+
+ def test_object(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ obj = self.view.get_object()
+ self.assertIsNone(obj)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertIsNone(context_object_name)
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ self.view.object = None
+ context_data = self.view.get_context_data()
+ self.assertEqual(
+ list(context_data.keys()), ["form", "view", "action", "age_category"]
+ )
+ self.assertEqual(context_data.get("action"), "add")
+ self.assertEqual(context_data.get("age_category"), "an adult")
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("people/self_register_form.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ())
class ChildCreateViewTestCase(TestCase):
@@ -378,155 +762,232 @@ class ChildCreateViewTestCase(TestCase):
def setUpClass(cls):
super().setUpClass()
- cls.url = "/people/add/child/"
-
- # users
cls.user = UserFactory()
- cls.authorized_user = UserFactory()
-
- # POST data
- cls.parent = AdultFactory(user=cls.authorized_user)
- child = ChildFactory.build()
- cls.data = {
- "username": child.username,
- "full_name": child.full_name,
- "gender": child.gender,
- "dob": child.dob,
+ cls.parent = AdultFactory(user=cls.user)
+ cls.person = ChildFactory.build()
+ cls.form_data = {
+ "username": cls.person.username,
+ "full_name": cls.person.full_name,
+ "gender": cls.person.gender,
+ "dob": cls.person.dob,
}
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
-
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.build_post_request(self.form_data)
+ self.view_class = views.ChildCreateView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
+ def build_post_request(self, data=None):
+ return self.factory.post("dummy_path", data=data)
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/person_form.html")
+ def create_duplicate(self):
+ data = self.form_data.copy()
+ data["username"] = ChildFactory.build().username
+ data["created_by"] = self.user
+ ChildFactory(**data)
- def test_context_data_contains_action(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("action"), "add")
+ # FormMixin
+ def test_initial(self):
+ self.view.setup(self.request)
+ initial = self.view.get_initial()
+ self.assertEqual(initial, {})
- def test_context_data_contains_age_category(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("age_category"), "a child")
+ def test_prefix(self):
+ self.view.setup(self.request)
+ prefix = self.view.get_prefix()
+ self.assertIsNone(prefix)
def test_form_class(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- form = response.context.get("form")
- self.assertEqual(form.__class__.__name__, "ChildCreationForm")
- self.assertIsInstance(form, import_string("django.forms.ModelForm"))
- self.assertIsInstance(form, import_string("people.forms.ChildCreationForm"))
+ self.view.setup(self.request)
+ form_class = self.view.get_form_class()
+ self.assertEqual(form_class, import_string("people.forms.ChildCreationForm"))
+
+ def test_form_kwargs(self):
+ self.view.setup(self.request)
+ form_kwargs = {
+ "initial": self.view.get_initial(),
+ "prefix": self.view.get_prefix(),
+ "data": self.request.POST,
+ "files": self.request.FILES,
+ }
+ self.assertEqual(self.view.get_form_kwargs(), form_kwargs)
+
+ def test_success_url_when_creator_is_the_parent(self):
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_url = self.view.get_success_url(is_parent=True)
+ self.assertEqual(success_url, reverse("core:dashboard"))
+
+ def test_success_url_when_creator_is_not_the_parent(self):
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_url = self.view.get_success_url()
+ self.assertEqual(
+ success_url,
+ reverse(
+ "people:parent_child_relationship_create",
+ kwargs={"username": self.person.username},
+ ),
+ )
def test_form_invalid(self):
- # setup
- data = self.data.copy()
- data["created_by"] = self.authorized_user
- ChildFactory(**data)
- data["full_name"] = data["full_name"] + " " + data["username"].title()
- data["username"] = ChildFactory.build().username
- self.client.force_login(self.authorized_user)
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_invalid(form)
+ self.assertEqual(response.status_code, 200)
- # test
- response = self.client.post(self.url, data)
- form = response.context.get("form")
- self.assertFalse(form.is_valid())
- self.assertEqual(form.errors, {"__all__": ["This person already exists"]})
+ # SuccessMessageMixin
+ def test_success_message(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_message = self.view.get_success_message(self.form_data)
+ self.assertEqual(
+ success_message, f"{self.person}'s information has been added successfully."
+ )
- def test_is_parent_form_valid(self):
+ @patch("django.contrib.messages.success")
+ def test_form_valid_when_creator_is_not_the_parent(self, mock_success):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
+ person = Person.objects.get(username=self.form_data["username"])
+ self.assertEqual(person.created_by, self.user)
+ self.assertEqual(person.user, None)
+
+ @patch("django.contrib.messages.info")
+ def test_create_relationship(self, mock_info):
# setup
- data = self.data.copy()
- data["is_parent"] = True
- self.client.force_login(self.authorized_user)
+ child = ChildFactory(**self.form_data)
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = child
+ self.view.create_relationship()
# test
- self.client.post(self.url, self.data)
- child = Person.objects.get(username=self.data["username"])
- self.assertEqual(child.created_by, self.authorized_user)
-
- def test_not_parent_form_valid(self):
- self.client.force_login(self.authorized_user)
- self.client.post(self.url, self.data)
- child = Person.objects.get(username=self.data["username"])
- self.assertEqual(child.created_by, self.authorized_user)
-
- def test_is_parent_success_url(self):
+ relationship = InterpersonalRelationship.objects.get(relative=child)
+ self.assertEqual(relationship.relation, "PC")
+ self.assertEqual(relationship.person, self.parent)
+ self.assertEqual(relationship.created_by, self.user)
+ self.assertTrue(mock_info.called)
+ message = f"A parent-child relationship between {self.parent} and {child}"
+ message += " has been added."
+ self.assertEqual(mock_info.call_args, call(self.request, message))
+
+ @patch("django.contrib.messages.success")
+ @patch("django.contrib.messages.info")
+ def test_form_valid_when_creator_is_the_parent(self, mock_success, mock_info):
# setup
- data = self.data.copy()
+ data = self.form_data.copy()
data["is_parent"] = True
- self.client.force_login(self.authorized_user)
+ self.request = self.build_post_request(data)
+ self.request.user = self.user
+ self.view.setup(self.request)
+ form = self.view.get_form()
# test
- response = self.client.post(self.url, data)
- self.assertRedirects(response, reverse("core:dashboard"))
-
- def test_not_parent_success_url(self):
- self.client.force_login(self.authorized_user)
- response = self.client.post(self.url, self.data)
- self.assertRedirects(
- response,
- reverse(
- "people:parent_child_relationship_create",
- kwargs={"username": self.data["username"]},
- ),
- )
-
-
-class PersonDetailViewTestCase(TestCase):
- @classmethod
- def setUpClass(cls):
- super().setUpClass()
-
- cls.person = PersonFactory()
- cls.url = cls.person.get_absolute_url()
-
- # users
- view_person = Permission.objects.filter(name="Can view person")
- cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(view_person))
- cls.staff_user = UserFactory(is_staff=True)
-
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
+ person = Person.objects.get(username=self.form_data["username"])
+ self.assertEqual(person.created_by, self.user)
+ self.assertEqual(person.user, None)
+ self.assertTrue(mock_info.called)
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ # ModelFormMixin
+ def test_form_valid_with_duplicate(self):
+ # setup
+ self.create_duplicate()
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
+ # test
self.assertEqual(response.status_code, 200)
-
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/person_detail.html")
-
- def test_context_data_contains_person(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("person"), self.person)
+ response.render()
+ error_message = "This person already exists"
+ self.assertInHTML(error_message, str(response.content))
+
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "slug")
+
+ def test_object(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ obj = self.view.get_object()
+ self.assertIsNone(obj)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertIsNone(context_object_name)
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ self.view.object = None
+ context_data = self.view.get_context_data()
+ self.assertEqual(
+ list(context_data.keys()), ["form", "view", "action", "age_category"]
+ )
+ self.assertEqual(context_data.get("action"), "add")
+ self.assertEqual(context_data.get("age_category"), "a child")
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("people/person_form.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ())
+
+ # UserPassesTestMixin
+ def test_test_func_false(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ self.assertFalse(self.view.test_func())
+
+ def test_test_func_true(self):
+ user = UserFactory()
+ AdultFactory(user=user)
+ self.request.user = user
+ self.view.setup(self.request)
+ self.assertTrue(self.view.test_func())
class PersonUpdateViewTestCase(TestCase):
@@ -534,80 +995,167 @@ class PersonUpdateViewTestCase(TestCase):
def setUpClass(cls):
super().setUpClass()
- cls.person = PersonFactory()
- cls.url = cls.person.get_absolute_url() + "update/"
-
- # users
- update_person = Permission.objects.filter(name="Can change person")
- view_person = Permission.objects.filter(name="Can view person")
- permissions = update_person | view_person
cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(permissions))
- cls.staff_user = UserFactory(is_staff=True)
-
- # POST data
- cls.data = {
+ cls.person = PersonFactory()
+ cls.form_data = {
"username": cls.person.username,
- "full_name": cls.person.full_name + " " + cls.person.username.title(),
+ "full_name": cls.person.full_name,
"gender": cls.person.gender,
"dob": cls.person.dob,
}
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
-
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
-
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.post("dummy_path", data=self.form_data)
+ self.view_class = views.PersonUpdateView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/person_form.html")
+ # FormMixin
+ def test_initial(self):
+ self.view.setup(self.request)
+ initial = self.view.get_initial()
+ self.assertEqual(initial, {})
- def test_context_data_contains_person(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("person"), self.person)
-
- def test_context_data_contains_action(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("action"), "update")
+ def test_prefix(self):
+ self.view.setup(self.request)
+ prefix = self.view.get_prefix()
+ self.assertIsNone(prefix)
def test_form_class(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- form = response.context.get("form")
- self.assertEqual(form.__class__.__name__, "PersonUpdateForm")
- self.assertIsInstance(form, import_string("django.forms.ModelForm"))
- self.assertIsInstance(form, import_string("people.forms.PersonUpdateForm"))
+ self.view.setup(self.request)
+ form_class = self.view.get_form_class()
+ self.assertEqual(form_class, import_string("people.forms.PersonUpdateForm"))
+
+ def test_form_kwargs(self):
+ self.view.setup(self.request)
+ form_kwargs = {
+ "initial": self.view.get_initial(),
+ "prefix": self.view.get_prefix(),
+ "data": self.request.POST,
+ "files": self.request.FILES,
+ }
+ self.assertEqual(self.view.get_form_kwargs(), form_kwargs)
def test_success_url(self):
- self.client.force_login(self.authorized_user)
- response = self.client.post(self.url, self.data)
- self.assertRedirects(response, self.person.get_absolute_url())
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_url = self.view.get_success_url()
+ self.assertEqual(
+ success_url,
+ reverse(
+ "people:person_detail", kwargs={"username": self.form_data["username"]}
+ ),
+ )
+ def test_form_invalid(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_invalid(form)
+ self.assertEqual(response.status_code, 200)
-class RelationshipsListViewTestCase(TestCase):
+ # SuccessMessageMixin
+ def test_success_message(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = self.person
+ success_message = self.view.get_success_message(self.form_data)
+ self.assertEqual(
+ success_message,
+ f"{self.person}'s information has been updated successfully.",
+ )
+
+ @patch("django.contrib.messages.success")
+ def test_form_valid(self, mock_success):
+ self.request.user = self.user
+ self.view.setup(self.request, username=self.person.username)
+ self.view.object = self.view.get_object()
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
+
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [self.person])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "username")
+
+ def test_object(self):
+ self.view.setup(self.request, username=self.person.username)
+ obj = self.view.get_object()
+ self.assertEqual(obj, self.person)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request, username=self.person.username)
+ obj = self.view.get_object()
+ context_object_name = self.view.get_context_object_name(obj)
+ self.assertEqual(context_object_name, "person")
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ self.view.object = None
+ context_data = self.view.get_context_data()
+ self.assertEqual(list(context_data.keys()), ["form", "view", "action"])
+ self.assertEqual(context_data.get("action"), "update")
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("people/person_form.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ("people.change_person",))
+
+
+class InterpersonalRelationshipsListViewTestCase(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- cls.url = "/people/relationships/"
- cls.table_head = """
+ cls.authorized_user = cls.get_authorized_user()
+
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.build_get_request()
+ self.view_class = views.RelationshipsListView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ def build_get_request(self, data=None):
+ return self.factory.get("dummy_path", data=data)
+
+ @staticmethod
+ def get_authorized_user():
+ view_relationship = Permission.objects.filter(
+ name="Can view interpersonal relationship"
+ )
+ return UserFactory(user_permissions=tuple(view_relationship))
+
+ @property
+ def table_head(self):
+ thead = """
# |
@@ -617,61 +1165,112 @@ def setUpClass(cls):
"""
- # users
- view_relationships = Permission.objects.filter(
- name="Can view interpersonal relationship"
+ return thead
+
+ # MultipleObjectMixin
+ def test_allow_empty(self):
+ self.view.setup(self.request)
+ allow_empty = self.view.get_allow_empty()
+ self.assertTrue(allow_empty)
+
+ def test_ordering(self):
+ self.view.setup(self.request)
+ ordering = self.view.get_ordering()
+ self.assertIsNone(ordering)
+
+ # SearchableListMixin
+ def test_search_fields(self):
+ self.view.setup(self.request)
+ search_fields = self.view.get_search_fields_with_filters()
+ expected_search_fields = [
+ ("person__username", "icontains"),
+ ("relative__username", "icontains"),
+ ]
+ self.assertEqual(search_fields, expected_search_fields)
+
+ def test_search_query(self):
+ search_term = "search query"
+ self.request = self.build_get_request({"q": search_term})
+ self.view.setup(self.request)
+ search_query = self.view.get_search_query()
+ self.assertEqual(search_query, search_term)
+
+ def test_queryset_without_search_query(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.assertQuerysetEqual(queryset, InterpersonalRelationship.objects.all())
+
+ def test_queryset_with_search_query(self):
+ relationships = InterpersonalRelationshipFactory.create_batch(10)
+ search_term = relationships[0].person.full_name.split()[0]
+ self.request = self.build_get_request({"q": search_term})
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.assertQuerysetEqual(
+ queryset, search_interpersonal_relationships(search_term)
)
- cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(view_relationships))
- cls.staff_user = UserFactory(is_staff=True)
-
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
-
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/relationships_list.html")
-
- def test_context_data_contains_relationships(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertIn("relationships", response.context)
-
- def test_is_paginated(self):
- InterpersonalRelationshipFactory.create_batch(11)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTrue(response.context.get("is_paginated"))
- self.assertEqual(len(response.context.get("relationships")), 10)
-
- def test_pagination_lists_all_items(self):
- InterpersonalRelationshipFactory.create_batch(12)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url + "?page=2")
- expected_relationships = list(InterpersonalRelationship.objects.all())[-2:]
- people = list(response.context.get("relationships"))
- self.assertEqual(people, expected_relationships)
+ # MultipleObjectMixin
+ def test_paginate_by(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ paginate_by = self.view.get_paginate_by(queryset)
+ self.assertEqual(paginate_by, 10)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertEqual(context_object_name, "relationships")
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.view.object_list = queryset
+ context_object_name = self.view.get_context_object_name(queryset)
+ context_data = self.view.get_context_data()
+ expected_context_data_keys = [
+ "paginator",
+ "page_obj",
+ "is_paginated",
+ "object_list",
+ context_object_name,
+ "view",
+ ]
+ self.assertEqual(list(context_data.keys()), expected_context_data_keys)
+
+ # MultipleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ self.view.object_list = self.view.get_queryset()
+ template_names = self.view.get_template_names()
+ self.assertIn("people/relationships_list.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(
+ permission_required, ("people.view_interpersonalrelationship",)
+ )
+ # template logic
def test_response_with_no_relationships(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
+ # setup
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
+
+ # test
with self.assertRaises(AssertionError):
self.assertInHTML(self.table_head, response.content.decode())
self.assertInHTML(
@@ -679,9 +1278,13 @@ def test_response_with_no_relationships(self):
)
def test_response_with_relationships(self):
- InterpersonalRelationshipFactory.create_batch(3)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
+ # setup
+ InterpersonalRelationshipFactory()
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
+
+ # test
with self.assertRaises(AssertionError):
self.assertInHTML(
"There are no interpersonal relationships yet!",
@@ -689,24 +1292,15 @@ def test_response_with_relationships(self):
)
self.assertInHTML(self.table_head, response.content.decode())
- def test_search_results(self):
+ def test_response_with_no_search_results(self):
# setup
- relationships = InterpersonalRelationshipFactory.create_batch(10)
- search_term = relationships[0].person.username
- self.client.force_login(self.authorized_user)
+ search_term = "does not exist"
+ self.request = self.build_get_request({"q": search_term})
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
# test
- response = self.client.get(f"{self.url}?q={search_term}")
- search_results = response.context.get("relationships")
- self.assertQuerysetEqual(
- search_results, search_interpersonal_relationships(search_term)
- )
-
- def test_response_with_no_search_results(self):
- InterpersonalRelationshipFactory.create_batch(10)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url + "?q=Does not exist")
- self.assertEqual(list(response.context.get("relationships")), [])
with self.assertRaises(AssertionError):
self.assertInHTML(self.table_head, response.content.decode())
self.assertInHTML(
@@ -714,83 +1308,168 @@ def test_response_with_no_search_results(self):
)
-class RelationshipCreateViewTestCase(TestCase):
+class InterpersonalRelationshipCreateViewTestCase(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
- cls.url = "/people/relationships/add/"
-
- # users
- create_relationship = Permission.objects.filter(
- name="Can add interpersonal relationship"
- )
- view_relationship = Permission.objects.filter(
- name="Can view interpersonal relationship"
- )
- permissions = create_relationship | view_relationship
cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(permissions))
- cls.staff_user = UserFactory(is_staff=True)
-
- # POST data
cls.person = PersonFactory()
cls.relative = PersonFactory()
- cls.relation = InterpersonalRelationshipFactory.build().relation
- cls.data = {
+ cls.relationship = InterpersonalRelationshipFactory.build(
+ person=cls.person, relative=cls.relative
+ )
+ cls.form_data = {
"person": cls.person.username,
"relative": cls.relative.username,
- "relation": cls.relation,
+ "relation": cls.relationship.relation,
}
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.post("dummy_path", data=self.form_data)
+ self.view_class = views.RelationshipCreateView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ def get_data(self):
+ data = self.form_data.copy()
+ data["person"] = self.person
+ data["relative"] = self.relative
+ return data
+
+ # FormMixin
+ def test_initial(self):
+ self.view.setup(self.request)
+ initial = self.view.get_initial()
+ self.assertEqual(initial, {})
+
+ def test_prefix(self):
+ self.view.setup(self.request)
+ prefix = self.view.get_prefix()
+ self.assertIsNone(prefix)
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ def test_form_class(self):
+ self.view.setup(self.request)
+ form_class = self.view.get_form_class()
+ self.assertEqual(
+ form_class,
+ import_string("people.forms.InterpersonalRelationshipCreationForm"),
+ )
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
+ def test_form_kwargs(self):
+ self.view.setup(self.request)
+ form_kwargs = {
+ "initial": self.view.get_initial(),
+ "prefix": self.view.get_prefix(),
+ "data": self.request.POST,
+ "files": self.request.FILES,
+ }
+ self.assertEqual(self.view.get_form_kwargs(), form_kwargs)
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
+ def test_success_url(self):
+ self.view.setup(self.request)
+ self.view.object = self.relationship
+ success_url = self.view.get_success_url()
+ self.assertEqual(success_url, reverse("people:relationships_list"))
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/relationship_form.html")
+ def test_form_invalid(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_invalid(form)
+ self.assertEqual(response.status_code, 200)
- def test_form_class(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- form = response.context.get("form")
+ # SuccessMessageMixin
+ def test_success_message(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = self.relationship
+ data = self.get_data()
+ success_message = self.view.get_success_message(data)
+ people = f"{self.person} and {self.relative}"
self.assertEqual(
- form.__class__.__name__, "InterpersonalRelationshipCreationForm"
- )
- self.assertIsInstance(form, import_string("django.forms.ModelForm"))
- self.assertIsInstance(
- form, import_string("people.forms.InterpersonalRelationshipCreationForm")
+ success_message,
+ f"The relationship between {people} has been added successfully.",
)
- def test_form_valid(self):
- self.client.force_login(self.authorized_user)
- self.client.post(self.url, self.data)
- relationship = InterpersonalRelationship.objects.get(
- person__username=self.data["person"]
+ @patch("django.contrib.messages.success")
+ def test_form_valid_without_duplicate(self, mock_success):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
+ relationship = InterpersonalRelationship.objects.get(person=self.person)
+ self.assertEqual(relationship.created_by, self.user)
+
+ # ModelFormMixin
+ def test_form_valid_with_duplicate(self):
+ data = self.get_data()
+ InterpersonalRelationshipFactory(**data)
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = None
+ form = self.view.get_form()
+ self.assertFalse(form.is_valid())
+ self.assertEqual(
+ form.errors, {"__all__": ["This interpersonal relationship already exists"]}
)
- self.assertEqual(relationship.created_by, self.authorized_user)
- def test_success_url(self):
- self.client.force_login(self.authorized_user)
- response = self.client.post(self.url, self.data)
- self.assertRedirects(response, reverse("people:relationships_list"))
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "slug")
+
+ def test_object(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ obj = self.view.get_object()
+ self.assertIsNone(obj)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertIsNone(context_object_name)
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ self.view.object = None
+ context_data = self.view.get_context_data()
+ self.assertEqual(list(context_data.keys()), ["form", "view"])
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("people/relationship_form.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ("people.add_interpersonalrelationship",))
class ParentChildRelationshipCreateViewTestCase(TestCase):
@@ -798,81 +1477,183 @@ class ParentChildRelationshipCreateViewTestCase(TestCase):
def setUpClass(cls):
super().setUpClass()
- # users
cls.user = UserFactory()
- cls.authorized_user = UserFactory()
- cls.staff_user = UserFactory(is_staff=True)
-
- # people
- cls.person = AdultFactory(user=cls.authorized_user)
+ cls.person = AdultFactory(user=cls.user)
cls.parent = AdultFactory()
cls.child = ChildFactory()
- cls.url = f"/people/relationships/add/{cls.child.username}/parent/"
-
- # POST data
- cls.data = {"person": cls.parent.username}
-
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
-
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
+ cls.form_data = {"person": cls.parent.username}
+ cls.relationship_data = {
+ "person": cls.parent,
+ "relative": cls.child,
+ "relation": "PC",
+ }
+ cls.relationship = InterpersonalRelationshipFactory.build(
+ **cls.relationship_data
+ )
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "people/relationship_form.html")
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.post("dummy_path", data=self.form_data)
+ self.view_class = views.ParentChildRelationshipCreateView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
- def test_response_with_nonexistent_child(self):
- self.client.force_login(self.authorized_user)
- url = self.url.replace(self.child.username, "nonexistent-child")
- response = self.client.get(url)
- self.assertEqual(response.status_code, 404)
+ # FormMixin
+ def test_initial(self):
+ self.view.setup(self.request)
+ initial = self.view.get_initial()
+ self.assertEqual(initial, {})
- def test_context_data_contains_child(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("child"), self.child)
+ def test_prefix(self):
+ self.view.setup(self.request)
+ prefix = self.view.get_prefix()
+ self.assertIsNone(prefix)
def test_form_class(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- form = response.context.get("form")
- self.assertEqual(form.__class__.__name__, "ParentChildRelationshipCreationForm")
- self.assertIsInstance(form, import_string("django.forms.ModelForm"))
- self.assertIsInstance(
- form, import_string("people.forms.ParentChildRelationshipCreationForm")
+ self.view.setup(self.request)
+ form_class = self.view.get_form_class()
+ self.assertEqual(
+ form_class,
+ import_string("people.forms.ParentChildRelationshipCreationForm"),
)
+ def test_form_kwargs(self):
+ self.view.setup(self.request)
+ form_kwargs = {
+ "initial": self.view.get_initial(),
+ "prefix": self.view.get_prefix(),
+ "data": self.request.POST,
+ "files": self.request.FILES,
+ }
+ self.assertEqual(self.view.get_form_kwargs(), form_kwargs)
+
+ def test_success_url(self):
+ self.view.setup(self.request)
+ self.view.object = self.relationship
+ success_url = self.view.get_success_url()
+ self.assertEqual(success_url, reverse("core:dashboard"))
+
def test_form_invalid(self):
- # setup
- data = {"person": self.parent, "relative": self.child, "relation": "PC"}
- InterpersonalRelationshipFactory(**data)
- self.client.force_login(self.authorized_user)
+ self.request.user = self.user
+ self.view.setup(self.request, username=self.child.username)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_invalid(form)
+ self.assertEqual(response.status_code, 200)
- # test
- response = self.client.post(self.url, self.data)
- form = response.context.get("form")
- self.assertFalse(form.is_valid())
+ # SuccessMessageMixin
+ def test_success_message(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.view.object = self.relationship
+ data = self.form_data.copy()
+ success_message = self.view.get_success_message(data)
+ people = f"{self.parent} and {self.child}"
self.assertEqual(
- form.errors, {"__all__": ["This interpersonal relationship already exists"]}
+ success_message,
+ f"A parent-child relationship between {people} has been added.",
)
- def test_form_valid(self):
- self.client.force_login(self.authorized_user)
- self.client.post(self.url, self.data)
- relationship = InterpersonalRelationship.objects.get(relative=self.child)
- self.assertEqual(relationship.created_by, self.authorized_user)
+ @patch("django.contrib.messages.success")
+ def test_form_valid_without_duplicate(self, mock_success):
+ self.request.user = self.user
+ self.view.setup(self.request, username=self.child.username)
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
+ relationship = InterpersonalRelationship.objects.get(person=self.parent)
+ self.assertEqual(relationship.created_by, self.user)
+ self.assertEqual(relationship.relation, "PC")
+
+ # ModelFormMixin
+ def test_form_valid_with_duplicate(self):
+ # setup
+ InterpersonalRelationshipFactory(**self.relationship_data)
+ self.request.user = self.user
+ self.view.setup(self.request, username=self.child.username)
+ self.view.object = None
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
- def test_success_url(self):
- self.client.force_login(self.authorized_user)
- response = self.client.post(self.url, self.data)
- self.assertRedirects(response, reverse("core:dashboard"))
+ # test
+ self.assertEqual(response.status_code, 200)
+ response.render()
+ error_message = "This interpersonal relationship already exists"
+ self.assertInHTML(error_message, str(response.content))
+
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "slug")
+
+ def test_object(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ obj = self.view.get_object()
+ self.assertIsNone(obj)
+
+ def test_child_with_existing_person(self):
+ self.view.setup(self.request, username=self.child.username)
+ obj = self.view.get_child()
+ self.assertEqual(obj, self.child)
+
+ def test_child_with_non_existent_person(self):
+ self.view.setup(self.request, username="non-existent-person")
+ with self.assertRaises(Http404):
+ self.view.get_child()
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertIsNone(context_object_name)
+
+ def test_context_data(self):
+ self.view.setup(self.request, username=self.child.username)
+ self.view.object = None
+ context_data = self.view.get_context_data()
+ self.assertEqual(list(context_data.keys()), ["form", "view", "child"])
+ self.assertEqual(context_data.get("child"), self.child)
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("people/relationship_form.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ())
+
+ # UserPassesTestMixin
+ def test_test_func_false(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ self.assertFalse(self.view.test_func())
+
+ def test_test_func_true(self):
+ self.request.user = self.user
+ self.view.setup(self.request)
+ self.assertTrue(self.view.test_func())
diff --git a/records/tests/test_views.py b/records/tests/test_views.py
index 54e9fbbd..217aa41d 100644
--- a/records/tests/test_views.py
+++ b/records/tests/test_views.py
@@ -1,10 +1,15 @@
-from django.contrib.auth.models import Permission
-from django.test import TestCase
+from unittest.mock import patch
+
+from django.contrib.auth.models import AnonymousUser, Permission
+from django.core.exceptions import ImproperlyConfigured
+from django.http.response import Http404
+from django.test import RequestFactory, TestCase
from django.urls import reverse
from django.utils.module_loading import import_string
from accounts.factories import UserFactory
from people.factories import PersonFactory
+from records import views
from records.factories import TemperatureRecordFactory
from records.models import TemperatureRecord
@@ -16,70 +21,137 @@ class TemperatureRecordsListViewTestCase(TestCase):
def setUpClass(cls):
super().setUpClass()
- cls.url = "/records/temperature/"
- cls.table_head = """
+ cls.authorized_user = cls.get_authorized_user()
+
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.build_get_request()
+ self.view_class = views.TemperatureRecordsListView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ def build_get_request(self, data=None):
+ return self.factory.get("dummy_path", data=data)
+
+ @staticmethod
+ def get_authorized_user():
+ view_temp = Permission.objects.filter(name="Can view temperature record")
+ return UserFactory(user_permissions=tuple(view_temp))
+
+ @property
+ def table_head(self):
+ thead = """
- # |
- Username |
- Temperature |
- Time |
+ # |
+ Username |
+ Temperature |
+ Time |
"""
- # users
- view_temp = Permission.objects.filter(name="Can view temperature record")
- cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(view_temp))
- cls.staff_user = UserFactory(is_staff=True)
-
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
-
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
-
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "records/temperature_records_list.html")
-
- def test_context_data_contains_temperature_records(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertIn("temperature_records", response.context)
-
- def test_is_paginated(self):
- TemperatureRecordFactory.create_batch(11)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTrue(response.context.get("is_paginated"))
- self.assertEqual(len(response.context.get("temperature_records")), 10)
-
- def test_pagination_lists_all_items(self):
- TemperatureRecordFactory.create_batch(12)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url + "?page=2")
- expected_records = list(TemperatureRecord.objects.all())[-2:]
- temp_records = list(response.context.get("temperature_records"))
- self.assertEqual(temp_records, expected_records)
-
+ return thead
+
+ # MultipleObjectMixin
+ def test_allow_empty(self):
+ self.view.setup(self.request)
+ allow_empty = self.view.get_allow_empty()
+ self.assertTrue(allow_empty)
+
+ def test_ordering(self):
+ self.view.setup(self.request)
+ ordering = self.view.get_ordering()
+ self.assertIsNone(ordering)
+
+ # SearchableListMixin
+ def test_search_fields(self):
+ self.view.setup(self.request)
+ search_fields = self.view.get_search_fields_with_filters()
+ expected_search_fields = [
+ ("person__username", "icontains"),
+ ("person__full_name", "icontains"),
+ ]
+ self.assertEqual(search_fields, expected_search_fields)
+
+ def test_search_query(self):
+ search_term = "search query"
+ self.request = self.build_get_request({"q": search_term})
+ self.view.setup(self.request)
+ search_query = self.view.get_search_query()
+ self.assertEqual(search_query, search_term)
+
+ def test_queryset_without_search_query(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.assertQuerysetEqual(queryset, TemperatureRecord.objects.all())
+
+ def test_queryset_with_search_query(self):
+ temp_records = TemperatureRecordFactory.create_batch(10)
+ search_term = temp_records[0].person.full_name.split()[0]
+ self.request = self.build_get_request({"q": search_term})
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.assertQuerysetEqual(queryset, search_temperature_records(search_term))
+
+ # MultipleObjectMixin
+ def test_paginate_by(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ paginate_by = self.view.get_paginate_by(queryset)
+ self.assertEqual(paginate_by, 10)
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertEqual(context_object_name, "temperature_records")
+
+ def test_context_data(self):
+ self.view.setup(self.request)
+ queryset = self.view.get_queryset()
+ self.view.object_list = queryset
+ context_object_name = self.view.get_context_object_name(queryset)
+ context_data = self.view.get_context_data()
+ expected_context_data_keys = [
+ "paginator",
+ "page_obj",
+ "is_paginated",
+ "object_list",
+ context_object_name,
+ "view",
+ ]
+ self.assertEqual(list(context_data.keys()), expected_context_data_keys)
+
+ # MultipleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ self.view.object_list = self.view.get_queryset()
+ template_names = self.view.get_template_names()
+ self.assertIn("records/temperature_records_list.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ("records.view_temperaturerecord",))
+
+ # template logic
def test_response_with_no_temperature_records(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
+ # setup
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
+
+ # test
with self.assertRaises(AssertionError):
self.assertInHTML(self.table_head, response.content.decode())
self.assertInHTML(
@@ -87,33 +159,28 @@ def test_response_with_no_temperature_records(self):
)
def test_response_with_temperature_records(self):
- TemperatureRecordFactory.create_batch(3)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
+ # setup
+ TemperatureRecordFactory()
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
+
+ # test
with self.assertRaises(AssertionError):
self.assertInHTML(
"There are no temperature records yet!", response.content.decode()
)
self.assertInHTML(self.table_head, response.content.decode())
- def test_search_results(self):
+ def test_response_with_no_search_results(self):
# setup
- temp_records = TemperatureRecordFactory.create_batch(10)
- search_term = temp_records[0].person.full_name.split()[0]
- self.client.force_login(self.authorized_user)
+ search_term = "does not exist"
+ self.request = self.build_get_request({"q": search_term})
+ self.request.user = self.authorized_user
+ response = self.view_func(self.request)
+ response.render()
# test
- response = self.client.get(f"{self.url}?q={search_term}")
- search_results = response.context.get("temperature_records")
- self.assertQuerysetEqual(
- search_results, search_temperature_records(search_term)
- )
-
- def test_response_with_no_search_results(self):
- TemperatureRecordFactory.create_batch(10)
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url + "?q=Does not exist")
- self.assertEqual(list(response.context.get("temperature_records")), [])
with self.assertRaises(AssertionError):
self.assertInHTML(self.table_head, response.content.decode())
self.assertInHTML(
@@ -126,91 +193,155 @@ class TemperatureRecordCreateViewTestCase(TestCase):
def setUpClass(cls):
super().setUpClass()
- # users
- create_temp = Permission.objects.filter(name="Can add temperature record")
- view_person = Permission.objects.filter(name="Can view person")
- permissions = create_temp | view_person
+ cls.person = PersonFactory()
cls.user = UserFactory()
- cls.authorized_user = UserFactory(user_permissions=tuple(permissions))
- cls.staff_user = UserFactory(is_staff=True)
+ cls.temp_record = TemperatureRecordFactory.build(person=cls.person)
+ cls.form_data = {"body_temperature": cls.temp_record.body_temperature}
+
+ def setUp(self):
+ self.factory = RequestFactory()
+ self.request = self.factory.post("dummy_path", data=self.form_data)
+ self.view_class = views.TemperatureRecordCreateView
+ self.view_func = self.view_class.as_view()
+ self.view = self.view_class()
+
+ # FormMixin
+ def test_initial(self):
+ self.view.setup(self.request)
+ initial = self.view.get_initial()
+ self.assertEqual(initial, {})
+
+ def test_prefix(self):
+ self.view.setup(self.request)
+ prefix = self.view.get_prefix()
+ self.assertIsNone(prefix)
- # person
- cls.person = PersonFactory()
- cls.url = f"/records/temperature/{cls.person.username}/add/"
+ def test_form_class(self):
+ self.view.setup(self.request)
+ form_class = self.view.get_form_class()
+ self.assertEqual(
+ form_class, import_string("records.forms.TemperatureRecordCreationForm")
+ )
- # POST data
- cls.data = {
- "body_temperature": TemperatureRecordFactory.build().body_temperature
+ def test_form_kwargs(self):
+ self.view.setup(self.request)
+ form_kwargs = {
+ "initial": self.view.get_initial(),
+ "prefix": self.view.get_prefix(),
+ "data": self.request.POST,
+ "files": self.request.FILES,
}
+ self.assertEqual(self.view.get_form_kwargs(), form_kwargs)
- def test_anonymous_user_response(self):
- response = self.client.get(self.url)
- self.assertRedirects(response, f"/accounts/login/?next={self.url}")
-
- def test_authenticated_user_response(self):
- self.client.force_login(self.user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_authorized_user_response(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 200)
-
- def test_staff_user_response(self):
- self.client.force_login(self.staff_user)
- response = self.client.get(self.url)
- self.assertEqual(response.status_code, 403)
-
- def test_response_with_nonexistent_person(self):
- self.client.force_login(self.authorized_user)
- url = self.url.replace(self.person.username, "nonexistent-username")
- response = self.client.get(url)
- self.assertEqual(response.status_code, 404)
-
- def test_context_data_contains_person(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertEqual(response.context.get("person"), self.person)
-
- def test_template_used(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- self.assertTemplateUsed(response, "records/temperature_record_form.html")
-
- def test_form_class(self):
- self.client.force_login(self.authorized_user)
- response = self.client.get(self.url)
- form = response.context.get("form")
- self.assertEqual(form.__class__.__name__, "TemperatureRecordCreationForm")
- self.assertIsInstance(form, import_string("django.forms.ModelForm"))
- self.assertIsInstance(
- form, import_string("records.forms.TemperatureRecordCreationForm")
- )
+ def test_success_url(self):
+ self.view.setup(self.request)
+ self.view.object = self.temp_record
+ success_url = self.view.get_success_url()
+ self.assertEqual(success_url, reverse("people:people_list"))
def test_form_invalid(self):
- # setup
- data = self.data.copy()
- data["person"] = self.person
- TemperatureRecordFactory(**data)
- self.client.force_login(self.authorized_user)
+ self.request.user = self.user
+ self.view.setup(self.request, username=self.person.username)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_invalid(form)
+ self.assertEqual(response.status_code, 200)
- # test
- response = self.client.post(self.url, self.data)
- form = response.context.get("form")
- self.assertFalse(form.is_valid())
+ # SuccessMessageMixin
+ def test_success_message(self):
+ self.request.user = self.user
+ self.view.setup(self.request, username=self.person.username)
+ self.view.object = self.temp_record
+ success_message = self.view.get_success_message(self.form_data)
self.assertEqual(
- form.errors,
- {"__all__": [f"{self.person}'s temperature record already exists"]},
+ success_message,
+ f"A temperature record for {self.person} has been added successfully.",
)
- def test_form_valid(self):
- self.client.force_login(self.authorized_user)
- self.client.post(self.url, self.data)
+ @patch("django.contrib.messages.success")
+ def test_form_valid_without_duplicate(self, mock_success):
+ self.request.user = self.user
+ self.view.setup(self.request, username=self.person.username)
+ form = self.view.get_form()
+ self.assertTrue(form.is_valid())
+ response = self.view.form_valid(form)
+ self.assertTrue(mock_success.called)
+ self.assertEqual(response.status_code, 302)
temp_record = TemperatureRecord.objects.get(person=self.person)
- self.assertEqual(temp_record.created_by, self.authorized_user)
-
- def test_success_url(self):
- self.client.force_login(self.authorized_user)
- response = self.client.post(self.url, self.data)
- self.assertRedirects(response, reverse("people:people_list"))
+ self.assertEqual(temp_record.created_by, self.user)
+
+ # ModelFormMixin
+ def test_form_valid_with_duplicate(self):
+ TemperatureRecordFactory(person=self.person, **self.form_data)
+ self.request.user = self.user
+ self.view.setup(self.request, username=self.person.username)
+ self.view.object = None
+ form = self.view.get_form()
+ response = self.view.form_valid(form)
+ self.assertEqual(response.status_code, 200)
+ response.render()
+ error_message = f"{self.person}'s temperature record already exists"
+ self.assertInHTML(error_message, str(response.content))
+
+ # SingleObjectMixin
+ def test_queryset(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ self.assertEqual(list(queryset), [])
+
+ def test_slug_field(self):
+ self.view.setup(self.request)
+ slug_field = self.view.get_slug_field()
+ self.assertEqual(slug_field, "slug")
+
+ def test_object(self):
+ self.view.setup(self.request, username=self.person.username)
+ with self.assertRaises(ImproperlyConfigured):
+ obj = self.view.get_object()
+ self.assertIsNone(obj)
+
+ def test_person_with_existing_person(self):
+ self.view.setup(self.request, username=self.person.username)
+ obj = self.view.get_person()
+ self.assertEqual(obj, self.person)
+
+ def test_person_with_non_existent_person(self):
+ self.view.setup(self.request, username="non-existent-person")
+ with self.assertRaises(Http404):
+ self.view.get_person()
+
+ def test_context_object_name(self):
+ self.view.setup(self.request)
+ with self.assertRaises(ImproperlyConfigured):
+ queryset = self.view.get_queryset()
+ context_object_name = self.view.get_context_object_name(queryset)
+ self.assertIsNone(context_object_name)
+
+ def test_context_data(self):
+ self.view.setup(self.request, username=self.person.username)
+ self.view.object = None
+ context_data = self.view.get_context_data()
+ self.assertEqual(list(context_data.keys()), ["form", "view", "person"])
+ self.assertEqual(context_data.get("person"), self.person)
+
+ # SingleObjectTemplateResponseMixin
+ def test_template_name(self):
+ self.view.setup(self.request)
+ template_names = self.view.get_template_names()
+ self.assertIn("records/temperature_record_form.html", template_names)
+
+ # LoginRequiredMixin
+ def test_login_required(self):
+ self.request.user = AnonymousUser()
+ self.view.setup(self.request)
+ response = self.view.dispatch(self.request)
+ self.assertEqual(response.status_code, 302)
+ self.assertIn(reverse("account_login"), response.url)
+
+ # PermissionRequiredMixin
+ def test_permission_required(self):
+ self.request.user = UserFactory()
+ self.view.setup(self.request)
+ permission_required = self.view.get_permission_required()
+ self.assertEqual(permission_required, ("records.add_temperaturerecord",))