"""Unit tests for the Settings validator.""" from __future__ import annotations import pytest from notify_bridge_server.config import Settings, _FORBIDDEN_SECRETS _GOOD = "a" * 40 def _make(**kwargs) -> Settings: defaults = dict(secret_key=_GOOD, cors_allowed_origins="http://localhost:8420") defaults.update(kwargs) return Settings(**defaults) class TestSecretKey: def test_accepts_long_random_key(self) -> None: _make() def test_rejects_default(self) -> None: with pytest.raises(ValueError, match="SECURITY"): _make(secret_key="change-me-in-production") def test_rejects_known_dev_keys(self) -> None: for bad in _FORBIDDEN_SECRETS: with pytest.raises(ValueError): _make(secret_key=bad) def test_rejects_short_key(self) -> None: with pytest.raises(ValueError, match="32 characters"): _make(secret_key="short") class TestCors: def test_rejects_wildcard(self) -> None: with pytest.raises(ValueError, match="wildcard"): _make(cors_allowed_origins="*") def test_rejects_missing_scheme(self) -> None: with pytest.raises(ValueError, match="scheme"): _make(cors_allowed_origins="example.com") def test_accepts_multiple(self) -> None: cfg = _make(cors_allowed_origins="http://localhost:8420,https://example.com") assert "http://localhost:8420" in cfg.cors_allowed_origins class TestNumericValidation: def test_rejects_zero_access_token_expiry(self) -> None: with pytest.raises(ValueError): _make(access_token_expire_minutes=0) def test_rejects_invalid_port(self) -> None: with pytest.raises(ValueError): _make(port=0) with pytest.raises(ValueError): _make(port=70000) def test_rejects_negative_retention(self) -> None: with pytest.raises(ValueError): _make(event_log_retention_days=-1)