"""Unit tests for the config module.""" import unittest import tempfile import os import json from pathlib import Path # Add the src directory to the path import sys sys.path.insert(0, str(Path(__file__).parent.parent / 'src')) from forensictrails.utils.config import Config class TestConfig(unittest.TestCase): """Test cases for Config class.""" def setUp(self): """Set up test fixtures.""" self.temp_dir = tempfile.mkdtemp() self.test_config_path = os.path.join(self.temp_dir, 'test_config.json') def tearDown(self): """Clean up test fixtures.""" if os.path.exists(self.test_config_path): os.remove(self.test_config_path) os.rmdir(self.temp_dir) def test_config_with_valid_file(self): """Test Config loads from valid JSON file.""" config_data = { 'database_path': 'custom.db', 'database_template': 'custom_schema.sql', 'database_schema_version': 2, 'log_path': 'custom.log', 'log_level': 'INFO' } with open(self.test_config_path, 'w') as f: json.dump(config_data, f) config = Config(self.test_config_path) self.assertEqual(config.database_path, 'custom.db') self.assertEqual(config.database_template, 'custom_schema.sql') self.assertEqual(config.database_schema_version, 2) self.assertEqual(config.log_path, 'custom.log') self.assertEqual(config.log_level, 'INFO') def test_config_with_nonexistent_file(self): """Test Config uses defaults when file doesn't exist.""" config = Config('/nonexistent/config.json') # Should use default values self.assertEqual(config.database_template, 'schema.sql') self.assertEqual(config.database_path, 'forensic_trails.db') self.assertEqual(config.database_schema_version, 1) self.assertEqual(config.log_path, 'forensic_trails.log') self.assertEqual(config.log_level, 'DEBUG') def test_config_with_partial_data(self): """Test Config uses defaults for missing keys.""" config_data = { 'database_path': 'partial.db', 'log_level': 'WARNING' } with open(self.test_config_path, 'w') as f: json.dump(config_data, f) config = Config(self.test_config_path) # Should use provided values self.assertEqual(config.database_path, 'partial.db') self.assertEqual(config.log_level, 'WARNING') # Should use defaults for missing keys self.assertEqual(config.database_template, 'schema.sql') self.assertEqual(config.database_schema_version, 1) self.assertEqual(config.log_path, 'forensic_trails.log') def test_config_with_empty_file(self): """Test Config handles empty JSON file.""" with open(self.test_config_path, 'w') as f: json.dump({}, f) config = Config(self.test_config_path) # Should use all defaults self.assertEqual(config.database_template, 'schema.sql') self.assertEqual(config.database_path, 'forensic_trails.db') self.assertEqual(config.database_schema_version, 1) self.assertEqual(config.log_path, 'forensic_trails.log') self.assertEqual(config.log_level, 'DEBUG') def test_config_with_extra_keys(self): """Test Config ignores extra keys in JSON file.""" config_data = { 'database_path': 'test.db', 'extra_key': 'should_be_ignored', 'another_key': 123 } with open(self.test_config_path, 'w') as f: json.dump(config_data, f) config = Config(self.test_config_path) # Should load valid keys self.assertEqual(config.database_path, 'test.db') # Should not have extra attributes self.assertFalse(hasattr(config, 'extra_key')) self.assertFalse(hasattr(config, 'another_key')) def test_config_default_constructor(self): """Test Config uses 'config.json' as default filename.""" # This just tests that it doesn't crash with default parameter # The actual config.json file may or may not exist in the project try: config = Config() # Should have all required attributes self.assertTrue(hasattr(config, 'database_path')) self.assertTrue(hasattr(config, 'database_template')) self.assertTrue(hasattr(config, 'database_schema_version')) self.assertTrue(hasattr(config, 'log_path')) self.assertTrue(hasattr(config, 'log_level')) except Exception as e: self.fail(f"Config() with default parameter raised exception: {e}") class TestConfigDataTypes(unittest.TestCase): """Test cases for Config data type handling.""" def setUp(self): """Set up test fixtures.""" self.temp_dir = tempfile.mkdtemp() self.test_config_path = os.path.join(self.temp_dir, 'test_config.json') def tearDown(self): """Clean up test fixtures.""" if os.path.exists(self.test_config_path): os.remove(self.test_config_path) os.rmdir(self.temp_dir) def test_config_string_values(self): """Test Config handles string values correctly.""" config_data = { 'database_path': 'test.db', 'log_level': 'ERROR' } with open(self.test_config_path, 'w') as f: json.dump(config_data, f) config = Config(self.test_config_path) self.assertIsInstance(config.database_path, str) self.assertIsInstance(config.log_level, str) def test_config_integer_values(self): """Test Config handles integer values correctly.""" config_data = { 'database_schema_version': 5 } with open(self.test_config_path, 'w') as f: json.dump(config_data, f) config = Config(self.test_config_path) self.assertIsInstance(config.database_schema_version, int) self.assertEqual(config.database_schema_version, 5) if __name__ == '__main__': unittest.main()