"""Tests for Know Thy Father — Phase 3: Holographic Synthesis.""" import json import tempfile from pathlib import Path import pytest from scripts.know_thy_father.synthesize_kernels import ( MeaningKernel, Theme, extract_themes, classify_emotional_weight, synthesize_meaning, process_manifest, generate_ledger_summary, _HASHTAG_THEMES, ) class TestThemeExtraction: """Test theme extraction from hashtags and text.""" def test_bitcoin_hashtag_maps_to_sovereignty(self): themes = extract_themes(["bitcoin"], "") assert Theme.SOVEREIGNTY in themes def test_timmytime_maps_to_fatherhood(self): themes = extract_themes(["TimmyTime"], "") assert Theme.FATHERHOOD in themes def test_burnchain_maps_to_trial(self): themes = extract_themes(["burnchain"], "") assert Theme.TRIAL in themes def test_keyword_detection_faith(self): themes = extract_themes([], "Jesus saves those who call on His name") assert Theme.FAITH in themes def test_keyword_detection_sovereignty(self): themes = extract_themes([], "Self-sovereignty is the foundation of freedom") assert Theme.SOVEREIGNTY in themes def test_no_themes_defaults_to_wisdom(self): themes = extract_themes([], "Just a normal tweet") assert Theme.WISDOM in themes def test_multiple_themes(self): themes = extract_themes(["bitcoin", "timmytime"], "Building sovereign systems") assert len(themes) >= 2 class TestEmotionalWeight: """Test emotional weight classification.""" def test_sacred_markers(self): assert classify_emotional_weight("Jesus saves", []) == "sacred" assert classify_emotional_weight("God's grace", []) == "sacred" def test_high_markers(self): assert classify_emotional_weight("A father's legacy", []) == "high" assert classify_emotional_weight("In the dark times", []) == "high" def test_timmytime_is_high(self): assert classify_emotional_weight("some text", ["TimmyTime"]) == "high" def test_default_is_medium(self): assert classify_emotional_weight("normal tweet", ["funny"]) == "medium" class TestMeaningSynthesis: """Test meaning synthesis from themes.""" def test_faith_plus_sovereignty(self): meaning = synthesize_meaning( [Theme.FAITH, Theme.SOVEREIGNTY], "", "photo" ) assert "faith" in meaning.lower() assert "sovereignty" in meaning.lower() def test_fatherhood_plus_wisdom(self): meaning = synthesize_meaning( [Theme.FATHERHOOD, Theme.WISDOM], "", "video" ) assert "father" in meaning.lower() def test_default_meaning(self): meaning = synthesize_meaning([Theme.CREATION], "", "photo") assert len(meaning) > 0 class TestMeaningKernel: """Test the MeaningKernel dataclass.""" def test_to_fact_store(self): kernel = MeaningKernel( kernel_id="ktf-123-456", source_tweet_id="123", source_media_id="456", media_type="photo", created_at="2026-04-01T00:00:00Z", themes=["sovereignty", "community"], meaning="Test meaning", description="Test description", emotional_weight="high", hashtags=["bitcoin"], ) fact = kernel.to_fact_store() assert fact["action"] == "add" assert "sovereignty" in fact["content"] assert fact["category"] == "project" assert "know-thy-father" in fact["tags"] assert fact["metadata"]["kernel_id"] == "ktf-123-456" assert fact["metadata"]["media_type"] == "photo" class TestProcessManifest: """Test the manifest processing pipeline.""" def test_process_manifest_creates_kernels(self): manifest_content = "\n".join([ json.dumps({ "tweet_id": "1001", "media_id": "m1", "media_type": "photo", "full_text": "Bitcoin is sovereign money", "hashtags": ["bitcoin"], "created_at": "2026-04-01T00:00:00Z", "local_media_path": "/tmp/media/m1.jpg", }), json.dumps({ "tweet_id": "1002", "media_id": "m2", "media_type": "video", "full_text": "Building for the next generation", "hashtags": ["TimmyTime"], "created_at": "2026-04-02T00:00:00Z", "local_media_path": "/tmp/media/m2.mp4", }), ]) with tempfile.NamedTemporaryFile(mode="w", suffix=".jsonl", delete=False) as f: f.write(manifest_content) manifest_path = Path(f.name) with tempfile.NamedTemporaryFile(suffix=".jsonl", delete=False) as f: output_path = Path(f.name) try: kernels = process_manifest(manifest_path, output_path) assert len(kernels) == 2 assert kernels[0].source_tweet_id == "1001" assert kernels[1].source_tweet_id == "1002" # Check output file with open(output_path) as f: lines = f.readlines() assert len(lines) == 2 # Parse first fact fact = json.loads(lines[0]) assert fact["action"] == "add" assert "know-thy-father" in fact["tags"] finally: manifest_path.unlink(missing_ok=True) output_path.unlink(missing_ok=True) def test_deduplicates_by_tweet_id(self): manifest_content = "\n".join([ json.dumps({"tweet_id": "1001", "media_id": "m1", "media_type": "photo", "full_text": "Test", "hashtags": [], "created_at": ""}), json.dumps({"tweet_id": "1001", "media_id": "m2", "media_type": "photo", "full_text": "Test duplicate", "hashtags": [], "created_at": ""}), ]) with tempfile.NamedTemporaryFile(mode="w", suffix=".jsonl", delete=False) as f: f.write(manifest_content) manifest_path = Path(f.name) try: kernels = process_manifest(manifest_path) assert len(kernels) == 1 # Deduplicated finally: manifest_path.unlink(missing_ok=True) class TestGenerateSummary: """Test ledger summary generation.""" def test_summary_structure(self): kernels = [ MeaningKernel( kernel_id="ktf-1", source_tweet_id="1", source_media_id="m1", media_type="photo", created_at="", themes=["sovereignty"], meaning="Test", description="", emotional_weight="high", ), MeaningKernel( kernel_id="ktf-2", source_tweet_id="2", source_media_id="m2", media_type="video", created_at="", themes=["faith", "sovereignty"], meaning="Test", description="", emotional_weight="sacred", ), ] summary = generate_ledger_summary(kernels) assert summary["total_kernels"] == 2 assert summary["sacred_kernel_count"] == 1 assert summary["theme_distribution"]["sovereignty"] == 2 assert summary["theme_distribution"]["faith"] == 1 assert "generated_at" in summary