feat: add isolated utility export modes

This commit is contained in:
Media
2026-08-12 18:48:03 -05:00
parent b934b69e5a
commit 7e6b916963
11 changed files with 1876 additions and 12 deletions
+108 -2
View File
@@ -14,7 +14,14 @@ from controller.service import ControllerService, ControllerUnavailableError
class FakeControllerService:
def __init__(self, *, enqueue_result=None, enqueue_error=None, health=None):
def __init__(
self,
*,
enqueue_result=None,
enqueue_error=None,
health=None,
export_jobs=None,
):
self.enqueue_result = enqueue_result or {
"status": "queued",
"slot": 3,
@@ -29,7 +36,9 @@ class FakeControllerService:
"router_state": "video",
"degraded_reasons": [],
}
self.export_jobs = list(export_jobs or [])
self.enqueue_calls = []
self.export_calls = []
def enqueue_download(self, url, submitter, note):
self.enqueue_calls.append((url, submitter, note))
@@ -37,6 +46,20 @@ class FakeControllerService:
raise self.enqueue_error
return dict(self.enqueue_result)
def enqueue_export(self, url, mode, submitter, note):
self.export_calls.append((url, mode, submitter, note))
if self.enqueue_error is not None:
raise self.enqueue_error
return {
"kind": "export",
"status": "queued",
"job_id": "export-job",
"mode": mode,
}
def list_export_jobs(self, *, limit=10):
return [dict(job) for job in self.export_jobs[:limit]]
def health(self):
return dict(self.health_result)
@@ -71,11 +94,94 @@ class FlaskFactoryTests(unittest.TestCase):
response = self._app(FakeControllerService()).test_client().get("/")
self.assertEqual(response.status_code, 200)
self.assertIn(b"Submit YouTube Playlist", response.data)
self.assertIn(b"Submit YouTube Media", response.data)
self.assertIn(b'action="/submit"', response.data)
self.assertIn(b'name="url"', response.data)
self.assertIn(b'name="submitter"', response.data)
self.assertIn(b'name="note"', response.data)
self.assertIn(b'name="download_mode"', response.data)
self.assertIn(b'value="player_slot" checked', response.data)
self.assertIn(b"MP4 Export", response.data)
self.assertIn(b"M4A Audio", response.data)
self.assertIn(b"MP3 Audio", response.data)
def test_older_clients_omitting_mode_still_use_player_slot(self):
service = FakeControllerService()
response = self._post(service, submitter=" Alice ")
self.assertEqual(response.status_code, 200)
self.assertEqual(
service.enqueue_calls,
[("https://www.youtube.com/playlist?list=PL1234567890", "Alice", None)],
)
self.assertEqual(service.export_calls, [])
def test_each_utility_mode_uses_export_path_without_player_slot(self):
for mode, label in (
("mp4", b"MP4 Export queued"),
("m4a", b"M4A Audio queued"),
("mp3", b"MP3 Audio queued"),
):
with self.subTest(mode=mode):
service = FakeControllerService()
response = self._post(
service,
download_mode=mode,
submitter="Operator",
note="Utility",
)
self.assertEqual(response.status_code, 200)
self.assertIn(label, response.data)
self.assertEqual(service.enqueue_calls, [])
self.assertEqual(
service.export_calls,
[
(
"https://www.youtube.com/playlist?list=PL1234567890",
mode,
"Operator",
"Utility",
)
],
)
def test_invalid_download_mode_is_rejected_server_side(self):
service = FakeControllerService()
response = self._post(service, download_mode="../../slot1")
self.assertEqual(response.status_code, 200)
self.assertIn(b"Invalid download type", response.data)
self.assertEqual(service.enqueue_calls, [])
self.assertEqual(service.export_calls, [])
def test_recent_export_status_shows_results_and_failures(self):
service = FakeControllerService(
export_jobs=[
{
"job_id": "one",
"mode": "mp4",
"status": "completed",
"output_paths": ["exports/video/one/Service.mp4"],
"error": None,
},
{
"job_id": "two",
"mode": "mp3",
"status": "failed",
"output_paths": [],
"error": "ffmpeg failed",
},
]
)
response = self._app(service).test_client().get("/")
self.assertEqual(response.status_code, 200)
self.assertIn(b"Recent utility exports", response.data)
self.assertIn(b"exports/video/one/Service.mp4", response.data)
self.assertIn(b"ffmpeg failed", response.data)
def test_submit_rejects_non_youtube_and_malformed_urls(self):
invalid_urls = (