chore: auto release commit (2026-06-19 09:53:29)
All checks were successful
技能自动化发布 / release (push) Successful in 7s
All checks were successful
技能自动化发布 / release (push) Successful in 7s
This commit is contained in:
246
tests/test_custom_platforms.py
Normal file
246
tests/test_custom_platforms.py
Normal file
@@ -0,0 +1,246 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""自定义平台:动态解析、platform ensure、add-web / pick-web / browser URL。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
JIANGCHANG_URL = "https://jc2009.com/admin/index.html"
|
||||
|
||||
|
||||
def _ensure_jiangchang(clean_db) -> None:
|
||||
from service.account_service import cmd_platform_ensure
|
||||
|
||||
rc = cmd_platform_ensure(
|
||||
key="jiangchang",
|
||||
display_name="匠厂后台",
|
||||
domain="generic",
|
||||
url=JIANGCHANG_URL,
|
||||
auth_strategy=None,
|
||||
aliases=json.dumps(["jc", "匠厂后台"], ensure_ascii=False),
|
||||
capabilities=None,
|
||||
)
|
||||
assert rc == 0
|
||||
|
||||
|
||||
class TestBuiltinPlatformsUnchanged:
|
||||
def test_douyin_alias(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
result = resolve_platform_key_dynamic("抖音", conn=clean_db)
|
||||
assert result.ok
|
||||
assert result.platform_key == "douyin"
|
||||
|
||||
def test_toutiao_key(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
result = resolve_platform_key_dynamic("toutiao", conn=clean_db)
|
||||
assert result.ok
|
||||
assert result.platform_key == "toutiao"
|
||||
|
||||
|
||||
class TestDynamicPlatformResolution:
|
||||
def test_unregistered_valid_key(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
result = resolve_platform_key_dynamic("unknown_custom", conn=clean_db)
|
||||
assert not result.ok
|
||||
assert result.error_code == "PLATFORM_NOT_REGISTERED"
|
||||
assert "platform ensure" in (result.message or "")
|
||||
|
||||
def test_invalid_platform_key_format(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
result = resolve_platform_key_dynamic("江厂 空格", conn=clean_db)
|
||||
assert not result.ok
|
||||
assert result.error_code == "INVALID_PLATFORM_KEY"
|
||||
|
||||
def test_empty_platform(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
result = resolve_platform_key_dynamic("", conn=clean_db)
|
||||
assert result.error_code == "INVALID_PLATFORM"
|
||||
|
||||
def test_registered_jiangchang(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
_ensure_jiangchang(clean_db)
|
||||
result = resolve_platform_key_dynamic("jiangchang", conn=clean_db)
|
||||
assert result.ok
|
||||
assert result.platform_key == "jiangchang"
|
||||
|
||||
def test_registered_alias_jc(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
_ensure_jiangchang(clean_db)
|
||||
result = resolve_platform_key_dynamic("jc", conn=clean_db)
|
||||
assert result.ok
|
||||
assert result.platform_key == "jiangchang"
|
||||
|
||||
|
||||
class TestPlatformEnsure:
|
||||
def test_ensure_returns_json(self, clean_db, capsys):
|
||||
from service.account_service import cmd_platform_ensure
|
||||
|
||||
rc = cmd_platform_ensure(
|
||||
key="jiangchang",
|
||||
display_name="匠厂后台",
|
||||
url=JIANGCHANG_URL,
|
||||
)
|
||||
assert rc == 0
|
||||
out = capsys.readouterr().out.strip()
|
||||
payload = json.loads(out)
|
||||
assert payload["ok"] is True
|
||||
assert payload["platform_key"] == "jiangchang"
|
||||
assert payload["action"] in ("created", "updated")
|
||||
|
||||
|
||||
class TestCustomPlatformAccounts:
|
||||
def test_add_web_after_ensure(self, clean_db):
|
||||
from service.account_service import cmd_account_add_web
|
||||
from db.accounts_repo import find_accounts
|
||||
|
||||
_ensure_jiangchang(clean_db)
|
||||
cmd_account_add_web(
|
||||
platform_input="jiangchang",
|
||||
login_id="manual",
|
||||
login_id_type="manual",
|
||||
label="匠厂后台 手工登录",
|
||||
tenant_id=None,
|
||||
environment="production",
|
||||
role="admin",
|
||||
provider_code=None,
|
||||
url=None,
|
||||
extra_json_str=None,
|
||||
profile_dir_override=None,
|
||||
)
|
||||
accs = find_accounts(platform_key="jiangchang")
|
||||
assert len(accs) == 1
|
||||
assert accs[0]["platform_key"] == "jiangchang"
|
||||
assert accs[0]["url"] == JIANGCHANG_URL
|
||||
assert accs[0]["profile_dir"]
|
||||
|
||||
def test_pick_web_after_ensure(self, clean_db, capsys):
|
||||
from service.account_service import cmd_account_add_web, cmd_account_pick_web
|
||||
|
||||
_ensure_jiangchang(clean_db)
|
||||
cmd_account_add_web(
|
||||
platform_input="jiangchang",
|
||||
login_id="manual",
|
||||
login_id_type="manual",
|
||||
label="匠厂后台",
|
||||
tenant_id=None,
|
||||
environment="production",
|
||||
role="admin",
|
||||
provider_code=None,
|
||||
url=None,
|
||||
extra_json_str=None,
|
||||
profile_dir_override=None,
|
||||
)
|
||||
capsys.readouterr()
|
||||
cmd_account_pick_web(
|
||||
platform_input="jiangchang",
|
||||
do_lease=True,
|
||||
holder="test-holder",
|
||||
ttl_sec=300,
|
||||
)
|
||||
out = capsys.readouterr().out.strip()
|
||||
payload = json.loads(out)
|
||||
assert payload["platform_key"] == "jiangchang"
|
||||
assert payload["profile_dir"]
|
||||
assert payload.get("lease_token")
|
||||
|
||||
def test_pick_web_unregistered_returns_structured_error(self, clean_db, capsys):
|
||||
from service.account_service import cmd_account_pick_web
|
||||
|
||||
cmd_account_pick_web(platform_input="unknown_custom")
|
||||
out = capsys.readouterr().out.strip()
|
||||
payload = json.loads(out)
|
||||
assert payload["success"] is False
|
||||
assert payload["error"]["code"] == "ERROR:PLATFORM_NOT_REGISTERED"
|
||||
assert "platform ensure" in payload["error"]["message"]
|
||||
|
||||
def test_add_web_unregistered_returns_structured_error(self, clean_db, capsys):
|
||||
from service.account_service import cmd_account_add_web
|
||||
|
||||
cmd_account_add_web(
|
||||
platform_input="unknown_custom",
|
||||
login_id="manual",
|
||||
login_id_type="manual",
|
||||
label="x",
|
||||
tenant_id=None,
|
||||
environment="production",
|
||||
role="admin",
|
||||
provider_code=None,
|
||||
url=None,
|
||||
extra_json_str=None,
|
||||
profile_dir_override=None,
|
||||
)
|
||||
out = capsys.readouterr().out.strip()
|
||||
payload = json.loads(out)
|
||||
assert payload["success"] is False
|
||||
assert payload["error"]["code"] == "ERROR:PLATFORM_NOT_REGISTERED"
|
||||
|
||||
|
||||
class TestBrowserServiceUrlResolution:
|
||||
def test_custom_platform_default_url_from_db(self, clean_db):
|
||||
from db.accounts_repo import insert_account, upsert_platform
|
||||
from service.browser_service import resolve_account_browser_url
|
||||
import time
|
||||
|
||||
now = int(time.time())
|
||||
upsert_platform(
|
||||
clean_db,
|
||||
key="jiangchang",
|
||||
display_name="匠厂后台",
|
||||
default_url=JIANGCHANG_URL,
|
||||
)
|
||||
aid = insert_account(
|
||||
conn=clean_db,
|
||||
platform_key="jiangchang",
|
||||
account_label="test",
|
||||
login_id=None,
|
||||
login_id_type="manual",
|
||||
tenant_id=None,
|
||||
environment="production",
|
||||
role="admin",
|
||||
provider_code="jiangchang",
|
||||
profile_dir="/tmp/test-profile",
|
||||
url="",
|
||||
extra_json="{}",
|
||||
now=now,
|
||||
auth_strategy="qr_code_manual",
|
||||
)
|
||||
clean_db.commit()
|
||||
account = {
|
||||
"id": aid,
|
||||
"platform_key": "jiangchang",
|
||||
"url": "",
|
||||
}
|
||||
assert resolve_account_browser_url(account, conn=clean_db) == JIANGCHANG_URL
|
||||
|
||||
def test_account_url_overrides_platform_default(self, clean_db):
|
||||
from service.browser_service import resolve_account_browser_url
|
||||
|
||||
account = {
|
||||
"platform_key": "jiangchang",
|
||||
"url": "https://custom.example.com/admin",
|
||||
}
|
||||
assert (
|
||||
resolve_account_browser_url(account, conn=clean_db)
|
||||
== "https://custom.example.com/admin"
|
||||
)
|
||||
|
||||
|
||||
class TestPlatformKeyFormatValidation:
|
||||
def test_ensure_rejects_invalid_key(self, clean_db, capsys):
|
||||
from service.account_service import cmd_platform_ensure
|
||||
|
||||
rc = cmd_platform_ensure(key="江厂 空格", display_name="bad")
|
||||
assert rc == 1
|
||||
out = capsys.readouterr().out.strip()
|
||||
payload = json.loads(out)
|
||||
assert payload["error"]["code"] == "ERROR:INVALID_PLATFORM_KEY"
|
||||
76
tests/test_platform_dynamic.py
Normal file
76
tests/test_platform_dynamic.py
Normal file
@@ -0,0 +1,76 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""resolve_platform_key_dynamic 与 JSON 解析边界。"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class TestResolvePlatformKeyDynamicParsing:
|
||||
def test_builtin_still_works_without_db_row(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
result = resolve_platform_key_dynamic("马士基", conn=clean_db)
|
||||
assert result.platform_key == "maersk"
|
||||
|
||||
def test_disabled_platform_returns_disabled(self, clean_db):
|
||||
from db.accounts_repo import upsert_platform
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
|
||||
upsert_platform(
|
||||
clean_db,
|
||||
key="custom_off",
|
||||
display_name="Off",
|
||||
default_url="",
|
||||
)
|
||||
clean_db.execute(
|
||||
"UPDATE platforms SET enabled = 0 WHERE platform_key = ?",
|
||||
("custom_off",),
|
||||
)
|
||||
clean_db.commit()
|
||||
result = resolve_platform_key_dynamic("custom_off", conn=clean_db)
|
||||
assert result.error_code == "PLATFORM_DISABLED"
|
||||
|
||||
def test_get_platform_spec_from_db(self, clean_db):
|
||||
from db.accounts_repo import upsert_platform
|
||||
from util.platforms import get_platform_spec
|
||||
|
||||
upsert_platform(
|
||||
clean_db,
|
||||
key="jiangchang",
|
||||
display_name="匠厂后台",
|
||||
default_url="https://jc2009.com/admin/index.html",
|
||||
)
|
||||
spec = get_platform_spec("jiangchang", conn=clean_db)
|
||||
assert spec["display_name"] == "匠厂后台"
|
||||
assert spec["default_url"] == "https://jc2009.com/admin/index.html"
|
||||
|
||||
def test_malformed_aliases_json_does_not_crash(self, clean_db):
|
||||
from util.platforms import resolve_platform_key_dynamic
|
||||
import time
|
||||
|
||||
now = int(time.time())
|
||||
clean_db.execute(
|
||||
"""
|
||||
INSERT INTO platforms (
|
||||
platform_key, display_name, domain, provider_code,
|
||||
default_url, aliases_json, capabilities_json,
|
||||
enabled, default_auth_strategy, created_at, updated_at
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, 1, NULL, ?, ?)
|
||||
""",
|
||||
(
|
||||
"bad_alias",
|
||||
"Bad",
|
||||
"generic",
|
||||
"bad_alias",
|
||||
"",
|
||||
"not-json",
|
||||
"{}",
|
||||
now,
|
||||
now,
|
||||
),
|
||||
)
|
||||
clean_db.commit()
|
||||
result = resolve_platform_key_dynamic("bad_alias", conn=clean_db)
|
||||
assert result.platform_key == "bad_alias"
|
||||
Reference in New Issue
Block a user