"""Unit tests for file integrity verification.""" import pytest from src.infrastructure.security.file_integrity import ( FileIntegrityManager, get_integrity_manager, ) class TestFileIntegrityManager: """Test the FileIntegrityManager class.""" def test_calculate_checksum(self, tmp_path): """Test checksum calculation for a file.""" # Create a test file test_file = tmp_path / "test.txt" test_file.write_text("Hello, World!") # Create integrity manager with temp checksum file checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) # Calculate checksum checksum = manager.calculate_checksum(test_file) # Verify checksum is a hex string assert isinstance(checksum, str) assert len(checksum) == 64 # SHA256 produces 64 hex chars assert all(c in "0123456789abcdef" for c in checksum) def test_calculate_checksum_nonexistent_file(self, tmp_path): """Test checksum calculation for nonexistent file.""" nonexistent = tmp_path / "nonexistent.txt" checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) with pytest.raises(FileNotFoundError): manager.calculate_checksum(nonexistent) def test_store_and_verify_checksum(self, tmp_path): """Test storing and verifying checksum.""" # Create test file test_file = tmp_path / "test.txt" test_file.write_text("Test content") checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) # Store checksum stored_checksum = manager.store_checksum(test_file) assert isinstance(stored_checksum, str) # Verify checksum assert manager.verify_checksum(test_file) def test_verify_checksum_modified_file(self, tmp_path): """Test checksum verification fails for modified file.""" # Create test file test_file = tmp_path / "test.txt" test_file.write_text("Original content") checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) # Store checksum manager.store_checksum(test_file) # Modify file test_file.write_text("Modified content") # Verification should fail assert not manager.verify_checksum(test_file) def test_verify_checksum_with_expected_value(self, tmp_path): """Test checksum verification with expected value.""" test_file = tmp_path / "test.txt" test_file.write_text("Known content") checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) # Calculate known checksum expected = manager.calculate_checksum(test_file) # Verify with expected checksum assert manager.verify_checksum(test_file, expected) # Verify with wrong checksum wrong_checksum = "a" * 64 assert not manager.verify_checksum(test_file, wrong_checksum) def test_has_checksum(self, tmp_path): """Test checking if checksum exists.""" test_file = tmp_path / "test.txt" test_file.write_text("Content") checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) # Initially no checksum assert not manager.has_checksum(test_file) # Store checksum manager.store_checksum(test_file) # Now has checksum assert manager.has_checksum(test_file) def test_remove_checksum(self, tmp_path): """Test removing checksum.""" test_file = tmp_path / "test.txt" test_file.write_text("Content") checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) # Store checksum manager.store_checksum(test_file) assert manager.has_checksum(test_file) # Remove checksum result = manager.remove_checksum(test_file) assert result is True assert not manager.has_checksum(test_file) # Try to remove again result = manager.remove_checksum(test_file) assert result is False def test_persistence(self, tmp_path): """Test that checksums persist across instances.""" test_file = tmp_path / "test.txt" test_file.write_text("Persistent content") checksum_file = tmp_path / "checksums.json" # Store checksum in first instance manager1 = FileIntegrityManager(checksum_file) manager1.store_checksum(test_file) # Load in second instance manager2 = FileIntegrityManager(checksum_file) assert manager2.has_checksum(test_file) assert manager2.verify_checksum(test_file) def test_get_integrity_manager_singleton(self): """Test that get_integrity_manager returns singleton.""" manager1 = get_integrity_manager() manager2 = get_integrity_manager() assert manager1 is manager2 def test_checksum_file_created_automatically(self, tmp_path): """Test that checksum file is created in data directory.""" test_file = tmp_path / "test.txt" test_file.write_text("Content") checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) # Store checksum manager.store_checksum(test_file) # Verify checksum file was created assert checksum_file.exists() def test_unsupported_algorithm(self, tmp_path): """Test that unsupported hash algorithm raises error.""" test_file = tmp_path / "test.txt" test_file.write_text("Content") checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) with pytest.raises(ValueError, match="Unsupported hash algorithm"): manager.calculate_checksum(test_file, algorithm="invalid") def test_corrupted_checksum_file(self, tmp_path): """Test handling of corrupted checksum file.""" test_file = tmp_path / "test.txt" test_file.write_text("Content") checksum_file = tmp_path / "checksums.json" # Create corrupted checksum file checksum_file.write_text("{ invalid json") # Manager should handle gracefully manager = FileIntegrityManager(checksum_file) assert manager.checksums == {} # Should be able to store new checksum manager.store_checksum(test_file) assert manager.has_checksum(test_file) def test_verify_checksum_no_stored_checksum(self, tmp_path): """Test verification when no checksum is stored.""" test_file = tmp_path / "test.txt" test_file.write_text("Content") checksum_file = tmp_path / "checksums.json" manager = FileIntegrityManager(checksum_file) # Verification should return False assert not manager.verify_checksum(test_file)