""" In-Memory 用户仓储测试. """ from __future__ import annotations from datetime import datetime import pytest from packages.adapters.in_memory.user_repository import InMemoryUserRepository from packages.domain.entities import User @pytest.fixture def repo(): return InMemoryUserRepository() @pytest.fixture def sample_user(): return User( id="user_1", email="test@example.com", display_name="Test User", username="testuser", password_hash="hashed", email_verified=True, email_verification_token="verify_token", password_reset_token="reset_token", wechat_openid="openid_123", wechat_unionid="unionid_123", phone="13800138000", ) class TestInMemoryUserRepositorySave: """保存用户.""" def test_save_new_user(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_id("user_1") assert found is not None assert found.email == "test@example.com" def test_save_updates_existing(self, repo, sample_user): repo.save(sample_user) sample_user.display_name = "Updated" repo.save(sample_user) found = repo.find_by_id("user_1") assert found.display_name == "Updated" def test_email_index_case_insensitive(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_email("TEST@EXAMPLE.COM") assert found is not None assert found.id == "user_1" def test_username_index_case_insensitive(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_username("TESTUSER") assert found is not None assert found.id == "user_1" class TestInMemoryUserRepositoryFind: """各种查找方式.""" def test_find_by_id_found(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_id("user_1") assert found.id == "user_1" def test_find_by_id_not_found(self, repo): assert repo.find_by_id("nonexistent") is None def test_find_by_email_found(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_email("test@example.com") assert found.id == "user_1" def test_find_by_email_not_found(self, repo): assert repo.find_by_email("no@example.com") is None def test_find_by_username_found(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_username("testuser") assert found.id == "user_1" def test_find_by_username_not_found(self, repo): assert repo.find_by_username("nobody") is None def test_find_by_verification_token(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_verification_token("verify_token") assert found.id == "user_1" def test_find_by_verification_token_not_found(self, repo): assert repo.find_by_verification_token("bad_token") is None def test_find_by_password_reset_token(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_password_reset_token("reset_token") assert found.id == "user_1" def test_find_by_password_reset_token_not_found(self, repo): assert repo.find_by_password_reset_token("bad_token") is None def test_find_by_wechat_openid(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_wechat_openid("openid_123") assert found.id == "user_1" def test_find_by_wechat_openid_not_found(self, repo): assert repo.find_by_wechat_openid("bad_openid") is None def test_find_by_wechat_unionid(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_wechat_unionid("unionid_123") assert found.id == "user_1" def test_find_by_wechat_unionid_empty_returns_none(self, repo): """空 unionid 直接返回 None.""" assert repo.find_by_wechat_unionid("") is None assert repo.find_by_wechat_unionid(None) is None # type: ignore def test_find_by_wechat_unionid_not_found(self, repo): assert repo.find_by_wechat_unionid("bad_unionid") is None def test_find_by_phone(self, repo, sample_user): repo.save(sample_user) found = repo.find_by_phone("13800138000") assert found.id == "user_1" def test_find_by_phone_empty_returns_none(self, repo): assert repo.find_by_phone("") is None assert repo.find_by_phone(None) is None # type: ignore def test_find_by_phone_not_found(self, repo): assert repo.find_by_phone("13900139000") is None def test_user_without_username_not_in_username_index(self, repo): user = User(id="u2", email="no_user@example.com", display_name="No Username") repo.save(user) assert repo.find_by_username("") is None class TestInMemoryUserRepositoryDelete: """删除用户.""" def test_delete_existing(self, repo, sample_user): repo.save(sample_user) result = repo.delete("user_1") assert result is True assert repo.find_by_id("user_1") is None assert repo.find_by_email("test@example.com") is None assert repo.find_by_username("testuser") is None assert repo.find_by_verification_token("verify_token") is None assert repo.find_by_password_reset_token("reset_token") is None def test_delete_nonexistent(self, repo): result = repo.delete("nonexistent") assert result is False def test_delete_cleans_wechat_and_phone_indexes(self, repo, sample_user): repo.save(sample_user) repo.delete("user_1") assert repo.find_by_wechat_openid("openid_123") is None assert repo.find_by_wechat_unionid("unionid_123") is None assert repo.find_by_phone("13800138000") is None class TestInMemoryUserRepositoryMultipleUsers: """多用户场景.""" def test_multiple_users(self, repo): for i in range(5): user = User( id=f"user_{i}", email=f"user{i}@example.com", display_name=f"User {i}", username=f"user{i}", ) repo.save(user) for i in range(5): assert repo.find_by_id(f"user_{i}") is not None assert repo.find_by_email(f"user{i}@example.com") is not None assert repo.find_by_username(f"user{i}") is not None