feat: feedback verbetering - 06

This commit is contained in:
kodi
2026-03-15 15:51:13 +01:00
parent ae6a9d8c45
commit 9537a29de3
17 changed files with 368 additions and 37 deletions
@@ -504,6 +504,108 @@ class FileOpsApiGoldenTest(unittest.TestCase):
self.assertTrue(target.joinpath("nested", "b.txt").exists())
self.assertTrue(target.exists())
def test_delete_batch_multi_select_starts_one_task_and_completes(self) -> None:
first = self.scope / "batch-a.txt"
second_dir = self.scope / "batch-dir"
second_nested = second_dir / "nested.txt"
first.write_text("a", encoding="utf-8")
second_dir.mkdir()
second_nested.write_text("b", encoding="utf-8")
response = self._post(
"/api/files/delete",
{
"paths": ["storage1/scope/batch-a.txt", "storage1/scope/batch-dir"],
"recursive_paths": ["storage1/scope/batch-dir"],
},
)
self.assertEqual(response.status_code, 202)
detail = self._wait_task(response.json()["task_id"])
self.assertEqual(detail["operation"], "delete")
self.assertEqual(detail["status"], "completed")
self.assertEqual(detail["source"], "2 items")
self.assertEqual(detail["done_items"], 2)
self.assertEqual(detail["total_items"], 2)
self.assertFalse(first.exists())
self.assertFalse(second_dir.exists())
def test_delete_batch_cancelled_after_current_delete_finishes(self) -> None:
blocking_fs = BlockingDeleteFilesystemAdapter()
path_guard = PathGuard({"storage1": str(self.root)})
service = FileOpsService(path_guard=path_guard, filesystem=blocking_fs)
delete_service = DeleteTaskService(
path_guard=path_guard,
repository=self.repo,
runner=TaskRunner(repository=self.repo, filesystem=blocking_fs),
)
task_service = TaskService(repository=self.repo)
async def _override_file_ops_service() -> FileOpsService:
return service
async def _override_delete_task_service() -> DeleteTaskService:
return delete_service
async def _override_task_service() -> TaskService:
return task_service
app.dependency_overrides[get_file_ops_service] = _override_file_ops_service
app.dependency_overrides[get_delete_task_service] = _override_delete_task_service
app.dependency_overrides[get_task_service] = _override_task_service
first = self.scope / "cancel-a.txt"
second = self.scope / "cancel-b.txt"
first.write_text("a", encoding="utf-8")
second.write_text("b", encoding="utf-8")
response = self._post(
"/api/files/delete",
{
"paths": ["storage1/scope/cancel-a.txt", "storage1/scope/cancel-b.txt"],
},
)
task_id = response.json()["task_id"]
self.assertTrue(blocking_fs.entered.wait(timeout=2.0))
running = self._wait_for_status(task_id, {"running"})
self.assertEqual(running["done_items"], 0)
self.assertEqual(running["total_items"], 2)
cancel_response = self._post(f"/api/tasks/{task_id}/cancel", {})
self.assertEqual(cancel_response.status_code, 200)
self.assertEqual(cancel_response.json()["status"], "cancelling")
blocking_fs.release.set()
detail = self._wait_task(task_id)
self.assertEqual(detail["status"], "cancelled")
self.assertEqual(detail["done_items"], 1)
self.assertEqual(detail["total_items"], 2)
self.assertFalse(first.exists())
self.assertTrue(second.exists())
def test_delete_batch_directory_only_empty_dirs_remains_honestly_coarse(self) -> None:
first = self.scope / "empty-a"
second = self.scope / "empty-b"
first.mkdir()
second.mkdir()
response = self._post(
"/api/files/delete",
{
"paths": ["storage1/scope/empty-a", "storage1/scope/empty-b"],
},
)
self.assertEqual(response.status_code, 202)
detail = self._wait_task(response.json()["task_id"])
self.assertEqual(detail["status"], "completed")
self.assertEqual(detail["done_items"], 0)
self.assertEqual(detail["total_items"], 0)
self.assertIsNone(detail["current_item"])
self.assertFalse(first.exists())
self.assertFalse(second.exists())
def test_delete_invalid_path(self) -> None:
response = self._post(
"/api/files/delete",