test: close coverage gaps found in final branch review
- add test_rebuild_inherits_the_parents_cover: covers the cover_path inheritance mechanism in the rebuild endpoint (Task 2's upload-retention design relied on it, but nothing exercised it) - tighten test_lineage_marker_survives_in_the_accessibility_tree to assert the literal " rebuilt" screen-reader text, not just that rebuilt_from is referenced somewhere in paintCard - normalize submit's youtube_url/genre/language the same way rebuild does, for symmetry, plus a pinning test - pin acquire's stage outputs to [meta.json, audio.wav] in test_acquire.py, since web.py's _require_source hardcodes those same filenames
This commit is contained in:
@@ -194,6 +194,8 @@ def create_app(cfg: Config, runner=run_pipeline) -> FastAPI:
|
|||||||
language: str | None = Form(None), bpm: float | None = Form(None),
|
language: str | None = Form(None), bpm: float | None = Form(None),
|
||||||
video: UploadFile | None = File(None),
|
video: UploadFile | None = File(None),
|
||||||
cover: UploadFile | None = File(None)):
|
cover: UploadFile | None = File(None)):
|
||||||
|
youtube_url, genre, language = (youtube_url or None, genre or None,
|
||||||
|
language or None)
|
||||||
has_video = bool(video and video.filename)
|
has_video = bool(video and video.filename)
|
||||||
if bool(youtube_url) == has_video:
|
if bool(youtube_url) == has_video:
|
||||||
raise HTTPException(400, "provide exactly one of youtube_url / video")
|
raise HTTPException(400, "provide exactly one of youtube_url / video")
|
||||||
|
|||||||
@@ -38,6 +38,12 @@ def test_youtube(tmp_path, monkeypatch):
|
|||||||
assert meta["video_file"] == "source_video.webm"
|
assert meta["video_file"] == "source_video.webm"
|
||||||
assert meta["thumbnail"] == "source_video.jpg"
|
assert meta["thumbnail"] == "source_video.jpg"
|
||||||
|
|
||||||
|
def test_outputs_are_meta_and_audio(tmp_path):
|
||||||
|
"""_require_source in web.py hardcodes these filenames; pin them here."""
|
||||||
|
ctx = make_ctx(tmp_path, youtube_url="https://yt/x")
|
||||||
|
outputs = acquire.acquire_stage().outputs(ctx)
|
||||||
|
assert [p.name for p in outputs] == ["meta.json", "audio.wav"]
|
||||||
|
|
||||||
def test_requires_exactly_one_source(tmp_path):
|
def test_requires_exactly_one_source(tmp_path):
|
||||||
import pytest
|
import pytest
|
||||||
from karaoke_maker.pipeline import PipelineError
|
from karaoke_maker.pipeline import PipelineError
|
||||||
|
|||||||
@@ -52,6 +52,16 @@ def test_failure_reported(tmp_path):
|
|||||||
assert job["error"] == "boom"
|
assert job["error"] == "boom"
|
||||||
|
|
||||||
|
|
||||||
|
def test_submit_normalises_a_blank_genre_to_none(tmp_path):
|
||||||
|
seen = []
|
||||||
|
client, _ = make_client(tmp_path, capture_runner_factory(seen))
|
||||||
|
resp = client.post("/api/jobs", data={
|
||||||
|
"title": "T", "artist": "A", "lyrics": "x",
|
||||||
|
"youtube_url": "http://y", "genre": ""})
|
||||||
|
wait_status(client, resp.json()["id"], "done")
|
||||||
|
assert seen[0]["inp"].genre is None
|
||||||
|
|
||||||
|
|
||||||
def test_requires_one_source(tmp_path):
|
def test_requires_one_source(tmp_path):
|
||||||
client, _ = make_client(tmp_path, ok_runner)
|
client, _ = make_client(tmp_path, ok_runner)
|
||||||
resp = client.post("/api/jobs", data={"title": "T", "artist": "A", "lyrics": "x"})
|
resp = client.post("/api/jobs", data={"title": "T", "artist": "A", "lyrics": "x"})
|
||||||
@@ -599,6 +609,7 @@ def test_lineage_marker_survives_in_the_accessibility_tree():
|
|||||||
html = _index_html()
|
html = _index_html()
|
||||||
body = _fn_body(html, "paintCard")
|
body = _fn_body(html, "paintCard")
|
||||||
assert "rebuilt_from" in body
|
assert "rebuilt_from" in body
|
||||||
|
assert '" rebuilt"' in body
|
||||||
assert '"sr-only"' in _fn_body(html, "jobCard")
|
assert '"sr-only"' in _fn_body(html, "jobCard")
|
||||||
|
|
||||||
|
|
||||||
@@ -815,6 +826,20 @@ def test_rebuild_inherits_the_parents_source(tmp_path):
|
|||||||
assert seen[1]["inp"].video_path == seen[0]["inp"].video_path
|
assert seen[1]["inp"].video_path == seen[0]["inp"].video_path
|
||||||
|
|
||||||
|
|
||||||
|
def test_rebuild_inherits_the_parents_cover(tmp_path):
|
||||||
|
seen = []
|
||||||
|
client, _ = make_client(tmp_path, capture_runner_factory(seen))
|
||||||
|
resp = client.post("/api/jobs", data={"title": "T", "artist": "A", "lyrics": "x",
|
||||||
|
"youtube_url": "http://y"},
|
||||||
|
files={"cover": ("c.jpg", io.BytesIO(b"img"), "image/jpeg")})
|
||||||
|
parent = resp.json()["id"]
|
||||||
|
wait_status(client, parent, "done")
|
||||||
|
child = client.post(f"/api/jobs/{parent}/rebuild",
|
||||||
|
data=rebuild_form(year="1998")).json()["id"]
|
||||||
|
wait_status(client, child, "done")
|
||||||
|
assert seen[1]["inp"].cover_path == seen[0]["inp"].cover_path
|
||||||
|
|
||||||
|
|
||||||
def test_rebuild_rejects_a_missing_upload_that_would_be_needed(tmp_path):
|
def test_rebuild_rejects_a_missing_upload_that_would_be_needed(tmp_path):
|
||||||
client, _ = make_client(tmp_path, ok_runner)
|
client, _ = make_client(tmp_path, ok_runner)
|
||||||
resp = client.post("/api/jobs", data={"title": "T", "artist": "A", "lyrics": "x"},
|
resp = client.post("/api/jobs", data={"title": "T", "artist": "A", "lyrics": "x"},
|
||||||
|
|||||||
Reference in New Issue
Block a user