Merge pull request #109 from christianlouis/copilot/fix-single-file-deletion-error

Fix single file deletion by parsing JSON response before page reload
This commit is contained in:
Christian Krakau-Louis
2026-02-07 19:45:04 +01:00
committed by GitHub
2 changed files with 108 additions and 72 deletions
+6 -1
View File
@@ -501,8 +501,13 @@
})
.then(response => {
if (!response.ok) {
throw new Error('Failed to delete file');
return response.json().then(err => {
throw new Error(err.detail || 'Failed to delete file');
});
}
return response.json();
})
.then(data => {
// Reload the page to show updated file list
window.location.reload();
})
+75 -44
View File
@@ -1,12 +1,53 @@
"""
Tests for bulk file operations (delete and reprocess).
"""
import pytest
from fastapi.testclient import TestClient
from app.models import FileRecord, ProcessingLog
from unittest.mock import patch, MagicMock
@pytest.mark.integration
@pytest.mark.requires_db
class TestSingleFileOperations:
"""Tests for single file operations."""
def test_single_file_delete_success(self, client: TestClient, db_session):
"""Test deletion of a single file."""
# Create a sample file
file_record = FileRecord(
filehash="hash1",
original_filename="test.pdf",
local_filename="/tmp/test.pdf",
file_size=1024,
mime_type="application/pdf",
)
db_session.add(file_record)
db_session.commit()
file_id = file_record.id
# Delete the file
response = client.delete(f"/api/files/{file_id}")
assert response.status_code == 200
data = response.json()
assert data["status"] == "success"
assert f"File record {file_id} deleted successfully" in data["message"]
# Verify file is deleted
file_record = (
db_session.query(FileRecord).filter(FileRecord.id == file_id).first()
)
assert file_record is None
def test_single_file_delete_nonexistent(self, client: TestClient, db_session):
"""Test deletion of a non-existent file."""
response = client.delete("/api/files/9999")
assert response.status_code == 404
data = response.json()
assert "not found" in data["detail"].lower()
@pytest.mark.integration
@pytest.mark.requires_db
class TestBulkOperations:
@@ -22,7 +63,7 @@ class TestBulkOperations:
original_filename=f"test{i}.pdf",
local_filename=f"/tmp/test{i}.pdf",
file_size=1024,
mime_type="application/pdf"
mime_type="application/pdf",
)
db_session.add(file_record)
db_session.flush()
@@ -30,10 +71,7 @@ class TestBulkOperations:
db_session.commit()
# Bulk delete
response = client.post(
"/api/files/bulk-delete",
json=file_ids
)
response = client.post("/api/files/bulk-delete", json=file_ids)
assert response.status_code == 200
data = response.json()
assert data["status"] == "success"
@@ -41,29 +79,27 @@ class TestBulkOperations:
# Verify files are deleted
for file_id in file_ids:
file_record = db_session.query(FileRecord).filter(FileRecord.id == file_id).first()
file_record = (
db_session.query(FileRecord).filter(FileRecord.id == file_id).first()
)
assert file_record is None
def test_bulk_delete_empty_list(self, client: TestClient, db_session):
"""Test bulk deletion with empty list."""
response = client.post(
"/api/files/bulk-delete",
json=[]
)
response = client.post("/api/files/bulk-delete", json=[])
assert response.status_code == 404
data = response.json()
assert "No files found" in data["detail"]
def test_bulk_delete_nonexistent_files(self, client: TestClient, db_session):
"""Test bulk deletion of non-existent files."""
response = client.post(
"/api/files/bulk-delete",
json=[9999, 9998]
)
response = client.post("/api/files/bulk-delete", json=[9999, 9998])
assert response.status_code == 404
@patch('app.api.files.process_document')
def test_bulk_reprocess_success(self, mock_process_document, client: TestClient, db_session):
@patch("app.api.files.process_document")
def test_bulk_reprocess_success(
self, mock_process_document, client: TestClient, db_session
):
"""Test bulk reprocessing of files."""
# Setup mock
mock_task = MagicMock()
@@ -78,7 +114,7 @@ class TestBulkOperations:
original_filename=f"test{i}.pdf",
local_filename=f"/tmp/test{i}.pdf",
file_size=1024,
mime_type="application/pdf"
mime_type="application/pdf",
)
db_session.add(file_record)
db_session.flush()
@@ -86,11 +122,8 @@ class TestBulkOperations:
db_session.commit()
# Mock os.path.exists to return True
with patch('os.path.exists', return_value=True):
response = client.post(
"/api/files/bulk-reprocess",
json=file_ids
)
with patch("os.path.exists", return_value=True):
response = client.post("/api/files/bulk-reprocess", json=file_ids)
assert response.status_code == 200
data = response.json()
@@ -98,8 +131,10 @@ class TestBulkOperations:
assert len(data["processed_files"]) == 2
assert len(data["task_ids"]) == 2
@patch('app.api.files.process_document')
def test_bulk_reprocess_missing_files(self, mock_process_document, client: TestClient, db_session):
@patch("app.api.files.process_document")
def test_bulk_reprocess_missing_files(
self, mock_process_document, client: TestClient, db_session
):
"""Test bulk reprocessing when some local files are missing."""
# Setup mock
mock_task = MagicMock()
@@ -112,9 +147,11 @@ class TestBulkOperations:
file_record = FileRecord(
filehash=f"hash{i}",
original_filename=f"test{i}.pdf",
local_filename=f"/tmp/test{i}.pdf" if i == 0 else None, # Second file has no local file
local_filename=(
f"/tmp/test{i}.pdf" if i == 0 else None
), # Second file has no local file
file_size=1024,
mime_type="application/pdf"
mime_type="application/pdf",
)
db_session.add(file_record)
db_session.flush()
@@ -122,11 +159,8 @@ class TestBulkOperations:
db_session.commit()
# Mock os.path.exists to return False for missing file
with patch('os.path.exists', return_value=False):
response = client.post(
"/api/files/bulk-reprocess",
json=file_ids
)
with patch("os.path.exists", return_value=False):
response = client.post("/api/files/bulk-reprocess", json=file_ids)
assert response.status_code == 200
data = response.json()
@@ -136,10 +170,7 @@ class TestBulkOperations:
def test_bulk_reprocess_nonexistent_files(self, client: TestClient, db_session):
"""Test bulk reprocessing of non-existent files."""
response = client.post(
"/api/files/bulk-reprocess",
json=[9999, 9998]
)
response = client.post("/api/files/bulk-reprocess", json=[9999, 9998])
assert response.status_code == 404
@@ -157,7 +188,7 @@ class TestStatusFilter:
original_filename="pending.pdf",
local_filename="/tmp/pending.pdf",
file_size=1024,
mime_type="application/pdf"
mime_type="application/pdf",
)
db_session.add(file1)
@@ -167,7 +198,7 @@ class TestStatusFilter:
original_filename="processing.pdf",
local_filename="/tmp/processing.pdf",
file_size=1024,
mime_type="application/pdf"
mime_type="application/pdf",
)
db_session.add(file2)
db_session.flush()
@@ -177,7 +208,7 @@ class TestStatusFilter:
task_id="task2",
step_name="OCR",
status="in_progress",
message="Processing..."
message="Processing...",
)
db_session.add(log2)
db_session.commit()
@@ -197,7 +228,7 @@ class TestStatusFilter:
original_filename="processing.pdf",
local_filename="/tmp/processing.pdf",
file_size=1024,
mime_type="application/pdf"
mime_type="application/pdf",
)
db_session.add(file_record)
db_session.flush()
@@ -207,7 +238,7 @@ class TestStatusFilter:
task_id="task1",
step_name="OCR",
status="in_progress",
message="Processing..."
message="Processing...",
)
db_session.add(log)
db_session.commit()
@@ -225,7 +256,7 @@ class TestStatusFilter:
original_filename="completed.pdf",
local_filename="/tmp/completed.pdf",
file_size=1024,
mime_type="application/pdf"
mime_type="application/pdf",
)
db_session.add(file_record)
db_session.flush()
@@ -235,7 +266,7 @@ class TestStatusFilter:
task_id="task1",
step_name="OCR",
status="success",
message="Completed"
message="Completed",
)
db_session.add(log)
db_session.commit()
@@ -253,7 +284,7 @@ class TestStatusFilter:
original_filename="failed.pdf",
local_filename="/tmp/failed.pdf",
file_size=1024,
mime_type="application/pdf"
mime_type="application/pdf",
)
db_session.add(file_record)
db_session.flush()
@@ -263,7 +294,7 @@ class TestStatusFilter:
task_id="task1",
step_name="OCR",
status="failure",
message="Failed"
message="Failed",
)
db_session.add(log)
db_session.commit()