# Copyright (c) 2026 Krzysztof Rudnicki. MIT licence. """Reading the bot's own journal back, without copying names out of it.""" from __future__ import annotations from signal_bot.analytics.journal import parse PREFIX = "2026-08-31T21:28:26+02:00 archlinux run.sh[101862]:" STAMP = "2026-08-31 21:28:26,217" def running(command: str, who: str = "ala") -> str: """One real journal line, in the shape journalctl -o short-iso emits.""" return f"{PREFIX} {STAMP} INFO signal_bot.dispatcher: running command {command} for {who}" def test_a_running_line_is_read() -> None: (line,) = parse([running("cat")]) assert (line.command, line.display_name, line.refused) == ("cat", "ala", False) def test_the_timestamp_comes_from_the_journal_not_the_bot() -> None: """The journal's stamp carries an offset; the bot's asctime does not. A naive stamp read as UTC lands the whole import two hours out, which is exactly what the hour columns exist to get right. """ (line,) = parse([running("cat")]) # 2026-08-31T21:28:26+02:00 is 19:28:26 UTC. assert line.at_ms == 1_788_204_506_000 def test_an_album_command_keeps_its_pseudonym_key() -> None: """`pack:p1`, not `pack`. A \\w+ pattern silently truncates at the colon. That truncation would collapse thirteen different album commands into one, which is the difference between "who is asked for most" and a single meaningless total. """ (line,) = parse([running("pack:p1")]) assert line.command == "pack:p1" def test_a_cooldown_refusal_is_read_as_one() -> None: text = ( f"{PREFIX} {STAMP} INFO signal_bot.decorators: " "cooldown refused cat for ala: told them 8 sekund" ) (line,) = parse([text]) assert (line.command, line.refused) == ("cat", True) def test_a_display_name_with_spaces_survives() -> None: """The pattern runs to end of line, because a display name is free text.""" (line,) = parse([running("cat", "ala z basia")]) assert line.display_name == "ala z basia" def test_lines_that_are_not_about_commands_are_skipped() -> None: """Startup banners, tracebacks, envelope shapes, other units.""" noise = [ "2026-08-31T21:00:00+02:00 archlinux systemd[1474]: Started Signal group bot.", f"{PREFIX} {STAMP} DEBUG signal_bot.dispatcher: envelope shape: {{'a': 'str'}}", "not a journal line at all", "", ] assert list(parse(noise)) == [] def test_a_line_whose_stamp_is_not_a_timestamp_is_skipped() -> None: """Never guess a time. A wrong hour is worse than a missing row.""" assert list(parse(["wednesday archlinux run.sh[1]: running command cat for ala"])) == [] def test_a_naive_stamp_is_refused() -> None: """Without an offset there is no way to know which hour this was.""" text = "2026-08-31T21:28:26 archlinux run.sh[1]: running command cat for ala" assert list(parse([text])) == [] def test_a_dst_boundary_is_read_from_the_offset() -> None: """Warsaw is +02:00 in summer and +01:00 in winter, and both occur. Reading the wall clock and assuming one offset puts half the year's rows an hour out, in a column whose whole purpose is the hour. """ summer = "2026-10-25T02:30:00+02:00 archlinux run.sh[1]: running command cat for ala" winter = "2026-10-25T02:30:00+01:00 archlinux run.sh[1]: running command cat for ala" (early,) = parse([summer]) (late,) = parse([winter]) assert late.at_ms - early.at_ms == 3_600_000