"""VerificationCode 领域实体单测.""" from datetime import datetime, timedelta, timezone import pytest from packages.domain.verification_code import VerificationCode class TestVerificationCodeCreate: def test_create_default_ttl(self): code = VerificationCode.create(recipient="test@example.com", code_type="email_bind") assert code.id assert code.recipient == "test@example.com" assert code.code_type == "email_bind" assert len(code.code) == 6 assert code.code.isdigit() assert code.used_at is None assert code.attempts == 0 # 默认5分钟过期 assert code.expires_at > code.created_at assert (code.expires_at - code.created_at).total_seconds() == pytest.approx(300, abs=1) def test_create_custom_ttl(self): code = VerificationCode.create(recipient="13800138000", code_type="phone_login", ttl_seconds=60) assert (code.expires_at - code.created_at).total_seconds() == pytest.approx(60, abs=1) def test_create_custom_code(self): code = VerificationCode.create(recipient="test@example.com", code_type="reset_password", custom_code="123456") assert code.code == "123456" def test_create_recipient_stripped(self): code = VerificationCode.create(recipient=" test@example.com ", code_type="email_bind") assert code.recipient == "test@example.com" class TestVerificationCodeStatus: def test_is_valid_initial(self): code = VerificationCode.create(recipient="test@example.com", code_type="email_bind") assert code.is_valid is True assert code.is_expired is False assert code.is_used is False def test_mark_used(self): code = VerificationCode.create(recipient="test@example.com", code_type="email_bind") code.mark_used() assert code.is_used is True assert code.used_at is not None assert code.is_valid is False def test_is_expired_future(self): code = VerificationCode.create(recipient="test@example.com", code_type="email_bind", ttl_seconds=3600) assert code.is_expired is False def test_increment_attempts(self): code = VerificationCode.create(recipient="test@example.com", code_type="email_bind") assert code.attempts == 0 code.increment_attempts() assert code.attempts == 1 code.increment_attempts() assert code.attempts == 2 def test_is_valid_after_expired(self): code = VerificationCode.create(recipient="test@example.com", code_type="email_bind", ttl_seconds=0) # 0秒TTL,立即可能过期(有极小概率因时间差没过) import time time.sleep(0.01) assert code.is_expired is True assert code.is_valid is False