2025-11-08 22:24:11 +01:00
|
|
|
import pytest
|
2025-11-08 22:36:29 +01:00
|
|
|
from unittest.mock import patch
|
2025-11-08 22:24:11 +01:00
|
|
|
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
|