113 lines
3.9 KiB
Python
113 lines
3.9 KiB
Python
"""Tests for the AuthProvider protocol and the DI factory (U11)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from agentkit.server.auth.providers import (
|
|
AuthProvider,
|
|
LocalAuthProvider,
|
|
StubOIDCProvider,
|
|
get_auth_provider,
|
|
reset_auth_provider,
|
|
)
|
|
from agentkit.server.auth.providers.base import AuthProvider as AuthProviderFromBase
|
|
from agentkit.server.auth.providers.exceptions import (
|
|
AuthProviderError,
|
|
InvalidCredentials,
|
|
ProviderNotImplemented,
|
|
)
|
|
|
|
|
|
class TestProtocolConformance:
|
|
"""The runtime_checkable Protocol accepts both real implementations."""
|
|
|
|
def test_local_passes_isinstance_check(self):
|
|
provider = LocalAuthProvider()
|
|
assert isinstance(provider, AuthProvider)
|
|
assert isinstance(provider, AuthProviderFromBase)
|
|
|
|
def test_stub_passes_isinstance_check(self):
|
|
provider = StubOIDCProvider()
|
|
assert isinstance(provider, AuthProvider)
|
|
assert isinstance(provider, AuthProviderFromBase)
|
|
|
|
|
|
class TestProviderNames:
|
|
def test_local_provider_name(self):
|
|
assert LocalAuthProvider.name == "local"
|
|
|
|
def test_stub_oidc_provider_name(self):
|
|
assert StubOIDCProvider.name == "oidc-stub"
|
|
|
|
|
|
class TestDiFactory:
|
|
"""``get_auth_provider`` is a memoized singleton, env-driven."""
|
|
|
|
def setup_method(self):
|
|
"""Reset cache and env before each test."""
|
|
reset_auth_provider()
|
|
self._saved_env = {}
|
|
for key in ("AGENTKIT_AUTH_PROVIDER",):
|
|
self._saved_env[key] = __import__("os").environ.pop(key, None)
|
|
|
|
def teardown_method(self):
|
|
for key, value in self._saved_env.items():
|
|
if value is not None:
|
|
__import__("os").environ[key] = value
|
|
reset_auth_provider()
|
|
|
|
def test_default_provider_is_local(self):
|
|
provider = get_auth_provider()
|
|
assert isinstance(provider, LocalAuthProvider)
|
|
assert provider.name == "local"
|
|
|
|
def test_oidc_stub_provider(self, monkeypatch):
|
|
monkeypatch.setenv("AGENTKIT_AUTH_PROVIDER", "oidc-stub")
|
|
reset_auth_provider()
|
|
provider = get_auth_provider()
|
|
assert isinstance(provider, StubOIDCProvider)
|
|
assert provider.name == "oidc-stub"
|
|
|
|
def test_unknown_provider_raises_value_error(self, monkeypatch):
|
|
monkeypatch.setenv("AGENTKIT_AUTH_PROVIDER", "ldap-unknown")
|
|
reset_auth_provider()
|
|
with pytest.raises(ValueError, match="unknown auth provider"):
|
|
get_auth_provider()
|
|
|
|
def test_factory_is_memoized(self):
|
|
first = get_auth_provider()
|
|
second = get_auth_provider()
|
|
assert first is second
|
|
|
|
def test_reset_clears_cache(self, monkeypatch):
|
|
first = get_auth_provider()
|
|
reset_auth_provider()
|
|
monkeypatch.setenv("AGENTKIT_AUTH_PROVIDER", "oidc-stub")
|
|
second = get_auth_provider()
|
|
assert first is not second
|
|
assert isinstance(second, StubOIDCProvider)
|
|
|
|
|
|
class TestExceptionHierarchy:
|
|
def test_invalid_credentials_inherits_auth_provider_error(self):
|
|
assert issubclass(InvalidCredentials, AuthProviderError)
|
|
assert issubclass(InvalidCredentials, Exception)
|
|
|
|
def test_provider_not_implemented_inherits_auth_provider_error(self):
|
|
assert issubclass(ProviderNotImplemented, AuthProviderError)
|
|
assert issubclass(ProviderNotImplemented, Exception)
|
|
|
|
def test_invalid_credentials_can_be_raised_and_caught(self):
|
|
with pytest.raises(InvalidCredentials):
|
|
raise InvalidCredentials("test message")
|
|
|
|
def test_invalid_credentials_caught_as_base(self):
|
|
"""Route layer catches AuthProviderError to handle all provider errors."""
|
|
with pytest.raises(AuthProviderError):
|
|
raise InvalidCredentials("test")
|
|
|
|
def test_provider_not_implemented_caught_as_base(self):
|
|
with pytest.raises(AuthProviderError):
|
|
raise ProviderNotImplemented("test")
|