fix: restore .env loading for --init-config

Регрессия от 1df1194 (#64): load_dotenv переехал с module-level в
Config.load_yaml(), но --init-config выходит до этого вызова, поэтому
_run_init_config больше не видел значения из .env — пользователь с
настройками только в .env получал пустой YAML, хотя docs/CONFIG.md
обещает чтение текущих значений из .env.

В начале _run_init_config добавлен load_dotenv(find_dotenv(usecwd=True),
override=False): поиск .env идёт от текущей директории (plain-вызов без
usecwd стартует от директории cli.py и .env пользователя не находит),
переменные окружения не перебиваются. Импорт модуля по-прежнему без
side effects — вызов внутри функции.

Регрессионный тест: test_init_config_reads_dotenv_file (реальный .env
в tmp_path + chdir, без мока os.environ на целевые переменные).

Refs #64
This commit is contained in:
Кокос Артем Николаевич
2026-07-17 14:45:31 +07:00
parent eef09538e6
commit 09f6062e8c
2 changed files with 54 additions and 1 deletions

View File

@@ -425,6 +425,49 @@ class TestInitConfig:
assert data["redmine"]["url"] == ""
assert data["redmine"]["api_key"] == ""
def test_init_config_reads_dotenv_file(self, tmp_path, monkeypatch):
"""#64: --init-config подхватывает значения из реального .env в cwd.
Регрессионный тест: после 1df1194 load_dotenv перестал выполняться
до _run_init_config, и пользователь с настройками только в .env
получал пустой YAML.
"""
import yaml
(tmp_path / ".env").write_text(
"REDMINE_URL=https://redmine.example.com\n"
"REDMINE_API_KEY=secret-from-dotenv\n"
"REDMINE_AUTHOR=ivan.ivanov\n"
"DEFAULT_FROM_DATE=2026-01-01\n"
"DEFAULT_TO_DATE=2026-01-31\n"
"SMTP_PASSWORD=smtp-secret\n"
)
monkeypatch.chdir(tmp_path)
# Целевые переменные не мокаются: значения должны прийти только из .env.
for var in (
"REDMINE_URL",
"REDMINE_API_KEY",
"REDMINE_AUTHOR",
"DEFAULT_FROM_DATE",
"DEFAULT_TO_DATE",
"SMTP_PASSWORD",
):
monkeypatch.delenv(var, raising=False)
config_path = tmp_path / "config.yml"
code = main(["--init-config", "--config-path", str(config_path)])
assert code == 0
with open(config_path) as fh:
data = yaml.safe_load(fh)
assert data["redmine"]["url"] == "https://redmine.example.com"
assert data["redmine"]["api_key"] == "${REDMINE_API_KEY}"
assert data["redmine"]["author"] == "ivan.ivanov"
assert data["period"]["default_from"] == "2026-01-01"
assert data["period"]["default_to"] == "2026-01-31"
assert data["email"]["smtp"]["password"] == "${SMTP_PASSWORD}"
@mock.patch.dict(os.environ, VALID_ENV, clear=True)
def test_init_config_includes_report_section(self, tmp_path):
"""--init-config генерирует секцию report с no_time: false."""