Skip to content

Commit

Permalink
FIND-81:detail page initial (#6)
Browse files Browse the repository at this point in the history
* FIND-81:remove search details path

* FIND-81:record details initial
  • Loading branch information
TNA-Allan authored Nov 19, 2024
1 parent dd2320f commit eb814f8
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 4 deletions.
Empty file added app/errors/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions app/errors/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.shortcuts import render


def custom_404_error_view(request, exception=None):
response = render(request, "404.html")
response.status_code = 404
return response
Empty file added app/records/__init__.py
Empty file.
7 changes: 7 additions & 0 deletions app/records/converters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from django.urls.converters import StringConverter


class IDConverter(StringConverter):
"""Converter used to extract id's from a URL."""

regex = r"([ACDFN][0-9]{1,8}|[a-f0-9]{8}-?([a-f0-9]{4}-?){3}[a-f0-9]{12}(_[1-9])?)"
22 changes: 22 additions & 0 deletions app/records/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from django.shortcuts import Http404
from django.template.response import TemplateResponse


def record_detail_view(request, id):
"""
View for rendering a record's details page.
"""
template_name = "records/record_detail.html"
context = {}
page_type = "Record details page"

page_title = f"Catalogue ID: {id}"

context.update(
page_type=page_type,
page_title=page_title,
)

return TemplateResponse(
request=request, template=template_name, context=context
)
1 change: 0 additions & 1 deletion app/search/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@
urlpatterns = [
path("", views.index, name="index"),
path("catalogue/", views.catalogue_index, name="catalogue"),
path("catalogue/id/<str:id>/", views.catalogue_item, name="catalogue_item"),
]
11 changes: 11 additions & 0 deletions app/templates/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% extends 'base.html' %}

{% block content %}
<div class="tna-section">
<div class="tna-container">
<div class="tna-column tna-column--width-2-3 tna-column--width-5-6-medium tna-column--full-small tna-column--full-tiny">
<h1 class="tna-heading-xl">Page Not Found</h1>
</div>
</div>
</div>
{% endblock %}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
{% extends 'base.html' %}

{%- set pageTitle = 'Catalogue item ' + id -%}

{% block content %}
<div class="tna-section">
<div class="tna-container">
<div class="tna-column tna-column--width-2-3 tna-column--width-5-6-medium tna-column--full-small tna-column--full-tiny">
<h1 class="tna-heading-xl">{{ pageTitle }}</h1>
<h1 class="tna-heading-xl">{{ page_title }}</h1>
</div>
</div>
</div>
Expand Down
5 changes: 5 additions & 0 deletions config/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

# Application definition
INSTALLED_APPS = [
"app.records",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
Expand Down Expand Up @@ -223,3 +224,7 @@
)

GA4_ID = os.environ.get("GA4_ID", "")

# Should always be False in production. Can be set to True in local environments
# to serve static files even when DEBUG is False
DJANGO_SERVE_STATIC = False
7 changes: 7 additions & 0 deletions config/settings/develop.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@

FORCE_HTTPS = strtobool(os.getenv("FORCE_HTTPS", "False"))

DJANGO_SERVE_STATIC = True

if not DEBUG and DJANGO_SERVE_STATIC:
STATICFILES_STORAGE = (
"django.contrib.staticfiles.storage.StaticFilesStorage"
)

if DEBUG:

INSTALLED_APPS += [ # noqa: F405
Expand Down
4 changes: 4 additions & 0 deletions config/settings/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,8 @@
}
}

# Allow integration tests to run without needing to collectstatic
# See https://docs.djangoproject.com/en/5.0/ref/contrib/staticfiles/#staticfilesstorage
STATICFILES_STORAGE = "django.contrib.staticfiles.storage.StaticFilesStorage"

CLIENT_BASE_URL = "https://rosetta.test/data"
19 changes: 18 additions & 1 deletion config/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,36 @@
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""

from app.errors import views as errors_view
from app.records import converters
from app.records import views as records_views
from django.apps import apps
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import include, path
from django.urls import include, path, register_converter

register_converter(converters.IDConverter, "id")

handler404 = "app.errors.views.custom_404_error_view"

urlpatterns = [
path("", include(("app.main.urls", "main"), namespace="main")),
path("healthcheck/", include("app.healthcheck.urls")),
path(
r"catalogue/id/<id:id>/",
records_views.record_detail_view,
name="details-page-machine-readable",
),
path(
"search/",
include(("app.search.urls", "search"), namespace="search"),
),
path(
r"404/",
errors_view.custom_404_error_view,
kwargs={"exception": Exception("Bad Request!")},
),
path("admin/", admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

Expand Down
Empty file added test/records/__init__.py
Empty file.
21 changes: 21 additions & 0 deletions test/records/test_id_formats.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import re

from app.records.converters import IDConverter
from django.test import SimpleTestCase


class TestIDFormats(SimpleTestCase):
def test_valid_formats(self):
for label, value in (
("longformat", "3717ee38900740728076a61a398fcb84"),
("guid", "4d8dae2c-b417-4614-8ed8-924b9b4beeac"),
("dri_guid_plus", "00149557ca64456a8a41e44f14621801_1"),
("iaid_A", "A13530124"),
("iaid_C", "C2341693"),
("iaid_D", "D431198"),
("iaid_F", "F257629"),
("iaid_N", "N14562581"),
):
id_regex = re.compile(IDConverter.regex)
with self.subTest(label):
self.assertTrue(id_regex.match(value))
46 changes: 46 additions & 0 deletions test/records/test_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from django.test import TestCase
from django.urls import resolve, reverse


class TestMachineReadableDetailsRouteResolution(TestCase):
def test_resolves_iaid(self):
resolver = resolve("/catalogue/id/C7810139/")

self.assertEqual(resolver.view_name, "details-page-machine-readable")
self.assertEqual(resolver.kwargs["id"], "C7810139")

def test_iaid_with_non_standard_prefix(self):
resolver = resolve("/catalogue/id/C123456/")

self.assertEqual(resolver.view_name, "details-page-machine-readable")
self.assertEqual(resolver.kwargs["id"], "C123456")

def test_resolves_uuid(self):
# Some IAIDs are UUIDs. Tested IAID is a real example
resolver = resolve(
"/catalogue/id/43f766a9-e968-4b82-93dc-8cf11a841d41/"
)

self.assertEqual(resolver.view_name, "details-page-machine-readable")
self.assertEqual(
resolver.kwargs["id"], "43f766a9-e968-4b82-93dc-8cf11a841d41"
)


class TestMachineReadableDetailsURL(TestCase):
def test_reverse_iaid(self):
url = reverse(
"details-page-machine-readable", kwargs={"id": "C7810139"}
)

self.assertEqual(url, "/catalogue/id/C7810139/")

def test_reverse_uuid(self):
url = reverse(
"details-page-machine-readable",
kwargs={"id": "43f766a9-e968-4b82-93dc-8cf11a841d41"},
)

self.assertEqual(
url, "/catalogue/id/43f766a9-e968-4b82-93dc-8cf11a841d41/"
)
20 changes: 20 additions & 0 deletions test/records/test_views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from django.test import TestCase


class TestRecordView(TestCase):

def test_no_matches_respond_with_404(self):

response = self.client.get("/catalogue/id/Z123456/")

self.assertEqual(response.status_code, 404)

def test_record_rendered_for_single_result(self):

response = self.client.get("/catalogue/id/C123456/")

self.assertEqual(response.status_code, 200)
self.assertEqual(
response.resolver_match.view_name, "details-page-machine-readable"
)
self.assertTemplateUsed("records/record_detail.html")

0 comments on commit eb814f8

Please sign in to comment.