"""Tests for verification service.""" import pytest from guardden.services.verification import ( ButtonChallengeGenerator, CaptchaChallengeGenerator, ChallengeType, EmojiChallengeGenerator, MathChallengeGenerator, VerificationService, ) class TestChallengeGenerators: """Tests for challenge generators.""" def test_button_challenge(self) -> None: """Test button challenge generation.""" gen = ButtonChallengeGenerator() challenge = gen.generate() assert challenge.challenge_type == ChallengeType.BUTTON assert challenge.answer == "verified" def test_captcha_challenge(self) -> None: """Test captcha challenge generation.""" gen = CaptchaChallengeGenerator(length=6) challenge = gen.generate() assert challenge.challenge_type == ChallengeType.CAPTCHA assert len(challenge.answer) == 6 assert challenge.answer.isalnum() def test_math_challenge(self) -> None: """Test math challenge generation.""" gen = MathChallengeGenerator() challenge = gen.generate() assert challenge.challenge_type == ChallengeType.MATH # Answer should be a number assert challenge.answer.lstrip("-").isdigit() def test_emoji_challenge(self) -> None: """Test emoji challenge generation.""" gen = EmojiChallengeGenerator() challenge = gen.generate() assert challenge.challenge_type == ChallengeType.EMOJI assert len(challenge.options) > 0 assert challenge.answer in challenge.options class TestVerificationService: """Tests for verification service.""" @pytest.fixture def service(self) -> VerificationService: return VerificationService() def test_create_challenge(self, service: VerificationService) -> None: """Test creating a challenge.""" pending = service.create_challenge( user_id=123, guild_id=456, challenge_type=ChallengeType.BUTTON, ) assert pending.user_id == 123 assert pending.guild_id == 456 assert pending.challenge.challenge_type == ChallengeType.BUTTON def test_get_pending(self, service: VerificationService) -> None: """Test retrieving pending verification.""" service.create_challenge(123, 456, ChallengeType.BUTTON) pending = service.get_pending(456, 123) assert pending is not None assert pending.user_id == 123 # Non-existent should return None assert service.get_pending(456, 999) is None def test_verify_correct(self, service: VerificationService) -> None: """Test successful verification.""" service.create_challenge(123, 456, ChallengeType.BUTTON) success, message = service.verify(456, 123, "verified") assert success is True assert "successful" in message.lower() # Should be removed after success assert service.get_pending(456, 123) is None def test_verify_incorrect(self, service: VerificationService) -> None: """Test failed verification.""" service.create_challenge(123, 456, ChallengeType.BUTTON) success, message = service.verify(456, 123, "wrong") assert success is False assert "incorrect" in message.lower() # Should still exist assert service.get_pending(456, 123) is not None def test_verify_max_attempts(self, service: VerificationService) -> None: """Test max attempts exceeded.""" service.create_challenge(123, 456, ChallengeType.BUTTON) # Use up all attempts for _ in range(3): service.verify(456, 123, "wrong") success, message = service.verify(456, 123, "verified") assert success is False assert "too many" in message.lower() def test_verify_no_pending(self, service: VerificationService) -> None: """Test verification with no pending challenge.""" success, message = service.verify(456, 123, "verified") assert success is False assert "no pending" in message.lower() def test_cancel(self, service: VerificationService) -> None: """Test canceling verification.""" service.create_challenge(123, 456, ChallengeType.BUTTON) assert service.cancel(456, 123) is True assert service.get_pending(456, 123) is None # Cancel non-existent returns False assert service.cancel(456, 123) is False def test_pending_count(self, service: VerificationService) -> None: """Test pending count per guild.""" service.create_challenge(1, 456, ChallengeType.BUTTON) service.create_challenge(2, 456, ChallengeType.BUTTON) service.create_challenge(3, 789, ChallengeType.BUTTON) assert service.get_pending_count(456) == 2 assert service.get_pending_count(789) == 1 assert service.get_pending_count(999) == 0