mirror of
https://github.com/zc-zhangchen/any-auto-register.git
synced 2026-05-08 16:24:07 +08:00
184 lines
6.5 KiB
Python
184 lines
6.5 KiB
Python
import unittest
|
|
from unittest import mock
|
|
|
|
from core.db import AccountModel
|
|
from services.chatgpt_sync import backfill_chatgpt_account_to_cpa, build_chatgpt_sync_account
|
|
|
|
|
|
class ChatGPTBackfillTests(unittest.TestCase):
|
|
def _make_account(self) -> AccountModel:
|
|
account = AccountModel(
|
|
platform="chatgpt",
|
|
email="demo@example.com",
|
|
password="secret",
|
|
token="access-token",
|
|
status="registered",
|
|
)
|
|
account.set_extra(
|
|
{
|
|
"access_token": "access-token",
|
|
"session_token": "session-token",
|
|
"mail_provider": "cfworker",
|
|
}
|
|
)
|
|
return account
|
|
|
|
def test_build_sync_account_preserves_user_id(self):
|
|
account = self._make_account()
|
|
account.user_id = "acct-123"
|
|
|
|
sync_account = build_chatgpt_sync_account(account)
|
|
|
|
self.assertEqual(sync_account.user_id, "acct-123")
|
|
|
|
def test_backfill_skips_when_remote_auth_exists(self):
|
|
account = self._make_account()
|
|
extra = account.get_extra()
|
|
extra["sync_statuses"] = {
|
|
"cliproxyapi": {
|
|
"uploaded": True,
|
|
"remote_state": "usable",
|
|
"message": "",
|
|
}
|
|
}
|
|
account.set_extra(extra)
|
|
|
|
with mock.patch("services.cliproxyapi_sync.sync_chatgpt_cliproxyapi_status") as sync_mock:
|
|
with mock.patch("platforms.chatgpt.status_probe.probe_local_chatgpt_status") as probe_mock:
|
|
result = backfill_chatgpt_account_to_cpa(account, commit=False)
|
|
|
|
self.assertTrue(result["ok"])
|
|
self.assertTrue(result["skipped"])
|
|
self.assertFalse(result["uploaded"])
|
|
self.assertIn("远端已存在", result["message"])
|
|
sync_mock.assert_not_called()
|
|
probe_mock.assert_not_called()
|
|
|
|
def test_backfill_fails_when_local_probe_invalid(self):
|
|
account = self._make_account()
|
|
extra = account.get_extra()
|
|
extra["sync_statuses"] = {
|
|
"cliproxyapi": {
|
|
"uploaded": False,
|
|
"remote_state": "not_found",
|
|
"message": "未发现",
|
|
}
|
|
}
|
|
account.set_extra(extra)
|
|
|
|
with mock.patch("services.cliproxyapi_sync.sync_chatgpt_cliproxyapi_status") as sync_mock:
|
|
with mock.patch(
|
|
"platforms.chatgpt.status_probe.probe_local_chatgpt_status",
|
|
return_value={
|
|
"auth": {
|
|
"state": "access_token_invalidated",
|
|
"http_status": 401,
|
|
"error_code": "token_invalidated",
|
|
"message": "invalidated",
|
|
},
|
|
"codex": {"state": "skipped_auth_invalid"},
|
|
},
|
|
):
|
|
with mock.patch("services.chatgpt_sync.upload_account_model_to_cpa") as upload_mock:
|
|
result = backfill_chatgpt_account_to_cpa(account, commit=False)
|
|
|
|
self.assertFalse(result["ok"])
|
|
self.assertFalse(result["uploaded"])
|
|
self.assertFalse(result["skipped"])
|
|
self.assertEqual(account.status, "invalid")
|
|
sync_mock.assert_not_called()
|
|
upload_mock.assert_not_called()
|
|
|
|
def test_backfill_uploads_and_resyncs_when_remote_missing_and_local_valid(self):
|
|
account = self._make_account()
|
|
extra = account.get_extra()
|
|
extra["sync_statuses"] = {
|
|
"cliproxyapi": {
|
|
"uploaded": False,
|
|
"remote_state": "not_found",
|
|
"message": "未发现",
|
|
}
|
|
}
|
|
account.set_extra(extra)
|
|
|
|
with mock.patch(
|
|
"services.cliproxyapi_sync.sync_chatgpt_cliproxyapi_status",
|
|
side_effect=[
|
|
{
|
|
"uploaded": True,
|
|
"remote_state": "usable",
|
|
"message": "远端可用",
|
|
},
|
|
],
|
|
) as sync_mock:
|
|
with mock.patch(
|
|
"platforms.chatgpt.status_probe.probe_local_chatgpt_status",
|
|
return_value={
|
|
"auth": {
|
|
"state": "access_token_valid",
|
|
"http_status": 200,
|
|
"error_code": "",
|
|
"message": "ok",
|
|
},
|
|
"subscription": {"plan": "free"},
|
|
"codex": {"state": "usable"},
|
|
},
|
|
):
|
|
with mock.patch(
|
|
"services.chatgpt_sync.upload_account_model_to_cpa",
|
|
return_value=(True, "上传成功"),
|
|
) as upload_mock:
|
|
result = backfill_chatgpt_account_to_cpa(account, commit=False)
|
|
|
|
self.assertTrue(result["ok"])
|
|
self.assertTrue(result["uploaded"])
|
|
self.assertFalse(result["skipped"])
|
|
self.assertIn("补传完成", result["message"])
|
|
self.assertEqual(sync_mock.call_count, 1)
|
|
upload_mock.assert_called_once()
|
|
|
|
def test_backfill_syncs_once_when_cache_missing(self):
|
|
account = self._make_account()
|
|
|
|
with mock.patch(
|
|
"services.cliproxyapi_sync.sync_chatgpt_cliproxyapi_status",
|
|
side_effect=[
|
|
{
|
|
"uploaded": False,
|
|
"remote_state": "not_found",
|
|
"message": "未发现",
|
|
},
|
|
{
|
|
"uploaded": True,
|
|
"remote_state": "usable",
|
|
"message": "远端可用",
|
|
},
|
|
],
|
|
) as sync_mock:
|
|
with mock.patch(
|
|
"platforms.chatgpt.status_probe.probe_local_chatgpt_status",
|
|
return_value={
|
|
"auth": {
|
|
"state": "access_token_valid",
|
|
"http_status": 200,
|
|
"error_code": "",
|
|
"message": "ok",
|
|
},
|
|
"subscription": {"plan": "free"},
|
|
"codex": {"state": "usable"},
|
|
},
|
|
):
|
|
with mock.patch(
|
|
"services.chatgpt_sync.upload_account_model_to_cpa",
|
|
return_value=(True, "上传成功"),
|
|
):
|
|
result = backfill_chatgpt_account_to_cpa(account, commit=False)
|
|
|
|
self.assertTrue(result["ok"])
|
|
self.assertTrue(result["uploaded"])
|
|
self.assertEqual(sync_mock.call_count, 2)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|