From 879b9566cbb291f1e5a84b74f019ecb8f031e50a Mon Sep 17 00:00:00 2001 From: yunyaozhou Date: Sat, 8 Aug 2026 13:41:16 +0800 Subject: [PATCH] fix: require native groups in workspace payload --- pyproject.toml | 2 +- sub2api_quota_tui.py | 4 ++-- tests/test_payload.py | 7 +++++++ uv.lock | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3ebf3ec..7a725ac 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "shusub2" -version = "0.3.8" +version = "0.3.9" description = "Aggregated operations TUI for Sub2API" readme = "README.md" requires-python = ">=3.11" diff --git a/sub2api_quota_tui.py b/sub2api_quota_tui.py index e7569a6..5503de2 100644 --- a/sub2api_quota_tui.py +++ b/sub2api_quota_tui.py @@ -27,7 +27,7 @@ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError APP_NAME = "shusub2" -FALLBACK_VERSION = "0.3.8" +FALLBACK_VERSION = "0.3.9" DEFAULT_WORKSPACE_URL = "https://price.tailbeb9ad.ts.net/api/ui-data?view=workspace" DEFAULT_WORKSPACE_URL_CONFIG_FILE = "~/.config/shusub2/workspace-url" DEFAULT_API_URL = "http://127.0.0.1:18318/api/tui/accounts" @@ -681,7 +681,7 @@ def workspace_account_contract_is_valid(rows: list[dict[str, Any]]) -> bool: if field in row and not isinstance(row.get(field), str): return False group_names = row.get("account_group_names") - if group_names is not None and ( + if ( not isinstance(group_names, list) or len(group_names) > 16 or any(not isinstance(name, str) for name in group_names) diff --git a/tests/test_payload.py b/tests/test_payload.py index eb97bf0..465d018 100644 --- a/tests/test_payload.py +++ b/tests/test_payload.py @@ -90,6 +90,7 @@ def workspace_payload_fixture() -> dict[str, object]: }, "account_rate_multiplier": 0.06, "account_rate_multiplier_cny": 0.003, + "account_group_names": ["GPT", "customer"], } ], }, @@ -1007,6 +1008,12 @@ class WorkspaceTests(unittest.TestCase): with self.assertRaisesRegex(RuntimeError, "account contract"): mod.fetch_workspace_payload("https://workspace.example.test/data", 3) + missing_native_groups = workspace_payload_fixture() + missing_native_groups["accounts"]["accounts"][0].pop("account_group_names") + with mock.patch.object(mod, "fetch_workspace_response", return_value=(missing_native_groups, "")): + with self.assertRaisesRegex(RuntimeError, "account contract"): + mod.fetch_workspace_payload("https://workspace.example.test/data", 3) + invalid_period = workspace_payload_fixture() invalid_period["traffic"].pop("ends_at") with mock.patch.object(mod, "fetch_workspace_response", return_value=(invalid_period, "")): diff --git a/uv.lock b/uv.lock index 639d225..c6d3e87 100644 --- a/uv.lock +++ b/uv.lock @@ -85,7 +85,7 @@ wheels = [ [[package]] name = "shusub2" -version = "0.3.8" +version = "0.3.9" source = { editable = "." } dependencies = [ { name = "textual" },