fix: default report period to current month

Без --date, env и YAML отчёт строится за текущий месяц: начало периода —
1-е число текущего месяца, конец — сегодня (date.today()), согласовано с
fallback default_to→today из #50. Приоритеты источников
(CLI > env > .env > YAML > дефолт) и precision=datetime не затронуты.

Сам fallback уже существовал в коде (хардкод устаревшего периода был
убран ранее); коммит фиксирует поведение детерминированными тестами с
моком date.today (RED проверен регрессионным зондом: при возврате
хардкода 2025-12-19--2026-01-31 тесты падают) и обновляет README и
docs/CONFIG.md: дефолт явно описан как «текущий месяц».

Closes #56
This commit is contained in:
Кокос Артем Николаевич
2026-07-17 13:38:14 +07:00
parent 1df1194f58
commit 1683b0f893
3 changed files with 63 additions and 2 deletions

View File

@@ -129,7 +129,7 @@ DEFAULT_TO_DATE=2026-01-31
| `REDMINE_USER` | Да, если нет токена | Логин Redmine. | | `REDMINE_USER` | Да, если нет токена | Логин Redmine. |
| `REDMINE_PASSWORD` | Да, если нет токена | Пароль Redmine. | | `REDMINE_PASSWORD` | Да, если нет токена | Пароль Redmine. |
| `REDMINE_AUTHOR` | Нет | Имя автора для отчёта. | | `REDMINE_AUTHOR` | Нет | Имя автора для отчёта. |
| `DEFAULT_FROM_DATE` | Нет | Начальная дата периода по умолчанию (`YYYY-MM-DD`). | | `DEFAULT_FROM_DATE` | Нет | Начальная дата периода по умолчанию (`YYYY-MM-DD`). Если не задана (и нет в YAML) — 1-е число текущего месяца. |
| `DEFAULT_TO_DATE` | Нет | Конечная дата периода по умолчанию (`YYYY-MM-DD`). Если не задана, а `DEFAULT_FROM_DATE` задана — используется сегодняшняя дата. | | `DEFAULT_TO_DATE` | Нет | Конечная дата периода по умолчанию (`YYYY-MM-DD`). Если не задана, а `DEFAULT_FROM_DATE` задана — используется сегодняшняя дата. |
| `REDMINE_VERIFY` | Нет | TLS-проверка: `true` (по умолчанию — стандартная проверка средствами requests) / `false` / путь к CA bundle. Семантика совпадает с `redmine.verify_ssl` в YAML. | | `REDMINE_VERIFY` | Нет | TLS-проверка: `true` (по умолчанию — стандартная проверка средствами requests) / `false` / путь к CA bundle. Семантика совпадает с `redmine.verify_ssl` в YAML. |
@@ -141,7 +141,8 @@ source .venv/bin/activate
### Основные сценарии ### Основные сценарии
Отчёт за период по умолчанию: Отчёт за период по умолчанию — текущий месяц (с 1-го числа по сегодня),
если период не задан через `--date`, env или YAML:
```bash ```bash
redmine-reporter redmine-reporter

View File

@@ -107,6 +107,13 @@ period:
Аналогично работает `DEFAULT_TO_DATE`: если переменная не задана, а Аналогично работает `DEFAULT_TO_DATE`: если переменная не задана, а
`DEFAULT_FROM_DATE` задана, конец периода = сегодня. `DEFAULT_FROM_DATE` задана, конец периода = сегодня.
### Период по умолчанию — текущий месяц
Если период не задан ни одним из источников (`--date`, `DEFAULT_FROM_DATE`,
`period.default_from`), отчёт строится за текущий месяц: начало периода —
1-е число текущего месяца, конец — сегодняшняя дата. Период вычисляется
на момент запуска и не хранится в коде или конфиге.
### `--commit` — автофиксация периода ### `--commit` — автофиксация периода
Флаг `--commit` сохраняет использованный период в YAML-конфиг, чтобы следующий запуск автоматически начинался с нового периода. Флаг `--commit` сохраняет использованный период в YAML-конфиг, чтобы следующий запуск автоматически начинался с нового периода.

View File

@@ -99,6 +99,59 @@ def test_get_default_date_range_fallback():
assert result == f"{start.isoformat()}--{today.isoformat()}" assert result == f"{start.isoformat()}--{today.isoformat()}"
# -- #56: дефолтный период — текущий месяц (детерминированные тесты) --
class TestDefaultPeriodIsCurrentMonth:
"""Без --date, env и YAML период = с 1-го числа текущего месяца по сегодня."""
@mock.patch.dict(os.environ, {}, clear=True)
def test_mid_month(self):
from datetime import date
with mock.patch("redmine_reporter.config.date") as mock_date:
mock_date.today.return_value = date(2026, 3, 14)
mock_date.side_effect = lambda *a, **kw: date(*a, **kw)
Config._app = None
assert Config.get_default_date_range() == "2026-03-01--2026-03-14"
@mock.patch.dict(os.environ, {}, clear=True)
def test_first_day_of_month(self):
from datetime import date
with mock.patch("redmine_reporter.config.date") as mock_date:
mock_date.today.return_value = date(2026, 5, 1)
mock_date.side_effect = lambda *a, **kw: date(*a, **kw)
Config._app = None
assert Config.get_default_date_range() == "2026-05-01--2026-05-01"
@mock.patch.dict(os.environ, {}, clear=True)
def test_yaml_default_from_falls_back_to_today(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 default_from: '2026-04-01'\n")
Config._app = AppConfig.from_yaml(yaml_path)
with mock.patch("redmine_reporter.config.date") as mock_date:
mock_date.today.return_value = date(2026, 4, 20)
mock_date.side_effect = lambda *a, **kw: date(*a, **kw)
assert Config.get_default_date_range() == "2026-04-01--2026-04-20"
@mock.patch.dict(os.environ, {"DEFAULT_FROM_DATE": "2026-02-01"}, clear=True)
def test_env_from_without_to_falls_back_to_today(self):
"""DEFAULT_FROM_DATE задана, DEFAULT_TO_DATE нет → конец = сегодня."""
from datetime import date
Config._app = None
with mock.patch("redmine_reporter.config.date") as mock_date:
mock_date.today.return_value = date(2026, 2, 10)
mock_date.side_effect = lambda *a, **kw: date(*a, **kw)
assert Config.get_default_date_range() == "2026-02-01--2026-02-10"
@mock.patch.dict(os.environ, {}, clear=True) @mock.patch.dict(os.environ, {}, clear=True)
def test_get_redmine_verify_default(): def test_get_redmine_verify_default():
"""Без явной настройки проверка TLS включена (стандартные CA requests).""" """Без явной настройки проверка TLS включена (стандартные CA requests)."""