Files
redmine-reporter/tests/test_utils.py
Кокос Артем Николаевич 5d1cf4ab74 feat: add --my-tasks mode for open assigned issues (#71)
List open Redmine issues assigned to the current (or overridden) user,
sorted by priority rank (P1..P5) then version due date with a stable id
tie-break. Renders an OSC 8 hyperlinked console table on stdout and a
counts/hours summary line on stderr; version due dates are fetched once
per unique version, unavailable versions degrade to an empty due date.

Also migrates the codebase to ruff 0.17.3 defaults (PEP 585/604
annotations, targeted noqa for intentional blind excepts and CLI root
logging). Behavior-neutral: 408 tests pass with -W error.
2026-10-28 15:26:41 +07:00

131 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from redmine_reporter.utils import (
get_month_name_from_range,
get_version,
hours_to_human,
)
def test_hours_to_human_zero():
assert hours_to_human(0) == "0ч"
assert hours_to_human(-1) == "0ч"
def test_hours_to_human_whole_hours():
assert hours_to_human(1.0) == "1ч"
assert hours_to_human(8.0) == "8ч"
def test_hours_to_human_minutes_only():
assert hours_to_human(0.75) == "45м"
assert hours_to_human(0.5) == "30м"
def test_hours_to_human_mixed():
assert hours_to_human(2.5) == "2ч 30м"
assert hours_to_human(1.5) == "1ч 30м"
def test_hours_to_human_rounding():
assert hours_to_human(3.1666) == "3ч 10м" # 190 минут -> 3ч 10м
def test_get_month_name_from_range():
assert get_month_name_from_range("2026-01-01", "2026-01-31") == "Январь"
assert get_month_name_from_range("2025-12-01", "2026-02-15") == "Февраль"
def test_get_month_name_from_range_all_months():
months = [
"Январь",
"Февраль",
"Март",
"Апрель",
"Май",
"Июнь",
"Июль",
"Август",
"Сентябрь",
"Октябрь",
"Ноябрь",
"Декабрь",
]
for i, name in enumerate(months, start=1):
to_date = f"2026-{i:02d}-01"
assert get_month_name_from_range("2026-01-01", to_date) == name
def test_get_month_name_from_range_invalid_fallback():
"""Невалидная дата -- возвращается 'Январь'."""
assert get_month_name_from_range("invalid", "also_invalid") == "Январь"
def test_get_version_with_attribute():
class MockIssue:
fixed_version = "v2.5.0"
assert get_version(MockIssue()) == "v2.5.0"
def test_get_version_without_attribute():
class MockIssue:
pass
assert get_version(MockIssue()) == "<N/A>"
def test_get_version_none_attribute():
class MockIssue:
fixed_version = None
assert get_version(MockIssue()) == "<N/A>"
def test_get_version_with_redminelib_version_object():
"""redminelib Version: str() возвращает ID, .name — человекочитаемое имя."""
class MockVersion:
"""Имитирует redminelib.resources.Version — str() даёт ID."""
def __init__(self, vid, name):
self.id = vid
self.name = name
def __str__(self):
return str(self.id)
class MockIssue:
fixed_version = MockVersion(42, "v2.5.0")
assert get_version(MockIssue()) == "v2.5.0"
def test_get_version_falls_back_to_str_when_no_name():
"""Если у объекта версии нет .name — fallback на str()."""
class MockVersionNoName:
def __str__(self):
return "fallback-id"
class MockIssue:
fixed_version = MockVersionNoName()
assert get_version(MockIssue()) == "fallback-id"
def test_get_version_custom_default():
"""Явный default заменяет <N/A>, когда версия не назначена."""
class MockIssue:
pass
assert get_version(MockIssue(), default="") == ""
def test_get_version_custom_default_not_used_when_version_present():
"""При наличии версии default не применяется."""
class MockIssue:
fixed_version = "v1.0"
assert get_version(MockIssue(), default="") == "v1.0"