Tighten configuration and export handling
This commit is contained in:
@@ -1,22 +1,44 @@
|
||||
import os
|
||||
import sys
|
||||
from io import StringIO
|
||||
from unittest import mock
|
||||
from redmine_reporter.cli import main
|
||||
from redmine_reporter.config import Config
|
||||
|
||||
import pytest
|
||||
|
||||
from redmine_reporter.cli import main, parse_date_range
|
||||
|
||||
VALID_ENV = {
|
||||
"REDMINE_URL": "https://red.eltex.loc",
|
||||
"REDMINE_API_KEY": "token",
|
||||
}
|
||||
|
||||
|
||||
# Config читает env при импорте -- патчим класс напрямую.
|
||||
# fetch_issues_with_spent_time импортируется в cli.py через "from .client import ...",
|
||||
# поэтому мокать нужно имя в модуле cli, а не в client.
|
||||
|
||||
|
||||
@mock.patch.multiple(
|
||||
Config,
|
||||
REDMINE_URL="https://red.eltex.loc",
|
||||
REDMINE_API_KEY=None,
|
||||
REDMINE_USER="x",
|
||||
REDMINE_PASSWORD="y",
|
||||
@pytest.mark.parametrize(
|
||||
"date_arg, expected",
|
||||
[
|
||||
("2026-01-01--2026-01-31", ("2026-01-01", "2026-01-31")),
|
||||
(" 2026-01-01 -- 2026-01-31 ", ("2026-01-01", "2026-01-31")),
|
||||
],
|
||||
)
|
||||
def test_parse_date_range_valid(date_arg, expected):
|
||||
assert parse_date_range(date_arg) == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"date_arg",
|
||||
[
|
||||
"20260101-20260131",
|
||||
"2026-1-01--2026-01-31",
|
||||
"2026-02-30--2026-03-01",
|
||||
"2026-02-01--2026-01-31",
|
||||
],
|
||||
)
|
||||
def test_parse_date_range_invalid(date_arg):
|
||||
with pytest.raises(ValueError):
|
||||
parse_date_range(date_arg)
|
||||
|
||||
|
||||
@mock.patch.dict(os.environ, VALID_ENV, clear=True)
|
||||
@mock.patch("redmine_reporter.cli.fetch_issues_with_spent_time")
|
||||
def test_cli_smoke_empty(mock_fetch):
|
||||
"""Пустой список задач -- выход 0, сообщение о 0 задачах."""
|
||||
@@ -31,13 +53,7 @@ def test_cli_smoke_empty(mock_fetch):
|
||||
assert "Total issues: 0" in captured.getvalue()
|
||||
|
||||
|
||||
@mock.patch.multiple(
|
||||
Config,
|
||||
REDMINE_URL="https://red.eltex.loc",
|
||||
REDMINE_API_KEY=None,
|
||||
REDMINE_USER="x",
|
||||
REDMINE_PASSWORD="y",
|
||||
)
|
||||
@mock.patch.dict(os.environ, VALID_ENV, clear=True)
|
||||
@mock.patch("redmine_reporter.cli.fetch_issues_with_spent_time")
|
||||
def test_cli_returns_zero_on_no_entries(mock_fetch):
|
||||
"""None от fetch (нет time entries) -- выход 0."""
|
||||
@@ -46,32 +62,21 @@ def test_cli_returns_zero_on_no_entries(mock_fetch):
|
||||
assert code == 0
|
||||
|
||||
|
||||
@mock.patch.multiple(
|
||||
Config,
|
||||
REDMINE_URL="",
|
||||
REDMINE_API_KEY=None,
|
||||
REDMINE_USER=None,
|
||||
REDMINE_PASSWORD=None,
|
||||
)
|
||||
@mock.patch.dict(os.environ, {}, clear=True)
|
||||
def test_cli_config_error():
|
||||
"""Невалидный конфиг -- выход 1."""
|
||||
code = main(["--date", "2026-01-01--2026-01-31"])
|
||||
assert code == 1
|
||||
|
||||
|
||||
@mock.patch.dict(os.environ, VALID_ENV, clear=True)
|
||||
def test_cli_invalid_date_format():
|
||||
"""Неверный формат даты -- выход 1."""
|
||||
code = main(["--date", "20260101-20260131"])
|
||||
assert code == 1
|
||||
|
||||
|
||||
@mock.patch.multiple(
|
||||
Config,
|
||||
REDMINE_URL="https://red.eltex.loc",
|
||||
REDMINE_API_KEY=None,
|
||||
REDMINE_USER="x",
|
||||
REDMINE_PASSWORD="y",
|
||||
)
|
||||
@mock.patch.dict(os.environ, VALID_ENV, clear=True)
|
||||
@mock.patch("redmine_reporter.cli.fetch_issues_with_spent_time")
|
||||
def test_cli_unknown_output_extension(mock_fetch, tmp_path):
|
||||
"""Неизвестное расширение файла -- выход 1."""
|
||||
@@ -81,13 +86,7 @@ def test_cli_unknown_output_extension(mock_fetch, tmp_path):
|
||||
assert code == 1
|
||||
|
||||
|
||||
@mock.patch.multiple(
|
||||
Config,
|
||||
REDMINE_URL="https://red.eltex.loc",
|
||||
REDMINE_API_KEY=None,
|
||||
REDMINE_USER="x",
|
||||
REDMINE_PASSWORD="y",
|
||||
)
|
||||
@mock.patch.dict(os.environ, VALID_ENV, clear=True)
|
||||
@mock.patch("redmine_reporter.cli.fetch_issues_with_spent_time")
|
||||
def test_cli_output_without_extension(mock_fetch, tmp_path):
|
||||
"""Файл без расширения -- выход 1 с подсказкой."""
|
||||
|
||||
Reference in New Issue
Block a user