refactor(views): split file views into summary, detail, process, and annotations pages
- /files/<id> → new summary page with navigation cards - /files/<id>/detail → document detail with metadata, preview, text - /files/<id>/process → processing pipeline status and history - /files/<id>/annotations → comments & annotations with EmbedPDF viewer - /files/<id>/comments → redirects to /annotations - Added embed-pdf-viewer as git submodule for PDF annotation viewer - Updated all navigation links across templates - Updated all tests to use new URL structure Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/12276514-bd3d-4e3e-84d9-5977d1f82b19
This commit is contained in:
+61
-35
@@ -1,4 +1,4 @@
|
||||
"""Tests for the comments and annotations UI on the file view page."""
|
||||
"""Tests for the comments and annotations UI on the file annotations page."""
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
@@ -7,7 +7,7 @@ from app.models import FileRecord
|
||||
|
||||
|
||||
def _create_file(db_session, tmp_path) -> FileRecord:
|
||||
"""Create a minimal FileRecord with a real file path for the view page."""
|
||||
"""Create a minimal FileRecord with a real file path for the annotations page."""
|
||||
file_path = tmp_path / "test.pdf"
|
||||
file_path.write_bytes(b"%PDF-1.4")
|
||||
f = FileRecord(
|
||||
@@ -26,77 +26,77 @@ def _create_file(db_session, tmp_path) -> FileRecord:
|
||||
|
||||
@pytest.mark.unit
|
||||
class TestCommentsUIRendering:
|
||||
"""Verify the file view page includes the comments panel HTML."""
|
||||
"""Verify the file annotations page includes the comments panel HTML."""
|
||||
|
||||
def test_view_page_contains_comments_section(self, client: TestClient, db_session, tmp_path):
|
||||
"""The view page should render the comments panel container."""
|
||||
def test_annotations_page_contains_comments_section(self, client: TestClient, db_session, tmp_path):
|
||||
"""The annotations page should render the comments panel container."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert 'id="comments-list"' in html
|
||||
assert 'id="comment-form"' in html
|
||||
assert 'id="comment-input"' in html
|
||||
|
||||
def test_view_page_contains_annotations_section(self, client: TestClient, db_session, tmp_path):
|
||||
"""The view page should render the annotations panel container."""
|
||||
def test_annotations_page_contains_annotations_section(self, client: TestClient, db_session, tmp_path):
|
||||
"""The annotations page should render the annotations panel container."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert 'id="annotations-list"' in html
|
||||
assert 'id="annotation-form"' in html
|
||||
assert 'id="annotation-content-input"' in html
|
||||
|
||||
def test_view_page_loads_comments_js(self, client: TestClient, db_session, tmp_path):
|
||||
"""The view page should include the comments JavaScript file."""
|
||||
def test_annotations_page_loads_comments_js(self, client: TestClient, db_session, tmp_path):
|
||||
"""The annotations page should include the comments JavaScript file."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
assert "js/comments.js" in resp.text
|
||||
|
||||
def test_view_page_loads_annotations_js(self, client: TestClient, db_session, tmp_path):
|
||||
"""The view page should include the annotations JavaScript file."""
|
||||
def test_annotations_page_loads_annotations_js(self, client: TestClient, db_session, tmp_path):
|
||||
"""The annotations page should include the annotations JavaScript file."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
assert "js/annotations.js" in resp.text
|
||||
|
||||
def test_view_page_has_mention_dropdown(self, client: TestClient, db_session, tmp_path):
|
||||
def test_annotations_page_has_mention_dropdown(self, client: TestClient, db_session, tmp_path):
|
||||
"""The mention autocomplete dropdown should be present."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
assert 'id="mention-dropdown"' in resp.text
|
||||
|
||||
def test_view_page_has_annotation_form_fields(self, client: TestClient, db_session, tmp_path):
|
||||
def test_annotations_page_has_annotation_form_fields(self, client: TestClient, db_session, tmp_path):
|
||||
"""Annotation form should have page, type, and color inputs."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert 'id="annotation-page-input"' in html
|
||||
assert 'id="annotation-type-input"' in html
|
||||
assert 'id="annotation-color-input"' in html
|
||||
|
||||
def test_view_page_has_collab_grid(self, client: TestClient, db_session, tmp_path):
|
||||
def test_annotations_page_has_collab_grid(self, client: TestClient, db_session, tmp_path):
|
||||
"""Comments and annotations should be in a side-by-side grid layout."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
assert "collab-grid" in resp.text
|
||||
|
||||
def test_view_page_no_comments_for_missing_file(self, client: TestClient):
|
||||
def test_annotations_page_no_comments_for_missing_file(self, client: TestClient):
|
||||
"""When file is not found, no comments section should appear."""
|
||||
resp = client.get("/files/99999")
|
||||
resp = client.get("/files/99999/annotations")
|
||||
assert resp.status_code == 200
|
||||
# The error block is shown, not the main content
|
||||
assert 'id="comments-list"' not in resp.text
|
||||
|
||||
def test_view_page_annotation_type_options(self, client: TestClient, db_session, tmp_path):
|
||||
def test_annotations_page_annotation_type_options(self, client: TestClient, db_session, tmp_path):
|
||||
"""Annotation type selector should include all four types."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert 'value="note"' in html
|
||||
@@ -104,38 +104,64 @@ class TestCommentsUIRendering:
|
||||
assert 'value="underline"' in html
|
||||
assert 'value="strikethrough"' in html
|
||||
|
||||
def test_view_page_comments_panel_accessibility(self, client: TestClient, db_session, tmp_path):
|
||||
def test_annotations_page_comments_panel_accessibility(self, client: TestClient, db_session, tmp_path):
|
||||
"""Comments panel should have proper ARIA attributes."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert 'aria-live="polite"' in html
|
||||
assert 'role="listbox"' in html
|
||||
|
||||
def test_view_page_init_script(self, client: TestClient, db_session, tmp_path):
|
||||
def test_annotations_page_init_script(self, client: TestClient, db_session, tmp_path):
|
||||
"""The init script should call initComments and initAnnotations."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert "initComments" in html
|
||||
assert "initAnnotations" in html
|
||||
|
||||
def test_detail_page_no_comments_section(self, client: TestClient, db_session, tmp_path):
|
||||
"""The detail page should NOT render the comments panel (moved to view page)."""
|
||||
def test_comments_url_redirects_to_annotations(self, client: TestClient, db_session, tmp_path):
|
||||
"""The /comments URL should redirect to /annotations."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}/detail")
|
||||
resp = client.get(f"/files/{f.id}/comments", follow_redirects=False)
|
||||
assert resp.status_code == 302
|
||||
assert f"/files/{f.id}/annotations" in resp.headers["location"]
|
||||
|
||||
def test_process_page_no_comments_section(self, client: TestClient, db_session, tmp_path):
|
||||
"""The process page should NOT render the comments panel."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}/process")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert 'id="comments-list"' not in html
|
||||
assert 'id="comment-form"' not in html
|
||||
|
||||
def test_detail_page_no_annotations_section(self, client: TestClient, db_session, tmp_path):
|
||||
"""The detail page should NOT render the annotations panel (moved to view page)."""
|
||||
def test_detail_page_no_comments_section(self, client: TestClient, db_session, tmp_path):
|
||||
"""The detail page should NOT render the comments panel."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}/detail")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert 'id="annotations-list"' not in html
|
||||
assert 'id="comments-list"' not in html
|
||||
assert 'id="annotation-form"' not in html
|
||||
|
||||
def test_annotations_page_has_embedpdf_viewer_for_pdf(self, client: TestClient, db_session, tmp_path):
|
||||
"""The annotations page should include the EmbedPDF viewer for PDF files."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}/annotations")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert 'id="embedpdf-viewer"' in html
|
||||
assert "@embedpdf/snippet" in html
|
||||
|
||||
def test_summary_page_renders(self, client: TestClient, db_session, tmp_path):
|
||||
"""The summary page at /files/{id} should render correctly."""
|
||||
f = _create_file(db_session, tmp_path)
|
||||
resp = client.get(f"/files/{f.id}")
|
||||
assert resp.status_code == 200
|
||||
html = resp.text
|
||||
assert "Document Detail" in html
|
||||
assert "Processing" in html
|
||||
assert "Comments" in html or "Annotations" in html
|
||||
|
||||
@@ -57,7 +57,7 @@ class TestFileViewPdfJs:
|
||||
pdf.write_bytes(b"%PDF-1.4 test")
|
||||
rec = _create_file_record(db_session, file_path=str(pdf), mime_type="application/pdf")
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
assert response.status_code == 200
|
||||
html = response.text
|
||||
|
||||
@@ -80,7 +80,7 @@ class TestFileViewPdfJs:
|
||||
pdf.write_bytes(b"%PDF-1.4 test")
|
||||
rec = _create_file_record(db_session, file_path=str(pdf), mime_type="application/pdf")
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
html = response.text
|
||||
|
||||
# The preview section should use pdf-viewer, not iframe
|
||||
@@ -93,7 +93,7 @@ class TestFileViewPdfJs:
|
||||
pdf.write_bytes(b"%PDF-1.4 test")
|
||||
rec = _create_file_record(db_session, file_path=str(pdf), mime_type="application/pdf")
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
html = response.text
|
||||
|
||||
assert 'id="pdf-prev-btn"' in html
|
||||
@@ -116,7 +116,7 @@ class TestFileViewImagePreview:
|
||||
img.write_bytes(b"\xff\xd8\xff\xe0" + b"\x00" * 100) # minimal JPEG header
|
||||
rec = _create_file_record(db_session, filename="photo.jpg", mime_type="image/jpeg", file_path=str(img))
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
assert response.status_code == 200
|
||||
html = response.text
|
||||
|
||||
@@ -132,7 +132,7 @@ class TestFileViewImagePreview:
|
||||
img.write_bytes(b"\x89PNG\r\n\x1a\n" + b"\x00" * 50)
|
||||
rec = _create_file_record(db_session, filename="photo.png", mime_type="image/png", file_path=str(img))
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
html = response.text
|
||||
|
||||
assert 'aria-label="Zoom in"' in html
|
||||
@@ -146,7 +146,7 @@ class TestFileViewImagePreview:
|
||||
img.write_bytes(b"RIFF" + b"\x00" * 50)
|
||||
rec = _create_file_record(db_session, filename="wide.webp", mime_type="image/webp", file_path=str(img))
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
html = response.text
|
||||
|
||||
# Pan support is implemented via JavaScript on img-wrap
|
||||
@@ -170,7 +170,7 @@ class TestFileViewTextPreview:
|
||||
txt.write_text("Hello world\nSecond line\n")
|
||||
rec = _create_file_record(db_session, filename="readme.txt", mime_type="text/plain", file_path=str(txt))
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
assert response.status_code == 200
|
||||
html = response.text
|
||||
|
||||
@@ -184,7 +184,7 @@ class TestFileViewTextPreview:
|
||||
txt.write_text("print('hello')\n")
|
||||
rec = _create_file_record(db_session, filename="code.py", mime_type="text/x-python", file_path=str(txt))
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
html = response.text
|
||||
|
||||
assert "copyTextPreview" in html
|
||||
@@ -196,7 +196,7 @@ class TestFileViewTextPreview:
|
||||
txt.write_text("a,b,c\n1,2,3\n")
|
||||
rec = _create_file_record(db_session, filename="data.csv", mime_type="text/csv", file_path=str(txt))
|
||||
|
||||
response = client.get(f"/files/{rec.id}")
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
html = response.text
|
||||
|
||||
# JS builds line-number spans
|
||||
@@ -218,7 +218,7 @@ class TestFileViewPreviewIcon:
|
||||
pdf.write_bytes(b"%PDF-1.4")
|
||||
rec = _create_file_record(db_session, file_path=str(pdf), mime_type="application/pdf")
|
||||
|
||||
html = client.get(f"/files/{rec.id}").text
|
||||
html = client.get(f"/files/{rec.id}/detail").text
|
||||
assert "fa-file-pdf" in html
|
||||
|
||||
def test_image_icon(self, client: TestClient, db_session, tmp_path):
|
||||
@@ -227,7 +227,7 @@ class TestFileViewPreviewIcon:
|
||||
img.write_bytes(b"\xff\xd8\xff\xe0" + b"\x00" * 10)
|
||||
rec = _create_file_record(db_session, filename="p.jpg", mime_type="image/jpeg", file_path=str(img))
|
||||
|
||||
html = client.get(f"/files/{rec.id}").text
|
||||
html = client.get(f"/files/{rec.id}/detail").text
|
||||
assert "fa-image" in html
|
||||
|
||||
def test_text_icon(self, client: TestClient, db_session, tmp_path):
|
||||
@@ -236,7 +236,7 @@ class TestFileViewPreviewIcon:
|
||||
txt.write_text("hello")
|
||||
rec = _create_file_record(db_session, filename="t.txt", mime_type="text/plain", file_path=str(txt))
|
||||
|
||||
html = client.get(f"/files/{rec.id}").text
|
||||
html = client.get(f"/files/{rec.id}/detail").text
|
||||
assert "fa-file-code" in html
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ class TestFileDetailBottomPreview:
|
||||
pdf.write_bytes(b"%PDF-1.4")
|
||||
rec = _create_file_record(db_session, file_path=str(pdf), processed_path=str(pdf))
|
||||
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
response = client.get(f"/files/{rec.id}/process")
|
||||
assert response.status_code == 200
|
||||
html = response.text
|
||||
|
||||
@@ -335,7 +335,7 @@ class TestFileDetailBottomPreview:
|
||||
pdf.write_bytes(b"%PDF-1.4")
|
||||
rec = _create_file_record(db_session, file_path=str(pdf), processed_path=str(pdf))
|
||||
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
response = client.get(f"/files/{rec.id}/process")
|
||||
html = response.text
|
||||
assert f"/api/files/{rec.id}/download" in html
|
||||
|
||||
@@ -350,7 +350,7 @@ class TestFileDetailBottomPreview:
|
||||
file_path=str(img),
|
||||
)
|
||||
|
||||
response = client.get(f"/files/{rec.id}/detail")
|
||||
response = client.get(f"/files/{rec.id}/process")
|
||||
html = response.text
|
||||
assert f"/api/files/{rec.id}/preview?version=original" in html
|
||||
|
||||
@@ -372,7 +372,7 @@ class TestFileViewOcrText:
|
||||
rec.ocr_text = "Sample extracted OCR text content"
|
||||
db_session.commit()
|
||||
|
||||
html = client.get(f"/files/{rec.id}").text
|
||||
html = client.get(f"/files/{rec.id}/detail").text
|
||||
assert "toggleOcrText" in html
|
||||
assert "ocr-text-block" in html
|
||||
assert "Sample extracted OCR text content" in html
|
||||
@@ -383,7 +383,7 @@ class TestFileViewOcrText:
|
||||
pdf.write_bytes(b"%PDF-1.4")
|
||||
rec = _create_file_record(db_session, file_path=str(pdf))
|
||||
|
||||
html = client.get(f"/files/{rec.id}").text
|
||||
html = client.get(f"/files/{rec.id}/detail").text
|
||||
assert "loadText" in html or "Extract" in html
|
||||
|
||||
|
||||
@@ -409,5 +409,5 @@ class TestFileViewNoFile:
|
||||
db_session.commit()
|
||||
db_session.refresh(rec)
|
||||
|
||||
html = client.get(f"/files/{rec.id}").text
|
||||
html = client.get(f"/files/{rec.id}/detail").text
|
||||
assert "No file available for preview" in html
|
||||
|
||||
@@ -447,7 +447,7 @@ class TestFileDetailView:
|
||||
db_session.commit()
|
||||
|
||||
# Test detail view
|
||||
response = client.get(f"/files/{file_record.id}/detail")
|
||||
response = client.get(f"/files/{file_record.id}/process")
|
||||
assert response.status_code == 200
|
||||
# Check that response contains HTML with file information
|
||||
assert b"File Information" in response.content
|
||||
@@ -504,7 +504,7 @@ class TestFileDetailView:
|
||||
db_session.commit()
|
||||
|
||||
# Test detail view
|
||||
response = client.get(f"/files/{file_record.id}/detail")
|
||||
response = client.get(f"/files/{file_record.id}/process")
|
||||
assert response.status_code == 200
|
||||
# Check that response contains branching visualization elements
|
||||
assert b"Process Flow Visualization" in response.content
|
||||
@@ -514,7 +514,7 @@ class TestFileDetailView:
|
||||
|
||||
def test_file_detail_view_nonexistent(self, client: TestClient):
|
||||
"""Test file detail view for nonexistent file."""
|
||||
response = client.get("/files/99999/detail")
|
||||
response = client.get("/files/99999/process")
|
||||
assert response.status_code == 200 # Returns page with error message
|
||||
assert b"not found" in response.content.lower()
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ def test_file_detail_page_with_metadata(client: TestClient, db_session, sample_p
|
||||
db_session.refresh(file_record)
|
||||
|
||||
# Get detail page
|
||||
response = client.get(f"/files/{file_record.id}/detail")
|
||||
response = client.get(f"/files/{file_record.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
html = response.text
|
||||
@@ -85,7 +85,7 @@ def test_file_detail_with_gpt_metadata(client: TestClient, db_session, sample_pd
|
||||
db_session.refresh(file_record)
|
||||
|
||||
# Get detail page
|
||||
response = client.get(f"/files/{file_record.id}/detail")
|
||||
response = client.get(f"/files/{file_record.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
html = response.text
|
||||
@@ -190,7 +190,7 @@ def test_file_detail_shows_file_status_indicators(client: TestClient, db_session
|
||||
db_session.commit()
|
||||
db_session.refresh(file_record)
|
||||
|
||||
response = client.get(f"/files/{file_record.id}/detail")
|
||||
response = client.get(f"/files/{file_record.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
html = response.text
|
||||
|
||||
@@ -142,7 +142,7 @@ class TestFileDetailPage:
|
||||
db_session.commit()
|
||||
|
||||
# Test file detail page
|
||||
response = client.get(f"/files/{file_record.id}/detail")
|
||||
response = client.get(f"/files/{file_record.id}/process")
|
||||
assert response.status_code == 200
|
||||
content = response.text
|
||||
assert "test.pdf" in content
|
||||
@@ -150,7 +150,7 @@ class TestFileDetailPage:
|
||||
def test_file_detail_page_with_missing_file(self, client: TestClient, db_session):
|
||||
"""Test file detail page with non-existent file"""
|
||||
# Try to access non-existent file
|
||||
response = client.get("/files/99999/detail")
|
||||
response = client.get("/files/99999/process")
|
||||
assert response.status_code == 200
|
||||
content = response.text
|
||||
assert "not found" in content.lower()
|
||||
@@ -193,7 +193,7 @@ class TestFileDetailPage:
|
||||
db_session.commit()
|
||||
|
||||
# Test file detail page
|
||||
response = client.get(f"/files/{file_record.id}/detail")
|
||||
response = client.get(f"/files/{file_record.id}/process")
|
||||
assert response.status_code == 200
|
||||
content = response.text
|
||||
assert "create_file_record" in content
|
||||
@@ -232,7 +232,7 @@ class TestFileDetailPage:
|
||||
db_session.commit()
|
||||
|
||||
# Test file detail page
|
||||
response = client.get(f"/files/{file_record.id}/detail")
|
||||
response = client.get(f"/files/{file_record.id}/process")
|
||||
assert response.status_code == 200
|
||||
content = response.text
|
||||
# Should show metadata
|
||||
|
||||
@@ -206,12 +206,12 @@ class TestFileDetailPage:
|
||||
db_session.add(file)
|
||||
db_session.commit()
|
||||
|
||||
response = client.get(f"/files/{file.id}/detail")
|
||||
response = client.get(f"/files/{file.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_file_detail_page_not_found(self, client: TestClient, db_session):
|
||||
"""Test file detail page for non-existent file."""
|
||||
response = client.get("/files/99999/detail")
|
||||
response = client.get("/files/99999/process")
|
||||
assert response.status_code == 200 # Still renders template with error
|
||||
|
||||
def test_file_detail_page_with_processing_logs(self, client: TestClient, db_session, tmp_path):
|
||||
@@ -244,7 +244,7 @@ class TestFileDetailPage:
|
||||
db_session.add(log2)
|
||||
db_session.commit()
|
||||
|
||||
response = client.get(f"/files/{file.id}/detail")
|
||||
response = client.get(f"/files/{file.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_file_detail_page_with_metadata_json(self, client: TestClient, db_session, tmp_path):
|
||||
@@ -272,7 +272,7 @@ class TestFileDetailPage:
|
||||
db_session.add(file)
|
||||
db_session.commit()
|
||||
|
||||
response = client.get(f"/files/{file.id}/detail")
|
||||
response = client.get(f"/files/{file.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_file_detail_checks_original_file_exists(self, client: TestClient, db_session, tmp_path):
|
||||
@@ -289,7 +289,7 @@ class TestFileDetailPage:
|
||||
db_session.add(file)
|
||||
db_session.commit()
|
||||
|
||||
response = client.get(f"/files/{file.id}/detail")
|
||||
response = client.get(f"/files/{file.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_file_detail_error_handling(self, client: TestClient, db_session):
|
||||
@@ -1113,7 +1113,7 @@ class TestFileDetailPageAdditional:
|
||||
db_session.add(file)
|
||||
db_session.commit()
|
||||
|
||||
response = client.get(f"/files/{file.id}/detail")
|
||||
response = client.get(f"/files/{file.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_file_detail_step_summary_fallback(self, client: TestClient, db_session, tmp_path):
|
||||
@@ -1144,7 +1144,7 @@ class TestFileDetailPageAdditional:
|
||||
db_session.commit()
|
||||
|
||||
with patch("app.utils.step_manager.get_step_summary", side_effect=Exception("Table not found")):
|
||||
response = client.get(f"/files/{file.id}/detail")
|
||||
response = client.get(f"/files/{file.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_file_detail_error_handling(self, client: TestClient, db_session):
|
||||
@@ -1155,7 +1155,7 @@ class TestFileDetailPageAdditional:
|
||||
Mock(status_code=200),
|
||||
]
|
||||
try:
|
||||
response = client.get("/files/1/detail")
|
||||
response = client.get("/files/1/process")
|
||||
assert response.status_code in (200, 500)
|
||||
except Exception:
|
||||
pass
|
||||
@@ -1638,7 +1638,7 @@ class TestFileDetailNoJsonSidecar:
|
||||
db_session.add(file)
|
||||
db_session.commit()
|
||||
|
||||
response = client.get(f"/files/{file.id}/detail")
|
||||
response = client.get(f"/files/{file.id}/process")
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@@ -1936,7 +1936,7 @@ class TestPipelineInfoInViews:
|
||||
pipeline = self._make_system_pipeline(db_session)
|
||||
file_rec = self._make_file(db_session, pipeline_id=None)
|
||||
|
||||
response = client.get(f"/files/{file_rec.id}/detail")
|
||||
response = client.get(f"/files/{file_rec.id}/process")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b"Standard Processing Pipeline" in response.content
|
||||
@@ -1946,7 +1946,7 @@ class TestPipelineInfoInViews:
|
||||
self._make_system_pipeline(db_session)
|
||||
file_rec = self._make_file(db_session, pipeline_id=None)
|
||||
|
||||
response = client.get(f"/files/{file_rec.id}/detail")
|
||||
response = client.get(f"/files/{file_rec.id}/process")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b"System Default" in response.content
|
||||
@@ -1956,28 +1956,28 @@ class TestPipelineInfoInViews:
|
||||
pipeline = self._make_custom_pipeline(db_session)
|
||||
file_rec = self._make_file(db_session, pipeline_id=pipeline.id)
|
||||
|
||||
response = client.get(f"/files/{file_rec.id}/detail")
|
||||
response = client.get(f"/files/{file_rec.id}/process")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b"My Custom Pipeline" in response.content
|
||||
assert b"Custom" in response.content
|
||||
|
||||
def test_file_view_page_includes_pipeline_name(self, client, db_session):
|
||||
"""GET /files/{id} response body contains the pipeline name in the sidebar."""
|
||||
"""GET /files/{id}/detail response body contains the pipeline name in the sidebar."""
|
||||
pipeline = self._make_system_pipeline(db_session)
|
||||
file_rec = self._make_file(db_session, pipeline_id=None)
|
||||
|
||||
response = client.get(f"/files/{file_rec.id}")
|
||||
response = client.get(f"/files/{file_rec.id}/detail")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b"Standard Processing Pipeline" in response.content
|
||||
|
||||
def test_file_view_page_no_pipeline_shows_standard(self, client, db_session):
|
||||
"""When no pipeline exists, file view shows 'Standard' fallback text."""
|
||||
"""When no pipeline exists, file detail view shows 'Standard' fallback text."""
|
||||
# No pipeline in DB
|
||||
file_rec = self._make_file(db_session, pipeline_id=None)
|
||||
|
||||
response = client.get(f"/files/{file_rec.id}")
|
||||
response = client.get(f"/files/{file_rec.id}/detail")
|
||||
|
||||
assert response.status_code == 200
|
||||
assert b"Standard" in response.content
|
||||
|
||||
Reference in New Issue
Block a user