agnes-the-ai-analyst/tests/test_sync_manifest.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

94 lines
3.8 KiB
Python

"""Tests for /api/sync/manifest — query_mode and source_type per table.
These tests target the `_build_manifest_for_user` helper directly so they can
exercise the query_mode/source_type joining logic without going through the
HTTP layer. The CLI (Task 7) relies on these fields to skip remote-mode
tables during download.
"""
import importlib
def _reload_db_module(monkeypatch, tmp_path):
"""Point DATA_DIR at tmp_path and reload db module so paths take effect."""
monkeypatch.setenv("DATA_DIR", str(tmp_path))
(tmp_path / "state").mkdir(exist_ok=True)
import src.db as db_module
importlib.reload(db_module)
return db_module
def test_manifest_includes_query_mode_for_local_table(tmp_path, monkeypatch):
"""Local-mode table must surface query_mode='local' in manifest."""
db_module = _reload_db_module(monkeypatch, tmp_path)
from src.repositories.sync_state import SyncStateRepository
from src.repositories.table_registry import TableRegistryRepository
from app.api.sync import _build_manifest_for_user
conn = db_module.get_system_db()
try:
TableRegistryRepository(conn).register(
id="orders", name="orders", source_type="keboola",
bucket="sales", source_table="orders", query_mode="local",
)
SyncStateRepository(conn).update_sync(
table_id="orders", rows=10, file_size_bytes=1024, hash="abc",
)
admin = {"role": "admin", "email": "a@x.com"}
manifest = _build_manifest_for_user(conn, admin)
assert manifest["tables"]["orders"]["query_mode"] == "local"
assert manifest["tables"]["orders"]["source_type"] == "keboola"
assert manifest["tables"]["orders"]["hash"] == "abc"
assert manifest["tables"]["orders"]["rows"] == 10
assert manifest["tables"]["orders"]["size_bytes"] == 1024
finally:
conn.close()
def test_manifest_includes_query_mode_for_remote_table(tmp_path, monkeypatch):
"""Remote-mode table (BQ) must surface query_mode='remote' in manifest."""
db_module = _reload_db_module(monkeypatch, tmp_path)
from src.repositories.sync_state import SyncStateRepository
from src.repositories.table_registry import TableRegistryRepository
from app.api.sync import _build_manifest_for_user
conn = db_module.get_system_db()
try:
TableRegistryRepository(conn).register(
id="bq_view", name="bq_view", source_type="bigquery",
bucket="ds", source_table="bq_view", query_mode="remote",
)
SyncStateRepository(conn).update_sync(
table_id="bq_view", rows=0, file_size_bytes=0, hash="",
)
admin = {"role": "admin", "email": "a@x.com"}
manifest = _build_manifest_for_user(conn, admin)
assert manifest["tables"]["bq_view"]["query_mode"] == "remote"
assert manifest["tables"]["bq_view"]["source_type"] == "bigquery"
finally:
conn.close()
def test_manifest_defaults_query_mode_local_for_unregistered_state(tmp_path, monkeypatch):
"""Sync state without a corresponding registry row must default query_mode='local'.
Defensive: if registry lookup misses (deleted entry, race), don't break the manifest.
"""
db_module = _reload_db_module(monkeypatch, tmp_path)
from src.repositories.sync_state import SyncStateRepository
from app.api.sync import _build_manifest_for_user
conn = db_module.get_system_db()
try:
SyncStateRepository(conn).update_sync(
table_id="orphan", rows=0, file_size_bytes=0, hash="",
)
admin = {"role": "admin", "email": "a@x.com"}
manifest = _build_manifest_for_user(conn, admin)
assert manifest["tables"]["orphan"]["query_mode"] == "local"
assert manifest["tables"]["orphan"]["source_type"] == ""
finally:
conn.close()