Files
xiaoxia-saas/tests/unit/test_in_memory_user_repository.py
T
xiaoxia cea83329c8
CI/CD Pipeline / Check if frontend-only change (push) Has been cancelled
CI/CD Pipeline / Validate - Code Quality (push) Has been cancelled
CI/CD Pipeline / Validate - Type Check (mypy) (push) Has been cancelled
CI/CD Pipeline / Validate - Migration (alembic) (push) Has been cancelled
CI/CD Pipeline / Unit Tests (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Lint (push) Has been cancelled
CI/CD Pipeline / Frontend Unit Tests (push) Has been cancelled
CI/CD Pipeline / PR Build API Image (push) Has been cancelled
CI/CD Pipeline / PR Build Web Image (push) Has been cancelled
CI/CD Pipeline / PR Build Worker Image (push) Has been cancelled
CI/CD Pipeline / Build Staging API Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Web Image (push) Has been cancelled
CI/CD Pipeline / Build Staging Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Has been cancelled
CI/CD Pipeline / Staging E2E Tests (push) Has been cancelled
CI/CD Pipeline / Staging API Integration Tests (push) Has been cancelled
CI/CD Pipeline / Build Production API Image (push) Has been cancelled
CI/CD Pipeline / Build Production Web Image (push) Has been cancelled
CI/CD Pipeline / Build Production Worker Image (push) Has been cancelled
CI/CD Pipeline / Deploy Production (push) Has been cancelled
CI/CD Pipeline / Production Browser E2E (push) Has been cancelled
CI/CD Pipeline / ACR Image Cleanup (push) Has been cancelled
test(P3-1): 第58波 in-memory仓储层单测(+57)
2026-07-24 22:03:50 +08:00

190 lines
6.3 KiB
Python
Executable File

"""
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