From 889a88034ed5c33f1a2e2f2a4fdc1a6da6dc13c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20H=C3=A4ttasch?= <benjamin.haettasch@fachschaft.informatik.tu-darmstadt.de> Date: Fri, 2 Dec 2022 21:52:53 +0100 Subject: [PATCH] Add view tests Introduce framework to simply test correct rendering of views Create tests for dashboard views Create tests for plan views Create tests for default admin views (add and change) of AKModel models --- AKDashboard/fixtures/dashboard.json | 13 + AKDashboard/tests.py | 12 + AKModel/fixtures/model.json | 670 ++++++++++++++++++++++++++++ AKModel/tests.py | 96 +++- AKPlan/tests.py | 29 +- 5 files changed, 818 insertions(+), 2 deletions(-) create mode 100644 AKDashboard/fixtures/dashboard.json create mode 100644 AKModel/fixtures/model.json diff --git a/AKDashboard/fixtures/dashboard.json b/AKDashboard/fixtures/dashboard.json new file mode 100644 index 00000000..dde1a64d --- /dev/null +++ b/AKDashboard/fixtures/dashboard.json @@ -0,0 +1,13 @@ +[ +{ + "model": "AKDashboard.dashboardbutton", + "pk": 1, + "fields": { + "text": "Wiki", + "url": "http://wiki.kif.rocks", + "icon": "fab,wikipedia-w", + "color": 2, + "event": 2 + } +} +] diff --git a/AKDashboard/tests.py b/AKDashboard/tests.py index f4fbff87..dc77d528 100644 --- a/AKDashboard/tests.py +++ b/AKDashboard/tests.py @@ -6,6 +6,7 @@ from django.utils.timezone import now from AKDashboard.models import DashboardButton from AKModel.models import Event, AK, AKCategory +from AKModel.tests import BasicViewTests class DashboardTests(TestCase): @@ -126,3 +127,14 @@ class DashboardTests(TestCase): response = self.client.get(url_event_dashboard) self.assertContains(response, "Dashboard Button Test") + + +class DashboardViewTests(BasicViewTests, TestCase): + fixtures = ['model.json', 'dashboard.json'] + + APP_NAME = 'dashboard' + + VIEWS = [ + ('dashboard', {}), + ('dashboard_event', {'slug': 'kif42'}), + ] diff --git a/AKModel/fixtures/model.json b/AKModel/fixtures/model.json new file mode 100644 index 00000000..b75d5093 --- /dev/null +++ b/AKModel/fixtures/model.json @@ -0,0 +1,670 @@ +[ +{ + "model": "AKModel.event", + "pk": 1, + "fields": { + "name": "KIF 23", + "slug": "kif23", + "place": "Neuland", + "timezone": "Europe/Berlin", + "start": "2020-10-01T17:41:22Z", + "end": "2020-10-04T17:41:30Z", + "reso_deadline": "2020-10-03T10:00:00Z", + "interest_start": null, + "interest_end": null, + "public": true, + "active": false, + "plan_hidden": true, + "plan_published_at": null, + "base_url": "", + "wiki_export_template_name": "", + "default_slot": "2.00", + "contact_email": "dummy@eyample.org" + } +}, +{ + "model": "AKModel.event", + "pk": 2, + "fields": { + "name": "KIF 42", + "slug": "kif42", + "place": "Neuland noch neuer", + "timezone": "Europe/Berlin", + "start": "2020-11-06T17:51:26Z", + "end": "2020-11-10T17:51:27Z", + "reso_deadline": "2020-11-08T17:51:42Z", + "interest_start": null, + "interest_end": null, + "public": true, + "active": true, + "plan_hidden": false, + "plan_published_at": "2022-12-01T21:50:01Z", + "base_url": "", + "wiki_export_template_name": "", + "default_slot": "2.00", + "contact_email": "dummy@example.org" + } +}, +{ + "model": "AKModel.akowner", + "pk": 1, + "fields": { + "name": "a", + "slug": "a", + "institution": "Uni X", + "link": "", + "event": 2 + } +}, +{ + "model": "AKModel.akowner", + "pk": 2, + "fields": { + "name": "b", + "slug": "b", + "institution": "Hochschule Y", + "link": "", + "event": 2 + } +}, +{ + "model": "AKModel.akowner", + "pk": 3, + "fields": { + "name": "c", + "slug": "c", + "institution": "", + "link": "", + "event": 1 + } +}, +{ + "model": "AKModel.akowner", + "pk": 4, + "fields": { + "name": "d", + "slug": "d", + "institution": "", + "link": "", + "event": 1 + } +}, +{ + "model": "AKModel.akcategory", + "pk": 1, + "fields": { + "name": "Spaâ–€", + "color": "275246", + "description": "", + "present_by_default": true, + "event": 1 + } +}, +{ + "model": "AKModel.akcategory", + "pk": 2, + "fields": { + "name": "Ernst", + "color": "234567", + "description": "", + "present_by_default": true, + "event": 1 + } +}, +{ + "model": "AKModel.akcategory", + "pk": 3, + "fields": { + "name": "Spaâ–€/Kultur", + "color": "333333", + "description": "", + "present_by_default": true, + "event": 2 + } +}, +{ + "model": "AKModel.akcategory", + "pk": 4, + "fields": { + "name": "Inhalt", + "color": "456789", + "description": "", + "present_by_default": true, + "event": 2 + } +}, +{ + "model": "AKModel.akcategory", + "pk": 5, + "fields": { + "name": "Meta", + "color": "111111", + "description": "", + "present_by_default": true, + "event": 2 + } +}, +{ + "model": "AKModel.aktrack", + "pk": 1, + "fields": { + "name": "Track 1", + "color": "", + "event": 2 + } +}, +{ + "model": "AKModel.aktag", + "pk": 1, + "fields": { + "name": "metametameta" + } +}, +{ + "model": "AKModel.akrequirement", + "pk": 1, + "fields": { + "name": "Beamer", + "event": 1 + } +}, +{ + "model": "AKModel.akrequirement", + "pk": 2, + "fields": { + "name": "Internet", + "event": 1 + } +}, +{ + "model": "AKModel.akrequirement", + "pk": 3, + "fields": { + "name": "BBB", + "event": 2 + } +}, +{ + "model": "AKModel.akrequirement", + "pk": 4, + "fields": { + "name": "Mumble", + "event": 2 + } +}, +{ + "model": "AKModel.akrequirement", + "pk": 5, + "fields": { + "name": "Matrix", + "event": 2 + } +}, +{ + "model": "AKModel.historicalak", + "pk": 1, + "fields": { + "id": 1, + "name": "Test AK Inhalt", + "short_name": "test1", + "description": "", + "link": "", + "protocol_link": "", + "reso": false, + "present": true, + "notes": "", + "interest": -1, + "category": 4, + "track": null, + "event": 2, + "history_date": "2021-05-04T10:28:59.265Z", + "history_change_reason": null, + "history_type": "+", + "history_user": null + } +}, +{ + "model": "AKModel.historicalak", + "pk": 2, + "fields": { + "id": 1, + "name": "Test AK Inhalt", + "short_name": "test1", + "description": "", + "link": "", + "protocol_link": "", + "reso": false, + "present": true, + "notes": "", + "interest": -1, + "category": 4, + "track": null, + "event": 2, + "history_date": "2021-05-04T10:28:59.305Z", + "history_change_reason": null, + "history_type": "~", + "history_user": null + } +}, +{ + "model": "AKModel.historicalak", + "pk": 3, + "fields": { + "id": 2, + "name": "Test AK Meta", + "short_name": "test2", + "description": "", + "link": "", + "protocol_link": "", + "reso": false, + "present": null, + "notes": "", + "interest": -1, + "category": 5, + "track": null, + "event": 2, + "history_date": "2021-05-04T10:29:40.296Z", + "history_change_reason": null, + "history_type": "+", + "history_user": null + } +}, +{ + "model": "AKModel.historicalak", + "pk": 4, + "fields": { + "id": 2, + "name": "Test AK Meta", + "short_name": "test2", + "description": "", + "link": "", + "protocol_link": "", + "reso": false, + "present": null, + "notes": "", + "interest": -1, + "category": 5, + "track": null, + "event": 2, + "history_date": "2021-05-04T10:29:40.355Z", + "history_change_reason": null, + "history_type": "~", + "history_user": null + } +}, +{ + "model": "AKModel.historicalak", + "pk": 5, + "fields": { + "id": 3, + "name": "AK Wish", + "short_name": "wish1", + "description": "Description of my Wish", + "link": "", + "protocol_link": "", + "reso": false, + "present": null, + "notes": "We need to find a volunteer first...", + "interest": -1, + "category": 3, + "track": null, + "event": 2, + "history_date": "2021-05-04T10:30:59.469Z", + "history_change_reason": null, + "history_type": "+", + "history_user": null + } +}, +{ + "model": "AKModel.historicalak", + "pk": 6, + "fields": { + "id": 3, + "name": "AK Wish", + "short_name": "wish1", + "description": "Description of my Wish", + "link": "", + "protocol_link": "", + "reso": false, + "present": null, + "notes": "We need to find a volunteer first...", + "interest": -1, + "category": 3, + "track": null, + "event": 2, + "history_date": "2021-05-04T10:30:59.509Z", + "history_change_reason": null, + "history_type": "~", + "history_user": null + } +}, +{ + "model": "AKModel.historicalak", + "pk": 7, + "fields": { + "id": 2, + "name": "Test AK Meta", + "short_name": "test2", + "description": "", + "link": "", + "protocol_link": "", + "reso": false, + "present": null, + "notes": "", + "interest": -1, + "category": 5, + "track": 1, + "event": 2, + "history_date": "2022-12-02T12:27:14.277Z", + "history_change_reason": null, + "history_type": "~", + "history_user": null + } +}, +{ + "model": "AKModel.ak", + "pk": 1, + "fields": { + "name": "Test AK Inhalt", + "short_name": "test1", + "description": "", + "link": "", + "protocol_link": "", + "category": 4, + "track": null, + "reso": false, + "present": true, + "notes": "", + "interest": -1, + "interest_counter": 0, + "event": 2, + "owners": [ + 1 + ], + "tags": [], + "requirements": [ + 3 + ], + "conflicts": [], + "prerequisites": [] + } +}, +{ + "model": "AKModel.ak", + "pk": 2, + "fields": { + "name": "Test AK Meta", + "short_name": "test2", + "description": "", + "link": "", + "protocol_link": "", + "category": 5, + "track": 1, + "reso": false, + "present": null, + "notes": "", + "interest": -1, + "interest_counter": 0, + "event": 2, + "owners": [ + 2 + ], + "tags": [ + 1 + ], + "requirements": [], + "conflicts": [], + "prerequisites": [] + } +}, +{ + "model": "AKModel.ak", + "pk": 3, + "fields": { + "name": "AK Wish", + "short_name": "wish1", + "description": "Description of my Wish", + "link": "", + "protocol_link": "", + "category": 3, + "track": null, + "reso": false, + "present": null, + "notes": "We need to find a volunteer first...", + "interest": -1, + "interest_counter": 0, + "event": 2, + "owners": [], + "tags": [], + "requirements": [ + 4 + ], + "conflicts": [ + 1 + ], + "prerequisites": [ + 2 + ] + } +}, +{ + "model": "AKModel.room", + "pk": 1, + "fields": { + "name": "Testraum", + "location": "BBB", + "capacity": -1, + "event": 2, + "properties": [ + 3 + ] + } +}, +{ + "model": "AKModel.room", + "pk": 2, + "fields": { + "name": "Testraum 2", + "location": "", + "capacity": 30, + "event": 2, + "properties": [] + } +}, +{ + "model": "AKModel.akslot", + "pk": 1, + "fields": { + "ak": 1, + "room": 2, + "start": "2020-11-06T18:30:00Z", + "duration": "2.00", + "fixed": false, + "event": 2, + "updated": "2022-12-02T12:23:11.856Z" + } +}, +{ + "model": "AKModel.akslot", + "pk": 2, + "fields": { + "ak": 2, + "room": 1, + "start": "2020-11-08T12:30:00Z", + "duration": "2.00", + "fixed": false, + "event": 2, + "updated": "2022-12-02T12:23:18.279Z" + } +}, +{ + "model": "AKModel.akslot", + "pk": 3, + "fields": { + "ak": 3, + "room": null, + "start": null, + "duration": "1.50", + "fixed": false, + "event": 2, + "updated": "2021-05-04T10:30:59.523Z" + } +}, +{ + "model": "AKModel.akslot", + "pk": 4, + "fields": { + "ak": 3, + "room": null, + "start": null, + "duration": "3.00", + "fixed": false, + "event": 2, + "updated": "2021-05-04T10:30:59.528Z" + } +}, +{ + "model": "AKModel.constraintviolation", + "pk": 1, + "fields": { + "type": "soa", + "level": 10, + "event": 2, + "ak_owner": null, + "room": null, + "requirement": null, + "category": null, + "comment": "", + "timestamp": "2022-12-02T12:23:11.875Z", + "manually_resolved": false, + "aks": [ + 1 + ], + "ak_slots": [ + 1 + ] + } +}, +{ + "model": "AKModel.constraintviolation", + "pk": 2, + "fields": { + "type": "rng", + "level": 10, + "event": 2, + "ak_owner": null, + "room": 2, + "requirement": 3, + "category": null, + "comment": "", + "timestamp": "2022-12-02T12:23:11.890Z", + "manually_resolved": false, + "aks": [ + 1 + ], + "ak_slots": [ + 1 + ] + } +}, +{ + "model": "AKModel.constraintviolation", + "pk": 3, + "fields": { + "type": "soa", + "level": 10, + "event": 2, + "ak_owner": null, + "room": null, + "requirement": null, + "category": null, + "comment": "", + "timestamp": "2022-12-02T12:23:18.301Z", + "manually_resolved": false, + "aks": [ + 2 + ], + "ak_slots": [ + 2 + ] + } +}, +{ + "model": "AKModel.availability", + "pk": 1, + "fields": { + "event": 2, + "person": null, + "room": null, + "ak": 1, + "ak_category": null, + "start": "2020-11-07T08:00:00Z", + "end": "2020-11-07T18:00:00Z" + } +}, +{ + "model": "AKModel.availability", + "pk": 2, + "fields": { + "event": 2, + "person": null, + "room": null, + "ak": 1, + "ak_category": null, + "start": "2020-11-09T10:00:00Z", + "end": "2020-11-09T16:30:00Z" + } +}, +{ + "model": "AKModel.availability", + "pk": 3, + "fields": { + "event": 2, + "person": null, + "room": 1, + "ak": null, + "ak_category": null, + "start": "2020-11-06T17:51:26Z", + "end": "2020-11-10T23:00:00Z" + } +}, +{ + "model": "AKModel.availability", + "pk": 4, + "fields": { + "event": 2, + "person": null, + "room": 2, + "ak": null, + "ak_category": null, + "start": "2020-11-06T17:51:26Z", + "end": "2020-11-06T21:00:00Z" + } +}, +{ + "model": "AKModel.availability", + "pk": 5, + "fields": { + "event": 2, + "person": null, + "room": 2, + "ak": null, + "ak_category": null, + "start": "2020-11-08T15:30:00Z", + "end": "2020-11-08T19:30:00Z" + } +}, +{ + "model": "AKModel.availability", + "pk": 6, + "fields": { + "event": 2, + "person": null, + "room": 2, + "ak": null, + "ak_category": null, + "start": "2020-11-07T18:30:00Z", + "end": "2020-11-07T21:30:00Z" + } +} +] diff --git a/AKModel/tests.py b/AKModel/tests.py index a39b155a..4ba5d32f 100644 --- a/AKModel/tests.py +++ b/AKModel/tests.py @@ -1 +1,95 @@ -# Create your tests here. +from django.contrib.auth.models import User +from django.test import TestCase +from django.urls import reverse_lazy + +from AKModel.models import Event, AKOwner, AKCategory, AKTrack, AKRequirement, AK, Room, AKSlot, AKOrgaMessage, \ + ConstraintViolation, DefaultSlot + + +class BasicViewTests: + VIEWS = [] + APP_NAME = '' + VIEWS_STAFF_ONLY = [] + + def setUp(self): + self.staff_user = User.objects.create( + username='Test Staff User', email='teststaff@example.com', password='staffpw', + is_staff=True, is_active=True + ) + self.admin_user = User.objects.create( + username='Test Admin User', email='testadmin@example.com', password='adminpw', + is_staff=True, is_superuser=True, is_active=True + ) + self.deactivated_user = User.objects.create( + username='Test Deactivated User', email='testdeactivated@example.com', password='deactivatedpw', + is_staff=True, is_active=False + ) + + def _name_and_url(self, view_name): + """ + Get full view name (with prefix if there is one) and url from raw view definition + + :param view_name: raw definition of a view + :type view_name: (str, dict) + :return: full view name with prefix if applicable, url of the view + :rtype: str, str + """ + view_name_with_prefix = f"{self.APP_NAME}:{view_name[0]}" if self.APP_NAME != "" else view_name[0] + url = reverse_lazy(view_name_with_prefix, kwargs=view_name[1]) + return view_name_with_prefix, url + + def testViewsFor200(self): + for view_name in self.VIEWS: + view_name_with_prefix, url = self._name_and_url(view_name) + response = self.client.get(url) + self.assertEqual(response.status_code, 200, msg=f"{view_name_with_prefix} ({url}) broken") + + def testAccessControlStaffOnly(self): + self.client.logout() + for view_name in self.VIEWS_STAFF_ONLY: + view_name_with_prefix, url = self._name_and_url(view_name) + response = self.client.get(url) + self.assertEqual(response.status_code, 302, msg=f"{view_name_with_prefix} ({url}) accessible by non-staff") + + self.client.force_login(self.staff_user) + for view_name in self.VIEWS_STAFF_ONLY: + view_name_with_prefix, url = self._name_and_url(view_name) + response = self.client.get(url) + self.assertEqual(response.status_code, 200, + msg=f"{view_name_with_prefix} ({url}) should be accessible for staff (but isn't)") + + self.client.force_login(self.deactivated_user) + for view_name in self.VIEWS_STAFF_ONLY: + view_name_with_prefix, url = self._name_and_url(view_name) + response = self.client.get(url) + self.assertEqual(response.status_code, 302, + msg=f"{view_name_with_prefix} ({url}) still accessible for deactivated user") + + +class ModelViewTests(BasicViewTests, TestCase): + fixtures = ['model.json'] + + ADMIN_MODELS = [ + (Event, 'event'), (AKOwner, 'akowner'), (AKCategory, 'akcategory'), (AKTrack, 'aktrack'), + (AKRequirement, 'akrequirement'), (AK, 'ak'), (Room, 'room'), (AKSlot, 'akslot'), + (AKOrgaMessage, 'akorgamessage'), (ConstraintViolation, 'constraintviolation'), + (DefaultSlot, 'defaultslot') + ] + + def testAdmin(self): + self.client.force_login(self.admin_user) + + for model in self.ADMIN_MODELS: + if model[1] == "event": + continue + view_name_with_prefix, url = self._name_and_url((f'admin:AKModel_{model[1]}_add', {})) + response = self.client.get(url) + self.assertEqual(response.status_code, 200, msg=f"Add form for model {model[1]} ({url}) broken") + + for model in self.ADMIN_MODELS: + m = model[0].objects.first() + if m is not None: + view_name_with_prefix, url = self._name_and_url((f'admin:AKModel_{model[1]}_change', {'object_id': m.pk})) + print(view_name_with_prefix) + response = self.client.get(url) + self.assertEqual(response.status_code, 200, msg=f"Edit form for model {model[1]} ({url}) broken") diff --git a/AKPlan/tests.py b/AKPlan/tests.py index a39b155a..8a7bd4e1 100644 --- a/AKPlan/tests.py +++ b/AKPlan/tests.py @@ -1 +1,28 @@ -# Create your tests here. +from django.test import TestCase + +from AKModel.tests import BasicViewTests + + +class PlanViewTests(BasicViewTests, TestCase): + fixtures = ['model.json'] + APP_NAME = 'plan' + + VIEWS = [ + ('plan_overview', {'event_slug': 'kif42'}), + ('plan_wall', {'event_slug': 'kif42'}), + ('plan_room', {'event_slug': 'kif42', 'pk': 2}), + ('plan_track', {'event_slug': 'kif42', 'pk': 1}), + ] + + def testPlanHidden(self): + view_name_with_prefix, url = self._name_and_url(('plan_overview', {'event_slug': 'kif23'})) + + self.client.logout() + response = self.client.get(url) + self.assertContains(response, "Plan is not visible (yet).", + msg_prefix="Plan is visible even though it shouldn't be") + + self.client.force_login(self.staff_user) + response = self.client.get(url) + self.assertNotContains(response, "Plan is not visible (yet).", + msg_prefix="Plan is not visible for staff user") -- GitLab