# Copyright (c) 2026 Krzysztof Rudnicki. MIT licence. """A deterministic history to run the period, record and streak queries over. Not a conftest fixture: it is a builder several test modules call with a different history each, rather than one shared shape. Counts come from arithmetic, never from ``random`` -- a fixture that changes between runs turns a real failure into a flake. """ from __future__ import annotations from dataclasses import dataclass from typing import TYPE_CHECKING from signal_bot.stats.events import MessageEvent if TYPE_CHECKING: from signal_bot.store import Store GROUP = "group-a==" ALA = ("u-ala", "Ala") KUHY = ("u-kuhy", "kuhy") BASIA = ("u-basia", "Basia") @dataclass(frozen=True, slots=True) class Shape: """The optional detail of a seeded day, so ``wrote`` stays legible.""" media: int = 0 hour: int = 12 chars: int = 10 commands: int = 0 group_id: str = GROUP def wrote( store: Store, day: str, who: tuple[str, str], count: int, shape: Shape | None = None, ) -> None: """Put ``count`` messages from one person into one group on one day.""" shape = shape or Shape() uuid, name = who for index in range(count): store.events.record( MessageEvent( group_id=shape.group_id, uuid=uuid, display_name=name, # Unique within (group, uuid) so the primary key does not # absorb them, and stable so two runs agree. sent_at_ms=int(day.replace("-", "")) * 1000 + index, day=day, local_hour=shape.hour, media_kind="image" if index < shape.media else "", media_count=1 if index < shape.media else 0, char_len=shape.chars, is_command=index < shape.commands, ) ) store.events.note_person(shape.group_id, uuid, name, "", day)