feat: drawer significance review panel (T98.2)
This commit is contained in:
@@ -187,3 +187,96 @@ def test_t98_1_branch_from_turn_emits_branch_created(client, tmp_path):
|
||||
)
|
||||
assert dup.status_code == 400
|
||||
assert seed_id < turn_id # sanity: turn is after chat_created
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# T98.2 — significance review panel.
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
def _seed_memories_for_significance(db: Path) -> list[int]:
|
||||
"""Seed three memories with significance levels 0, 1, 2. Returns ids.
|
||||
|
||||
Uses ``append_and_apply`` (vs ``append_event`` + a final ``project``)
|
||||
so each row is applied exactly once — the chat row was already
|
||||
materialised by ``_seed_chat`` and a re-projection would conflict
|
||||
on ``chats.id`` UNIQUE.
|
||||
"""
|
||||
ids: list[int] = []
|
||||
with open_db(db) as conn:
|
||||
for sig in (0, 1, 2):
|
||||
append_and_apply(
|
||||
conn,
|
||||
kind="memory_written",
|
||||
payload={
|
||||
"owner_id": "bot_a",
|
||||
"chat_id": "chat_bot_a",
|
||||
"pov_summary": f"memory at significance {sig}",
|
||||
"witness_you": 1,
|
||||
"witness_host": 1,
|
||||
"witness_guest": 0,
|
||||
"significance": sig,
|
||||
},
|
||||
)
|
||||
rows = conn.execute(
|
||||
"SELECT id FROM memories WHERE chat_id = 'chat_bot_a' "
|
||||
"ORDER BY id ASC"
|
||||
).fetchall()
|
||||
ids = [int(r[0]) for r in rows]
|
||||
return ids
|
||||
|
||||
|
||||
def test_t98_2_distribution_renders_per_significance_bucket(client, tmp_path):
|
||||
db = tmp_path / "test.db"
|
||||
_seed_chat(db)
|
||||
_seed_memories_for_significance(db)
|
||||
|
||||
response = client.get("/chats/chat_bot_a/drawer")
|
||||
assert response.status_code == 200
|
||||
body = response.text
|
||||
|
||||
# Section heading + bar entries for each significance level.
|
||||
assert "<h3>Significance review</h3>" in body
|
||||
# All four buckets appear by their canonical label even when count=0.
|
||||
assert ">★★ (3)<" in body or "(3)" in body
|
||||
# The distribution markup names each level explicitly.
|
||||
for level in (0, 1, 2, 3):
|
||||
assert f"sig-bar sig-{level}" in body
|
||||
# Three seeded memories (sigs 0, 1, 2) — each has a count = 1 bar.
|
||||
# We don't pin exact text formatting, just verify the per-level bars
|
||||
# are present.
|
||||
|
||||
|
||||
def test_t98_2_edit_significance_via_existing_route_lands_manual_edit(
|
||||
client, tmp_path
|
||||
):
|
||||
db = tmp_path / "test.db"
|
||||
_seed_chat(db)
|
||||
ids = _seed_memories_for_significance(db)
|
||||
|
||||
target_id = ids[0] # initially significance=0
|
||||
response = client.post(
|
||||
f"/chats/chat_bot_a/drawer/memory/{target_id}/significance",
|
||||
data={"significance": "3"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
with open_db(db) as conn:
|
||||
# Significance updated in the projected table.
|
||||
row = conn.execute(
|
||||
"SELECT significance FROM memories WHERE id = ?", (target_id,)
|
||||
).fetchone()
|
||||
assert int(row[0]) == 3
|
||||
|
||||
# manual_edit landed in the event log with the prior snapshot.
|
||||
import json as _json
|
||||
|
||||
log_rows = conn.execute(
|
||||
"SELECT payload_json FROM event_log "
|
||||
"WHERE kind = 'manual_edit' ORDER BY id DESC LIMIT 1"
|
||||
).fetchone()
|
||||
payload = _json.loads(log_rows[0])
|
||||
assert payload["target_kind"] == "memory_significance"
|
||||
assert int(payload["target_id"]) == target_id
|
||||
assert payload["prior_value"] == 0
|
||||
assert payload["new_value"] == 3
|
||||
|
||||
Reference in New Issue
Block a user