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
120 lines
3.4 KiB
Python
120 lines
3.4 KiB
Python
"""Exercise prisma.project — init, load, anchors, backfill."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from prisma.project import (
|
|
_backfill_cohort,
|
|
_find_anchor_id,
|
|
_html_escape,
|
|
_html_unescape,
|
|
_load_note,
|
|
init,
|
|
load,
|
|
)
|
|
from zot.db import Db
|
|
from zot.schema import create_db
|
|
|
|
|
|
def _setup(tmp_path):
|
|
path = str(tmp_path / "z.sqlite")
|
|
con = create_db(path)
|
|
con.close()
|
|
return path
|
|
|
|
|
|
class TestHtmlHelpers:
|
|
def test_escape(self):
|
|
assert _html_escape("<b>&</b>") == "<b>&</b>"
|
|
|
|
def test_unescape(self):
|
|
assert _html_unescape("<b>&</b>") == "<b>&</b>"
|
|
|
|
|
|
class TestInit:
|
|
def test_creates_project(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
project = init(db, "skin-subs")
|
|
assert project.name == "skin-subs"
|
|
assert len(project.criteria) > 0
|
|
assert len(project.extraction_template) > 0
|
|
assert len(project.reasons) > 0
|
|
|
|
def test_idempotent(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
p1 = init(db, "skin-subs")
|
|
p2 = init(db, "skin-subs")
|
|
assert p1.criteria == p2.criteria
|
|
|
|
def test_unknown_project(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
with pytest.raises(ValueError, match="no starter"):
|
|
init(db, "nonexistent-project")
|
|
|
|
|
|
class TestLoad:
|
|
def test_loads_existing(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
init(db, "skin-subs")
|
|
with Db(path) as db:
|
|
project = load(db, "skin-subs")
|
|
assert project.name == "skin-subs"
|
|
assert len(project.criteria) > 0
|
|
|
|
def test_missing_project(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
with pytest.raises(LookupError, match="not found"):
|
|
load(db, "nonexistent")
|
|
|
|
|
|
class TestFindAnchorId:
|
|
def test_not_found(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
assert _find_anchor_id(db, "project:nope", "prisma:criteria") is None
|
|
|
|
|
|
class TestLoadNote:
|
|
def test_missing_anchor(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
with pytest.raises(LookupError, match="not found"):
|
|
_load_note(db, "project:nope", "prisma:criteria")
|
|
|
|
|
|
class TestBackfillCohort:
|
|
def test_tags_legacy_items(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
from zot.db import TYPE_MAP
|
|
|
|
iid = db.create_item(TYPE_MAP["document"])
|
|
db.sync_tags(iid, ["cohort:skin-subs"])
|
|
db.commit()
|
|
n = _backfill_cohort(
|
|
db, legacy="cohort:skin-subs", project_tag="project:skin-subs"
|
|
)
|
|
assert n >= 1
|
|
|
|
def test_idempotent(self, tmp_path):
|
|
path = _setup(tmp_path)
|
|
with Db(path) as db:
|
|
from zot.db import TYPE_MAP
|
|
|
|
iid = db.create_item(TYPE_MAP["document"])
|
|
db.sync_tags(iid, ["cohort:skin-subs"])
|
|
db.commit()
|
|
_backfill_cohort(
|
|
db, legacy="cohort:skin-subs", project_tag="project:skin-subs"
|
|
)
|
|
n2 = _backfill_cohort(
|
|
db, legacy="cohort:skin-subs", project_tag="project:skin-subs"
|
|
)
|
|
assert n2 == 0
|