import pytest from unittest.mock import patch from retoors.helpers.env_manager import ensure_env_file_exists, get_or_create_session_secret_key from cryptography.fernet import Fernet @pytest.fixture def mock_env_path(tmp_path): """Fixture to provide a temporary .env file path.""" return tmp_path / ".env" @pytest.fixture(autouse=True) def mock_dotenv_load(): """Mock dotenv.load_dotenv to prevent actual file loading during tests.""" with patch('dotenv.load_dotenv') as mock_load: yield mock_load def test_ensure_env_file_exists_creates_file(mock_env_path): """Test that .env file is created if it doesn't exist.""" assert not mock_env_path.exists() ensure_env_file_exists(mock_env_path) assert mock_env_path.exists() content = mock_env_path.read_text() assert "PRICE_PER_GB=0.05" in content assert "SMTP_HOST=localhost" in content def test_ensure_env_file_exists_does_not_overwrite(mock_env_path): """Test that .env file is not overwritten if it already exists.""" mock_env_path.write_text("EXISTING_VAR=true\n") ensure_env_file_exists(mock_env_path) assert mock_env_path.exists() content = mock_env_path.read_text() assert "EXISTING_VAR=true" in content # Ensure default content is not added if file already exists assert "PRICE_PER_GB=0.05" not in content @patch('os.getenv') @patch('cryptography.fernet.Fernet.generate_key') def test_get_or_create_session_secret_key_generates_new_key(mock_generate_key, mock_getenv, mock_env_path, mock_dotenv_load): """Test that a new key is generated and saved if not found.""" mock_getenv.return_value = None # Use a dummy key for the mock's return value mock_generate_key.return_value = b'dummy_generated_key_for_testing_1234567890' ensure_env_file_exists(mock_env_path) # Ensure .env exists key = get_or_create_session_secret_key(mock_env_path) assert key == b'dummy_generated_key_for_testing_1234567890' mock_generate_key.assert_called_once() mock_dotenv_load.assert_called_once_with(dotenv_path=mock_env_path) content = mock_env_path.read_text() assert f"SESSION_SECRET_KEY={b'dummy_generated_key_for_testing_1234567890'.decode('utf-8')}" in content @patch('os.getenv') def test_get_or_create_session_secret_key_uses_existing_valid_key(mock_getenv, mock_env_path, mock_dotenv_load): """Test that an existing valid key is used.""" valid_key = Fernet.generate_key() mock_getenv.return_value = valid_key.decode('utf-8') ensure_env_file_exists(mock_env_path) # Ensure .env exists # Write the valid key to the mock .env file for the function to "find" it with open(mock_env_path, 'a') as f: f.write(f'\nSESSION_SECRET_KEY={valid_key.decode("utf-8")}\n') key = get_or_create_session_secret_key(mock_env_path) assert key == valid_key mock_dotenv_load.assert_not_called() # Should not reload if key is found and valid mock_getenv.assert_called_once_with('SESSION_SECRET_KEY') @patch('os.getenv') @patch('cryptography.fernet.Fernet.generate_key') def test_get_or_create_session_secret_key_generates_on_invalid_existing_key(mock_generate_key, mock_getenv, mock_env_path, mock_dotenv_load): """Test that a new key is generated if the existing one is invalid.""" invalid_key_str = "this-is-an-invalid-key" mock_getenv.return_value = invalid_key_str # Use a dummy key for the mock's return value mock_generate_key.return_value = b'another_dummy_key_for_testing_0987654321' ensure_env_file_exists(mock_env_path) # Ensure .env exists # Write the invalid key to the mock .env file with open(mock_env_path, 'a') as f: f.write(f'\nSESSION_SECRET_KEY={invalid_key_str}\n') key = get_or_create_session_secret_key(mock_env_path) assert key == b'another_dummy_key_for_testing_0987654321' mock_generate_key.assert_called_once() mock_dotenv_load.assert_called_once_with(dotenv_path=mock_env_path) content = mock_env_path.read_text() assert f"SESSION_SECRET_KEY={b'another_dummy_key_for_testing_0987654321'.decode('utf-8')}" in content # Ensure the invalid key is effectively replaced or a new one appended # The current implementation appends, so we check for both assert invalid_key_str in content