Skip to content

Commit

Permalink
Merge pull request #379 from nationalarchives/FCL-73-other-versions-a…
Browse files Browse the repository at this point in the history
…s-documents

Provide versions of a document as a list of Documents
  • Loading branch information
dragon-dxw authored Sep 12, 2023
2 parents 0d592d4 + 2b0d3ba commit f13a469
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 2 deletions.
11 changes: 11 additions & 0 deletions src/caselawclient/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,14 @@ class DocumentNotFoundError(MarklogicAPIError):
# This error does not come from Marklogic, but is an error raised by this API...
status_code = 404
default_message = "The document was not found"


class NotSupportedOnVersion(MarklogicAPIError):
# This error does not come from Marklogic, but is an error raised by this API...
status_code = 400
default_message = "An operation was attempted on a version of a document which cannot occur on a version."


class OnlySupportedOnVersion(MarklogicAPIError):
status_code = 400
default_message = "The operation requested cannot be performed on a document that is not a version."
46 changes: 45 additions & 1 deletion src/caselawclient/models/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
from lxml import etree
from requests_toolbelt.multipart import decoder

from ..errors import DocumentNotFoundError
from caselawclient.models.utilities import extract_version

from ..errors import (
DocumentNotFoundError,
NotSupportedOnVersion,
OnlySupportedOnVersion,
)
from ..xml_helpers import get_xpath_match_string, get_xpath_match_strings
from .utilities import VersionsDict, get_judgment_root, render_versions
from .utilities.aws import (
Expand Down Expand Up @@ -237,6 +243,44 @@ def versions(self) -> list[VersionsDict]:
except AttributeError:
return []

@cached_property
def versions_as_documents(self) -> list[Any]:
"""
Returns a list of `Document` subclasses corresponding to the versions of the document. The first entry is:
* the most recent
* the highest numbered
Note that this is only valid on the managed document -- a `DLS-DOCUMENTVERSION` error will occur if the document
this is called on is itself a version.
"""
if self.is_version:
raise NotSupportedOnVersion(
"Cannot get versions of a version for {self.uri}"
)
docs = []
for version in self.versions:
doc_uri = DocumentURIString(version["uri"])
docs.append(self.api_client.get_document_by_uri(doc_uri))
return docs

@cached_property
def version_number(self) -> int:
"""
Note that the highest number is the most recent version.
Raises an exception if it is not a version (e.g. /2022/eat/1 is not a version)
"""
version = extract_version(self.uri)
if version == 0:
raise OnlySupportedOnVersion(
f"Version number requested for {self.uri} which is not a version"
)
return version

@cached_property
def is_version(self) -> bool:
"Is this document a potentially historic version of a document, or is it the main document itself?"
return extract_version(self.uri) != 0

@cached_property
def content_as_xml(self) -> str:
return self.api_client.get_judgment_xml(self.uri, show_unpublished=True)
Expand Down
32 changes: 31 additions & 1 deletion tests/models/test_documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@
from lxml import etree

from caselawclient.Client import MarklogicApiClient
from caselawclient.errors import DocumentNotFoundError
from caselawclient.errors import (
DocumentNotFoundError,
NotSupportedOnVersion,
OnlySupportedOnVersion,
)
from caselawclient.models.documents import (
DOCUMENT_STATUS_HOLD,
DOCUMENT_STATUS_IN_PROGRESS,
Expand Down Expand Up @@ -169,6 +173,32 @@ def test_document_best_identifier(self, mock_api_client):
example_document = Document("uri", mock_api_client)
assert example_document.best_human_identifier is None

def test_document_version_of_a_version_fails(self, mock_api_client):
version_document = Document("test/1234_xml_versions/9-1234", mock_api_client)
with pytest.raises(NotSupportedOnVersion):
version_document.versions_as_documents

def test_document_versions_happy_case(self, mock_api_client):
version_document = Document("test/1234", mock_api_client)
version_document.versions = [
{"uri": "test/1234_xml_versions/2-1234.xml"},
{"uri": "test/1234_xml_versions/1-1234.xml"},
]
version_document.versions_as_documents[
0
].uri = "test/1234_xml_versions/2-1234.xml"

def test_document_version_number_when_not_version(self, mock_api_client):
base_document = Document("test/1234", mock_api_client)
with pytest.raises(OnlySupportedOnVersion):
base_document.version_number
assert not base_document.is_version

def test_document_version_number_when_is_version(self, mock_api_client):
version_document = Document("test/1234_xml_versions/9-1234", mock_api_client)
assert version_document.version_number == 9
assert version_document.is_version


class TestDocumentValidation:
def test_judgment_is_failure(self, mock_api_client):
Expand Down

0 comments on commit f13a469

Please sign in to comment.