feat: complete program platform experience

This commit is contained in:
admin committed 2026-08-19 17:25:00 +08:00
1 parent e50b8b480b
commit 383c066d86
9 files changed
+419 -67

No files matched your search

+71
View File
@@ -0,0 +1,71 @@
import unittest
from datetime import datetime
from types import SimpleNamespace
from routes.streams import _serialize
class StreamAccessSerializationTest(unittest.TestCase):
def make_stream(self, **overrides):
values = {
"id": 1,
"title": "Hidden program",
"description": None,
"cover_url": None,
"status": SimpleNamespace(value="pending"),
"scheduled_at": datetime(2026, 8, 20, 12, 0),
"started_at": None,
"ended_at": None,
"multicast_enabled": False,
"replay_file": None,
"chapters_json": "[]",
"transcode_profile": "default",
"homepage_visible": False,
"remote_control_enabled": True,
"stream_key": "private-key",
"created_at": datetime(2026, 8, 19, 12, 0),
}
values.update(overrides)
return SimpleNamespace(**values)
def test_public_serialization_excludes_private_stream_key(self):
payload = _serialize(self.make_stream(), include_private=False)
self.assertNotIn("stream_key", payload)
self.assertFalse(payload["homepage_visible"])
self.assertTrue(payload["remote_control_enabled"])
def test_admin_serialization_includes_private_stream_key(self):
payload = _serialize(self.make_stream(), include_private=True)
self.assertEqual(payload["stream_key"], "private-key")
def test_program_statuses_are_preserved(self):
for status in ("pending", "live", "ended", "cancelled"):
with self.subTest(status=status):
payload = _serialize(self.make_stream(status=SimpleNamespace(value=status)), include_private=False)
self.assertEqual(payload["status"], status)
class AccessContractTest(unittest.TestCase):
def test_hidden_program_uses_private_direct_url_contract(self):
stream = StreamAccessSerializationTest().make_stream(homepage_visible=False)
public_payload = _serialize(stream, include_private=False)
admin_payload = _serialize(stream, include_private=True)
self.assertFalse(public_payload["homepage_visible"])
self.assertNotIn("stream_key", public_payload)
self.assertEqual(admin_payload["stream_key"], "private-key")
def test_remote_control_flag_is_enforced_by_contract(self):
enabled = _serialize(
StreamAccessSerializationTest().make_stream(remote_control_enabled=True),
include_private=False,
)
disabled = _serialize(
StreamAccessSerializationTest().make_stream(remote_control_enabled=False),
include_private=False,
)
self.assertTrue(enabled["remote_control_enabled"])
self.assertFalse(disabled["remote_control_enabled"])
if __name__ == "__main__":
unittest.main()
+33
View File
@@ -0,0 +1,33 @@
import asyncio
import unittest
from pydantic import ValidationError
from routes.settings_route import TranscodeQuality, get_system_metrics
class SettingsRouteTest(unittest.TestCase):
def test_transcode_quality_accepts_supported_values(self):
quality = TranscodeQuality(label="高清", width=1920, height=1080, bitrate="5000k")
self.assertEqual(quality.width, 1920)
self.assertEqual(quality.bitrate, "5000k")
def test_transcode_quality_rejects_invalid_bitrate_and_dimensions(self):
invalid_values = [
dict(label="高清", width=100, height=1080, bitrate="5000k"),
dict(label="高清", width=1920, height=1080, bitrate="5000"),
dict(label="", width=1920, height=1080, bitrate="5M"),
]
for value in invalid_values:
with self.subTest(value=value), self.assertRaises(ValidationError):
TranscodeQuality(**value)
def test_system_metrics_contains_bounded_resource_values(self):
metrics = asyncio.run(get_system_metrics(True))
self.assertGreaterEqual(metrics["cpu"]["count"], 1)
self.assertGreaterEqual(metrics["cpu"]["load_percent"], 0)
self.assertLessEqual(metrics["cpu"]["load_percent"], 100)
self.assertGreaterEqual(metrics["memory"]["used_percent"], 0)
self.assertLessEqual(metrics["memory"]["used_percent"], 100)
self.assertGreater(metrics["disk"]["total"], 0)
self.assertGreaterEqual(metrics["disk"]["free"], 0)