Files
musicseerr/backend/tests/test_audiodb_settings.py
Harvey 0f25ebc26d Plex Integration + Music Source Integration Improvements (#37)
* plex integration

* The big one - Full Music Source page rework + Playlist importing + Full Plex Integration + Discovery Options + More Like This/Surprise Me/Instant Mix + More...

* Music source track page - Play all / shuffle fixes

* lint

* format

* fix type checks

* format
2026-04-13 23:39:01 +01:00

136 lines
5.0 KiB
Python

"""Tests for AudioDB settings, API key masking, round-trips, and validation."""
import pytest
import msgspec
from api.v1.schemas.advanced_settings import (
AdvancedSettings,
AdvancedSettingsFrontend,
_mask_api_key,
_is_masked_api_key,
)
class TestMaskApiKey:
def test_long_key_shows_last_three(self) -> None:
assert _mask_api_key("myapikey123") == "***...123"
def test_four_char_key(self) -> None:
assert _mask_api_key("1234") == "***...234"
def test_three_char_key_fully_masked(self) -> None:
assert _mask_api_key("123") == "***"
def test_two_char_key_fully_masked(self) -> None:
assert _mask_api_key("ab") == "***"
def test_one_char_key_fully_masked(self) -> None:
assert _mask_api_key("x") == "***"
def test_empty_key_fully_masked(self) -> None:
assert _mask_api_key("") == "***"
class TestIsMaskedApiKey:
def test_masked_with_suffix(self) -> None:
assert _is_masked_api_key("***...123") is True
def test_masked_short(self) -> None:
assert _is_masked_api_key("***") is True
def test_plaintext_key(self) -> None:
assert _is_masked_api_key("mynewkey") is False
def test_empty_string(self) -> None:
assert _is_masked_api_key("") is False
def test_partial_asterisks(self) -> None:
assert _is_masked_api_key("** not masked") is False
def test_triple_asterisks_with_extra(self) -> None:
assert _is_masked_api_key("***extra") is True
class TestApiKeyRoundTrip:
def test_from_backend_masks_long_key(self) -> None:
backend = AdvancedSettings(audiodb_api_key="secretkey")
frontend = AdvancedSettingsFrontend.from_backend(backend)
assert frontend.audiodb_api_key == "***...key"
def test_from_backend_masks_default_key(self) -> None:
backend = AdvancedSettings(audiodb_api_key="123")
frontend = AdvancedSettingsFrontend.from_backend(backend)
assert frontend.audiodb_api_key == "***"
def test_to_backend_passes_masked_key_through(self) -> None:
frontend = AdvancedSettingsFrontend(audiodb_api_key="***...key")
backend = frontend.to_backend()
assert backend.audiodb_api_key == "***...key"
def test_to_backend_passes_new_plaintext_key(self) -> None:
frontend = AdvancedSettingsFrontend(audiodb_api_key="newkey456")
backend = frontend.to_backend()
assert backend.audiodb_api_key == "newkey456"
def test_default_api_key_is_123(self) -> None:
settings = AdvancedSettings()
assert settings.audiodb_api_key == "123"
def test_frontend_default_api_key_is_123(self) -> None:
frontend = AdvancedSettingsFrontend()
assert frontend.audiodb_api_key == "123"
class TestApiKeyEmptyGuard:
def test_empty_key_coerced_to_default(self) -> None:
settings = AdvancedSettings(audiodb_api_key="")
assert settings.audiodb_api_key == "123"
def test_whitespace_key_coerced_to_default(self) -> None:
settings = AdvancedSettings(audiodb_api_key=" ")
assert settings.audiodb_api_key == "123"
def test_valid_key_preserved(self) -> None:
settings = AdvancedSettings(audiodb_api_key="premium_key")
assert settings.audiodb_api_key == "premium_key"
class TestRecentlyViewedBytesTTLRoundTrip:
def test_default_backend_value(self) -> None:
settings = AdvancedSettings()
assert settings.cache_ttl_recently_viewed_bytes == 172800
def test_default_frontend_value(self) -> None:
frontend = AdvancedSettingsFrontend()
assert frontend.cache_ttl_recently_viewed_bytes == 48
def test_roundtrip_preserves_value(self) -> None:
backend = AdvancedSettings(cache_ttl_recently_viewed_bytes=172800)
frontend = AdvancedSettingsFrontend.from_backend(backend)
assert frontend.cache_ttl_recently_viewed_bytes == 48
restored = frontend.to_backend()
assert restored.cache_ttl_recently_viewed_bytes == 172800
def test_roundtrip_custom_value(self) -> None:
backend = AdvancedSettings(cache_ttl_recently_viewed_bytes=36000)
frontend = AdvancedSettingsFrontend.from_backend(backend)
assert frontend.cache_ttl_recently_viewed_bytes == 10
restored = frontend.to_backend()
assert restored.cache_ttl_recently_viewed_bytes == 36000
def test_backend_validation_rejects_too_low(self) -> None:
with pytest.raises(msgspec.ValidationError):
AdvancedSettings(cache_ttl_recently_viewed_bytes=3599)
def test_backend_validation_rejects_too_high(self) -> None:
with pytest.raises(msgspec.ValidationError):
AdvancedSettings(cache_ttl_recently_viewed_bytes=604801)
def test_frontend_validation_rejects_too_high(self) -> None:
with pytest.raises(msgspec.ValidationError):
AdvancedSettingsFrontend(cache_ttl_recently_viewed_bytes=169)
def test_frontend_validation_rejects_too_low(self) -> None:
with pytest.raises(msgspec.ValidationError):
AdvancedSettingsFrontend(cache_ttl_recently_viewed_bytes=0)