import sys import pytest from io import StringIO from unittest import mock from redmine_reporter.cli import main from redmine_reporter.config import Config # 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_USER="x", REDMINE_PASSWORD="y", ) @mock.patch("redmine_reporter.cli.fetch_issues_with_spent_time") def test_cli_smoke_empty(mock_fetch): """Пустой список задач -- выход 0, сообщение о 0 задачах.""" mock_fetch.return_value = [] captured = StringIO() old_stdout, sys.stdout = sys.stdout, captured try: code = main(["--date", "2026-01-01--2026-01-31"]) finally: sys.stdout = old_stdout assert code == 0 assert "Total issues: 0" in captured.getvalue() @mock.patch.multiple( Config, REDMINE_URL="https://red.eltex.loc", REDMINE_USER="x", REDMINE_PASSWORD="y", ) @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.""" mock_fetch.return_value = None code = main(["--date", "2026-01-01--2026-01-31"]) assert code == 0 @mock.patch.multiple( Config, REDMINE_URL="", REDMINE_USER=None, REDMINE_PASSWORD=None, ) def test_cli_config_error(): """Невалидный конфиг -- выход 1.""" code = main(["--date", "2026-01-01--2026-01-31"]) assert code == 1 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_USER="x", REDMINE_PASSWORD="y", ) @mock.patch("redmine_reporter.cli.fetch_issues_with_spent_time") def test_cli_unknown_output_extension(mock_fetch, tmp_path): """Неизвестное расширение файла -- выход 1.""" mock_fetch.return_value = [] output = str(tmp_path / "report.xyz") code = main(["--date", "2026-01-01--2026-01-31", "--output", output]) assert code == 1 @mock.patch.multiple( Config, REDMINE_URL="https://red.eltex.loc", REDMINE_USER="x", REDMINE_PASSWORD="y", ) @mock.patch("redmine_reporter.cli.fetch_issues_with_spent_time") def test_cli_output_without_extension(mock_fetch, tmp_path): """Файл без расширения -- выход 1 с подсказкой.""" mock_fetch.return_value = [] output = str(tmp_path / "report") code = main(["--date", "2026-01-01--2026-01-31", "--output", output]) assert code == 1