update for mcp
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
"""Tests for the notification store's per-user read-state contract.
|
||||
|
||||
These pin the core property that makes broadcast-to-everyone work without a
|
||||
subscription model: one notification row is shared by all users, and each
|
||||
user's read state is tracked independently against it.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from app.infrastructure.perception.mock_notification_store import MockNotificationStore
|
||||
|
||||
|
||||
def _store_with_one_notification() -> MockNotificationStore:
|
||||
store = MockNotificationStore()
|
||||
store.create(
|
||||
event_id="evt-001",
|
||||
kind="new",
|
||||
title="《电动汽车安全要求》国家标准第三版正式发布",
|
||||
impact_level="high",
|
||||
summary=None,
|
||||
)
|
||||
return store
|
||||
|
||||
|
||||
def test_a_new_notification_is_unread_for_everyone():
|
||||
"""Nobody has read it yet, so unread_count is 1 for any user."""
|
||||
store = _store_with_one_notification()
|
||||
assert store.unread_count("user-a") == 1
|
||||
assert store.unread_count("user-b") == 1
|
||||
|
||||
|
||||
def test_mark_all_read_zeroes_the_count_for_that_user():
|
||||
"""Reading clears the count for the user who read it."""
|
||||
store = _store_with_one_notification()
|
||||
marked = store.mark_all_read("user-a")
|
||||
assert marked == 1
|
||||
assert store.unread_count("user-a") == 0
|
||||
|
||||
|
||||
def test_one_users_read_state_does_not_affect_another():
|
||||
"""The whole point of read receipts over per-user fan-out: independence."""
|
||||
store = _store_with_one_notification()
|
||||
store.mark_all_read("user-a")
|
||||
assert store.unread_count("user-a") == 0
|
||||
assert store.unread_count("user-b") == 1
|
||||
|
||||
|
||||
def test_list_for_user_reports_the_read_flag_correctly():
|
||||
"""The list endpoint must reflect this user's own read state per item."""
|
||||
store = _store_with_one_notification()
|
||||
store.mark_all_read("user-a")
|
||||
|
||||
items_a = store.list_for_user("user-a")
|
||||
items_b = store.list_for_user("user-b")
|
||||
|
||||
assert len(items_a) == 1
|
||||
assert items_a[0]["read"] is True
|
||||
assert items_b[0]["read"] is False
|
||||
|
||||
|
||||
def test_list_for_user_orders_newest_first():
|
||||
"""Notifications appear most-recent-first regardless of creation order."""
|
||||
store = MockNotificationStore()
|
||||
store.create(event_id="evt-1", kind="new", title="first", impact_level="low", summary=None)
|
||||
store.create(event_id="evt-2", kind="new", title="second", impact_level="low", summary=None)
|
||||
|
||||
items = store.list_for_user("user-a")
|
||||
|
||||
assert [item["title"] for item in items] == ["second", "first"]
|
||||
|
||||
|
||||
def test_mark_all_read_is_a_no_op_on_an_empty_feed():
|
||||
"""Reading an empty feed must not raise and reports zero marked."""
|
||||
store = MockNotificationStore()
|
||||
assert store.mark_all_read("user-a") == 0
|
||||
|
||||
|
||||
def test_mark_all_read_does_not_recount_already_read_notifications():
|
||||
"""Calling mark_all_read twice must not double-count as newly marked."""
|
||||
store = _store_with_one_notification()
|
||||
first = store.mark_all_read("user-a")
|
||||
second = store.mark_all_read("user-a")
|
||||
assert first == 1
|
||||
assert second == 0
|
||||
Reference in New Issue
Block a user