Didactopus/tests/test_notebook_page.py

114 lines
4.3 KiB
Python

from __future__ import annotations
import json
from pathlib import Path
from didactopus.notebook_page import (
build_notebook_page_from_groundrecall_bundle,
export_notebook_page_from_groundrecall_bundle,
)
def _sample_bundle() -> dict:
return {
"bundle_kind": "groundrecall_query_bundle",
"concept": {
"concept_id": "concept::natural-selection",
"title": "Natural Selection",
"description": "Differential survival and reproduction.",
"aliases": ["selection"],
},
"relevant_claims": [
{"claim_id": "clm_001", "claim_text": "Selection can change trait frequencies."},
{"claim_id": "clm_002", "claim_text": "Selection depends on heritable variation."},
],
"relations": [
{
"relation_id": "rel_001",
"source_id": "concept::variation",
"target_id": "concept::natural-selection",
"relation_type": "prerequisite",
},
{
"relation_id": "rel_002",
"source_id": "concept::natural-selection",
"target_id": "concept::adaptation",
"relation_type": "historical_successor",
},
{
"relation_id": "rel_003",
"source_id": "concept::natural-selection",
"target_id": "concept::common-descent",
"relation_type": "supports",
},
],
"related_concepts": [
{
"concept_id": "concept::variation",
"title": "Variation",
"description": "Differences among individuals.",
},
{
"concept_id": "concept::adaptation",
"title": "Adaptation",
"description": "Traits fit to local conditions.",
},
{
"concept_id": "concept::common-descent",
"title": "Common Descent",
"description": "Shared ancestry of organisms.",
},
],
"supporting_observations": [
{
"observation_id": "obs_001",
"text": "Population differences can affect survival.",
"origin_path": "texts/futuyma/ch1.md",
"grounding_status": "grounded",
}
],
"source_artifacts": [
{
"artifact_id": "art_001",
"artifact_kind": "compiled_page",
"title": "Evolutionary Biology Chapter 1",
"path": "texts/futuyma/ch1.md",
}
],
"review_candidates": [
{
"candidate_id": "concept::natural-selection",
"finding_codes": ["bridge_concept"],
"rationale": "Natural Selection | lane=conflict_resolution | priority=12 | graph=bridge_concept",
}
],
"suggested_next_actions": ["Inspect supporting observations before export."],
}
def test_build_notebook_page_buckets_graph_navigation() -> None:
page = build_notebook_page_from_groundrecall_bundle(_sample_bundle())
assert page["page_kind"] == "didactopus_notebook_page"
assert page["concept"]["title"] == "Natural Selection"
assert page["summary"]["claim_count"] == 2
assert page["graph_navigation"]["antecedent_concepts"][0]["title"] == "Variation"
assert page["graph_navigation"]["derivative_concepts"][0]["title"] == "Adaptation"
assert page["graph_navigation"]["closer_concepts"][0]["title"] == "Common Descent"
assert page["supporting_sources"][0]["supporting_observation_count"] == 1
assert page["review_context"]["graph_codes"] == ["bridge_concept"]
assert page["illustration_opportunities"]
def test_export_notebook_page_writes_json(tmp_path: Path) -> None:
bundle_path = tmp_path / "groundrecall_query_bundle.json"
out_path = tmp_path / "notebook_page.json"
bundle_path.write_text(json.dumps(_sample_bundle()), encoding="utf-8")
payload = export_notebook_page_from_groundrecall_bundle(bundle_path, out_path)
assert out_path.exists()
assert payload["page_path"].endswith("notebook_page.json")
written = json.loads(out_path.read_text(encoding="utf-8"))
assert written["concept"]["concept_id"] == "concept::natural-selection"