"""Unit tests for configuration system.""" import pytest import json from pathlib import Path from tagging_system.config import ( TaggingConfig, DirectoryMapping, TagHierarchy, SensitivePatterns, load_config, save_config ) class TestDirectoryMapping: """Test DirectoryMapping model.""" def test_directory_mapping_creation(self): """Test DirectoryMapping creation.""" mapping = DirectoryMapping( pattern="100-project", primary_tag="project", hierarchical_tags=["tech"], exclude_patterns=["*.tmp"] ) assert mapping.pattern == "100-project" assert mapping.primary_tag == "project" assert mapping.hierarchical_tags == ["tech"] assert mapping.exclude_patterns == ["*.tmp"] class TestTagHierarchy: """Test TagHierarchy model.""" def test_tag_hierarchy_creation(self): """Test TagHierarchy creation.""" hierarchy = TagHierarchy( root="tech", children={"ai": TagHierarchy("ai")}, aliases=["technology"] ) assert hierarchy.root == "tech" assert "ai" in hierarchy.children assert hierarchy.aliases == ["technology"] def test_get_full_path(self): """Test get_full_path method.""" hierarchy = TagHierarchy("tech") assert hierarchy.get_full_path() == "tech" assert hierarchy.get_full_path("ai") == "tech/ai" assert hierarchy.get_full_path("ai/llm") == "tech/ai/llm" class TestSensitivePatterns: """Test SensitivePatterns model.""" def test_sensitive_patterns_defaults(self): """Test SensitivePatterns default values.""" patterns = SensitivePatterns() assert len(patterns.credential_patterns) > 0 assert len(patterns.personal_patterns) > 0 assert len(patterns.financial_patterns) > 0 assert any("api" in pattern for pattern in patterns.credential_patterns) class TestTaggingConfig: """Test TaggingConfig model.""" def test_tagging_config_defaults(self): """Test TaggingConfig default values.""" config = TaggingConfig() assert len(config.directory_mappings) > 0 assert len(config.tag_hierarchies) > 0 assert len(config.excluded_directories) > 0 assert config.tag_format_rules["case"] == "kebab" def test_get_directory_mapping(self): """Test get_directory_mapping method.""" config = TaggingConfig() mapping = config.get_directory_mapping("100-project/AI/test.md") assert mapping is not None assert mapping.primary_tag == "project" no_mapping = config.get_directory_mapping("unknown/path") assert no_mapping is None def test_get_tag_hierarchy(self): """Test get_tag_hierarchy method.""" config = TaggingConfig() tech_hierarchy = config.get_tag_hierarchy("tech") assert tech_hierarchy is not None assert tech_hierarchy.root == "tech" unknown_hierarchy = config.get_tag_hierarchy("unknown") assert unknown_hierarchy is None def test_is_excluded_directory(self): """Test is_excluded_directory method.""" config = TaggingConfig() assert config.is_excluded_directory(".obsidian/plugins") is True assert config.is_excluded_directory("100-project/AI") is False def test_is_excluded_file(self): """Test is_excluded_file method.""" config = TaggingConfig() assert config.is_excluded_file("test.pyc") is True assert config.is_excluded_file(".DS_Store") is True assert config.is_excluded_file("test.md") is False class TestConfigLoading: """Test configuration loading and saving.""" def test_load_default_config(self): """Test loading default config when no file exists.""" config = load_config() assert isinstance(config, TaggingConfig) assert len(config.directory_mappings) > 0 def test_load_config_creates_default_file(self, tmp_path: Path): """Test that load_config creates default file when path doesn't exist.""" config_path = tmp_path / "config.yaml" config = load_config(config_path) assert isinstance(config, TaggingConfig) assert config_path.exists() def test_save_and_load_config(self, tmp_path: Path): """Test saving and loading configuration.""" config_path = tmp_path / "test_config.yaml" original_config = TaggingConfig() original_config.excluded_directories.append("test_exclude") save_config(original_config, config_path) loaded_config = load_config(config_path) assert config_path.exists() assert "test_exclude" in loaded_config.excluded_directories def test_load_json_config(self, tmp_path: Path): """Test loading JSON configuration.""" config_path = tmp_path / "config.json" config_data = { "excluded_directories": [".test", ".custom"], "tag_format_rules": {"case": "snake"} } with open(config_path, 'w') as f: json.dump(config_data, f) config = load_config(config_path) assert ".test" in config.excluded_directories assert ".custom" in config.excluded_directories assert config.tag_format_rules["case"] == "snake" def test_load_invalid_config_returns_default(self, tmp_path: Path): """Test that invalid config file returns default config.""" config_path = tmp_path / "invalid.yaml" config_path.write_text("invalid: yaml: content: [") config = load_config(config_path) # Should return default config on error assert isinstance(config, TaggingConfig) assert len(config.directory_mappings) > 0