agnes-the-ai-analyst/tests/test_v2_client.py
ZdenekSrotyr 2e1dfb7553
feat(v2): claude-driven fetch primitives + 0.14.0 (#102)
Replaces the BigQuery wrap-view pattern with a discovery + scoped-fetch toolkit driven by the analyst's Claude session. Adds /api/v2/{catalog,schema,sample,scan,scan/estimate}, da catalog/schema/describe/fetch/snapshot/disk-info CLI commands, sqlglot-backed WHERE validator, process-local quota tracker, agent rails skill (cli/skills/agnes-data-querying.md). BREAKING: BQ wrap views off by default — set data_source.bigquery.legacy_wrap_views=true for one cycle. Backward-compat field_validator on primary_key. Catalog cache now matches documented 300s TTL with RBAC fresh per request. Cuts release v0.14.0.
2026-04-29 01:07:19 +02:00

56 lines
1.8 KiB
Python

# tests/test_v2_client.py
import json
import pyarrow as pa
import pytest
from unittest.mock import MagicMock, patch
from cli.v2_client import (
api_get_json,
api_post_arrow,
api_post_json,
V2ClientError,
)
def _fake_response(*, status=200, json_body=None, arrow_body=None, content_type=None):
resp = MagicMock()
resp.status_code = status
if json_body is not None:
resp.json.return_value = json_body
resp.text = json.dumps(json_body)
resp.content = resp.text.encode()
if arrow_body is not None:
resp.content = arrow_body
if content_type:
resp.headers = {"content-type": content_type}
else:
resp.headers = {}
return resp
class TestApiGetJson:
def test_200_returns_parsed_json(self):
with patch("cli.v2_client.httpx.get") as m:
m.return_value = _fake_response(json_body={"hello": "world"})
assert api_get_json("/api/v2/catalog") == {"hello": "world"}
def test_4xx_raises_v2clienterror(self):
with patch("cli.v2_client.httpx.get") as m:
m.return_value = _fake_response(status=403, json_body={"detail": "nope"})
with pytest.raises(V2ClientError) as e:
api_get_json("/api/v2/catalog")
assert e.value.status_code == 403
class TestApiPostArrow:
def test_returns_arrow_table(self):
from app.api.v2_arrow import arrow_table_to_ipc_bytes
ipc = arrow_table_to_ipc_bytes(pa.table({"x": [1, 2, 3]}))
with patch("cli.v2_client.httpx.post") as m:
m.return_value = _fake_response(
arrow_body=ipc,
content_type="application/vnd.apache.arrow.stream",
)
got = api_post_arrow("/api/v2/scan", {"table_id": "x"})
assert got.num_rows == 3
assert got.column_names == ["x"]