49 lines
1.5 KiB
Python
49 lines
1.5 KiB
Python
from __future__ import annotations
|
|
|
|
import httpx
|
|
import pytest
|
|
|
|
from app.crm import CrmClient, CrmOutcome
|
|
|
|
|
|
def make_client(handler) -> CrmClient:
|
|
client = CrmClient.__new__(CrmClient)
|
|
client._base_url = "https://portal.example/rest/1/token/"
|
|
client._host = "portal.example"
|
|
client._client = httpx.AsyncClient(
|
|
transport=httpx.MockTransport(handler), follow_redirects=False
|
|
)
|
|
return client
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_crm_success_and_no_redirect() -> None:
|
|
client = make_client(
|
|
lambda request: httpx.Response(200, json={"result": {"ID": "42"}}, request=request)
|
|
)
|
|
result = await client.call("crm.contact.get", {"id": "42"}, mutating=False)
|
|
assert result.outcome == CrmOutcome.SUCCEEDED
|
|
assert result.result["ID"] == "42"
|
|
await client.close()
|
|
|
|
redirecting = make_client(
|
|
lambda request: httpx.Response(
|
|
302, headers={"Location": "https://evil.example/"}, request=request
|
|
)
|
|
)
|
|
result = await redirecting.call("crm.contact.get", {"id": "42"}, mutating=False)
|
|
assert result.outcome == CrmOutcome.PERMANENT
|
|
assert result.error_code == "crm_redirect_rejected"
|
|
await redirecting.close()
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_mutating_timeout_is_uncertain() -> None:
|
|
def timeout(request):
|
|
raise httpx.ReadTimeout("timed out", request=request)
|
|
|
|
client = make_client(timeout)
|
|
result = await client.call("crm.contact.add", {"fields": {}}, mutating=True)
|
|
assert result.outcome == CrmOutcome.UNCERTAIN
|
|
await client.close()
|