From ff5b7e5ed8e71a6110d006eed64551b4cd0823f0 Mon Sep 17 00:00:00 2001 From: Josh Stegmaier <104993387+joshuastegmaier@users.noreply.github.com> Date: Wed, 13 Nov 2024 14:01:12 -0500 Subject: [PATCH] Testing conditionals in various views (#2590) * Added home page tests * Added topic detail view test * Added test for campaign detail view conditionals * Removed superfluous conditional in campaign detail view * Added tests for project detail view conditionals * Added tests for project detail view conditionals * Added tests for item detail view conditionals * Added tests for asset detail view conditionals --- concordia/tests/test_top_level_views.py | 25 ++- concordia/tests/test_views.py | 229 ++++++++++++++++++++++-- concordia/views.py | 10 +- 3 files changed, 240 insertions(+), 24 deletions(-) diff --git a/concordia/tests/test_top_level_views.py b/concordia/tests/test_top_level_views.py index 81ec3012e..a180ddf9b 100644 --- a/concordia/tests/test_top_level_views.py +++ b/concordia/tests/test_top_level_views.py @@ -11,7 +11,7 @@ from django.urls import reverse from maintenance_mode.core import get_maintenance_mode, set_maintenance_mode -from concordia.models import Guide, SimplePage +from concordia.models import Banner, CarouselSlide, Guide, OverlayPosition, SimplePage from concordia.views import simple_page from .utils import ( @@ -39,9 +39,32 @@ def test_healthz(self): def test_homepage(self): response = self.client.get(reverse("homepage")) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, "home.html") + banner = Banner.objects.create( + slug="test-banner", text="Test Banner", active=True + ) + response = self.client.get(reverse("homepage")) + context = response.context + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, "home.html") + self.assertIn("banner", context) + self.assertEqual(context["banner"].text, banner.text) + banner.delete() + + slide = CarouselSlide.objects.create( + published=True, + overlay_position=OverlayPosition.LEFT, + headline="Test Headline", + ) + response = self.client.get(reverse("homepage")) + context = response.context self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, "home.html") + self.assertIn("firstslide", context) + self.assertEqual(context["firstslide"].headline, slide.headline) + slide.delete() def test_contact_us_get(self): response = self.client.get(reverse("contact")) diff --git a/concordia/tests/test_views.py b/concordia/tests/test_views.py index d478b5afe..a5acb7505 100644 --- a/concordia/tests/test_views.py +++ b/concordia/tests/test_views.py @@ -25,6 +25,7 @@ TranscriptionStatus, ) from concordia.tasks import ( + campaign_report, delete_old_tombstoned_reservations, expire_inactive_asset_reservations, tombstone_old_active_asset_reservations, @@ -49,6 +50,7 @@ create_guide, create_item, create_project, + create_tag_collection, create_topic, create_transcription, ) @@ -224,6 +226,22 @@ def test_topic_detail_view(self): ) self.assertContains(response, c.title) + response = self.client.get( + reverse("topic-detail", args=(c.slug,)), + {"transcription_status": "not_started"}, + ) + context = response.context + + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed( + response, template_name="transcriptions/topic_detail.html" + ) + self.assertContains(response, c.title) + self.assertIn("sublevel_querystring", context) + self.assertEqual( + context["sublevel_querystring"], "transcription_status=not_started" + ) + def test_unlisted_topic_detail_view(self): c2 = create_topic( title="GET Unlisted Topic", unlisted=True, slug="get-unlisted-topic" @@ -241,31 +259,66 @@ def test_campaign_detail_view(self): """ Test GET on route /campaigns/ (campaign) """ - c = create_campaign(title="GET Campaign", slug="get-campaign") - + campaign = create_campaign(title="GET Campaign", slug="get-campaign") response = self.client.get( - reverse("transcriptions:campaign-detail", args=(c.slug,)) + reverse("transcriptions:campaign-detail", args=(campaign.slug,)) ) - self.assertEqual(response.status_code, 200) self.assertTemplateUsed( response, template_name="transcriptions/campaign_detail.html" ) - self.assertContains(response, c.title) + self.assertContains(response, campaign.title) + # Filter by reviewable parameter check + response = self.client.get( + reverse("transcriptions:campaign-detail", args=(campaign.slug,)), + {"filter_by_reviewable": True}, + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed( + response, template_name="transcriptions/campaign_detail.html" + ) + self.assertContains(response, campaign.title) + # Bad status parameter check + response = self.client.get( + reverse("transcriptions:campaign-detail", args=(campaign.slug,)), + {"transcription_status": "bad_parameter"}, + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed( + response, template_name="transcriptions/campaign_detail.html" + ) + self.assertContains(response, campaign.title) - c2 = create_campaign( + # Unlisted + campaign = create_campaign( title="GET Unlisted Campaign", unlisted=True, slug="get-unlisted-campaign" ) - - response2 = self.client.get( - reverse("transcriptions:campaign-detail", args=(c2.slug,)) + response = self.client.get( + reverse("transcriptions:campaign-detail", args=(campaign.slug,)) + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed( + response, template_name="transcriptions/campaign_detail.html" ) + self.assertContains(response, campaign.title) - self.assertEqual(response2.status_code, 200) + # Retired + campaign = create_campaign( + title="GET Retired Campaign", + slug="get-retired-campaign", + status=Campaign.Status.RETIRED, + ) + # We need a site report for a retired campaign because + # that's where the view pulls data from + campaign_report(campaign=campaign) + response = self.client.get( + reverse("transcriptions:campaign-detail", args=(campaign.slug,)) + ) + self.assertEqual(response.status_code, 200) self.assertTemplateUsed( - response2, template_name="transcriptions/campaign_detail.html" + response, template_name="transcriptions/campaign_detail_retired.html" ) - self.assertContains(response2, c2.title) + self.assertContains(response, campaign.title) def test_campaign_unicode_slug(self): """Confirm that Unicode characters are usable in Campaign URLs""" @@ -306,13 +359,11 @@ def test_empty_item_detail_view(self): args=(item.project.campaign.slug, item.project.slug, item.item_id), ) ) - self.assertEqual(response.status_code, 200) self.assertTemplateUsed( response, template_name="transcriptions/item_detail.html" ) self.assertContains(response, item.title) - self.assertEqual(0, response.context["not_started_percent"]) self.assertEqual(0, response.context["in_progress_percent"]) self.assertEqual(0, response.context["submitted_percent"]) @@ -353,19 +404,55 @@ def test_item_detail_view(self): args=(item.project.campaign.slug, item.project.slug, item.item_id), ) ) - self.assertEqual(response.status_code, 200) self.assertTemplateUsed( response, template_name="transcriptions/item_detail.html" ) self.assertContains(response, item.title) - # We have 10 total, 6 of which have transcription records and of those # 6, 3 have been submitted and one of those was accepted: self.assertEqual(40, response.context["not_started_percent"]) self.assertEqual(30, response.context["in_progress_percent"]) self.assertEqual(20, response.context["submitted_percent"]) self.assertEqual(10, response.context["completed_percent"]) + # Filter by reviewable parameter check + response = self.client.get( + reverse( + "transcriptions:item-detail", + args=(item.project.campaign.slug, item.project.slug, item.item_id), + ), + {"filter_by_reviewable": True}, + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed( + response, template_name="transcriptions/item_detail.html" + ) + # Bad status parameter check + response = self.client.get( + reverse( + "transcriptions:item-detail", + args=(item.project.campaign.slug, item.project.slug, item.item_id), + ), + {"transcription_status": "bad_parameter"}, + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed( + response, template_name="transcriptions/item_detail.html" + ) + + # Non-existent item in an existing campaign + response = self.client.get( + reverse( + "transcriptions:item-detail", + args=(item.project.campaign.slug, item.project.slug, "bad-id"), + ) + ) + self.assertRedirects( + response, + reverse( + "transcriptions:campaign-detail", args=(item.project.campaign.slug,) + ), + ) def test_asset_unicode_slug(self): """Confirm that Unicode characters are usable in Asset URLs""" @@ -385,7 +472,7 @@ def test_asset_detail_view(self): """ self.login_user() - asset = create_asset() + asset = create_asset(sequence=100) self.transcription = asset.transcription_set.create( user_id=self.user.id, text="Test transcription 1" @@ -397,6 +484,8 @@ def test_asset_detail_view(self): title = "Transcription: Basic Rules" create_guide(title=title) + tag_collection = create_tag_collection(asset=asset) + response = self.client.get( reverse( "transcriptions:asset-detail", @@ -412,6 +501,75 @@ def test_asset_detail_view(self): self.assertIn("cards", response.context) self.assertIn("guides", response.context) self.assertEqual(title, response.context["guides"][0]["title"]) + self.assertIn("tags", response.context) + self.assertEqual([tag_collection.tags.all()[0].value], response.context["tags"]) + + # Next and previous asset checks + previous_asset = create_asset( + item=asset.item, slug="previous-asset", sequence=1 + ) + next_asset = create_asset(item=asset.item, slug="next-asset", sequence=1000) + response = self.client.get( + reverse( + "transcriptions:asset-detail", + kwargs={ + "campaign_slug": asset.item.project.campaign.slug, + "project_slug": asset.item.project.slug, + "item_id": asset.item.item_id, + "slug": asset.slug, + }, + ) + ) + self.assertEqual(response.status_code, 200) + self.assertIn("previous_asset_url", response.context) + self.assertEqual( + previous_asset.get_absolute_url(), response.context["previous_asset_url"] + ) + self.assertIn("next_asset_url", response.context) + self.assertEqual( + next_asset.get_absolute_url(), response.context["next_asset_url"] + ) + + # Download URL iiif check + asset.download_url = "http://tile.loc.gov/image-services/iiif/service:music:mussuffrage:mussuffrage-100183:mussuffrage-100183.0001/full/pct:100/0/default.jpg" + asset.save() + response = self.client.get( + reverse( + "transcriptions:asset-detail", + kwargs={ + "campaign_slug": asset.item.project.campaign.slug, + "project_slug": asset.item.project.slug, + "item_id": asset.item.item_id, + "slug": asset.slug, + }, + ) + ) + self.assertEqual(response.status_code, 200) + self.assertIn("thumbnail_url", response.context) + self.assertEqual( + "https://tile.loc.gov/image-services/iiif/service:music:mussuffrage:mussuffrage-100183:mussuffrage-100183.0001/full/!512,512/0/default.jpg", + response.context["thumbnail_url"], + ) + + # Non-existent asset in an existing campaign + response = self.client.get( + reverse( + "transcriptions:asset-detail", + kwargs={ + "campaign_slug": asset.item.project.campaign.slug, + "project_slug": asset.item.project.slug, + "item_id": asset.item.item_id, + "slug": "bad-slug", + }, + ) + ) + self.assertRedirects( + response, + reverse( + "transcriptions:campaign-detail", + args=(asset.item.project.campaign.slug,), + ), + ) @patch.object(Asset, "get_ocr_transcript") def test_generate_ocr_transcription(self, mock): @@ -442,11 +600,46 @@ def test_project_detail_view(self): args=(project.campaign.slug, project.slug), ) ) - self.assertEqual(response.status_code, 200) self.assertTemplateUsed( response, template_name="transcriptions/project_detail.html" ) + # Filter by reviewable parameter check + response = self.client.get( + reverse( + "transcriptions:project-detail", + args=(project.campaign.slug, project.slug), + ), + {"filter_by_reviewable": True}, + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed( + response, template_name="transcriptions/project_detail.html" + ) + # Bad status parameter check + response = self.client.get( + reverse( + "transcriptions:project-detail", + args=(project.campaign.slug, project.slug), + ), + {"transcription_status": "bad_parameter"}, + ) + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed( + response, template_name="transcriptions/project_detail.html" + ) + + # Non-existent project in an existing campaign + response = self.client.get( + reverse( + "transcriptions:project-detail", + args=(project.campaign.slug, "bad-slug"), + ) + ) + self.assertRedirects( + response, + reverse("transcriptions:campaign-detail", args=(project.campaign.slug,)), + ) def test_project_unicode_slug(self): """Confirm that Unicode characters are usable in Project URLs""" diff --git a/concordia/views.py b/concordia/views.py index def878a61..6bfdf4573 100644 --- a/concordia/views.py +++ b/concordia/views.py @@ -819,6 +819,7 @@ def get_context_data(self, *args, **kwargs): ctx = super().get_context_data(*args, **kwargs) banner = Banner.objects.filter(active=True).first() + if banner is not None: ctx["banner"] = banner @@ -1187,11 +1188,10 @@ def serialize_context(self, context): return ctx def get_template_names(self): - if self.object: - if self.object.status == Campaign.Status.COMPLETED: - return [self.completed_template_name] - elif self.object.status == Campaign.Status.RETIRED: - return [self.retired_template_name] + if self.object.status == Campaign.Status.COMPLETED: + return [self.completed_template_name] + elif self.object.status == Campaign.Status.RETIRED: + return [self.retired_template_name] return super().get_template_names()