77 lines
2.5 KiB
Python
77 lines
2.5 KiB
Python
"""Tests for KeyringCredentialStore (mocked keyring backend)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
import types
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from ci_orchestrator.credentials import KeyringCredentialStore
|
|
|
|
|
|
def _install_fake_keyring(monkeypatch: pytest.MonkeyPatch, **behaviour: Any) -> None:
|
|
fake = types.ModuleType("keyring")
|
|
|
|
def get_credential(target: str, _username: str | None) -> Any:
|
|
return behaviour.get("credential_map", {}).get(target)
|
|
|
|
def get_password(service: str, target: str) -> str | None:
|
|
return behaviour.get("password_map", {}).get((service, target))
|
|
|
|
fake.get_credential = get_credential # type: ignore[attr-defined]
|
|
fake.get_password = get_password # type: ignore[attr-defined]
|
|
monkeypatch.setitem(sys.modules, "keyring", fake)
|
|
|
|
|
|
class _FakeCred:
|
|
def __init__(self, username: str, password: str) -> None:
|
|
self.username = username
|
|
self.password = password
|
|
|
|
|
|
def test_get_returns_credential(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
_install_fake_keyring(
|
|
monkeypatch,
|
|
credential_map={"BuildVMGuest": _FakeCred("Administrator", "s3cret")},
|
|
)
|
|
cred = KeyringCredentialStore().get("BuildVMGuest")
|
|
assert cred.username == "Administrator"
|
|
assert cred.password == "s3cret"
|
|
|
|
|
|
def test_get_falls_back_to_password(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
_install_fake_keyring(
|
|
monkeypatch,
|
|
credential_map={},
|
|
password_map={("ci", "GiteaPAT"): "tokentoken"},
|
|
)
|
|
cred = KeyringCredentialStore().get("GiteaPAT")
|
|
assert cred.username == "GiteaPAT"
|
|
assert cred.password == "tokentoken"
|
|
|
|
|
|
def test_get_raises_keyerror_when_unknown(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
_install_fake_keyring(monkeypatch, credential_map={}, password_map={})
|
|
with pytest.raises(KeyError):
|
|
KeyringCredentialStore().get("missing")
|
|
|
|
|
|
def test_credential_store_protocol_can_be_implemented() -> None:
|
|
"""Cover the Protocol body (pass / ...)."""
|
|
from ci_orchestrator.credentials import Credential, CredentialStore
|
|
|
|
class _Impl:
|
|
def get(self, target: str) -> Credential:
|
|
return Credential(username="u", password="p")
|
|
|
|
store: CredentialStore = _Impl()
|
|
assert store.get("x").username == "u"
|
|
|
|
|
|
def test_get_raises_when_missing(monkeypatch: pytest.MonkeyPatch) -> None:
|
|
_install_fake_keyring(monkeypatch, credential_map={}, password_map={})
|
|
with pytest.raises(KeyError):
|
|
KeyringCredentialStore().get("Unknown")
|