# Copyright (c) 2026 Krzysztof Rudnicki. MIT licence. """SQLite persistence, including survival across a restart.""" from __future__ import annotations from typing import TYPE_CHECKING from signal_bot.store import Store, open_store if TYPE_CHECKING: from pathlib import Path def test_increment_creates_and_accumulates(store: Store) -> None: store.increment("u1", "Alice") store.increment("u1", "Alice") store.increment("u2", "Bob") assert [(t.display_name, t.count) for t in store.tallies()] == [("Alice", 2), ("Bob", 1)] def test_display_name_is_refreshed(store: Store) -> None: store.increment("u1", "Alice") store.increment("u1", "Alicja") assert store.tallies()[0].display_name == "Alicja" def test_tallies_sorted_by_count_then_name(store: Store) -> None: store.increment("u1", "Zoe") store.increment("u2", "Adam") assert [t.display_name for t in store.tallies()] == ["Adam", "Zoe"] def test_reset_clears_everything(store: Store) -> None: store.increment("u1", "Alice") store.reset_tallies() assert store.tallies() == [] def test_tallies_survive_a_restart(tmp_path: Path) -> None: """The old bot kept the day's tally in a module global.""" db = str(tmp_path / "bot.sqlite3") with open_store(db) as first: first.increment("u1", "Alice") with open_store(db) as second: assert second.tallies()[0].count == 1 def test_last_used_is_none_before_first_use(store: Store) -> None: assert store.last_used("u1", "cat") is None def test_record_use_tracks_cooldown_and_daily(store: Store) -> None: store.record_use("u1", "cat", 100.0, "2026-08-29") assert store.last_used("u1", "cat") == 100.0 assert store.uses_today("u1", "cat", "2026-08-29") == 1 store.record_use("u1", "cat", 200.0, "2026-08-29") assert store.last_used("u1", "cat") == 200.0 assert store.uses_today("u1", "cat", "2026-08-29") == 2 def test_daily_counter_is_per_day(store: Store) -> None: store.record_use("u1", "cat", 100.0, "2026-08-29") assert store.uses_today("u1", "cat", "2026-08-30") == 0 def test_uses_today_is_per_user_and_command(store: Store) -> None: store.record_use("u1", "cat", 100.0, "2026-08-29") assert store.uses_today("u2", "cat", "2026-08-29") == 0 assert store.uses_today("u1", "dog", "2026-08-29") == 0 def test_votes_are_deduplicated_per_person(store: Store) -> None: store.add_vote("traps", "u1", 100.0) store.add_vote("traps", "u1", 101.0) store.add_vote("traps", "u2", 102.0) assert store.count_votes("traps", 0.0) == 2 def test_votes_outside_the_window_are_ignored(store: Store) -> None: store.add_vote("cmd", "u1", 100.0) assert store.count_votes("cmd", 150.0) == 0 def test_clear_votes(store: Store) -> None: store.add_vote("cmd", "u1", 100.0) store.clear_votes("cmd") assert store.count_votes("cmd", 0.0) == 0 def test_store_is_a_context_manager(tmp_path: Path) -> None: with Store(str(tmp_path / "x.sqlite3")) as opened: opened.increment("u1", "Alice") assert opened.tallies.__self__ is opened