add a monitoring camera setting for cetana

This commit is contained in:
Your Name
2026-10-31 21:08:26 +03:30
parent 33aebe9b14
commit 093e0b9d1a
11 changed files with 732 additions and 9 deletions
+78 -1
View File
@@ -1,12 +1,18 @@
from django.test import TestCase
from apps.core.settings_service import SettingsService
from apps.live_monitoring.models import Camera
from apps.live_monitoring.protocols import PROTOCOL_KEYS, detect_protocol_from_url
from apps.live_monitoring.services import StreamAccessService
class StreamAccessTests(TestCase):
def setUp(self):
self.camera = Camera.objects.create(name="Cam1", stream_url="https://example.com/live.m3u8")
self.camera = Camera.objects.create(
name="Cam1",
protocol="hls",
stream_url="https://example.com/live.m3u8",
)
self.service = StreamAccessService()
def test_issue_and_verify_token(self):
@@ -24,3 +30,74 @@ class StreamAccessTests(TestCase):
def test_expired_token_rejected(self):
token, _ = self.service.issue_token(self.camera, ttl=-1)
self.assertIsNone(self.service.verify_token(token))
def test_ttl_comes_from_settings(self):
SettingsService().set("camera.stream_ttl_seconds", 120)
token, exp = self.service.issue_token(self.camera)
payload = self.service.verify_token(token)
self.assertAlmostEqual(payload["exp"], exp, delta=1)
# Token should expire roughly 120s from now (not the old 3600 default).
import time
self.assertLess(payload["exp"] - int(time.time()), 130)
def test_resolve_hls_stream(self):
result = self.service.resolve_stream(self.camera)
self.assertEqual(result["protocol"], "hls")
self.assertEqual(result["stream_url"], "https://example.com/live.m3u8")
self.assertTrue(result["browser_native"])
self.assertEqual(result["player"], "hls")
def test_rtsp_requires_gateway_or_errors(self):
cam = Camera.objects.create(
name="RTSP Cam",
protocol="rtsp",
stream_url="rtsp://user:secret@192.168.1.10:554/stream1",
)
result = self.service.resolve_stream(cam)
self.assertIsNone(result["stream_url"])
self.assertIn("media gateway", result["error"].lower())
def test_rtsp_rewrites_through_gateway(self):
SettingsService().set("camera.media_gateway_url", "https://media.example.com")
cam = Camera.objects.create(
name="RTSP Cam",
protocol="rtsp",
stream_url="rtsp://user:secret@192.168.1.10:554/stream1",
)
result = self.service.resolve_stream(cam)
self.assertEqual(result["protocol"], "hls")
self.assertEqual(result["stream_url"], f"https://media.example.com/{cam.id}/index.m3u8")
self.assertNotIn("secret", result["stream_url"])
def test_strips_embedded_credentials(self):
cam = Camera.objects.create(
name="Cred Cam",
protocol="http",
stream_url="https://user:pass@cdn.example.com/live.mp4",
)
result = self.service.resolve_stream(cam)
self.assertEqual(result["stream_url"], "https://cdn.example.com/live.mp4")
def test_inherits_default_protocol_from_settings(self):
SettingsService().set("camera.default_protocol", "mjpeg")
cam = Camera.objects.create(name="Inherit", stream_url="https://cam/video.mjpg")
self.assertEqual(cam.resolved_protocol(), "mjpeg")
def test_monitoring_disabled(self):
SettingsService().set("camera.enabled", False)
result = self.service.resolve_stream(self.camera)
self.assertIsNone(result["stream_url"])
self.assertIn("disabled", result["error"].lower())
class ProtocolCatalogTests(TestCase):
def test_all_standard_protocols_registered(self):
for key in ("rtsp", "rtmp", "hls", "dash", "webrtc", "mjpeg", "http", "onvif", "srt"):
self.assertIn(key, PROTOCOL_KEYS)
def test_detect_from_url(self):
self.assertEqual(detect_protocol_from_url("rtsp://x/y"), "rtsp")
self.assertEqual(detect_protocol_from_url("https://x/a.m3u8"), "hls")
self.assertEqual(detect_protocol_from_url("https://x/a.mpd"), "dash")
self.assertEqual(detect_protocol_from_url("srt://1.2.3.4:9000"), "srt")