# -*- coding: utf-8 -*- """Чистые функции без сервера: гигиена гостевого текста и гейт «бар открыт».""" import sys from datetime import datetime, timedelta from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from server import BAR_TZ, bar_is_open, next_bar_opening # noqa: E402 from storage import clean_guest_text # noqa: E402 # 2026-10-05 — понедельник; от него строим любой день недели MONDAY = datetime(2026, 10, 5, 12, 0, tzinfo=BAR_TZ) def dt(day: str, hour: int, minute: int = 0) -> datetime: shift = "mon tue wed thu fri sat sun".split().index(day) return MONDAY.replace(hour=hour, minute=minute) + timedelta(days=shift) # ------------------------------------------------------------- clean_guest_text def test_clean_text_removes_hidden_chars(): assert clean_guest_text("Кола\u200b", 60) == "Кола" # zero-width space assert clean_guest_text("\ufeffпиво\u200e", 60) == "пиво" # BOM + LRM assert clean_guest_text("a\x00b\x1f[c]\x7f", 60) == "ab[c]" # control chars assert clean_guest_text("ab\u202edc", 60) == "abdc" # bidi override def test_clean_text_keeps_normal_text_and_emoji(): text = "Столик у окна, пиво 🍺 и — тире" assert clean_guest_text(text, 60) == text def test_clean_text_truncates_to_limit(): assert len(clean_guest_text("х" * 500, 60)) == 60 # ------------------------------------------------------------------ бар открыт? def test_bar_open_in_the_evening(): assert bar_is_open(dt("fri", 21)) is True assert bar_is_open(dt("sat", 21)) is True assert bar_is_open(dt("sun", 20)) is True def test_bar_closed_monday_evening(): # понедельник — вечерних сессий нет (BAR_CLOSED_WEEKDAY) assert bar_is_open(dt("mon", 21)) is False def test_bar_tail_after_midnight(): assert bar_is_open(dt("sat", 2)) is True # хвост пятницы до 03:00 assert bar_is_open(dt("sun", 2)) is True # хвост субботы до 03:00 assert bar_is_open(dt("tue", 0, 30)) is False # во вторник хвоста нет assert bar_is_open(dt("sat", 3, 30)) is False # хвост закончился def test_preorder_window_is_one_hour(): now = dt("fri", 18, 30) opening = next_bar_opening(now) assert opening is not None and (opening - now) <= timedelta(hours=1) now2 = dt("fri", 17, 0) opening2 = next_bar_opening(now2) assert (opening2 - now2) > timedelta(hours=1) def test_next_opening_skips_monday(): # воскресенье 21:00 → ближайшее открытие во вторник 19:00, не в понедельник opening = next_bar_opening(dt("sun", 21)) assert opening is not None assert opening.weekday() == 1 # вторник