from django.contrib.auth import get_user_model from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.test import Client from hypothesis import given from hypothesis import strategies as st from hypothesis.extra.django import TestCase, from_model from paperwork.models import ( Certification, CertificationDefinition, CertificationVersion, Department, InstructorOrVendor, Waiver, ) class PermissionRequiredViewTestCaseMixin: permissions = [] path = None @classmethod def setUpTestData(cls): User = get_user_model() cls.client = Client() cls.user_without_permission = User.objects.create_user( username="user_without_permission" ) cls.user_with_permission = User.objects.create_user( username="user_with_permission" ) resolved_permissions = [ Permission.objects.get( content_type=ContentType.objects.get_for_model(permission["model"]), codename=permission["codename"], ) for permission in cls.permissions ] cls.user_with_permission.user_permissions.add(*resolved_permissions) def test_missing_permission(self) -> None: self.client.force_login(self.user_without_permission) response = self.client.get(self.path) self.assertEqual(response.status_code, 403) class WaiverReportTestCase(PermissionRequiredViewTestCaseMixin, TestCase): permissions = [{"model": Waiver, "codename": "view_waiver"}] path = "/paperwork/waivers" @given(waivers=st.lists(from_model(Waiver, number=st.none()))) def test_waiver_report(self, waivers: list[Waiver]) -> None: self.client.force_login(self.user_with_permission) response = self.client.get(self.path) self.assertEqual(response.status_code, 200) class InstructorOrVendorReportTestCase(PermissionRequiredViewTestCaseMixin, TestCase): permissions = [{"model": InstructorOrVendor, "codename": "view_instructororvendor"}] path = "/paperwork/instructors-and-vendors" @given( instructors_or_vendors=st.lists( from_model(InstructorOrVendor, serial=st.none()) ) ) def test_waiver_report( self, instructors_or_vendors: list[InstructorOrVendor] ) -> None: self.client.force_login(self.user_with_permission) response = self.client.get(self.path) self.assertEqual(response.status_code, 200) @st.composite def random_certifications(draw): departments = draw(st.lists(from_model(Department), min_size=1)) definitions = draw( st.lists( from_model( CertificationDefinition, department=st.sampled_from(departments) ), min_size=1, ) ) certification_versions = draw( st.lists( from_model(CertificationVersion, definition=st.sampled_from(definitions)), min_size=1, ) ) return draw( st.lists( from_model( Certification, number=st.none(), certification_version=st.sampled_from(certification_versions), ) ) ) class CertifiersReportTestCase(PermissionRequiredViewTestCaseMixin, TestCase): permissions = [{"model": Certification, "codename": "view_certification"}] path = "/paperwork/certifiers" @given(certifications=random_certifications()) def test_certifers_report(self, certifications: list[Certification]) -> None: self.client.force_login(self.user_with_permission) response = self.client.get(self.path) self.assertEqual(response.status_code, 200) class CertificationCountReportTestCase(PermissionRequiredViewTestCaseMixin, TestCase): permissions = [{"model": Certification, "codename": "view_certification"}] path = "/paperwork/certification-count" @given(certifications=random_certifications()) def test_certification_count_report( self, certifications: list[Certification] ) -> None: self.client.force_login(self.user_with_permission) response = self.client.get(self.path) self.assertEqual(response.status_code, 200)