diff options
| author | Danilo M. <danix@danix.xyz> | 2026-06-30 10:56:51 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-06-30 10:56:51 +0200 |
| commit | 092e05361a534a8f35d7b551afa77004e30cf201 (patch) | |
| tree | ecbe8c664cd4ca0f2d64cca8e5999ded5919d3e6 /tests/unit | |
| parent | 8e7cb60beaa6fe01c1e4de57d90f434bcb3bd6a7 (diff) | |
| download | firefly-cli-092e05361a534a8f35d7b551afa77004e30cf201.tar.gz firefly-cli-092e05361a534a8f35d7b551afa77004e30cf201.zip | |
feat: HTTP client with auth and error surfacing
Diffstat (limited to 'tests/unit')
| -rw-r--r-- | tests/unit/test_client.py | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/tests/unit/test_client.py b/tests/unit/test_client.py new file mode 100644 index 0000000..e63be08 --- /dev/null +++ b/tests/unit/test_client.py @@ -0,0 +1,47 @@ +import json, unittest +from unittest.mock import patch, MagicMock +from io import BytesIO +import urllib.error +from firefly_cli.client import Client +from firefly_cli.errors import ApiError + +def fake_response(payload, status=200): + r = MagicMock() + r.read.return_value = json.dumps(payload).encode() + r.status = status + r.__enter__.return_value = r + r.__exit__.return_value = False + return r + +class TestClient(unittest.TestCase): + def setUp(self): + self.c = Client("https://f.example", "tok") + + @patch("firefly_cli.client.urllib.request.urlopen") + def test_get_builds_url_and_headers(self, urlopen): + urlopen.return_value = fake_response({"data": []}) + out = self.c.request("GET", "/api/v1/accounts", params={"type": "asset"}) + req = urlopen.call_args[0][0] + self.assertEqual(req.full_url, "https://f.example/api/v1/accounts?type=asset") + self.assertEqual(req.get_header("Authorization"), "Bearer tok") + self.assertEqual(req.get_header("Accept"), "application/vnd.api+json") + self.assertEqual(out, {"data": []}) + + @patch("firefly_cli.client.urllib.request.urlopen") + def test_post_sends_json_body(self, urlopen): + urlopen.return_value = fake_response({"data": {"id": "9"}}) + self.c.request("POST", "/api/v1/transactions", body={"x": 1}) + req = urlopen.call_args[0][0] + self.assertEqual(req.get_method(), "POST") + self.assertEqual(json.loads(req.data), {"x": 1}) + self.assertEqual(req.get_header("Content-type"), "application/json") + + @patch("firefly_cli.client.urllib.request.urlopen") + def test_http_error_becomes_apierror(self, urlopen): + body = json.dumps({"message": "boom"}).encode() + urlopen.side_effect = urllib.error.HTTPError( + "u", 422, "Unprocessable", {}, BytesIO(body)) + with self.assertRaises(ApiError) as ctx: + self.c.request("GET", "/api/v1/accounts") + self.assertEqual(ctx.exception.status, 422) + self.assertEqual(ctx.exception.body["message"], "boom") |
