signal-bot/tests/test_help_album.py
Krzysztof kuhy Rudnicki da016e1b94
Some checks failed
CI / check (push) Has been cancelled
CI / web (push) Has been cancelled
!dodaj lands in a queue; the management page approves it into the album
A photo sent to the chat no longer enters the album by itself. pack_add
strips it, checks it against the album and the queue, and writes it to
pending/ with a sidecar naming the people and labels the sender proposed;
the reply is "czeka na zatwierdzenie". The management page lists the queue
above the tagger, with the proposal pre-ticked, and Approve moves the file
in, mints the labels, records approved_at and asks the bot to rebuild its
table through /_reload -- the same publish path every other data change
takes, so PackHolder.reload is gone. A reload the bot refuses is reported
on the page, not rolled back: the photo is in the album either way.

The personal-data gate now reads pending/*.json too, so a label that is
still waiting for approval is forbidden in the tree already. The e2e run
boots the management page beside the bot with the same environment,
proves the queue is stripped and never reaches media/, approves it through
the real routes, and has !losowe answer with the photo afterwards without
a restart; exiftool is found through media_strip.locate() there rather
than PATH, which lacks vendor_perl on Arch.

!gadaj is dropped from !odcisz: it was within a typo of !dodaj, and the
nearest-command suggestion must never be a coin toss.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-04 22:55:39 +02:00

111 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 DESCRIPTION as ADD_DESCRIPTION
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 f"!dodaj — {ADD_DESCRIPTION}" 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