This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
from _helpers import TempDirMixin
|
||||
|
||||
from app import client_policy
|
||||
|
||||
|
||||
class ClientPolicyTests(TempDirMixin, unittest.TestCase):
|
||||
def _payload(self, *, check=True, enforce=False):
|
||||
return {
|
||||
"policy_version": 1,
|
||||
"subscription_check_enabled": check,
|
||||
"subscription_enforcement_enabled": enforce,
|
||||
"updated_at": "2026-07-28T15:19:19+08:00",
|
||||
}
|
||||
|
||||
def test_parse_supports_off_observe_and_enforce(self):
|
||||
off = client_policy.parse_client_policy(
|
||||
self._payload(check=False, enforce=False)
|
||||
)
|
||||
observe = client_policy.parse_client_policy(
|
||||
self._payload(check=True, enforce=False)
|
||||
)
|
||||
enforce = client_policy.parse_client_policy(
|
||||
self._payload(check=True, enforce=True)
|
||||
)
|
||||
|
||||
self.assertEqual("off", off.mode)
|
||||
self.assertEqual("observe", observe.mode)
|
||||
self.assertEqual("enforce", enforce.mode)
|
||||
|
||||
def test_illegal_combination_is_normalized_to_off(self):
|
||||
policy = client_policy.parse_client_policy(
|
||||
self._payload(check=False, enforce=True)
|
||||
)
|
||||
|
||||
self.assertEqual("off", policy.mode)
|
||||
self.assertFalse(policy.subscription_enforcement_enabled)
|
||||
self.assertIn("组合非法", policy.warning)
|
||||
|
||||
def test_parser_rejects_loose_types_or_timestamp_without_timezone(self):
|
||||
invalid_bool = self._payload()
|
||||
invalid_bool["subscription_check_enabled"] = 1
|
||||
invalid_time = self._payload()
|
||||
invalid_time["updated_at"] = "2026-07-28T15:19:19"
|
||||
|
||||
with self.assertRaises(client_policy.ClientPolicyError):
|
||||
client_policy.parse_client_policy(invalid_bool)
|
||||
with self.assertRaises(client_policy.ClientPolicyError):
|
||||
client_policy.parse_client_policy(invalid_time)
|
||||
|
||||
def test_valid_remote_policy_is_cached_without_sensitive_fields(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
path = os.path.join(temp_dir, "config", "client_policy.json")
|
||||
remote = client_policy.parse_client_policy(
|
||||
self._payload(check=True, enforce=True)
|
||||
)
|
||||
|
||||
resolved = client_policy.resolve_client_policy(remote, path=path)
|
||||
loaded = client_policy.load_cached_policy(path=path)
|
||||
|
||||
self.assertEqual("remote", resolved.source)
|
||||
self.assertEqual("cache", loaded.source)
|
||||
self.assertEqual("enforce", loaded.mode)
|
||||
with open(path, "r", encoding="utf-8") as handle:
|
||||
raw = json.load(handle)
|
||||
self.assertIn("cached_at", raw)
|
||||
self.assertNotIn("api_key", json.dumps(raw).lower())
|
||||
self.assertNotIn("account", json.dumps(raw).lower())
|
||||
|
||||
def test_missing_remote_uses_cache_then_observation_fallback(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
path = os.path.join(temp_dir, "client_policy.json")
|
||||
cached = client_policy.parse_client_policy(
|
||||
self._payload(check=False, enforce=False)
|
||||
)
|
||||
client_policy.save_cached_policy(cached, path=path)
|
||||
|
||||
from_cache = client_policy.resolve_client_policy(None, path=path)
|
||||
self.assertEqual("cache", from_cache.source)
|
||||
self.assertEqual("off", from_cache.mode)
|
||||
|
||||
with open(path, "w", encoding="utf-8") as handle:
|
||||
handle.write("{broken")
|
||||
fallback = client_policy.resolve_client_policy(None, path=path)
|
||||
self.assertEqual("fallback", fallback.source)
|
||||
self.assertEqual("observe", fallback.mode)
|
||||
self.assertIn("观察模式", fallback.warning)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user