Files

151 lines
5.2 KiB
Python
Raw Permalink Normal View History

from __future__ import annotations
from datetime import datetime
from uuid import UUID, uuid4
import pytest
from schemas.enums import NotificationTargetMode
from v1.notifications.service import NotificationService
class _FakeNotification:
def __init__(
self,
*,
id: UUID,
target_mode: NotificationTargetMode = NotificationTargetMode.ALL_USERS,
status: str = "published",
deleted_at: datetime | None = None,
):
self.id = id
self.target_mode = target_mode
self.status = status
self.deleted_at = deleted_at
class _TrackingNotificationRepository:
def __init__(self, notifications: list[_FakeNotification]) -> None:
self._notifications = notifications
self.linked_notification_ids: list[list[UUID]] = []
self.linked_is_first: list[bool] = []
async def link_notifications_for_registered_user(
self, *, user_id: UUID, is_first_registration: bool
) -> int:
target_modes: list[NotificationTargetMode]
if is_first_registration:
target_modes = [
NotificationTargetMode.NEW_USERS,
NotificationTargetMode.ALL_USERS,
]
else:
target_modes = [NotificationTargetMode.ALL_USERS]
matched = [
n
for n in self._notifications
if n.status == "published"
and n.deleted_at is None
and n.target_mode in target_modes
]
self.linked_notification_ids.append([n.id for n in matched])
self.linked_is_first.append(is_first_registration)
return len(matched)
@pytest.fixture
def notification_new_users() -> _FakeNotification:
return _FakeNotification(id=uuid4(), target_mode=NotificationTargetMode.NEW_USERS)
@pytest.fixture
def notification_all_users() -> _FakeNotification:
return _FakeNotification(id=uuid4(), target_mode=NotificationTargetMode.ALL_USERS)
@pytest.fixture
def notification_exist_users() -> _FakeNotification:
return _FakeNotification(id=uuid4(), target_mode=NotificationTargetMode.EXIST_USERS)
class TestLinkNotificationsForRegisteredUser:
@pytest.mark.asyncio
async def test_first_registration_gets_new_users_and_all_users(
self,
notification_new_users: _FakeNotification,
notification_all_users: _FakeNotification,
notification_exist_users: _FakeNotification,
) -> None:
repo = _TrackingNotificationRepository(
[notification_new_users, notification_all_users, notification_exist_users]
)
service = NotificationService(repository=repo) # type: ignore[arg-type]
count = await service.link_notifications_for_registered_user(
user_id=uuid4(), is_first_registration=True
)
assert count == 2
linked_ids = repo.linked_notification_ids[0]
assert notification_new_users.id in linked_ids
assert notification_all_users.id in linked_ids
assert notification_exist_users.id not in linked_ids
@pytest.mark.asyncio
async def test_reregistered_user_only_gets_all_users(
self,
notification_new_users: _FakeNotification,
notification_all_users: _FakeNotification,
notification_exist_users: _FakeNotification,
) -> None:
repo = _TrackingNotificationRepository(
[notification_new_users, notification_all_users, notification_exist_users]
)
service = NotificationService(repository=repo) # type: ignore[arg-type]
count = await service.link_notifications_for_registered_user(
user_id=uuid4(), is_first_registration=False
)
assert count == 1
linked_ids = repo.linked_notification_ids[0]
assert notification_new_users.id not in linked_ids
assert notification_all_users.id in linked_ids
assert notification_exist_users.id not in linked_ids
@pytest.mark.asyncio
async def test_no_published_notifications_returns_zero(self) -> None:
repo = _TrackingNotificationRepository([])
service = NotificationService(repository=repo) # type: ignore[arg-type]
count = await service.link_notifications_for_registered_user(
user_id=uuid4(), is_first_registration=True
)
assert count == 0
@pytest.mark.asyncio
async def test_only_new_users_notification_first_registration(self) -> None:
n = _FakeNotification(id=uuid4(), target_mode=NotificationTargetMode.NEW_USERS)
repo = _TrackingNotificationRepository([n])
service = NotificationService(repository=repo) # type: ignore[arg-type]
count = await service.link_notifications_for_registered_user(
user_id=uuid4(), is_first_registration=True
)
assert count == 1
@pytest.mark.asyncio
async def test_only_new_users_notification_reregistered(self) -> None:
n = _FakeNotification(id=uuid4(), target_mode=NotificationTargetMode.NEW_USERS)
repo = _TrackingNotificationRepository([n])
service = NotificationService(repository=repo) # type: ignore[arg-type]
count = await service.link_notifications_for_registered_user(
user_id=uuid4(), is_first_registration=False
)
assert count == 0