Fix Zotero table models for Zotero 9:
- Remove stale Annotations/Highlights/Transaction* models
- Add ItemAnnotations, RetractedItems, DeletedCollections,
DeletedSearches, DbDebug1
- Fix ItemAttachments, Libraries, Users column mismatches
New test files covering all major modules:
- cli/{bib,prisma,rec,zot,mail,run} deep exercising tests
- mail/{droplet,postmark,resend,cloudflare} lifecycle tests
- bib/{iom,oig,pincite,sync,regulations_gov,email_ingest,format,store}
- prisma/{vpn,fetch,export,llm,screen,eligibility,extract,project,ingest,flow}
- aco/lake/{unity,quality,deploy} + api/aco coverage gaps
- zot/{ops,db,extract,duck} + rec/{report,engine,base,pricers}
- pfs/{pipe,rules,eq,files}
Add pytest-xdist for parallel test execution.
Tracks #353
135 lines
4.1 KiB
Python
135 lines
4.1 KiB
Python
"""Exercise aco.lake.quality — monitors, refresh."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from unittest.mock import MagicMock
|
|
|
|
from aco.lake.quality import (
|
|
_default_profiles,
|
|
list_monitors,
|
|
run_refresh,
|
|
setup_monitors,
|
|
)
|
|
|
|
|
|
def _mock_client():
|
|
ws = MagicMock()
|
|
client = MagicMock()
|
|
client._ws = ws
|
|
return client, ws
|
|
|
|
|
|
class TestDefaultProfiles:
|
|
def test_generates(self):
|
|
profiles = _default_profiles("cat", "schema")
|
|
assert len(profiles) == 1
|
|
assert "cat.schema" in profiles[0].table
|
|
|
|
|
|
class TestSetupMonitors:
|
|
def test_dry_run(self):
|
|
client, ws = _mock_client()
|
|
tbl = MagicMock()
|
|
tbl.full_name = "cat.raw.table1"
|
|
tbl.name = "table1"
|
|
ws.tables.list.return_value = [tbl]
|
|
|
|
actions = setup_monitors(client, "cat", ["raw"], dry_run=True)
|
|
assert len(actions) == 1
|
|
assert "[dry-run]" in actions[0]
|
|
|
|
def test_creates_monitor(self):
|
|
client, ws = _mock_client()
|
|
tbl = MagicMock()
|
|
tbl.full_name = "cat.raw.table1"
|
|
tbl.name = "table1"
|
|
ws.tables.list.return_value = [tbl]
|
|
ws.quality_monitors.get.side_effect = Exception("not found")
|
|
ws.schemas.get.side_effect = Exception("not found")
|
|
|
|
actions = setup_monitors(client, "cat", ["raw"], dry_run=False)
|
|
assert any("created" in a for a in actions)
|
|
|
|
def test_monitor_exists(self):
|
|
client, ws = _mock_client()
|
|
tbl = MagicMock()
|
|
tbl.full_name = "cat.raw.table1"
|
|
tbl.name = "table1"
|
|
ws.tables.list.return_value = [tbl]
|
|
ws.quality_monitors.get.return_value = MagicMock()
|
|
|
|
actions = setup_monitors(client, "cat", ["raw"], dry_run=False)
|
|
assert any("[exists]" in a for a in actions)
|
|
|
|
def test_list_error(self):
|
|
client, ws = _mock_client()
|
|
ws.tables.list.side_effect = Exception("no access")
|
|
|
|
actions = setup_monitors(client, "cat", ["raw"], dry_run=False)
|
|
assert any("ERROR" in a for a in actions)
|
|
|
|
def test_create_error(self):
|
|
client, ws = _mock_client()
|
|
tbl = MagicMock()
|
|
tbl.full_name = "cat.raw.table1"
|
|
tbl.name = "table1"
|
|
ws.tables.list.return_value = [tbl]
|
|
ws.quality_monitors.get.side_effect = Exception("not found")
|
|
ws.quality_monitors.create.side_effect = Exception("create failed")
|
|
|
|
actions = setup_monitors(client, "cat", ["raw"], dry_run=False)
|
|
assert any("ERROR" in a for a in actions)
|
|
|
|
|
|
class TestListMonitors:
|
|
def test_lists(self):
|
|
client, ws = _mock_client()
|
|
schema = MagicMock()
|
|
schema.name = "raw"
|
|
ws.schemas.list.return_value = [schema]
|
|
|
|
tbl = MagicMock()
|
|
tbl.full_name = "cat.raw.table1"
|
|
tbl.name = "table1"
|
|
ws.tables.list.return_value = [tbl]
|
|
|
|
mon = MagicMock()
|
|
mon.status = "ACTIVE"
|
|
mon.dashboard_id = "dash1"
|
|
ws.quality_monitors.get.return_value = mon
|
|
|
|
results = list_monitors(client, "cat")
|
|
assert len(results) == 1
|
|
assert results[0].status == "ACTIVE"
|
|
|
|
def test_skips_internal_schemas(self):
|
|
client, ws = _mock_client()
|
|
schema = MagicMock()
|
|
schema.name = "_monitoring"
|
|
ws.schemas.list.return_value = [schema]
|
|
results = list_monitors(client, "cat")
|
|
assert len(results) == 0
|
|
|
|
def test_handles_table_error(self):
|
|
client, ws = _mock_client()
|
|
schema = MagicMock()
|
|
schema.name = "raw"
|
|
ws.schemas.list.return_value = [schema]
|
|
ws.tables.list.side_effect = Exception("no access")
|
|
results = list_monitors(client, "cat")
|
|
assert len(results) == 0
|
|
|
|
|
|
class TestRunRefresh:
|
|
def test_success(self):
|
|
client, ws = _mock_client()
|
|
resp = MagicMock()
|
|
resp.refresh_id = "r123"
|
|
ws.quality_monitors.run_refresh.return_value = resp
|
|
assert run_refresh(client, "cat.raw.table1") == "r123"
|
|
|
|
def test_failure(self):
|
|
client, ws = _mock_client()
|
|
ws.quality_monitors.run_refresh.side_effect = Exception("fail")
|
|
assert run_refresh(client, "cat.raw.table1") is None
|