diff --git a/redmine_reporter/config.py b/redmine_reporter/config.py index 11a4e62..7a5bd6f 100644 --- a/redmine_reporter/config.py +++ b/redmine_reporter/config.py @@ -370,8 +370,10 @@ class Config: def get_default_date_range(cls) -> str: from_env = os.getenv("DEFAULT_FROM_DATE", "").strip() to_env = os.getenv("DEFAULT_TO_DATE", "").strip() - if from_env and to_env: - return f"{from_env}--{to_env}" + today_str = date.today().isoformat() + + if from_env: + return f"{from_env}--{to_env or today_str}" if ( cls._app @@ -386,17 +388,12 @@ class Config: ) return f"{nf}--{nt}" - if cls._app and cls._app.period_default_from and cls._app.period_default_to: - return f"{cls._app.period_default_from}--{cls._app.period_default_to}" + if cls._app and cls._app.period_default_from: + default_to = cls._app.period_default_to or today_str + return f"{cls._app.period_default_from}--{default_to}" - today = date.today() - start = today.replace(day=1) - if today.month == 12: - next_month = today.replace(year=today.year + 1, month=1, day=1) - else: - next_month = today.replace(month=today.month + 1, day=1) - end = next_month - timedelta(days=1) - return f"{start.isoformat()}--{end.isoformat()}" + start = date.today().replace(day=1) + return f"{start.isoformat()}--{today_str}" @classmethod def validate(cls) -> None: diff --git a/tests/test_config.py b/tests/test_config.py index 21348d5..c1feb7b 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -79,21 +79,29 @@ 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, + {"DEFAULT_FROM_DATE": "2026-01-01"}, + clear=True, +) +def test_get_default_date_range_from_env_without_to(): + """Если DEFAULT_TO_DATE не задан, конец периода — сегодня.""" + from datetime import date + + today = date.today().isoformat() + assert Config.get_default_date_range() == f"2026-01-01--{today}" + + @mock.patch.dict(os.environ, {}, clear=True) def test_get_default_date_range_fallback(): - """Если даты не заданы -- используется текущий месяц.""" - from datetime import date, timedelta + """Если даты не заданы -- используется текущий месяц с начала до сегодня.""" + from datetime import date today = date.today() start = today.replace(day=1) - if today.month == 12: - next_month = today.replace(year=today.year + 1, month=1, day=1) - else: - next_month = today.replace(month=today.month + 1, day=1) - end = next_month - timedelta(days=1) result = Config.get_default_date_range() - assert result == f"{start.isoformat()}--{end.isoformat()}" + assert result == f"{start.isoformat()}--{today.isoformat()}" @mock.patch.dict(os.environ, {}, clear=True) @@ -567,6 +575,24 @@ class TestDefaultDateRangeWithLastUsed: result = Config.get_default_date_range() assert result == "2026-04-01--2026-04-15" + @mock.patch.dict(os.environ, {}, clear=True) + def test_falls_back_to_today_when_default_to_missing(self): + """Если default_from задан, а default_to нет — конец периода сегодня.""" + from datetime import date + + with tempfile.TemporaryDirectory() as tmp: + yaml_path = Path(tmp) / "config.yml" + yaml_path.write_text( + "period:\n" + " precision: date\n" + " dynamic: false\n" + " default_from: '2026-04-01'\n" + ) + Config._app = AppConfig.from_yaml(yaml_path) + today = date.today().isoformat() + result = Config.get_default_date_range() + assert result == f"2026-04-01--{today}" + class TestGetEmailConfig: """Tests for Config.get_email_config()."""