generated from john/python-template
142 lines
5.4 KiB
Python
142 lines
5.4 KiB
Python
"""Tests for the jobs page route."""
|
|
|
|
import asyncio
|
|
from uuid import uuid4
|
|
|
|
import pytest
|
|
|
|
from transcription.db import session_scope
|
|
from transcription.db.models import Document
|
|
from transcription.db.models import JobStatus
|
|
|
|
|
|
@pytest.mark.integration
|
|
class TestPageRendering:
|
|
"""Verify jobs routes render correctly with real app wiring."""
|
|
|
|
def test_jobs_page_renders_empty_state(self, app_client):
|
|
"""GET /ui/jobs renders the page and empty-state text when no jobs exist."""
|
|
_, client = app_client
|
|
response = client.get("/ui/jobs")
|
|
|
|
assert response.status_code == 200
|
|
assert "Create job" in response.text
|
|
assert "No jobs yet." in response.text
|
|
|
|
def test_job_create_page_requires_existing_documents(self, app_client):
|
|
"""GET /ui/jobs/new shows guidance when no Documents exist."""
|
|
_, client = app_client
|
|
|
|
response = client.get("/ui/jobs/new")
|
|
|
|
assert response.status_code == 200
|
|
assert "Create job" in response.text
|
|
assert "No documents available. Create a Document before creating a Job." in response.text
|
|
assert "Create document" in response.text
|
|
|
|
def test_job_create_page_lists_available_documents(self, app_client):
|
|
"""GET /ui/jobs/new renders document choices when Documents exist."""
|
|
_, client = app_client
|
|
|
|
async def _seed_document() -> None:
|
|
async with session_scope() as session:
|
|
session.add(Document(name="Seeded Document"))
|
|
await session.commit()
|
|
|
|
asyncio.run(_seed_document())
|
|
|
|
response = client.get("/ui/jobs/new")
|
|
|
|
assert response.status_code == 200
|
|
assert "Create job" in response.text
|
|
assert "Seeded Document" in response.text
|
|
assert "Files are processed alphabetically by original filename." in response.text
|
|
assert "No files uploaded yet." in response.text
|
|
assert "Select source files or a folder" in response.text
|
|
|
|
def test_jobs_page_lists_seeded_jobs(self, app_client, seed_job):
|
|
"""GET /ui/jobs lists seeded jobs from the in-memory database."""
|
|
_, client = app_client
|
|
seed_job(filename="sample.pdf", status=JobStatus.TRANSCRIBED, transcription_text="done")
|
|
|
|
response = client.get("/ui/jobs")
|
|
|
|
assert response.status_code == 200
|
|
assert "sample.pdf" in response.text
|
|
assert "transcribed" in response.text
|
|
|
|
def test_job_detail_page_renders_document_links(self, app_client, seed_job):
|
|
"""GET /ui/jobs/{job_id} renders document-scoped navigation links."""
|
|
_, client = app_client
|
|
job_id = seed_job(
|
|
filename="detail.pdf",
|
|
status=JobStatus.TRANSCRIBED,
|
|
transcription_text="original text",
|
|
)
|
|
|
|
response = client.get(f"/ui/jobs/{job_id}")
|
|
|
|
assert response.status_code == 200
|
|
assert "Job" in response.text
|
|
assert "Provider:" in response.text
|
|
assert "Model:" in response.text
|
|
assert "Prompt:" in response.text
|
|
assert "Retry count:" in response.text
|
|
assert "Last updated:" in response.text
|
|
assert "Document Links" in response.text
|
|
assert "Sources" in response.text
|
|
assert "Jobs" in response.text
|
|
assert "Delete job" not in response.text
|
|
|
|
def test_job_detail_page_rejects_invalid_id(self, app_client):
|
|
"""GET /ui/jobs/{job_id} shows validation feedback for malformed IDs."""
|
|
_, client = app_client
|
|
response = client.get("/ui/jobs/not-a-uuid")
|
|
|
|
assert response.status_code == 200
|
|
assert "Invalid job id" in response.text
|
|
|
|
def test_job_detail_page_handles_missing_job(self, app_client):
|
|
"""GET /ui/jobs/{job_id} shows not-found state for unknown IDs."""
|
|
_, client = app_client
|
|
missing_id = uuid4()
|
|
response = client.get(f"/ui/jobs/{missing_id}")
|
|
|
|
assert response.status_code == 200
|
|
assert "Job not found" in response.text
|
|
|
|
def test_job_detail_page_hides_delete_action(self, app_client, seed_job):
|
|
"""GET /ui/jobs/{job_id} does not expose job deletion controls in this revision."""
|
|
_, client = app_client
|
|
job_id = seed_job(
|
|
filename="no-revision.pdf",
|
|
status=JobStatus.TRANSCRIBED,
|
|
transcription_text="original text",
|
|
)
|
|
|
|
response = client.get(f"/ui/jobs/{job_id}")
|
|
|
|
assert response.status_code == 200
|
|
assert "Delete job" not in response.text
|
|
|
|
def test_job_delete_page_shows_confirmation_when_not_processing(self, app_client, seed_job):
|
|
_, client = app_client
|
|
job_id = seed_job(filename="delete-ready.pdf", status=JobStatus.TRANSCRIBED)
|
|
|
|
response = client.get(f"/ui/jobs/{job_id}/delete")
|
|
|
|
assert response.status_code == 200
|
|
assert "Delete job" in response.text
|
|
assert "This action permanently deletes the job." in response.text
|
|
assert "Delete job permanently" in response.text
|
|
|
|
def test_job_delete_page_shows_blocked_state_when_processing(self, app_client, seed_job):
|
|
_, client = app_client
|
|
job_id = seed_job(filename="delete-blocked.pdf", status=JobStatus.PROCESSING)
|
|
|
|
response = client.get(f"/ui/jobs/{job_id}/delete")
|
|
|
|
assert response.status_code == 200
|
|
assert "Delete is blocked while the job is processing." in response.text
|
|
assert "Wait for processing to complete, then retry delete." in response.text
|