Skip to content

Commit

Permalink
softdelete tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tykling committed Jan 21, 2025
1 parent 371f5b4 commit b67cebb
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 11 deletions.
14 changes: 7 additions & 7 deletions src/files/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class BaseFileAdmin(admin.ModelAdmin[BaseFile]):
"deleted",
)
list_filter = ("license", "uploader", "attribution", "approved", "published", "deleted")
actions = ("approve", "unapprove", "publish", "unpublish", "softdelete", "undelete")
actions = ("approve", "unapprove", "publish", "unpublish", "softdelete", "unsoftdelete")
exclude = ("tags",)

def get_queryset(self, request: HttpRequest) -> QuerySet[BaseFile]:
Expand Down Expand Up @@ -108,7 +108,7 @@ def has_softdelete_basefile_permission(self, request: HttpRequest, obj: BaseFile
return request.user.has_perm("softdelete_basefile", obj)

def has_unsoftdelete_basefile_permission(self, request: HttpRequest, obj: BaseFile | None = None) -> bool:
"""Called by the admin to check if the user has permission to undelete this type of/this specific object."""
"""Called by the admin to check if the user has permission to unsoftdelete this type of/this specific object."""
if obj is None:
return True
return request.user.has_perm("unsoftdelete_basefile", obj)
Expand Down Expand Up @@ -184,19 +184,19 @@ def softdelete(self, request: HttpRequest, queryset: QuerySet[BaseFile]) -> None
valid = get_objects_for_user(request.user, "files.softdelete_basefile", klass=queryset)
valids = valid.count()
updated = valid.softdelete()
self.send_message(request, selected=selected, valid=valids, updated=updated, action="deleted")
self.send_message(request, selected=selected, valid=valids, updated=updated, action="softdeleted")

@admin.action(
description="Unsoftdelete selected %(verbose_name_plural)s",
permissions=["unsoftdelete_basefile"],
)
def undelete(self, request: HttpRequest, queryset: QuerySet[BaseFile]) -> None:
"""Admin action to undelete files."""
def unsoftdelete(self, request: HttpRequest, queryset: QuerySet[BaseFile]) -> None:
"""Admin action to unsoftdelete files."""
selected = queryset.count()
valid = get_objects_for_user(request.user, "files.unsoftdelete_basefile", klass=queryset)
valids = valid.count()
updated = valid.undelete()
self.send_message(request, selected=selected, valid=valids, updated=updated, action="undeleted")
updated = valid.unsoftdelete()
self.send_message(request, selected=selected, valid=valids, updated=updated, action="unsoftdeleted")

def permissions(self, obj: BaseFile) -> str:
"""Return all defined permissions for this object."""
Expand Down
27 changes: 26 additions & 1 deletion src/files/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ def file_update(
},
summary="Soft-delete a file.",
)
def file_delete(
def file_softdelete(
request: HttpRequest, file_uuid: uuid.UUID, *, check: bool = False
) -> tuple[int, dict[str, str] | None]:
"""Mark a file for deletion."""
Expand All @@ -589,6 +589,31 @@ def file_delete(
return 204, None


@router.patch(
"/{file_uuid}/unsoftdelete/",
response={
200: SingleFileResponseSchema,
202: ApiMessageSchema,
403: ApiMessageSchema,
404: ApiMessageSchema,
},
summary="Un-soft-delete a file.",
)
def file_unsoftdelete(
request: HttpRequest, file_uuid: uuid.UUID, *, check: bool = False
) -> tuple[int, dict[str, str] | None]:
"""Unmark a file for deletion."""
basefile = get_object_or_404(BaseFile.bmanager.all(), uuid=file_uuid)
if not request.user.has_perm("unsoftdelete_basefile", basefile):
return 403, {"message": "Permission denied."}
if check:
# check mode requested, don't change anything
return 202, {"message": "OK"}
# ok go
basefile.unsoftdelete()
return 200, {"bma_response": basefile, "message": "File undeleted."}


############## TAGS #########################################################
@router.post(
"/{file_uuid}/tag/",
Expand Down
2 changes: 1 addition & 1 deletion src/files/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ def softdelete(self) -> int:
"""Soft-delete files in queryset."""
return self.change_bool(field="deleted", value=True)

def undelete(self) -> int:
def unsoftdelete(self) -> int:
"""Undelete files in queryset."""
return self.change_bool(field="deleted", value=False)

Expand Down
4 changes: 2 additions & 2 deletions src/files/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,8 +319,8 @@ def softdelete(self) -> None:
"""Soft delete this file."""
self.update_field(field="deleted", value=True)

def undelete(self) -> None:
"""Undelete this file."""
def unsoftdelete(self) -> None:
"""Unsoftdelete this file."""
self.update_field(field="deleted", value=False)

def add_initial_permissions(self) -> None:
Expand Down
21 changes: 21 additions & 0 deletions src/files/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,27 @@ def test_file_softdelete(self) -> None:
)
assert response.status_code == 204

# undelete file, wrong user
response = self.client.patch(
reverse("api-v1-json:file_unsoftdelete", kwargs={"file_uuid": self.file_uuid}),
headers={"authorization": self.tokens[self.user0]},
)
assert response.status_code == 403

# undelete file, check mode
response = self.client.patch(
reverse("api-v1-json:file_unsoftdelete", kwargs={"file_uuid": self.file_uuid}) + "?check=true",
headers={"authorization": self.tokens[self.superuser]},
)
assert response.status_code == 202

# undelete file
response = self.client.patch(
reverse("api-v1-json:file_unsoftdelete", kwargs={"file_uuid": self.file_uuid}),
headers={"authorization": self.tokens[self.superuser]},
)
assert response.status_code == 200

def test_metadata_get_404(self) -> None:
"""Get file metadata get with wrong uuid returns 404."""
response = self.client.get(
Expand Down

0 comments on commit b67cebb

Please sign in to comment.