"""Upload status-polling tests. Covers two things: 1. Regression coverage for the queued-vs-processing template bug reported after a real deployment: a file sitting in 'queued' status (before the background trigger/cron picks it up) was rendering the same text as a genuinely in-progress parse, making the two states indistinguishable. 2. The real percentage progress bar (Ch12: total_lines is now counted on first pickup, so processed/total renders as an actual percentage instead of an indeterminate spinner). """ from __future__ import annotations from app.models.log_file import LogFile def _make_log_file(db, status: str, processed_lines: int = 0, total_lines: int | None = None) -> LogFile: log_file = LogFile( filename="sample.log.gz", server_type="apache", format_string="", status=status, processed_lines=processed_lines, total_lines=total_lines, size_bytes=123, checksum=f"checksum-for-{status}-{processed_lines}-{total_lines}", ) db.session.add(log_file) db.session.commit() return log_file def test_queued_status_renders_queued_template_not_processing(logged_in_client, db): log_file = _make_log_file(db, status="queued") resp = logged_in_client.get(f"/api/uploads/{log_file.id}/status") assert resp.status_code == 200 assert b"sample.log.gz" in resp.data assert b"queued" in resp.data.lower() assert b"analyzing" not in resp.data.lower() def test_processing_status_without_total_shows_indeterminate(logged_in_client, db): log_file = _make_log_file(db, status="processing", processed_lines=42) resp = logged_in_client.get(f"/api/uploads/{log_file.id}/status") assert resp.status_code == 200 assert b"sample.log.gz" in resp.data assert b"42" in resp.data assert b"analyzing" in resp.data.lower() def test_processing_status_with_total_shows_real_percentage(logged_in_client, db): log_file = _make_log_file(db, status="processing", processed_lines=25, total_lines=100) resp = logged_in_client.get(f"/api/uploads/{log_file.id}/status") assert resp.status_code == 200 assert b"25%" in resp.data assert b"25" in resp.data and b"100" in resp.data def test_done_status_renders_done_template(logged_in_client, db): log_file = _make_log_file(db, status="done", processed_lines=100, total_lines=100) resp = logged_in_client.get(f"/api/uploads/{log_file.id}/status") assert resp.status_code == 200 assert b"sample.log.gz" in resp.data assert b"done" in resp.data.lower() assert b"100" in resp.data def test_error_status_renders_error_template(logged_in_client, db): log_file = _make_log_file(db, status="error") log_file.error_message = "boom" db.session.commit() resp = logged_in_client.get(f"/api/uploads/{log_file.id}/status") assert resp.status_code == 200 assert b"sample.log.gz" in resp.data assert b"boom" in resp.data def test_json_status_includes_total_lines(logged_in_client, db): log_file = _make_log_file(db, status="processing", processed_lines=10, total_lines=50) resp = logged_in_client.get( f"/api/uploads/{log_file.id}/status", headers={"Accept": "application/json"} ) assert resp.status_code == 200 data = resp.get_json()["data"] assert data["processed_lines"] == 10 assert data["total_lines"] == 50