""" Tests for backend/models.py (Pydantic v2 validation). No DB or network calls — pure unit tests. """ from __future__ import annotations import os os.environ.setdefault("BOT_TOKEN", "test-bot-token") os.environ.setdefault("CHAT_ID", "-1001234567890") os.environ.setdefault("WEBHOOK_SECRET", "test-webhook-secret") os.environ.setdefault("WEBHOOK_URL", "https://example.com/api/webhook/telegram") os.environ.setdefault("FRONTEND_ORIGIN", "http://localhost:3000") import pytest from pydantic import ValidationError from backend.models import GeoData, RegisterRequest, SignalRequest # --------------------------------------------------------------------------- # RegisterRequest # --------------------------------------------------------------------------- def test_register_request_valid(): req = RegisterRequest(uuid="550e8400-e29b-41d4-a716-446655440000", name="Alice") assert req.uuid == "550e8400-e29b-41d4-a716-446655440000" assert req.name == "Alice" def test_register_request_empty_name(): with pytest.raises(ValidationError): RegisterRequest(uuid="550e8400-e29b-41d4-a716-446655440000", name="") def test_register_request_missing_uuid(): with pytest.raises(ValidationError): RegisterRequest(name="Alice") # type: ignore[call-arg] def test_register_request_empty_uuid(): with pytest.raises(ValidationError): RegisterRequest(uuid="", name="Alice") def test_register_request_name_max_length(): """name longer than 100 chars raises ValidationError.""" with pytest.raises(ValidationError): RegisterRequest(uuid="550e8400-e29b-41d4-a716-446655440000", name="x" * 101) def test_register_request_name_exactly_100(): req = RegisterRequest(uuid="550e8400-e29b-41d4-a716-446655440000", name="x" * 100) assert len(req.name) == 100 # --------------------------------------------------------------------------- # GeoData # --------------------------------------------------------------------------- def test_geo_data_valid(): geo = GeoData(lat=55.7558, lon=37.6173, accuracy=15.0) assert geo.lat == 55.7558 assert geo.lon == 37.6173 assert geo.accuracy == 15.0 def test_geo_data_lat_out_of_range_high(): with pytest.raises(ValidationError): GeoData(lat=90.1, lon=0.0, accuracy=10.0) def test_geo_data_lat_out_of_range_low(): with pytest.raises(ValidationError): GeoData(lat=-90.1, lon=0.0, accuracy=10.0) def test_geo_data_lon_out_of_range_high(): with pytest.raises(ValidationError): GeoData(lat=0.0, lon=180.1, accuracy=10.0) def test_geo_data_lon_out_of_range_low(): with pytest.raises(ValidationError): GeoData(lat=0.0, lon=-180.1, accuracy=10.0) def test_geo_data_accuracy_zero(): """accuracy must be strictly > 0.""" with pytest.raises(ValidationError): GeoData(lat=0.0, lon=0.0, accuracy=0.0) def test_geo_data_boundary_values(): """Boundary values -90/90 lat and -180/180 lon are valid.""" geo = GeoData(lat=90.0, lon=180.0, accuracy=1.0) assert geo.lat == 90.0 assert geo.lon == 180.0 # --------------------------------------------------------------------------- # SignalRequest # --------------------------------------------------------------------------- def test_signal_request_valid(): req = SignalRequest( user_id="550e8400-e29b-41d4-a716-446655440000", timestamp=1742478000000, geo={"lat": 55.7558, "lon": 37.6173, "accuracy": 15.0}, ) assert req.user_id == "550e8400-e29b-41d4-a716-446655440000" assert req.timestamp == 1742478000000 assert req.geo is not None assert req.geo.lat == 55.7558 def test_signal_request_no_geo(): req = SignalRequest( user_id="550e8400-e29b-41d4-a716-446655440000", timestamp=1742478000000, geo=None, ) assert req.geo is None def test_signal_request_missing_user_id(): with pytest.raises(ValidationError): SignalRequest(timestamp=1742478000000) # type: ignore[call-arg] def test_signal_request_empty_user_id(): with pytest.raises(ValidationError): SignalRequest(user_id="", timestamp=1742478000000) def test_signal_request_timestamp_zero(): """timestamp must be > 0.""" with pytest.raises(ValidationError): SignalRequest(user_id="550e8400-e29b-41d4-a716-446655440000", timestamp=0) def test_signal_request_timestamp_negative(): with pytest.raises(ValidationError): SignalRequest(user_id="550e8400-e29b-41d4-a716-446655440000", timestamp=-1)