"""Tests for entity_manager module.""" import json import sys import tempfile from pathlib import Path from unittest import mock import pytest # Add parent to path sys.path.insert(0, str(Path(__file__).parent.parent)) import cortex.entity_manager as em class TestNormalize: def test_basic(self): assert em.normalize("Hello World") == "hello world" def test_underscores(self): assert em.normalize("my_entity") == "my-entity" def test_whitespace(self): assert em.normalize(" test ") == "test" class TestLoadJson: def test_missing_file(self): assert em.load_json(Path("/nonexistent/file.json")) == {} def test_valid_json(self, tmp_path): f = tmp_path / "test.json" f.write_text('{"key": "value"}') assert em.load_json(f) == {"key": "value"} def test_invalid_json(self, tmp_path): f = tmp_path / "bad.json" f.write_text("not json") assert em.load_json(f) == {} class TestSaveJson: def test_creates_dirs(self, tmp_path): f = tmp_path / "sub" / "dir" / "test.json" em.save_json(f, {"hello": "world"}) assert json.loads(f.read_text()) == {"hello": "world"} class TestExtractEntities: def test_known_entity(self): known = {"acme-corp": {"type": "company"}} result = em.extract_entities("Working with Acme Corp today", known) assert "acme-corp" in result def test_mention(self): result = em.extract_entities("Talked to @johndoe about it", {}) assert "johndoe" in result assert result["johndoe"]["type"] == "person" def test_capitalized_multi_word(self): result = em.extract_entities("Met with John Smith yesterday", {}) assert "john smith" in result def test_acronym(self): result = em.extract_entities("The ACME project is going well", {}) assert "acme" in result assert result["acme"]["type"] == "organization" def test_stop_words_filtered(self): result = em.extract_entities("The system is working fine", {}) # None of these should be extracted as entities for word in ["the", "system", "working"]: assert word not in result def test_empty_text(self): result = em.extract_entities("", {}) assert result == {} def test_short_mention_filtered(self): """Mentions shorter than 3 chars should be filtered.""" result = em.extract_entities("@ab said hi", {}) assert "ab" not in result class TestCmdBootstrap: def test_bootstrap_with_empty_areas(self, tmp_path): with mock.patch.object(em, "LIFE_AREAS", tmp_path): with mock.patch.object(em, "ENTITIES_FILE", tmp_path / "entities.json"): with mock.patch.object(em, "RELATIONSHIPS_FILE", tmp_path / "rels.json"): em.cmd_bootstrap() assert (tmp_path / "entities.json").exists() class TestCmdRelate: def test_create_relationship(self, tmp_path): with mock.patch.object(em, "RELATIONSHIPS_FILE", tmp_path / "rels.json"): with mock.patch.object(em, "ENTITIES_FILE", tmp_path / "entities.json"): em.cmd_relate("Alice", "Bob", "colleague") rels = json.loads((tmp_path / "rels.json").read_text()) assert len(rels) == 1 key = list(rels.keys())[0] assert "colleague" in rels[key]["types"] def test_update_relationship(self, tmp_path): with mock.patch.object(em, "RELATIONSHIPS_FILE", tmp_path / "rels.json"): with mock.patch.object(em, "ENTITIES_FILE", tmp_path / "entities.json"): em.cmd_relate("Alice", "Bob", "colleague") em.cmd_relate("Alice", "Bob", "friend") rels = json.loads((tmp_path / "rels.json").read_text()) key = list(rels.keys())[0] assert rels[key]["count"] == 2