feat: resolve account platforms prioritizing structural snapshot values and correction on existing accounts
This commit is contained in:
@@ -479,3 +479,102 @@ def test_organize_groups_force_alignment(db_session, monkeypatch):
|
||||
# 既然已经一致,不会触发 update_account
|
||||
assert len(updated_accounts) == 0
|
||||
assert "已存在且已对齐 2" in response_aligned.message
|
||||
|
||||
|
||||
def test_organize_groups_corrects_mismatched_platform_instead_of_recreating(db_session, monkeypatch):
|
||||
"""测试一键整理遇到已存在账号平台错配时,只调用 update_account() 修正平台,不创建新账号。"""
|
||||
from app.models.snapshot import UpstreamRateSnapshot
|
||||
|
||||
w = Website(
|
||||
name="W1",
|
||||
site_type="sub2api",
|
||||
base_url="http://w1",
|
||||
enabled=True,
|
||||
auth_config_json="{}",
|
||||
timeout_seconds=30
|
||||
)
|
||||
u1 = Upstream(name="U1", base_url="http://u1")
|
||||
db_session.add_all([w, u1])
|
||||
db_session.commit()
|
||||
db_session.refresh(w)
|
||||
db_session.refresh(u1)
|
||||
|
||||
# 绑定关系:目标分组 TG1 ↔ G1
|
||||
b1 = WebsiteGroupBinding(
|
||||
website_id=w.id,
|
||||
target_group_id="TG1",
|
||||
target_group_name="TG1-Group",
|
||||
source_groups_json=json.dumps([{"upstream_id": u1.id, "group_id": "G1"}]),
|
||||
enabled=True
|
||||
)
|
||||
db_session.add(b1)
|
||||
|
||||
# G1: 已导入,导入的目标分组为 TG1,账号为 ACC-G1
|
||||
k1 = UpstreamGeneratedKey(
|
||||
upstream_id=u1.id,
|
||||
group_id="G1",
|
||||
group_name="G1-Group",
|
||||
key_name="Key-G1",
|
||||
key_value="sk-g1-secret",
|
||||
status="imported",
|
||||
imported_website_id=w.id,
|
||||
imported_account_id="ACC-G1",
|
||||
imported_target_group_id="TG1",
|
||||
)
|
||||
db_session.add(k1)
|
||||
|
||||
# 写入快照指定平台为 anthropic
|
||||
snapshot = UpstreamRateSnapshot(
|
||||
upstream_id=u1.id,
|
||||
snapshot_json=json.dumps({
|
||||
"groups": {
|
||||
"G1": {
|
||||
"group_name": "G1-Group",
|
||||
"rate": 0.1,
|
||||
"platform": "anthropic"
|
||||
}
|
||||
}
|
||||
})
|
||||
)
|
||||
db_session.add(snapshot)
|
||||
db_session.commit()
|
||||
|
||||
updated_accounts = []
|
||||
create_called = False
|
||||
|
||||
class MockClient:
|
||||
def __init__(self, **kwargs): pass
|
||||
def __enter__(self): return self
|
||||
def __exit__(self, *a): pass
|
||||
def get_groups(self, *a, **kw):
|
||||
return [{"id": "TG1", "name": "TG1-Group"}]
|
||||
def list_accounts(self):
|
||||
return [
|
||||
{
|
||||
"id": "ACC-G1",
|
||||
"name": "SmartUp-G1",
|
||||
"group_ids": ["TG1"],
|
||||
"platform": "openai",
|
||||
}
|
||||
]
|
||||
def extract_id(self, val):
|
||||
return val.get("id") if isinstance(val, dict) else str(val)
|
||||
def create_account(self, body):
|
||||
nonlocal create_called
|
||||
create_called = True
|
||||
return {"id": "NEW-ACC", "name": body["name"], "group_ids": body["group_ids"]}
|
||||
def update_account(self, account_id, body):
|
||||
updated_accounts.append((account_id, body))
|
||||
return {"id": account_id, "platform": body.get("platform")}
|
||||
|
||||
monkeypatch.setattr("app.routers.websites.Sub2ApiWebsiteClient", MockClient)
|
||||
monkeypatch.setattr("app.routers.websites.sync_account_priorities_for_website", lambda db, wid: [])
|
||||
|
||||
response = organize_website_groups(wid=w.id, db=db_session)
|
||||
|
||||
assert response.success is True
|
||||
assert not create_called
|
||||
assert len(updated_accounts) == 1
|
||||
assert updated_accounts[0][0] == "ACC-G1"
|
||||
assert updated_accounts[0][1]["platform"] == "anthropic"
|
||||
assert "平台从 openai 修正为 anthropic" in response.items[0].message
|
||||
|
||||
Reference in New Issue
Block a user