Files
devx/tests/unit/test_utils_api.py
T
emilandemo 3d4b4940ff
Post-merge / detect-and-configure (push) Successful in 16s
Post-merge / release-and-maintain (push) Successful in 1m2s
DEVX-153: feat: sync missing features from v0.49.x line to master
Co-authored-by: emil User <emil.simeonov@tutanota.com>
2026-08-09 01:09:20 +00:00

172 lines
5.7 KiB
Python

"""Unit tests for devx.utils.api.APIClient."""
from __future__ import annotations
from unittest.mock import MagicMock, patch
import pytest
import requests
from devx.utils.api import APIClient
class TestAPIClient:
@patch("devx.utils.api.requests.request")
def test_get(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {"Authorization": "Bearer token"})
result = client.get("/users")
assert result is mock_resp
mock_req.assert_called_once_with(
"GET",
"https://api.example.com/users",
headers={"Authorization": "Bearer token"},
timeout=30,
verify=True,
)
@patch("devx.utils.api.requests.request")
def test_post(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {})
client.post("/users", json={"name": "alice"})
mock_req.assert_called_once_with(
"POST",
"https://api.example.com/users",
headers={},
timeout=30,
verify=True,
json={"name": "alice"},
)
@patch("devx.utils.api.requests.request")
def test_put(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {})
client.put("/users/1", json={"name": "bob"})
mock_req.assert_called_once_with(
"PUT",
"https://api.example.com/users/1",
headers={},
timeout=30,
verify=True,
json={"name": "bob"},
)
@patch("devx.utils.api.requests.request")
def test_delete(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {})
client.delete("/users/1")
mock_req.assert_called_once_with(
"DELETE",
"https://api.example.com/users/1",
headers={},
timeout=30,
verify=True,
)
@patch("devx.utils.api.requests.request")
def test_patch(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {})
client.patch("/users/1", json={"name": "carol"})
mock_req.assert_called_once_with(
"PATCH",
"https://api.example.com/users/1",
headers={},
timeout=30,
verify=True,
json={"name": "carol"},
)
@patch("devx.utils.api.requests.request")
def test_auth_tuple(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {}, auth=("admin", "pass"))
client.get("/data")
mock_req.assert_called_once_with(
"GET",
"https://api.example.com/data",
headers={},
timeout=30,
verify=True,
auth=("admin", "pass"),
)
@patch("devx.utils.api.requests.request")
def test_custom_timeout_and_verify(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {}, timeout=60, verify=False)
client.get("/data")
mock_req.assert_called_once_with(
"GET",
"https://api.example.com/data",
headers={},
timeout=60,
verify=False,
)
@patch("devx.utils.api.requests.request")
def test_raises_on_error(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.side_effect = requests.HTTPError("500")
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {})
with pytest.raises(requests.HTTPError):
client.get("/fail")
@patch("devx.utils.api.requests.request")
def test_strips_trailing_slash(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com/", {})
client.get("/users")
mock_req.assert_called_once_with(
"GET",
"https://api.example.com/users",
headers={},
timeout=30,
verify=True,
)
@patch("devx.utils.api.requests.request")
def test_kwargs_override_defaults(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {}, timeout=30)
client.get("/slow", timeout=120)
mock_req.assert_called_once_with(
"GET",
"https://api.example.com/slow",
headers={},
timeout=120,
verify=True,
)
@patch("devx.utils.api.requests.request")
def test_no_auth_when_not_set(self, mock_req):
mock_resp = MagicMock()
mock_resp.raise_for_status.return_value = None
mock_req.return_value = mock_resp
client = APIClient("https://api.example.com", {})
client.get("/data")
call_kwargs = mock_req.call_args.kwargs
assert "auth" not in call_kwargs