Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide versions of a document as a list of Documents #379

Merged
merged 2 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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:
dragon-dxw marked this conversation as resolved.
Show resolved Hide resolved
"""
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