import pytest from src.domain.placement import format_display_string, parse_format_duration, parse_format_string class TestParseFormatString: """Тесты для parse_format_string — парсинг строки формата в (top_minutes, feed_minutes).""" def test_standard_format_1_24(self) -> None: assert parse_format_string('1 / 24') == (60, 1440) def test_standard_format_no_spaces(self) -> None: assert parse_format_string('1/48') == (60, 2880) def test_standard_format_1_72(self) -> None: assert parse_format_string('1 / 72') == (60, 4320) def test_days_format_7(self) -> None: assert parse_format_string('1 / (7 дней)') == (60, 10080) def test_days_format_30(self) -> None: assert parse_format_string('1 / (30 дней)') == (60, 43200) def test_no_deletion(self) -> None: assert parse_format_string('1 / (без удаления)') == (60, 0) def test_no_deletion_no_parens(self) -> None: assert parse_format_string('1 / без удаления') == (60, 0) def test_top_2_hours(self) -> None: assert parse_format_string('2 / 24') == (120, 1440) def test_top_2_no_space(self) -> None: assert parse_format_string('2/48') == (120, 2880) def test_top_2_72(self) -> None: assert parse_format_string('2/72') == (120, 4320) def test_top_minutes_value_30(self) -> None: """Значение > 12 интерпретируется как минуты.""" assert parse_format_string('30 / 24') == (30, 1440) def test_none_input(self) -> None: assert parse_format_string(None) == (None, None) def test_empty_string(self) -> None: assert parse_format_string('') == (None, None) def test_whitespace_string(self) -> None: assert parse_format_string(' ') == (None, None) def test_unparseable_string(self) -> None: assert parse_format_string('пост') == (None, None) def test_no_slash(self) -> None: assert parse_format_string('24') == (None, None) def test_days_short_form(self) -> None: assert parse_format_string('1 / 7д') == (60, 10080) def test_days_short_form_dn(self) -> None: assert parse_format_string('1 / 7 дн') == (60, 10080) def test_with_unit_suffixes(self) -> None: assert parse_format_string('1ч / 24ч') == (60, 1440) def test_with_unit_suffixes_days(self) -> None: assert parse_format_string('1ч / 7д') == (60, 10080) class TestFormatDisplayString: """Тесты для format_display_string — формирование строки из числовых значений.""" def test_hours_hours(self) -> None: assert format_display_string(60, 1440) == '1ч / 24ч' def test_minutes_hours(self) -> None: assert format_display_string(30, 1440) == '30мин / 24ч' def test_no_deletion(self) -> None: assert format_display_string(60, 0) == '1ч / без удаления' def test_days(self) -> None: assert format_display_string(60, 10080) == '1ч / 7д' def test_none_none(self) -> None: assert format_display_string(None, None) is None def test_2h_48h(self) -> None: assert format_display_string(120, 2880) == '2ч / 48ч' def test_2h_30d(self) -> None: assert format_display_string(120, 43200) == '2ч / 30д' def test_top_only(self) -> None: assert format_display_string(60, None) == '1ч / ?' def test_feed_only(self) -> None: assert format_display_string(None, 1440) == '? / 24ч' def test_36h(self) -> None: assert format_display_string(60, 2160) == '1ч / 36ч' def test_72h(self) -> None: assert format_display_string(60, 4320) == '1ч / 72ч' def test_90d(self) -> None: assert format_display_string(60, 129600) == '1ч / 90д' class TestParseFormatDuration: """Тесты обратной совместимости parse_format_duration — возвращает feed time в секундах.""" def test_1_24(self) -> None: assert parse_format_duration('1 / 24') == 86400 def test_1_48(self) -> None: assert parse_format_duration('1/48') == 172800 def test_1_72(self) -> None: assert parse_format_duration('1 / 72') == 259200 def test_7_days(self) -> None: assert parse_format_duration('1 / (7 дней)') == 604800 def test_30_days(self) -> None: assert parse_format_duration('1 / (30 дней)') == 2592000 def test_no_deletion(self) -> None: assert parse_format_duration('1 / (без удаления)') is None def test_none(self) -> None: assert parse_format_duration(None) is None def test_empty(self) -> None: assert parse_format_duration('') is None def test_2_24(self) -> None: assert parse_format_duration('2 / 24') == 86400 class TestRoundtrip: """Тесты round-trip: parse → format → parse.""" @pytest.mark.parametrize( 'top,feed', [ (60, 1440), (60, 2880), (60, 10080), (60, 0), (120, 1440), (120, 43200), (30, 1440), ], ) def test_roundtrip(self, top: int, feed: int) -> None: display = format_display_string(top, feed) assert display is not None parsed_top, parsed_feed = parse_format_string(display) assert parsed_top == top assert parsed_feed == feed