dotb_ai-platform/tests/test_admin_user_application.py

81 lines
2.4 KiB
Python

import pytest
from ai_platform.platform.application.admin_users import (
AdminUserAlreadyExists,
AdminUserUseCases,
)
class Repository:
def __init__(self, *, existing: bool = False, conflict_on_create: bool = False) -> None:
self.existing = existing
self.conflict_on_create = conflict_on_create
self.created: tuple[str, str] | None = None
async def exists(self, email: str) -> bool:
assert email == "admin@example.invalid"
return self.existing
async def create(self, email: str, password_hash: str) -> None:
if self.conflict_on_create:
raise AdminUserAlreadyExists
self.created = (email, password_hash)
class Transaction:
def __init__(self) -> None:
self.commits = 0
self.rollbacks = 0
async def commit(self) -> None:
self.commits += 1
async def rollback(self) -> None:
self.rollbacks += 1
def make_use_case(repository: Repository, transaction: Transaction) -> AdminUserUseCases:
return AdminUserUseCases(
repository=repository,
hash_password=lambda password: f"hashed:{password}",
commit=transaction.commit,
rollback=transaction.rollback,
)
async def test_create_normalizes_email_hashes_password_and_commits():
repository = Repository()
transaction = Transaction()
use_case = make_use_case(repository, transaction)
await use_case.create(" Admin@Example.Invalid ", "test-password")
assert repository.created == ("admin@example.invalid", "hashed:test-password")
assert transaction.commits == 1
assert transaction.rollbacks == 0
async def test_existing_admin_is_rejected_without_mutation():
repository = Repository(existing=True)
transaction = Transaction()
use_case = make_use_case(repository, transaction)
with pytest.raises(AdminUserAlreadyExists):
await use_case.create("admin@example.invalid", "test-password")
assert repository.created is None
assert transaction.commits == 0
assert transaction.rollbacks == 0
async def test_concurrent_duplicate_admin_creation_rolls_back():
repository = Repository(conflict_on_create=True)
transaction = Transaction()
use_case = make_use_case(repository, transaction)
with pytest.raises(AdminUserAlreadyExists):
await use_case.create("admin@example.invalid", "test-password")
assert transaction.commits == 0
assert transaction.rollbacks == 1