This commit is contained in:
parent
84e33024a7
commit
d58eb67764
2 changed files with 58 additions and 4 deletions
|
|
@ -340,7 +340,7 @@ async def save_credential(
|
|||
async with pool.acquire() as conn:
|
||||
row = await conn.fetchrow(
|
||||
"""
|
||||
INSERT INTO app.admin_provider_credential (
|
||||
INSERT INTO app.admin_provider_credential AS existing (
|
||||
provider, token_encrypted, token_hint, auth_kind, updated_by, updated_at,
|
||||
refresh_token_encrypted, extra
|
||||
)
|
||||
|
|
@ -351,8 +351,14 @@ async def save_credential(
|
|||
auth_kind = EXCLUDED.auth_kind,
|
||||
updated_by = EXCLUDED.updated_by,
|
||||
updated_at = now(),
|
||||
refresh_token_encrypted = COALESCE(EXCLUDED.refresh_token_encrypted, refresh_token_encrypted),
|
||||
extra = CASE WHEN EXCLUDED.extra::text = '{}'::jsonb THEN extra ELSE EXCLUDED.extra END,
|
||||
refresh_token_encrypted = COALESCE(
|
||||
EXCLUDED.refresh_token_encrypted,
|
||||
existing.refresh_token_encrypted
|
||||
),
|
||||
extra = CASE
|
||||
WHEN EXCLUDED.extra = '{}'::jsonb THEN existing.extra
|
||||
ELSE EXCLUDED.extra
|
||||
END,
|
||||
last_verified_at = NULL,
|
||||
last_verify_ok = NULL,
|
||||
last_verify_error = NULL
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"""provider 자격증명 서비스(암호화·카탈로그) 단위 테스트."""
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
from pydantic import SecretStr
|
||||
|
||||
|
|
@ -73,5 +73,53 @@ class CatalogTest(unittest.TestCase):
|
|||
self.assertIn("codex", codes)
|
||||
|
||||
|
||||
class SaveCredentialQueryTest(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_upsert_preserves_omitted_refresh_and_extra(self):
|
||||
row = {
|
||||
"provider": "openrouter",
|
||||
"token_hint": "…next",
|
||||
"auth_kind": "oauth_token",
|
||||
"updated_by": "admin@example.com",
|
||||
"updated_at": None,
|
||||
"last_verified_at": None,
|
||||
"last_verify_ok": None,
|
||||
"last_verify_error": None,
|
||||
"refresh_token_encrypted": None,
|
||||
"extra": {},
|
||||
}
|
||||
conn = AsyncMock()
|
||||
conn.fetchrow.return_value = row
|
||||
|
||||
class _Acquire:
|
||||
async def __aenter__(self):
|
||||
return conn
|
||||
|
||||
async def __aexit__(self, exc_type, exc, traceback):
|
||||
return False
|
||||
|
||||
class _Pool:
|
||||
def acquire(self):
|
||||
return _Acquire()
|
||||
|
||||
with (
|
||||
patch.object(svc, "ensure_table", AsyncMock()),
|
||||
patch.object(svc, "get_pool", return_value=_Pool()),
|
||||
patch.object(svc.settings, "provider_credential_secret", SecretStr("unit-test-master-secret-0123456789")),
|
||||
):
|
||||
await svc.save_credential(
|
||||
provider="openrouter",
|
||||
token="new-access-token",
|
||||
auth_kind="oauth_token",
|
||||
updated_by="admin@example.com",
|
||||
)
|
||||
|
||||
query = conn.fetchrow.await_args.args[0]
|
||||
self.assertIn("INSERT INTO app.admin_provider_credential AS existing", query)
|
||||
self.assertIn("EXCLUDED.refresh_token_encrypted,\n existing.refresh_token_encrypted", query)
|
||||
self.assertIn("WHEN EXCLUDED.extra = '{}'::jsonb THEN existing.extra", query)
|
||||
self.assertEqual(conn.fetchrow.await_args.args[6], None)
|
||||
self.assertEqual(conn.fetchrow.await_args.args[7], "{}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue