Skip to content
8 changes: 8 additions & 0 deletions layer/nrlf/core/dynamodb/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ def delete_by_id(self, id_: str, can_ignore_delete_fail: bool = False):
key = f"D#{id_}"
try:
self.table.delete_item(Key={"pk": key, "sk": key})
logger.log(LogReference.REPOSITORY027, id=id_)
except Exception as exc:
if can_ignore_delete_fail:
logger.log(
Expand All @@ -352,6 +353,13 @@ def delete_by_id(self, id_: str, can_ignore_delete_fail: bool = False):
stacklevel=5,
error=str(exc),
)
else:
raise OperationOutcomeError(
status_code="500",
severity="error",
code="exception",
details=SpineErrorConcept.from_code("INTERNAL_SERVER_ERROR"),
) from exc

def _query(self, **kwargs) -> Iterator[DocumentPointer]:
"""
Expand Down
123 changes: 121 additions & 2 deletions layer/nrlf/core/dynamodb/tests/test_repository.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,33 @@
from unittest.mock import patch

import pytest
from moto import mock_aws

from nrlf.core.constants import PointerTypes
from nrlf.core.dynamodb.repository import _get_sk_ids_for_type
from nrlf.core.dynamodb.model import DocumentPointer
from nrlf.core.dynamodb.repository import (
DocumentPointerRepository,
_get_sk_ids_for_type,
)
from nrlf.core.errors import OperationOutcomeError
from nrlf.core.log_references import LogReference
from nrlf.tests.data import load_document_reference
from nrlf.tests.dynamodb import mock_repository

# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


def make_document_pointer(id: str = "Y05868-99999-99999-999999") -> DocumentPointer:
doc_ref = load_document_reference("Y05868-736253002-Valid")
doc_ref.id = id
return DocumentPointer.from_document_reference(doc_ref)


# ---------------------------------------------------------------------------
# _get_sk_ids_for_type
# ---------------------------------------------------------------------------


def test_get_sk_ids_for_type_exception_thrown_for_invalid_type():
Expand Down Expand Up @@ -30,4 +56,97 @@ def test_get_sk_ids_for_type_exception_thrown_if_new_type_has_no_category():
)


# TODO: Add unit tests for Repository Class
# ---------------------------------------------------------------------------
# DocumentPointerRepository.supersede
# ---------------------------------------------------------------------------


@mock_aws
@mock_repository
def test_supersede_creates_new_and_deletes_old(repository: DocumentPointerRepository):
old_doc = make_document_pointer(id="Y05868-OLD0001")
repository.create(old_doc)
assert repository.get_by_id("Y05868-OLD0001") is not None

new_doc = make_document_pointer(id="Y05868-NEW0001")
result = repository.supersede(new_doc, ids_to_delete=["Y05868-OLD0001"])

assert result.id == "Y05868-NEW0001"
assert repository.get_by_id("Y05868-NEW0001") is not None
assert repository.get_by_id("Y05868-OLD0001") is None


@mock_aws
@mock_repository
@patch("nrlf.core.dynamodb.repository.logger")
def test_supersede_with_can_ignore_delete_fail(
mock_logger,
repository: DocumentPointerRepository,
):
new_doc = make_document_pointer(id="Y05868-NEW0003")

with patch.object(
repository.table,
"delete_item",
side_effect=Exception("simulated delete failure"),
):
result = repository.supersede(
new_doc,
ids_to_delete=["Y05868-NONEXISTENT"],
can_ignore_delete_fail=True,
)

assert result.id == "Y05868-NEW0003"
log_codes = [c.args[0] for c in mock_logger.log.call_args_list]
assert LogReference.REPOSITORY026a in log_codes


# ---------------------------------------------------------------------------
# DocumentPointerRepository.delete_by_id
# ---------------------------------------------------------------------------


@mock_aws
@mock_repository
def test_delete_by_id_removes_document_pointer(repository: DocumentPointerRepository):
doc = make_document_pointer()
repository.create(doc)
assert repository.get_by_id(doc.id) is not None

repository.delete_by_id(doc.id)

assert repository.get_by_id(doc.id) is None


@mock_aws
@mock_repository
def test_delete_by_id_raises_error_when_can_ignore_delete_fail_is_false(
repository: DocumentPointerRepository,
):
with patch.object(
repository.table,
"delete_item",
side_effect=Exception("simulated delete failure"),
):
with pytest.raises(OperationOutcomeError) as exc_info:
repository.delete_by_id("Y05868-NONEXISTENT", can_ignore_delete_fail=False)

assert exc_info.value.status_code == "500"


@mock_aws
@mock_repository
@patch("nrlf.core.dynamodb.repository.logger")
def test_delete_by_id_ignores_error_when_can_ignore_delete_fail_is_true(
mock_logger,
repository: DocumentPointerRepository,
):
with patch.object(
repository.table,
"delete_item",
side_effect=Exception("simulated delete failure"),
):
repository.delete_by_id("Y05868-NONEXISTENT", can_ignore_delete_fail=True)

log_codes = [c.args[0] for c in mock_logger.log.call_args_list]
assert LogReference.REPOSITORY026a in log_codes
Loading