85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
|
|
import httpx
|
||
|
|
|
||
|
|
from qonto_assistant.contracts import QontoCredentials
|
||
|
|
from qonto_assistant.qonto_client import QontoClient
|
||
|
|
|
||
|
|
|
||
|
|
class StubCredentialProvider:
|
||
|
|
def __init__(self) -> None:
|
||
|
|
self.invalidated = False
|
||
|
|
|
||
|
|
def get_credentials(self) -> QontoCredentials:
|
||
|
|
return QontoCredentials(api_user="binky-user", api_key="top-secret")
|
||
|
|
|
||
|
|
def invalidate(self) -> None:
|
||
|
|
self.invalidated = True
|
||
|
|
|
||
|
|
|
||
|
|
def test_client_sends_legacy_api_key_header_and_params() -> None:
|
||
|
|
provider = StubCredentialProvider()
|
||
|
|
seen: dict[str, object] = {}
|
||
|
|
|
||
|
|
def handler(request: httpx.Request) -> httpx.Response:
|
||
|
|
seen["auth"] = request.headers["Authorization"]
|
||
|
|
seen["path"] = request.url.path
|
||
|
|
seen["params"] = dict(request.url.params)
|
||
|
|
return httpx.Response(200, json={"transactions": []})
|
||
|
|
|
||
|
|
client = QontoClient(
|
||
|
|
base_url="https://example.test",
|
||
|
|
organization_path="/v2/organization",
|
||
|
|
transactions_path="/v2/transactions",
|
||
|
|
auth_mode="legacy_api_key",
|
||
|
|
timeout_seconds=1,
|
||
|
|
max_retries=0,
|
||
|
|
credential_provider=provider,
|
||
|
|
transport=httpx.MockTransport(handler),
|
||
|
|
)
|
||
|
|
|
||
|
|
client.list_transactions(
|
||
|
|
iban="DE1234567890",
|
||
|
|
page=2,
|
||
|
|
page_size=25,
|
||
|
|
window_days=14,
|
||
|
|
status="completed",
|
||
|
|
side="debit",
|
||
|
|
)
|
||
|
|
|
||
|
|
assert seen["auth"] == "binky-user:top-secret"
|
||
|
|
assert seen["path"] == "/v2/transactions"
|
||
|
|
assert seen["params"] == {
|
||
|
|
"iban": "DE1234567890",
|
||
|
|
"current_page": "2",
|
||
|
|
"per_page": "25",
|
||
|
|
"window_days": "14",
|
||
|
|
"status": "completed",
|
||
|
|
"side": "debit",
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def test_client_invalidates_cached_credentials_on_auth_failure() -> None:
|
||
|
|
provider = StubCredentialProvider()
|
||
|
|
|
||
|
|
def handler(_: httpx.Request) -> httpx.Response:
|
||
|
|
return httpx.Response(401, json={"error": "unauthorized"})
|
||
|
|
|
||
|
|
client = QontoClient(
|
||
|
|
base_url="https://example.test",
|
||
|
|
organization_path="/v2/organization",
|
||
|
|
transactions_path="/v2/transactions",
|
||
|
|
auth_mode="legacy_api_key",
|
||
|
|
timeout_seconds=1,
|
||
|
|
max_retries=0,
|
||
|
|
credential_provider=provider,
|
||
|
|
transport=httpx.MockTransport(handler),
|
||
|
|
)
|
||
|
|
|
||
|
|
try:
|
||
|
|
client.get_organization()
|
||
|
|
except Exception as exc: # noqa: BLE001
|
||
|
|
assert getattr(exc, "error_code", None) == "qonto_auth_failed"
|
||
|
|
else:
|
||
|
|
raise AssertionError("Expected Qonto auth failure")
|
||
|
|
|
||
|
|
assert provider.invalidated is True
|