"""Small unit tests: working hours, Bosnian formatting, SMS templates, crypto.""" from datetime import datetime from zoneinfo import ZoneInfo from gogo import crypto from gogo.hours import DEFAULT_WORKING_HOURS, hours_summary_bs, is_open_at from gogo.i18n import fmt_price, fmt_slot from gogo.models import Tenant from gogo.sms.templates import render_sms TZ = ZoneInfo("Europe/Sarajevo") def test_is_open_at(): wh = DEFAULT_WORKING_HOURS assert is_open_at(wh, datetime(2026, 7, 15, 10, 0, tzinfo=TZ), TZ) # Wed 10:00 assert not is_open_at(wh, datetime(2026, 7, 15, 20, 0, tzinfo=TZ), TZ) # Wed 20:00 assert not is_open_at(wh, datetime(2026, 7, 19, 10, 0, tzinfo=TZ), TZ) # Sun assert is_open_at(wh, datetime(2026, 7, 18, 13, 59, tzinfo=TZ), TZ) # Sat 13:59 assert not is_open_at(wh, datetime(2026, 7, 18, 14, 0, tzinfo=TZ), TZ) # Sat 14:00 def test_hours_summary_bs(): s = hours_summary_bs(DEFAULT_WORKING_HOURS) assert "ponedjeljak: 09:00–18:00" in s assert "nedjelja: zatvoreno" in s def test_fmt_slot_bosnian(): dt = datetime(2026, 7, 15, 17, 0, tzinfo=TZ) # Wednesday assert fmt_slot(dt) == "srijeda, 15.07. u 17:00" def test_fmt_price(): assert fmt_price(60, 90) == "60–90 KM" assert fmt_price(25, 25) == "25 KM" assert fmt_price(30, None) == "30 KM" assert fmt_price(None, None) == "cijena na upit" def make_tenant(**kw): defaults = dict(name="Salon Merima", sms_templates={}) defaults.update(kw) return Tenant(**defaults) def test_sms_default_templates(): t = make_tenant() body = render_sms( t, "confirmation", usluga="Manikir", dan="srijeda", datum="15.07.2026.", vrijeme="17:00" ) assert body == "Potvrđen termin: Manikir, srijeda 15.07.2026. u 17:00h — Salon Merima." def test_sms_tenant_override(): t = make_tenant(sms_templates={"rejection": "{salon}: ne može, žao nam je."}) assert render_sms(t, "rejection") == "Salon Merima: ne može, žao nam je." def test_sms_unknown_placeholder_left_intact(): t = make_tenant(sms_templates={"missed_call": "Pozovite {salon} — {nepoznato}"}) assert render_sms(t, "missed_call", link="x") == "Pozovite Salon Merima — {nepoznato}" def test_crypto_roundtrip(): assert crypto.decrypt(crypto.encrypt("tajna-lozinka")) == "tajna-lozinka"