169 lines
4.4 KiB
Python
169 lines
4.4 KiB
Python
"""
|
|
API endpoint tests for Scenar Creator v4.
|
|
"""
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from app.main import app
|
|
|
|
|
|
@pytest.fixture
|
|
def client():
|
|
return TestClient(app)
|
|
|
|
|
|
def make_valid_doc(multiday=False):
|
|
blocks = [{
|
|
"id": "b1",
|
|
"date": "2026-03-01",
|
|
"start": "09:00",
|
|
"end": "10:00",
|
|
"title": "Opening",
|
|
"type_id": "ws"
|
|
}]
|
|
if multiday:
|
|
blocks.append({
|
|
"id": "b2",
|
|
"date": "2026-03-02",
|
|
"start": "10:00",
|
|
"end": "11:30",
|
|
"title": "Day 2 Session",
|
|
"type_id": "ws"
|
|
})
|
|
return {
|
|
"version": "1.0",
|
|
"event": {
|
|
"title": "Test Event",
|
|
"date_from": "2026-03-01",
|
|
"date_to": "2026-03-02" if multiday else "2026-03-01"
|
|
},
|
|
"program_types": [{"id": "ws", "name": "Workshop", "color": "#FF0000"}],
|
|
"blocks": blocks
|
|
}
|
|
|
|
|
|
def test_health(client):
|
|
r = client.get("/api/health")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["status"] == "ok"
|
|
assert data["version"] == "4.1.0"
|
|
|
|
|
|
def test_root_returns_html(client):
|
|
r = client.get("/")
|
|
assert r.status_code == 200
|
|
assert "text/html" in r.headers["content-type"]
|
|
assert "Scen" in r.text and "Creator" in r.text
|
|
|
|
|
|
def test_validate_valid(client):
|
|
doc = make_valid_doc()
|
|
r = client.post("/api/validate", json=doc)
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["valid"] is True
|
|
assert data["errors"] == []
|
|
|
|
|
|
def test_validate_unknown_type(client):
|
|
doc = make_valid_doc()
|
|
doc["blocks"][0]["type_id"] = "UNKNOWN"
|
|
r = client.post("/api/validate", json=doc)
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["valid"] is False
|
|
assert any("UNKNOWN" in e for e in data["errors"])
|
|
|
|
|
|
def test_validate_no_blocks(client):
|
|
doc = make_valid_doc()
|
|
doc["blocks"] = []
|
|
r = client.post("/api/validate", json=doc)
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["valid"] is False
|
|
|
|
|
|
def test_validate_no_types(client):
|
|
doc = make_valid_doc()
|
|
doc["program_types"] = []
|
|
r = client.post("/api/validate", json=doc)
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["valid"] is False
|
|
|
|
|
|
def test_sample_endpoint(client):
|
|
r = client.get("/api/sample")
|
|
assert r.status_code == 200
|
|
data = r.json()
|
|
assert data["version"] == "1.0"
|
|
assert data["event"]["title"] == "Zimní výjezd oddílu"
|
|
assert len(data["program_types"]) >= 3
|
|
# multi-day sample
|
|
assert data["event"]["date_from"] == "2026-03-01"
|
|
assert data["event"]["date_to"] == "2026-03-02"
|
|
# blocks for both days
|
|
dates = {b["date"] for b in data["blocks"]}
|
|
assert "2026-03-01" in dates
|
|
assert "2026-03-02" in dates
|
|
|
|
|
|
def test_generate_pdf(client):
|
|
doc = make_valid_doc()
|
|
r = client.post("/api/generate-pdf", json=doc)
|
|
assert r.status_code == 200
|
|
assert r.headers["content-type"] == "application/pdf"
|
|
assert r.content[:5] == b'%PDF-'
|
|
|
|
|
|
def test_generate_pdf_multiday(client):
|
|
doc = make_valid_doc(multiday=True)
|
|
r = client.post("/api/generate-pdf", json=doc)
|
|
assert r.status_code == 200
|
|
assert r.content[:5] == b'%PDF-'
|
|
|
|
|
|
def test_generate_pdf_overnight_block(client):
|
|
"""Block that crosses midnight: end < start."""
|
|
doc = make_valid_doc()
|
|
doc["blocks"][0]["start"] = "23:00"
|
|
doc["blocks"][0]["end"] = "01:30" # overnight
|
|
r = client.post("/api/generate-pdf", json=doc)
|
|
assert r.status_code == 200
|
|
assert r.content[:5] == b'%PDF-'
|
|
|
|
|
|
def test_generate_pdf_no_blocks(client):
|
|
doc = make_valid_doc()
|
|
doc["blocks"] = []
|
|
r = client.post("/api/generate-pdf", json=doc)
|
|
assert r.status_code == 422
|
|
|
|
|
|
def test_swagger_docs(client):
|
|
r = client.get("/docs")
|
|
assert r.status_code == 200
|
|
|
|
|
|
def test_backward_compat_date_field(client):
|
|
"""Old JSON with 'date' (not date_from/date_to) should still validate."""
|
|
doc = {
|
|
"version": "1.0",
|
|
"event": {"title": "Old Format", "date": "2026-03-01"},
|
|
"program_types": [{"id": "t1", "name": "Type", "color": "#0000FF"}],
|
|
"blocks": [{
|
|
"id": "bx",
|
|
"date": "2026-03-01",
|
|
"start": "10:00",
|
|
"end": "11:00",
|
|
"title": "Session",
|
|
"type_id": "t1"
|
|
}]
|
|
}
|
|
r = client.post("/api/validate", json=doc)
|
|
assert r.status_code == 200
|
|
assert r.json()["valid"] is True
|