Files
redmine-reporter/tests/test_config.py
Артём Кокос 3a6d1b7ba7 Fix .env override priority and password whitespace stripping
Change load_dotenv() to load_dotenv(override=False) so real environment
variables always take priority over stale .env files. This prevents a
hardcoded or outdated REDMINE_API_KEY in .env from silently overriding
a fresh token exported in the shell (#15).

Add .strip() to get_redmine_password() for consistency with all other
config getters — trailing whitespace in .env no longer causes silent
auth failures (#35).

Closes #15, closes #35
2026-06-25 21:06:19 +07:00

126 lines
3.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
from unittest import mock
import pytest
from redmine_reporter.config import DEFAULT_REDMINE_VERIFY, Config
@mock.patch.dict(
os.environ,
{
"REDMINE_URL": "https://red.eltex.loc/",
"REDMINE_USER": "test",
"REDMINE_PASSWORD": "secret",
},
clear=True,
)
def test_config_valid_with_password_fallback():
Config.validate() # не должно быть исключения
@mock.patch.dict(
os.environ,
{
"REDMINE_URL": "https://red.eltex.loc/",
"REDMINE_API_KEY": "token",
},
clear=True,
)
def test_config_valid_with_api_key():
Config.validate() # не должно быть исключения
@mock.patch.dict(os.environ, {}, clear=True)
def test_config_missing_url():
with pytest.raises(ValueError, match="REDMINE_URL"):
Config.validate()
@mock.patch.dict(os.environ, {"REDMINE_URL": "https://red.eltex.loc/"}, clear=True)
def test_config_missing_auth():
with pytest.raises(ValueError, match="REDMINE_API_KEY"):
Config.validate()
@mock.patch.dict(os.environ, {"REDMINE_URL": " https://red.eltex.loc/ "}, clear=True)
def test_get_redmine_url_strips_spaces_and_trailing_slash():
assert Config.get_redmine_url() == "https://red.eltex.loc"
@mock.patch.dict(os.environ, {"REDMINE_AUTHOR": " Иванов И.И. "}, clear=True)
def test_get_author():
assert Config.get_author("") == "Иванов И.И."
assert Config.get_author("Петров П.П.") == "Петров П.П."
@mock.patch.dict(os.environ, {}, clear=True)
def test_get_author_fallback():
"""Если ни CLI, ни .env не задали автора -- возвращается пустая строка."""
assert Config.get_author("") == ""
@mock.patch.dict(
os.environ,
{
"DEFAULT_FROM_DATE": "2026-01-01",
"DEFAULT_TO_DATE": "2026-01-31",
},
clear=True,
)
def test_get_default_date_range_from_env():
assert Config.get_default_date_range() == "2026-01-01--2026-01-31"
@mock.patch.dict(os.environ, {}, clear=True)
def test_get_default_date_range_fallback():
"""Если даты не заданы -- используется хардкод-заглушка."""
result = Config.get_default_date_range()
assert "--" in result # формат YYYY-MM-DD--YYYY-MM-DD
@mock.patch.dict(os.environ, {}, clear=True)
def test_get_redmine_verify_default():
assert Config.get_redmine_verify() == DEFAULT_REDMINE_VERIFY
@pytest.mark.parametrize("value", ["0", "false", "False", "no", "off"])
def test_get_redmine_verify_false_values(value):
with mock.patch.dict(os.environ, {"REDMINE_VERIFY": value}, clear=True):
assert Config.get_redmine_verify() is False
@pytest.mark.parametrize("value", ["1", "true", "True", "yes", "on"])
def test_get_redmine_verify_true_values(value):
with mock.patch.dict(os.environ, {"REDMINE_VERIFY": value}, clear=True):
assert Config.get_redmine_verify() is True
@mock.patch.dict(os.environ, {"REDMINE_VERIFY": "/tmp/redmine-ca.pem"}, clear=True)
def test_get_redmine_verify_custom_path():
assert Config.get_redmine_verify() == "/tmp/redmine-ca.pem"
# -- #15: .env не должен переопределять переменные окружения --
@mock.patch("dotenv.load_dotenv")
def test_env_var_takes_priority_over_dotenv(mock_load):
"""load_dotenv вызывается с override=False — env vars не перебиваются .env."""
import importlib
from redmine_reporter import config as cfg_mod
importlib.reload(cfg_mod)
mock_load.assert_called_once_with(override=False)
# -- #35: get_redmine_password должен делать .strip() --
@mock.patch.dict(os.environ, {"REDMINE_PASSWORD": " secret123 "}, clear=True)
def test_get_redmine_password_strips_whitespace():
"""Пароль обрезается от whitespace, как и все остальные геттеры."""
assert Config.get_redmine_password() == "secret123"