"""Tests for spam detection rule behavior.""" import time from collections import OrderedDict from types import SimpleNamespace from typing import Optional from unittest.mock import MagicMock from umabot.bot import UmaBot from umabot.rules.spam_detector import SpamDetector def make_submission(post_id: str, username: str, created_utc: Optional[float] = None): """Create a submission-like test object.""" return SimpleNamespace( id=post_id, author=SimpleNamespace(name=username), created_utc=created_utc if created_utc is not None else time.time(), ) def make_config(max_posts_per_day: int = 3): """Create a minimal config-like object for tests.""" return SimpleNamespace( max_posts_per_day=max_posts_per_day, subreddit_name="okbuddyumamusume", ) def test_spam_detector_removes_fourth_unique_post_same_day(): """Fourth unique post in the same UTC day should be removed.""" detector = SpamDetector(make_config()) assert detector.should_remove(make_submission("p1", "alice")) is False assert detector.should_remove(make_submission("p2", "alice")) is False assert detector.should_remove(make_submission("p3", "alice")) is False assert detector.should_remove(make_submission("p4", "alice")) is True def test_spam_detector_does_not_double_count_same_submission(): """Seeing the same submission again should not increment the user's count.""" detector = SpamDetector(make_config()) submission = make_submission("p1", "alice") assert detector.should_remove(submission) is False assert detector.should_remove(submission) is False assert detector.should_remove(make_submission("p2", "alice")) is False assert detector.should_remove(make_submission("p3", "alice")) is False assert detector.should_remove(make_submission("p4", "alice")) is True def test_spam_detector_ignores_old_submission_seen_today(): """Old submissions should not be treated as today's posts.""" detector = SpamDetector(make_config()) two_days_ago = time.time() - (2 * 24 * 60 * 60) assert detector.should_remove(make_submission("old", "alice", two_days_ago)) is False assert detector.should_remove(make_submission("p1", "alice")) is False assert detector.should_remove(make_submission("p2", "alice")) is False assert detector.should_remove(make_submission("p3", "alice")) is False def test_cleanup_processed_submissions_prunes_oldest_entries(): """Processed submission cleanup should keep the most recently seen IDs.""" bot = UmaBot.__new__(UmaBot) bot.logger = MagicMock() bot.processed_submissions = OrderedDict((str(i), None) for i in range(1005)) UmaBot._cleanup_processed_submissions(bot) assert len(bot.processed_submissions) == 1000 assert "0" not in bot.processed_submissions assert "4" not in bot.processed_submissions assert "5" in bot.processed_submissions