Files
intercept/tests/test_sstv_routes.py
T
James Smith 96172ca593 style: apply ruff-format to entire codebase
First-time run of ruff-format via pre-commit hook normalises quote
style, trailing commas, and whitespace across 188 Python files.
No logic changes.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-05 14:48:11 +01:00

138 lines
4.6 KiB
Python

"""Tests for ISS SSTV route behavior."""
from __future__ import annotations
import json
from unittest.mock import MagicMock, patch
import pytest
from utils.sstv import ISS_SSTV_FREQ
def _login_session(client) -> None:
"""Mark the Flask test session as authenticated."""
with client.session_transaction() as sess:
sess["logged_in"] = True
sess["username"] = "test"
sess["role"] = "admin"
class TestSSTVRoutes:
"""ISS SSTV route tests."""
def test_status_reports_fm_modulation(self, client):
"""GET /sstv/status should report the fixed ISS modulation."""
_login_session(client)
mock_decoder = MagicMock()
mock_decoder.decoder_available = "python-sstv"
mock_decoder.is_running = False
mock_decoder.get_images.return_value = []
mock_decoder.doppler_enabled = False
mock_decoder.last_doppler_info = None
with (
patch("routes.sstv.is_sstv_available", return_value=True),
patch("routes.sstv.get_sstv_decoder", return_value=mock_decoder),
):
response = client.get("/sstv/status")
assert response.status_code == 200
data = response.get_json()
assert data["available"] is True
assert data["modulation"] == "fm"
assert data["iss_frequency"] == ISS_SSTV_FREQ
def test_start_uses_fm_and_normalizes_supported_iss_frequency(self, client):
"""POST /sstv/start should enforce FM and snap near ISS values."""
_login_session(client)
mock_decoder = MagicMock()
mock_decoder.is_running = False
mock_decoder.start.return_value = True
mock_decoder.doppler_enabled = False
mock_decoder.last_doppler_info = None
payload = {
"frequency": ISS_SSTV_FREQ + 0.02, # Within tolerance; should normalize.
"modulation": "FM",
"device": 0,
}
with (
patch("routes.sstv.is_sstv_available", return_value=True),
patch("routes.sstv.get_sstv_decoder", return_value=mock_decoder),
patch("routes.sstv.app_module.claim_sdr_device", return_value=None),
):
response = client.post(
"/sstv/start",
data=json.dumps(payload),
content_type="application/json",
)
assert response.status_code == 200
data = response.get_json()
assert data["status"] == "started"
assert data["modulation"] == "fm"
assert data["frequency"] == pytest.approx(ISS_SSTV_FREQ)
mock_decoder.start.assert_called_once()
call_kwargs = mock_decoder.start.call_args.kwargs
assert call_kwargs["modulation"] == "fm"
assert call_kwargs["frequency"] == pytest.approx(ISS_SSTV_FREQ)
def test_start_rejects_non_fm_modulation(self, client):
"""POST /sstv/start should reject non-FM modulation requests."""
_login_session(client)
mock_decoder = MagicMock()
mock_decoder.is_running = False
payload = {
"frequency": ISS_SSTV_FREQ,
"modulation": "usb",
"device": 0,
}
with (
patch("routes.sstv.is_sstv_available", return_value=True),
patch("routes.sstv.get_sstv_decoder", return_value=mock_decoder),
):
response = client.post(
"/sstv/start",
data=json.dumps(payload),
content_type="application/json",
)
assert response.status_code == 400
data = response.get_json()
assert data["status"] == "error"
assert "Modulation must be fm" in data["message"]
mock_decoder.start.assert_not_called()
def test_start_rejects_non_iss_frequency(self, client):
"""POST /sstv/start should reject unsupported non-ISS frequencies."""
_login_session(client)
mock_decoder = MagicMock()
mock_decoder.is_running = False
payload = {
"frequency": 14.230,
"modulation": "fm",
"device": 0,
}
with (
patch("routes.sstv.is_sstv_available", return_value=True),
patch("routes.sstv.get_sstv_decoder", return_value=mock_decoder),
):
response = client.post(
"/sstv/start",
data=json.dumps(payload),
content_type="application/json",
)
assert response.status_code == 400
data = response.get_json()
assert data["status"] == "error"
assert "Supported ISS SSTV frequency" in data["message"]
mock_decoder.start.assert_not_called()