mirror of
https://github.com/kuhyx/signal-bot.git
synced 2026-11-11 11:57:33 +01:00
Anybody may ask; ten quiet minutes is the whole downside, so there is no trust gate on the way in and no cooldown. The confirmation is the last thing said: below it the dispatcher drops every reply in that group -- commands, the near-miss suggestion, and the nightly report, which is held back (never marked) rather than lost. Messages are still counted. !odcisz is the one command that runs through a mute, and only for TRUSTED_INVITERS; a stranger is refused without a reply, because a refusal is a reply. Unset, anybody may -- the same reading InviteTrust gives an unset variable, now shared as trust.is_trusted. There is deliberately no !unmute alias: it is one edit from !mute, and tests/test_nearest.py forbids two commands within reach of each other. The state is a deadline in group_meta, so it survives a restart and a reload and is cleared with the group. tests/test_help_command.py hit the 250-line cap and its album half moved to tests/test_help_album.py. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
110 lines
4.0 KiB
Python
110 lines
4.0 KiB
Python
# Copyright (c) 2026 Krzysztof Rudnicki. MIT licence.
|
|
"""!pomoc with a photo album: its own headings, and invisible elsewhere.
|
|
|
|
Split out of test_help_command.py at the 250-line cap; the seam is "what
|
|
the album adds to the list", which the other file never registers.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING
|
|
|
|
from signal_bot.help_command import ALBUM_HEADING, PACK_HEADING, render_help
|
|
from signal_bot.pack_add import register_add_command
|
|
from signal_bot.pack_command import register_pack_commands
|
|
from signal_bot.pack_holder import PackHolder
|
|
from signal_bot.pack_load import load as load_pack
|
|
from signal_bot.pack_random import register_random_command
|
|
from tests import pack_fixture
|
|
from tests.conftest import SECOND_GROUP, WATCHED_GROUP
|
|
from tests.test_help_command import full_registry
|
|
|
|
if TYPE_CHECKING:
|
|
from pathlib import Path
|
|
|
|
from signal_bot.media_sniff import MediaKind
|
|
|
|
|
|
def test_an_album_gets_its_own_heading_and_a_hint(tmp_path: Path) -> None:
|
|
"""And the hint is built from real triggers, because they are the example."""
|
|
registry = full_registry()
|
|
register_pack_commands(registry, PackHolder(load_pack(pack_fixture.build(tmp_path / "pack"))))
|
|
|
|
text = render_help(registry.commands, WATCHED_GROUP)
|
|
|
|
assert f"\n{PACK_HEADING}\n" in text
|
|
assert "!alfa — losowe zdjęcie tej osoby" in text
|
|
assert "Kilka naraz (!alfa !beta)" in text
|
|
|
|
|
|
def test_the_album_is_invisible_in_every_other_group(tmp_path: Path) -> None:
|
|
"""The list is what would announce a private command family to strangers."""
|
|
registry = full_registry()
|
|
register_pack_commands(registry, PackHolder(load_pack(pack_fixture.build(tmp_path / "pack"))))
|
|
|
|
text = render_help(registry.commands, SECOND_GROUP)
|
|
|
|
assert PACK_HEADING not in text
|
|
assert "alfa" not in text
|
|
assert "!kot" in text
|
|
|
|
|
|
def test_a_pack_of_one_prints_no_hint(tmp_path: Path) -> None:
|
|
""" "Combine them" needs two things to combine."""
|
|
root = pack_fixture.build(
|
|
tmp_path / "pack",
|
|
people=[{"key": "p1", "triggers": ["!alfa"]}],
|
|
combos=[],
|
|
tags={},
|
|
)
|
|
registry = full_registry()
|
|
register_pack_commands(registry, PackHolder(load_pack(root)))
|
|
|
|
text = render_help(registry.commands, WATCHED_GROUP)
|
|
|
|
assert PACK_HEADING in text
|
|
assert "Kilka naraz" not in text
|
|
|
|
|
|
class _NoStripper:
|
|
"""Registration needs a stripper; rendering help never calls one."""
|
|
|
|
def strip(self, payload: bytes, kind: MediaKind) -> bytes | None:
|
|
return payload
|
|
|
|
|
|
def test_the_album_commands_get_their_own_block(tmp_path: Path) -> None:
|
|
"""Their own heading, so the "kilka naraz" hint keeps describing people.
|
|
|
|
And neither description may name anybody: !pomoc prints them, and the
|
|
trigger is the only place a name is allowed to appear.
|
|
"""
|
|
holder = PackHolder(load_pack(pack_fixture.build(tmp_path / "pack")))
|
|
registry = full_registry()
|
|
register_pack_commands(registry, holder)
|
|
register_random_command(registry, holder, ("!losowe",))
|
|
register_add_command(registry, holder, _NoStripper(), ("!dodaj",))
|
|
|
|
text = render_help(registry.commands, WATCHED_GROUP)
|
|
|
|
assert f"\n{ALBUM_HEADING}\n" in text
|
|
assert "!dodaj — dodaje załączone zdjęcie do albumu z podanymi etykietami" in text
|
|
assert "!losowe — losowe zdjęcie z albumu, opcjonalnie po etykiecie" in text
|
|
# The people's block is still its own, with its own hint.
|
|
assert f"\n{PACK_HEADING}\n" in text
|
|
assert "Kilka naraz (!alfa !beta)" in text
|
|
|
|
|
|
def test_the_album_commands_are_invisible_in_every_other_group(tmp_path: Path) -> None:
|
|
holder = PackHolder(load_pack(pack_fixture.build(tmp_path / "pack")))
|
|
registry = full_registry()
|
|
register_pack_commands(registry, holder)
|
|
register_random_command(registry, holder, ("!losowe",))
|
|
register_add_command(registry, holder, _NoStripper(), ("!dodaj",))
|
|
|
|
text = render_help(registry.commands, SECOND_GROUP)
|
|
|
|
assert ALBUM_HEADING not in text
|
|
assert "!dodaj" not in text
|
|
assert "!losowe" not in text
|