/
/
/
1"""Test MusicMe provider helpers (decrypt)."""
2
3import pytest
4
5from music_assistant.providers.musicme.helpers import decrypt
6
7
8class TestDecrypt:
9 """Tests for the MusicMe XOR 0xAA decrypt function."""
10
11 def test_decrypt_valid_response(self) -> None:
12 """Test decrypting a real MusicMe API response."""
13 # This is an actual encrypted error response from the MusicMe API:
14 # {"code":2,"type":"OperationForbidden","message":"invalid credentials"}
15 encrypted = (
16 "4A29BFAE794933B19DF3C4888688C7CFD9D9CBCDCF889088C3C4DCCBC6C3CE"
17 "8AC9D8CFCECFC4DEC3CBC6D988D7D188C9C5CECF8890988688DED3DACF8890"
18 "88E5DACFD8CBDEC3C5C4ECC5D8C8C3CECECF8F6B9EA2"
19 )
20 result = decrypt(encrypted)
21 parsed = __import__("json").loads(result)
22 assert parsed["code"] == 2
23 assert parsed["type"] == "OperationForbidden"
24 assert parsed["message"] == "invalid credentials"
25
26 def test_decrypt_too_short(self) -> None:
27 """Test that short payloads raise ValueError."""
28 with pytest.raises(ValueError, match="too short"):
29 decrypt("ABC")
30
31 def test_decrypt_exactly_20_chars(self) -> None:
32 """Test edge case: exactly 20 characters results in empty payload after processing."""
33 # After stripping 10+8=18 chars, only 2 chars remain.
34 # The marker search + offset leaves an empty string, which is now rejected.
35 with pytest.raises(ValueError, match="empty after processing"):
36 decrypt("A" * 20)
37
38 def test_decrypt_marker_at_odd_index(self) -> None:
39 """Test that the marker detection works for '8' and 'B' at odd indices."""
40 # Build a payload where position 1 (odd) has '8' as marker
41 # Padding: 10 front + 8 back = 18 chars overhead
42 # After front strip, first char at index 1 should be '8'
43 # This is a synthetic test â the result may not be valid JSON
44 # but the function should not crash
45 payload = "0123456789" + "A8" + "CC" * 10 + "12345678"
46 result = decrypt(payload)
47 assert isinstance(result, str)
48
49 def test_decrypt_returns_string(self) -> None:
50 """Test that decrypt always returns a string."""
51 # Minimal valid-ish payload (padded, with some hex content)
52 payload = "0123456789" + "AA" * 20 + "12345678"
53 result = decrypt(payload)
54 assert isinstance(result, str)
55 assert len(result) > 0
56