57 unit tests covering clean helpers, API signing, and field mapping fixes (FIX-E06, FIX-M16, BUG-01, BUG-03); integration tests for webhook endpoints with mocked DB; Forgejo CI workflow with TimescaleDB service container. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
60 lines
2.6 KiB
Python
60 lines
2.6 KiB
Python
"""Unit tests for Tracksolid API MD5 signature generation."""
|
|
import sys
|
|
import os
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.dirname(__file__))))
|
|
|
|
os.environ.setdefault("TRACKSOLID_APP_KEY", "test_key")
|
|
os.environ.setdefault("TRACKSOLID_APP_SECRET", "test_secret")
|
|
os.environ.setdefault("TRACKSOLID_USER_ID", "test_user")
|
|
os.environ.setdefault("TRACKSOLID_PWD_MD5", "test_md5")
|
|
os.environ.setdefault("DATABASE_URL", "postgresql://test:test@localhost:5432/test")
|
|
|
|
from ts_shared_rev import build_sign
|
|
|
|
|
|
class TestBuildSign:
|
|
def test_basic_signature(self):
|
|
"""Known input + secret produces expected MD5."""
|
|
params = {"method": "jimi.test", "app_key": "mykey", "v": "1.0"}
|
|
secret = "mysecret"
|
|
result = build_sign(params, secret)
|
|
# Verify it's a 32-char uppercase hex string
|
|
assert len(result) == 32
|
|
assert result == result.upper()
|
|
assert all(c in "0123456789ABCDEF" for c in result)
|
|
|
|
def test_sign_key_excluded(self):
|
|
"""The 'sign' key itself must be excluded from signing."""
|
|
params_with = {"method": "test", "sign": "old_sign", "v": "1.0"}
|
|
params_without = {"method": "test", "v": "1.0"}
|
|
secret = "secret"
|
|
assert build_sign(params_with, secret) == build_sign(params_without, secret)
|
|
|
|
def test_none_values_excluded(self):
|
|
"""Keys with None values are excluded from signing."""
|
|
params_with_none = {"method": "test", "optional": None, "v": "1.0"}
|
|
params_without_none = {"method": "test", "v": "1.0"}
|
|
secret = "secret"
|
|
assert build_sign(params_with_none, secret) == build_sign(params_without_none, secret)
|
|
|
|
def test_alphabetical_key_ordering(self):
|
|
"""Keys are sorted alphabetically for consistent signing."""
|
|
params_abc = {"a": "1", "b": "2", "c": "3"}
|
|
params_cba = {"c": "3", "b": "2", "a": "1"}
|
|
secret = "secret"
|
|
assert build_sign(params_abc, secret) == build_sign(params_cba, secret)
|
|
|
|
def test_different_secrets_produce_different_signs(self):
|
|
params = {"method": "test"}
|
|
assert build_sign(params, "secret1") != build_sign(params, "secret2")
|
|
|
|
def test_known_hash(self):
|
|
"""Verify against a manually computed hash."""
|
|
import hashlib
|
|
params = {"app_key": "ABC", "method": "test", "v": "1.0"}
|
|
secret = "XYZ"
|
|
sorted_keys = sorted(params.keys())
|
|
raw = secret + "".join(f"{k}{params[k]}" for k in sorted_keys) + secret
|
|
expected = hashlib.md5(raw.encode("utf-8")).hexdigest().upper()
|
|
assert build_sign(params, secret) == expected
|