Skip to content

Commit

Permalink
PDCT-445 Implemented soft delete for families. (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
katybaulch authored Oct 24, 2023
1 parent e0ab24c commit 0d45b21
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 22 deletions.
45 changes: 31 additions & 14 deletions app/repository/family.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
from app.clients.db.models.app.users import Organisation
from app.clients.db.models.law_policy.collection import CollectionFamily
from sqlalchemy.orm import Session
from app.clients.db.models.law_policy.family import FamilyOrganisation, Slug
from app.clients.db.models.law_policy.family import (
DocumentStatus,
FamilyDocument,
FamilyOrganisation,
FamilyStatus,
Slug,
)
from app.clients.db.models.law_policy.geography import Geography
from app.clients.db.models.law_policy.metadata import (
FamilyMetadata,
Expand All @@ -18,7 +24,7 @@
from app.clients.db.models.law_policy import Family
from sqlalchemy.exc import NoResultFound
from sqlalchemy_utils import escape_like
from sqlalchemy import Column, or_, update as db_update, delete as db_delete
from sqlalchemy import Column, or_, update as db_update
from sqlalchemy.orm import Query

from app.repository.helpers import generate_import_id, generate_slug
Expand Down Expand Up @@ -299,18 +305,29 @@ def delete(db: Session, import_id: str) -> bool:
:param str import_id: The family import id to delete.
:return bool: True if deleted False if not.
"""
commands = [
db_delete(FamilyOrganisation).where(
FamilyOrganisation.family_import_id == import_id
),
db_delete(FamilyMetadata).where(FamilyMetadata.family_import_id == import_id),
db_delete(Slug).where(Slug.family_import_id == import_id),
db_delete(Family).where(Family.import_id == import_id),
]
for c in commands:
result = db.execute(c)

return result.rowcount > 0 # type: ignore
found = db.query(Family).filter(Family.import_id == import_id).one_or_none()
if found is None:
return False

# Soft delete all documents associated with the family.
result = db.execute(
db_update(FamilyDocument)
.filter(FamilyDocument.family_import_id == import_id)
.values(document_status=DocumentStatus.DELETED)
)
if result.rowcount == 0: # type: ignore
msg = f"Could not soft delete documents in family : {import_id}"
_LOGGER.error(msg)
raise RepositoryError(msg)

# Check family has been soft deleted if all documents have also been soft deleted.
fam_deleted = db.query(Family).filter(Family.import_id == import_id).one()
if fam_deleted.family_status != FamilyStatus.DELETED: # type: ignore
msg = f"Could not soft delete family : {import_id}"
_LOGGER.error(msg)
raise RepositoryError(msg)

return bool(fam_deleted.family_status == FamilyStatus.DELETED)


def get_organisation(db: Session, family_import_id: str) -> Optional[Organisation]:
Expand Down
1 change: 0 additions & 1 deletion app/service/family.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,6 @@ def delete(import_id: str, db: Session = db_session.get_db()) -> bool:
msg = f"Unable to delete family {import_id}"
_LOGGER.exception(msg)
raise RepositoryError(msg)
return family_repo.delete(db, import_id)


@validate_call(config=ConfigDict(arbitrary_types_allowed=True))
Expand Down
34 changes: 27 additions & 7 deletions integration_tests/family/test_delete.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
from fastapi.testclient import TestClient
from fastapi import status
from sqlalchemy.orm import Session
from app.clients.db.models.law_policy.family import Family

from app.clients.db.models.law_policy import (
Family,
FamilyDocument,
DocumentStatus,
FamilyStatus,
)
from integration_tests.setup_db import setup_db


def test_delete_family(client: TestClient, test_db: Session, admin_user_header_token):
setup_db(test_db)
response = client.delete(
"/api/v1/families/A.0.0.2", headers=admin_user_header_token
"/api/v1/families/A.0.0.3", headers=admin_user_header_token
)
assert response.status_code == status.HTTP_200_OK
n = test_db.query(Family).count()
assert n == 2
assert test_db.query(Family).count() == 3
assert (
test_db.query(FamilyDocument)
.filter(FamilyDocument.document_status == DocumentStatus.DELETED)
.count()
== 2
)
family = test_db.query(Family).filter(Family.import_id == "A.0.0.3").all()
assert len(family) == 1
assert family[0].family_status == FamilyStatus.DELETED


def test_delete_family_when_not_authenticated(client: TestClient, test_db: Session):
Expand All @@ -28,11 +42,17 @@ def test_delete_family_rollback(
):
setup_db(test_db)
response = client.delete(
"/api/v1/families/A.0.0.2", headers=admin_user_header_token
"/api/v1/families/A.0.0.3", headers=admin_user_header_token
)
assert response.status_code == status.HTTP_503_SERVICE_UNAVAILABLE
n = test_db.query(Family).count()
assert n == 3
assert (
test_db.query(FamilyDocument)
.filter(FamilyDocument.document_status == DocumentStatus.DELETED)
.count()
== 0
)
test_family = test_db.query(Family).filter(Family.import_id == "A.0.0.3").one()
assert test_family.family_status != FamilyStatus.DELETED


def test_delete_family_when_not_found(
Expand Down

0 comments on commit 0d45b21

Please sign in to comment.