CI / test (push) Canceled after 0s
## Summary epic r04 - begin refactor ## Change Type - [x] Cowork feature - [ ] Bug fix - [ ] Core AI contribution - [ ] Test / hardening - [ ] Performance - [ ] Documentation ## Related Work Cowork Task: Core Repo: http://34.143.229.138/gitea-admin/fsg-ai-core-assets Core AI Issue: Core Task: Related PR: ## Scope What is intentionally included? What is intentionally NOT included? ## Validation - [ ] Unit tests - [ ] Integration tests - [ ] Manual verification - [ ] Regression check Commands / evidence: ## Security Impact Permission / credential / network / customer data impact: ## Compatibility - [ ] No breaking change - [ ] Breaking change documented ## Reviewer Notes Anything Cowork reviewers should pay attention to. --------- Co-authored-by: Anh Tran Nguyen Minh <anhtnm1@fpt.com> Co-authored-by: Huong Le Thi Thien <huongltt35@fpt.com> Co-authored-by: Nam Pham Dinh Thanh <nampdt@fpt.com> Co-authored-by: Vu Dam Tuan <vudt15@fpt.com> Co-authored-by: Hiep Ha Van <hiephv3@fpt.com> Co-authored-by: Lam Hoang Van <lamhv7@fpt.com> Reviewed-on: #7 Co-authored-by: Duy Le Huu <duylh19@fpt.com>
94 lines
2.9 KiB
Python
94 lines
2.9 KiB
Python
"""KeyringAdapter — R02-T04.
|
|
|
|
Không đụng vào keyring thật của máy chạy test: tiêm một backend giả. Test mà
|
|
ghi vào Credential Manager thật thì để lại rác trên máy người khác, và trên CI
|
|
thì không có kho nào để ghi.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from cowork_local.infrastructure.secrets.keyring_adapter import KeyringAdapter
|
|
from cowork_local.infrastructure.secrets.secret_store import SecretStore, provider_key
|
|
|
|
|
|
class _KeyringGia:
|
|
"""Đủ giống thư viện keyring để adapter dùng được."""
|
|
|
|
def __init__(self, hong: bool = False):
|
|
self.kho: dict[tuple[str, str], str] = {}
|
|
self.hong = hong
|
|
|
|
def get_password(self, service, key):
|
|
if self.hong:
|
|
raise RuntimeError("kho bí mật không phản hồi")
|
|
return self.kho.get((service, key))
|
|
|
|
def set_password(self, service, key, value):
|
|
if self.hong:
|
|
raise RuntimeError("kho bí mật không phản hồi")
|
|
self.kho[(service, key)] = value
|
|
|
|
def delete_password(self, service, key):
|
|
if self.hong:
|
|
raise RuntimeError("kho bí mật không phản hồi")
|
|
del self.kho[(service, key)]
|
|
|
|
|
|
@pytest.fixture
|
|
def store():
|
|
a = KeyringAdapter(service="test-cowork")
|
|
a._backend = _KeyringGia()
|
|
a._available = True
|
|
return a
|
|
|
|
|
|
def test_khop_hop_dong_secret_store(store):
|
|
assert isinstance(store, SecretStore)
|
|
|
|
|
|
def test_luu_doc_xoa(store):
|
|
k = provider_key("openai")
|
|
assert store.get(k) is None
|
|
assert store.has(k) is False
|
|
|
|
store.set(k, "sk-that-la-bi-mat")
|
|
assert store.get(k) == "sk-that-la-bi-mat"
|
|
assert store.has(k) is True
|
|
|
|
store.delete(k)
|
|
assert store.get(k) is None
|
|
|
|
|
|
def test_moi_provider_mot_khoa_rieng(store):
|
|
store.set(provider_key("openai"), "khoa-openai")
|
|
store.set(provider_key("anthropic"), "khoa-anthropic")
|
|
assert store.get(provider_key("openai")) == "khoa-openai"
|
|
assert store.get(provider_key("anthropic")) == "khoa-anthropic"
|
|
|
|
|
|
def test_may_khong_co_kho_thi_im_lang_chu_khong_sap():
|
|
"""Linux headless và CI không có Secret Service. App vẫn phải chạy."""
|
|
a = KeyringAdapter(service="test-cowork")
|
|
a._backend = None
|
|
a._available = False
|
|
|
|
assert a.available is False
|
|
assert a.get("bat-ky") is None
|
|
a.set("bat-ky", "gia-tri") # không ném lỗi
|
|
a.delete("bat-ky") # không ném lỗi
|
|
assert a.has("bat-ky") is False
|
|
|
|
|
|
def test_kho_loi_giua_chung_thi_khong_lam_sap_app(store):
|
|
"""Keyring có thể hỏng lúc đang chạy — mất DBus, người dùng khoá máy."""
|
|
store._backend.hong = True
|
|
|
|
assert store.get("x") is None # nuốt lỗi, trả None
|
|
store.set("x", "y") # nuốt lỗi
|
|
store.delete("x") # nuốt lỗi
|
|
|
|
|
|
def test_xoa_khoa_khong_ton_tai_thi_bo_qua(store):
|
|
store.delete(provider_key("chua-bao-gio-luu")) # không ném lỗi
|