""" Recollection rendering tests — hit path, zero-hit path, pending-conflict marker, and prompt injection position. """ import pytest from festinger import cache from festinger.recollection import ( query_edges, render_hit, render_zero_hit, build_recollection_block, inject_recollection, ) from tests.helpers import reset_cache, add_soas, add_urd class TestHitPath: def setup_method(self): reset_cache() self.michigan = add_soas(101, "michigan", saliency=1.5) self.usa = add_soas(102, "usa", saliency=0.8) self.geography = add_soas(5, "geography", saliency=0.0) self.state = add_soas(103, "state", saliency=0.7) self.type_dim = add_soas(1, "type", saliency=0.0) add_urd(concept_id=101, parent_id=102, dim_id=5, is_isa=False, confidence=0.9) add_urd(concept_id=101, parent_id=103, dim_id=1, is_isa=True, confidence=0.9) def test_query_returns_both_edges(self): edges = query_edges(101, confidence_floor=0.5, recency_days=90) assert len(edges) == 2 def test_render_hit_format(self): edges = query_edges(101, confidence_floor=0.5, recency_days=90) line = render_hit("michigan", edges, concept_id=101) assert line.startswith("michigan:") assert "[geography] usa" in line assert "[type] state" in line def test_pending_conflict_adds_question_mark(self): cache.pending_conflicts.add(101) edges = query_edges(101, confidence_floor=0.5, recency_days=90) line = render_hit("michigan", edges, concept_id=101) # All dim labels should have ? when concept has pending conflict assert "[geography?]" in line or "[type?]" in line def test_confidence_floor_filters_edges(self): # Add a low-confidence edge add_urd(concept_id=101, parent_id=5, dim_id=5, is_isa=False, confidence=0.2) edges = query_edges(101, confidence_floor=0.6, recency_days=90) # Should not include the 0.2 confidence edge low_conf = [e for e in edges if e.confidence < 0.6] assert low_conf == [] def test_block_contains_recollection_tags(self): block = build_recollection_block([101], confidence_floor=0.5, recency_days=90) assert block is not None assert block.startswith("") assert block.endswith("") class TestZeroHitPath: def setup_method(self): reset_cache() add_soas(201, "ramanujan", saliency=1.5) # No URD edges for ramanujan def test_zero_hit_render(self): line = render_zero_hit("ramanujan") assert "ramanujan" in line assert "no recollection" in line assert "gutask iknowthat" in line def test_zero_hit_in_block(self): block = build_recollection_block([201], confidence_floor=0.5, recency_days=90) assert block is not None assert "? ramanujan" in block assert "gutask iknowthat" in block def test_block_is_none_when_no_salient_concepts(self): block = build_recollection_block([], confidence_floor=0.5, recency_days=90) assert block is None class TestPromptInjection: def setup_method(self): reset_cache() add_soas(101, "michigan", saliency=1.5) add_soas(102, "usa", saliency=0.8) add_soas(5, "geography", saliency=0.0) add_urd(concept_id=101, parent_id=102, dim_id=5, is_isa=False, confidence=0.9) def _block(self): return build_recollection_block([101], confidence_floor=0.5, recency_days=90) def test_injected_into_existing_system_message(self): messages = [ {"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "Tell me about michigan."}, ] block = self._block() result = inject_recollection(messages, block) system = next(m for m in result if m["role"] == "system") assert system["content"].startswith("") assert "You are a helpful assistant." in system["content"] def test_injected_at_position_0_when_no_system_message(self): messages = [{"role": "user", "content": "Tell me about michigan."}] block = self._block() result = inject_recollection(messages, block) assert result[0]["role"] == "system" assert "" in result[0]["content"] assert result[1]["role"] == "user" def test_original_messages_not_mutated(self): original = [ {"role": "system", "content": "You are helpful."}, {"role": "user", "content": "michigan?"}, ] inject_recollection(original, self._block()) # Original list and dicts must be unchanged assert original[0]["content"] == "You are helpful." def test_user_message_preserved_after_injection(self): messages = [ {"role": "system", "content": "System prompt."}, {"role": "user", "content": "michigan?"}, ] result = inject_recollection(messages, self._block()) user_msgs = [m for m in result if m["role"] == "user"] assert user_msgs[0]["content"] == "michigan?"