diff --git a/ds_judgements_public_ui/templates/judgment/press_summaries/list.html b/ds_judgements_public_ui/templates/judgment/press_summaries/list.html
index 9d0e7ebfa..942f98c6f 100644
--- a/ds_judgements_public_ui/templates/judgment/press_summaries/list.html
+++ b/ds_judgements_public_ui/templates/judgment/press_summaries/list.html
@@ -3,7 +3,7 @@
{% block precontent %}
This is a judgment in HTML.
",
- )
-
- judgment_mock.return_value.content_as_xml = kwargs.pop(
- "xml",
- """
-
- This is a judgment in HTML.
", decoded_response)
+ self.assertIn("This is a judgment.
", decoded_response)
self.assertIn('
@@ -176,7 +179,7 @@ def test_label_when_press_summary(self, mock_get_document_by_uri, mock_pdf):
THEN response should contain the press summary label
"""
- mock_get_document_by_uri.return_value = JudgmentFactory.build(document_noun="press summary", is_published=True)
+ mock_get_document_by_uri.return_value = PressSummaryFactory.build(is_published=True)
response = self.client.get("/test/2023/123") # has to match factory to avoid redirect.
xpath_query = "//p[@class='judgment-toolbar__press-summary-title']"
@@ -202,19 +205,19 @@ class TestViewRelatedDocumentButton:
@patch("judgments.views.detail.detail_html.DocumentPdf", autospec=True)
@patch("judgments.views.detail.detail_html.get_published_document_by_uri")
@pytest.mark.parametrize(
- "uri,expected_text,expected_href,document_noun",
+ "uri,expected_text,expected_href,document_class_factory",
[
(
"eat/2023/1/press-summary/1",
"View Judgment",
"eat/2023/1",
- "press summary",
+ PressSummaryFactory,
),
(
"eat/2023/1",
"View Press Summary",
"eat/2023/1/press-summary/1",
- "judgment",
+ JudgmentFactory,
),
],
)
@@ -225,7 +228,7 @@ def test_view_related_document_button_when_document_with_related_document(
uri,
expected_text,
expected_href,
- document_noun,
+ document_class_factory,
):
"""
GIVEN a document with an associated document
@@ -234,12 +237,9 @@ def test_view_related_document_button_when_document_with_related_document(
"""
def get_document_by_uri_side_effect(document_uri, cache_if_not_found=False):
- if document_uri == uri:
- return JudgmentFactory.build(uri=uri, is_published=True, document_noun=document_noun)
- elif document_uri == expected_href:
- return JudgmentFactory.build(uri=expected_href, is_published=True, document_noun=document_noun)
- else:
+ if document_uri not in [uri, expected_href]:
raise DocumentNotFoundError()
+ return document_class_factory.build(uri=document_uri, is_published=True)
mock_get_document_by_uri.side_effect = get_document_by_uri_side_effect
@@ -252,19 +252,19 @@ def get_document_by_uri_side_effect(document_uri, cache_if_not_found=False):
@patch("judgments.views.detail.detail_html.DocumentPdf", autospec=True)
@patch("judgments.views.detail.detail_html.get_published_document_by_uri")
@pytest.mark.parametrize(
- "uri,expected_text,expected_href,document_noun",
+ "uri,expected_text,expected_href,document_class_factory",
[
(
"eat/2023/1/press-summary/1",
"View Judgment",
"eat/2023/1",
- "press summary",
+ PressSummaryFactory,
),
(
"eat/2023/1",
"View Press Summary",
"eat/2023/1/press-summary/1",
- "judgment",
+ JudgmentFactory,
),
],
)
@@ -275,7 +275,7 @@ def test_view_related_document_button_when_document_with_related_document_and_qu
uri,
expected_text,
expected_href,
- document_noun,
+ document_class_factory,
):
"""
GIVEN a document with an associated document
@@ -284,12 +284,9 @@ def test_view_related_document_button_when_document_with_related_document_and_qu
"""
def get_document_by_uri_side_effect(document_uri, cache_if_not_found=False):
- if document_uri == uri:
- return JudgmentFactory.build(uri=uri, is_published=True, document_noun=document_noun)
- elif document_uri == expected_href:
- return JudgmentFactory.build(uri=expected_href, is_published=True, document_noun=document_noun)
- else:
+ if document_uri not in [uri, expected_href]:
raise DocumentNotFoundError()
+ return document_class_factory.build(uri=document_uri, is_published=True)
mock_get_document_by_uri.side_effect = get_document_by_uri_side_effect
@@ -351,13 +348,17 @@ def pj(uri, cache_if_not_found=False):
return PressSummaryFactory.build(
uri="eat/2023/1/press-summary/1",
is_published=True,
- name="Press Summary of Judgment A",
+ body=DocumentBodyFactory.build(
+ name="Press Summary of Judgment A",
+ ),
)
else:
return JudgmentFactory.build(
uri="eat/2023/1/the_judgment_uri",
is_published=True,
- name="The Title of Judgment A",
+ body=DocumentBodyFactory.build(
+ name="The Title of Judgment A",
+ ),
)
mock_get_document_by_uri.side_effect = pj
@@ -385,7 +386,9 @@ def test_breadcrumb_when_judgment(self, mock_get_document_by_uri, mock_pdf):
mock_get_document_by_uri.return_value = JudgmentFactory.build(
uri="eat/2023/1",
is_published=True,
- name="Judgment A",
+ body=DocumentBodyFactory.build(
+ name="Judgment A",
+ ),
)
response = self.client.get("/eat/2023/1")
assert_response_contains_text(response, "Judgment A", "//div[@class='breadcrumbs']")
@@ -439,14 +442,18 @@ def get_document_by_uri_side_effect(document_uri, cache_if_not_found=False):
return PressSummaryFactory.build(
uri="eat/2023/1/press-summary/1",
is_published=True,
- name="Press Summary of Judgment A (with some slightly different wording)",
+ body=DocumentBodyFactory.build(
+ name="Press Summary of Judgment A (with some slightly different wording)",
+ ),
neutral_citation="Judgment_A_NCN",
)
elif document_uri == "eat/2023/1":
return JudgmentFactory.build(
uri="eat/2023/1",
is_published=True,
- name="Judgment A",
+ body=DocumentBodyFactory.build(
+ name="Judgment A",
+ ),
neutral_citation="Judgment_A_NCN",
)
else:
@@ -472,7 +479,7 @@ def test_document_headings_when_judgment(self, mock_get_document_by_uri, mock_pd
mock_get_document_by_uri.return_value = JudgmentFactory.build(
uri="eat/2023/1",
is_published=True,
- name="Judgment A",
+ body=DocumentBodyFactory.build(name="Judgment A"),
neutral_citation="Judgment_A_NCN",
)
response = self.client.get("/eat/2023/1")
@@ -499,13 +506,15 @@ def get_document_by_uri_side_effect(document_uri, cache_if_not_found=False):
return JudgmentFactory.build(
uri="eat/2023/1/press-summary/1",
is_published=True,
- name="Press Summary of Judgment A (with some slightly different wording)",
+ body=DocumentBodyFactory.build(
+ name="Press Summary of Judgment A (with some slightly different wording)"
+ ),
)
else:
return JudgmentFactory.build(
uri="eat/2023/1",
is_published=True,
- name="Judgment A",
+ body=DocumentBodyFactory.build(name="Judgment A"),
)
mock_get_document_by_uri.side_effect = get_document_by_uri_side_effect
@@ -529,7 +538,7 @@ def test_html_title_when_judgment(self, mock_get_document_by_uri, mock_pdf):
mock_get_document_by_uri.return_value = JudgmentFactory.build(
uri="eat/2023/1",
is_published=True,
- name="Judgment A",
+ body=DocumentBodyFactory.build(name="Judgment A"),
)
response = self.client.get("/eat/2023/1")
title = "Judgment A - Find Case Law - The National Archives"
@@ -544,8 +553,8 @@ def test_document_baseclass_raises_error(self, get_document):
uri="eat/2023/1",
is_published=True,
name="Judgment A",
+ neutral_citation=None,
)
- doc.best_human_identifier = None
get_document.return_value = doc
with pytest.raises(NoNeutralCitationError):
self.client.get("/eat/2023/1")
diff --git a/judgments/tests/test_factories.py b/judgments/tests/test_factories.py
deleted file mode 100644
index 58b7ba1b9..000000000
--- a/judgments/tests/test_factories.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import pytest
-from caselawclient.models.documents import DocumentURIString
-from factories import JudgmentFactory
-
-
-class TestJudgmentFactory:
- def test_default_uri(self):
- # The default URI gets a test where others don't because without a URI judgments fall apart
- judgment = JudgmentFactory.build()
-
- assert isinstance(judgment.uri, str)
- assert judgment.uri != ""
-
- @pytest.mark.parametrize(
- "parameter, value",
- [
- ("uri", "test/2022/321"),
- ("name", "Some Test Name"),
- ("neutral_citation", "[2022] Test 321"),
- ("court", "The Test Court"),
- ("judgment_date_as_string", "2022-03-04"),
- ("is_published", True),
- ("is_sensitive", True),
- ("is_anonymised", True),
- ("has_supplementary_materials", True),
- ("is_failure", True),
- ("source_name", "Uploader Test"),
- ("source_email", "test@example.com"),
- ("consignment_reference", "TDR-54321"),
- ("assigned_to", "Assignee"),
- ("versions", ["1", "2"]),
- ],
- )
- def test_params(self, parameter, value):
- judgment = JudgmentFactory.build(**{parameter: value})
-
- assert getattr(judgment, parameter) == value
-
- def test_html(self):
- judgment = JudgmentFactory.build(html="
Testing HTML
")
-
- assert judgment.content_as_html(DocumentURIString("")) == "
Testing HTML
"
-
- def test_xml(self):
- judgment = JudgmentFactory.build(xml="
Testing XML
")
-
- assert judgment.content_as_xml == "
Testing XML
"
diff --git a/judgments/tests/test_judgment_utils.py b/judgments/tests/test_judgment_utils.py
index 4a27b387c..114f6b2cc 100644
--- a/judgments/tests/test_judgment_utils.py
+++ b/judgments/tests/test_judgment_utils.py
@@ -2,9 +2,9 @@
import pytest
from caselawclient.errors import DocumentNotFoundError
+from caselawclient.factories import JudgmentFactory
from caselawclient.models.documents import DocumentURIString
from django.http import Http404
-from factories import JudgmentFactory
from judgments.utils import (
get_published_document_by_uri,
diff --git a/judgments/tests/test_pdf.py b/judgments/tests/test_pdf.py
index 508239452..ce19ec927 100644
--- a/judgments/tests/test_pdf.py
+++ b/judgments/tests/test_pdf.py
@@ -1,8 +1,10 @@
from os import environ
from unittest.mock import Mock, patch
+from caselawclient.factories import JudgmentFactory
+from caselawclient.models.documents import DocumentURIString
+
from judgments.models.document_pdf import DocumentPdf
-from judgments.tests.factories import JudgmentFactory
from judgments.utils import formatted_document_uri
@@ -56,7 +58,7 @@ def test_generates_uri_if_does_not_exist(self):
@patch.dict(environ, {"ASSETS_CDN_BASE_URL": "https://example.org"})
def generate_uri_generates_the_correct_uri_with_base_url(self):
- document_pdf = DocumentPdf("foo/bar/baz")
+ document_pdf = DocumentPdf(DocumentURIString("foo/bar/baz"))
assert document_pdf.generate_uri() == "https://example.org/foo_bar_baz.pdf"
@@ -69,6 +71,6 @@ def generate_uri_generates_the_correct_uri_with_base_url(self):
},
)
def test_generate_uri_generates_the_correct_uri_with_base_url(self):
- document_pdf = DocumentPdf("foo/bar/baz")
+ document_pdf = DocumentPdf(DocumentURIString("foo/bar/baz"))
assert document_pdf.generate_uri() == "https://bucket.s3.region.amazonaws.com/foo/bar/baz/foo_bar_baz.pdf"
diff --git a/judgments/tests/test_press_summaries.py b/judgments/tests/test_press_summaries.py
index a54816b4d..c1c62e89a 100644
--- a/judgments/tests/test_press_summaries.py
+++ b/judgments/tests/test_press_summaries.py
@@ -1,8 +1,8 @@
from unittest.mock import Mock, patch
+from caselawclient.factories import PressSummaryFactory
from django.test import TestCase
from django.urls import reverse
-from factories import PressSummaryFactory
from judgments.utils import linked_doc_title, press_summary_list_breadcrumbs
from judgments.views.press_summaries import press_summaries
@@ -34,7 +34,7 @@ def test_view_returns_template_response_for_multiple_press_summaries(
"judgment/press_summaries/list.html",
context={
"page_title": f"{linked_doc_title(press_summary_1)} - Press Summaries",
- "judgement_name": linked_doc_title(press_summary_1),
+ "judgment_name": linked_doc_title(press_summary_1),
"breadcrumbs": press_summary_list_breadcrumbs(press_summary_1),
"press_summaries": excepted_press_summaries,
},
@@ -74,11 +74,11 @@ def test_shows_multiple_when_multiple_present(self, mock_get_press_summaries_for
decoded_response,
)
self.assertIn(
- press_summary_1.name,
+ press_summary_1.body.name,
decoded_response,
)
self.assertIn(
- press_summary_2.name,
+ press_summary_2.body.name,
decoded_response,
)
diff --git a/judgments/tests/test_utils.py b/judgments/tests/test_utils.py
index a6c90c150..1a4570dfa 100644
--- a/judgments/tests/test_utils.py
+++ b/judgments/tests/test_utils.py
@@ -3,10 +3,11 @@
from unittest.mock import Mock
from caselawclient.errors import DocumentNotFoundError
+from caselawclient.factories import DocumentBodyFactory, JudgmentFactory, PressSummaryFactory
+from caselawclient.models.documents import DocumentURIString
from ds_caselaw_utils import courts as all_courts
from ds_caselaw_utils.courts import CourtCode
-from judgments.tests.factories import JudgmentFactory, PressSummaryFactory
from judgments.utils import (
formatted_document_uri,
get_document_by_uri,
@@ -55,7 +56,7 @@ def test_formatted_document_uri(self):
("xml", "/data.xml"),
("html", "/data.html"),
]
- document_uri = "ewhc/comm/2024/253"
+ document_uri = DocumentURIString("ewhc/comm/2024/253")
for format, suffix in test_params:
with self.subTest(format=format, suffix=suffix):
self.assertEqual(
@@ -71,14 +72,14 @@ def test_linked_doc_url_returns_press_summary_for_a_judgement(self):
def test_linked_doc_url_returns_judgement_for_a_press_summary(self):
document = PressSummaryFactory.build(uri="/foo/bar/press-summary/1")
- assert linked_doc_url(document) == "/foo/bar"
+ assert linked_doc_url(document) == "foo/bar"
def test_linked_doc_title_removes_prefix_for_press_summary(self):
- document = PressSummaryFactory.build(name="Press Summary of Arkell v Pressdram")
+ document = PressSummaryFactory.build(body=DocumentBodyFactory.build(name="Press Summary of Arkell v Pressdram"))
assert linked_doc_title(document) == "Arkell v Pressdram"
def test_linked_doc_title_adds_prefix_for_judgment(self):
- document = JudgmentFactory.build(name="Arkell v Pressdram")
+ document = JudgmentFactory.build(body=DocumentBodyFactory.build(name="Arkell v Pressdram"))
assert linked_doc_title(document) == "Press Summary of Arkell v Pressdram"
def test_press_summary_list_breadcrumbs(self):
diff --git a/judgments/tests/tests.py b/judgments/tests/tests.py
index 5220997bd..adc02a198 100644
--- a/judgments/tests/tests.py
+++ b/judgments/tests/tests.py
@@ -1,8 +1,8 @@
import re
from unittest.mock import patch
+from caselawclient.factories import JudgmentFactory
from django.test import TestCase
-from factories import JudgmentFactory
from judgments import converters, utils
from judgments.models.court_dates import CourtDates
@@ -173,7 +173,7 @@ def test_xml(self, mock_get_document_by_uri):
mock_get_document_by_uri.return_value = JudgmentFactory.build(is_published=True)
response = self.client.get("/eat/2023/1/data.xml")
mock_get_document_by_uri.assert_called_with("eat/2023/1")
- self.assertContains(response, "This is a judgment in XML.")
+ self.assertContains(response, "This is some XML of a judgment")
self.assertEqual(response.headers.get("X-Robots-Tag"), "noindex,nofollow")
@patch("judgments.views.detail.detail_xml.get_published_document_by_uri")
@@ -181,7 +181,7 @@ def test_xml_press_summary(self, mock_get_document_by_uri):
mock_get_document_by_uri.return_value = JudgmentFactory.build(is_published=True)
response = self.client.get("/eat/2023/1/press-summary/1/data.xml")
mock_get_document_by_uri.assert_called_with("eat/2023/1/press-summary/1")
- self.assertContains(response, "This is a judgment in XML.")
+ self.assertContains(response, "This is some XML of a judgment")
self.assertEqual(response.headers.get("X-Robots-Tag"), "noindex,nofollow")
@patch.object(PdfDetailView, "pdf_stylesheets", [])
diff --git a/judgments/tests/utils/assertions.py b/judgments/tests/utils/assertions.py
index ad6920d2d..39169e72d 100644
--- a/judgments/tests/utils/assertions.py
+++ b/judgments/tests/utils/assertions.py
@@ -64,7 +64,6 @@ def assert_not_contains_html(response, contained_html):
def assert_response_contains_text(response, contained_text, xpath_query):
container_tree = parse_html(response.content.decode())
-
assert is_contained_by_xpath(container_tree, xpath_query, contained_text)
diff --git a/judgments/utils/utils.py b/judgments/utils/utils.py
index ff2bd2c13..cf123019e 100644
--- a/judgments/utils/utils.py
+++ b/judgments/utils/utils.py
@@ -13,6 +13,7 @@
from django.conf import settings
from django.urls import reverse
from ds_caselaw_utils.neutral import neutral_url
+from ds_caselaw_utils.types import NeutralCitationString
from judgments.fixtures.stop_words import stop_words
@@ -230,7 +231,7 @@ def get_press_summaries_for_document_uri(document_uri: str) -> list[PressSummary
return api_client.get_press_summaries_for_document_uri(DocumentURIString(document_uri))
-def formatted_document_uri(document_uri: str, format: Optional[str] = None) -> str:
+def formatted_document_uri(document_uri: DocumentURIString, format: Optional[str] = None) -> str:
url = reverse("detail", args=[document_uri])
if format == "pdf":
url = url + "/data.pdf"
@@ -255,9 +256,9 @@ def linked_doc_url(document: Document) -> DocumentURIString:
def linked_doc_title(document: Document):
press_summary_title_prefix = "Press Summary of "
if document.document_noun == "press summary":
- return document.name.removeprefix(press_summary_title_prefix)
+ return document.body.name.removeprefix(press_summary_title_prefix)
else:
- return press_summary_title_prefix + document.name
+ return press_summary_title_prefix + document.body.name
def press_summary_list_breadcrumbs(press_summary: Document):
@@ -275,30 +276,34 @@ def press_summary_list_breadcrumbs(press_summary: Document):
not_alphanumeric = re.compile("[^a-zA-Z0-9]")
-def replace_parens(string):
+def replace_parens(string: str) -> str:
return normalise_spaces(re.sub("\\(.+\\)", "", string))
-def preprocess_title(string):
+def preprocess_title(string: str) -> str:
return preprocess_query(replace_parens(string)).lower().strip()
-def preprocess_ncn(string):
+def preprocess_ncn(string: str) -> str:
return re.sub(not_alphanumeric, "", preprocess_query(string).lower()).strip()
-def is_exact_ncn_match(result, query):
+def is_exact_ncn_match(result, query: str) -> bool:
return preprocess_ncn(query) == preprocess_ncn(result.neutral_citation)
-def search_results_have_exact_ncn(search_results, query):
+def search_results_have_exact_ncn(search_results, query: str) -> bool:
for search_result in search_results:
if is_exact_ncn_match(search_result, query):
return True
return False
-def show_no_exact_ncn_warning(search_results, query_text: str, page: int):
+def show_no_exact_ncn_warning(search_results, query_text: str, page: int) -> bool:
return (
- not (search_results_have_exact_ncn(search_results, query_text)) and bool(neutral_url(query_text)) and page == 1
+ not (search_results_have_exact_ncn(search_results, query_text))
+ and bool(
+ neutral_url(NeutralCitationString(query_text))
+ ) ## TODO: This is horrible, because we don't know query_text is a valid NCN at this point
+ and page == 1
)
diff --git a/judgments/views/detail/detail_html.py b/judgments/views/detail/detail_html.py
index cd7300cb3..fddd62725 100644
--- a/judgments/views/detail/detail_html.py
+++ b/judgments/views/detail/detail_html.py
@@ -84,7 +84,7 @@ def detail_html(request, document_uri):
}
)
else:
- breadcrumbs.append({"text": document.name})
+ breadcrumbs.append({"text": document.body.name})
context["breadcrumbs"] = breadcrumbs
context["query"] = query
@@ -95,7 +95,7 @@ def detail_html(request, document_uri):
context["page_canonical_url"] = document.public_uri
context["document_canonical_url"] = request.build_absolute_uri("/" + document.uri)
context["feedback_survey_document_uri"] = document.uri # TODO: Remove this from context
- context["page_title"] = document.name # TODO: Remove this from context
+ context["page_title"] = document.body.name # TODO: Remove this from context
context["pdf_uri"] = pdf.uri # TODO: Remove this from context
return TemplateResponse(request, "judgment/detail.html", context=context)
diff --git a/judgments/views/detail/detail_xml.py b/judgments/views/detail/detail_xml.py
index b69eec85f..a2f341daf 100644
--- a/judgments/views/detail/detail_xml.py
+++ b/judgments/views/detail/detail_xml.py
@@ -1,3 +1,4 @@
+from caselawclient.models.documents import DocumentURIString
from django.http import HttpResponse
from judgments.utils import (
@@ -5,10 +6,10 @@
)
-def detail_xml(_request, document_uri):
+def detail_xml(_request, document_uri: DocumentURIString) -> HttpResponse:
document = get_published_document_by_uri(document_uri)
- document_xml = document.content_as_xml
+ document_xml = document.body.content_as_xml
response = HttpResponse(document_xml, content_type="application/xml")
response["Content-Disposition"] = f"attachment; filename={document.uri}.xml"
diff --git a/judgments/views/press_summaries.py b/judgments/views/press_summaries.py
index 3d754e8b5..64eeac392 100644
--- a/judgments/views/press_summaries.py
+++ b/judgments/views/press_summaries.py
@@ -21,13 +21,13 @@ def press_summaries(request, document_uri):
permanent=False,
)
- judgement_name = linked_doc_title(press_summaries[0])
+ judgment_name = linked_doc_title(press_summaries[0])
return TemplateResponse(
request,
"judgment/press_summaries/list.html",
context={
- "page_title": f"{judgement_name} - Press Summaries",
- "judgement_name": judgement_name,
+ "page_title": f"{judgment_name} - Press Summaries",
+ "judgment_name": judgment_name,
"breadcrumbs": press_summary_list_breadcrumbs(press_summaries[0]),
"press_summaries": press_summaries,
},
diff --git a/requirements/base.txt b/requirements/base.txt
index 35f1f96ab..e974bb10b 100644
--- a/requirements/base.txt
+++ b/requirements/base.txt
@@ -9,8 +9,8 @@ django-environ==0.11.2 # https://github.com/joke2k/django-environ
django-model-utils==5.0.0 # https://github.com/jazzband/django-model-utils
requests~=2.32.2
wsgi-basic-auth~=1.1.0
-ds-caselaw-marklogic-api-client~=25.0.0
-ds-caselaw-utils==1.7.0
+ds-caselaw-marklogic-api-client~=27.1.0
+ds-caselaw-utils==2.0.0
rollbar
django-weasyprint==2.3.0
django-waffle==4.1.0 # https://github.com/django-waffle/django-waffle