fix(gateway): route kanban notifications to creator profile

This commit is contained in:
Mike Nguyen 2026-05-11 02:43:55 +00:00 committed by Teknium
parent 9e005d6779
commit ba5640fa11
5 changed files with 159 additions and 6 deletions

View file

@ -319,3 +319,113 @@ def test_dispatcher_tick_does_not_call_init_db(kanban_home, monkeypatch):
"_kanban_notifier_watcher must not call _kb.init_db(board=slug) — "
"see issue #21378."
)
@pytest.mark.asyncio
async def test_notifier_skips_subscription_owned_by_other_profile(kanban_home):
"""Each gateway keeps its watcher on, but only the subscribing profile claims."""
import hermes_cli.kanban_db as kb
from gateway.run import GatewayRunner
from gateway.config import Platform
conn = kb.connect()
try:
tid = kb.create_task(conn, title="owned task", assignee="backend-engineer")
kb.add_notify_sub(
conn,
task_id=tid,
platform="telegram",
chat_id="chat1",
notifier_profile="default",
)
kb.complete_task(conn, tid, result="done")
finally:
conn.close()
runner = object.__new__(GatewayRunner)
runner._running = True
runner._kanban_sub_fail_counts = {}
runner._kanban_notifier_profile = "business-partner"
fake_adapter = MagicMock()
fake_adapter.send = AsyncMock()
runner.adapters = {Platform.TELEGRAM: fake_adapter}
_orig_sleep = asyncio.sleep
tick_count = 0
async def _fast_sleep(_):
nonlocal tick_count
await _orig_sleep(0)
tick_count += 1
if tick_count >= 3:
runner._running = False
with patch("gateway.run.asyncio.sleep", side_effect=_fast_sleep):
await asyncio.wait_for(
runner._kanban_notifier_watcher(interval=1),
timeout=10.0,
)
fake_adapter.send.assert_not_called()
conn = kb.connect()
try:
subs = kb.list_notify_subs(conn, tid)
finally:
conn.close()
assert len(subs) == 1
assert int(subs[0]["last_event_id"]) == 0, "wrong profile must not claim the event"
@pytest.mark.asyncio
async def test_notifier_delivers_subscription_owned_by_current_profile(kanban_home):
"""The gateway for the profile that created/subscribed the task reports it."""
import hermes_cli.kanban_db as kb
from gateway.run import GatewayRunner
from gateway.config import Platform
conn = kb.connect()
try:
tid = kb.create_task(conn, title="owned task", assignee="backend-engineer")
kb.add_notify_sub(
conn,
task_id=tid,
platform="telegram",
chat_id="chat1",
notifier_profile="default",
)
kb.complete_task(conn, tid, result="done")
finally:
conn.close()
runner = object.__new__(GatewayRunner)
runner._running = True
runner._kanban_sub_fail_counts = {}
runner._kanban_notifier_profile = "default"
fake_adapter = MagicMock()
async def _send_and_stop(chat_id, msg, metadata=None):
runner._running = False
fake_adapter.send = AsyncMock(side_effect=_send_and_stop)
runner.adapters = {Platform.TELEGRAM: fake_adapter}
_orig_sleep = asyncio.sleep
async def _fast_sleep(_):
await _orig_sleep(0)
with patch("gateway.run.asyncio.sleep", side_effect=_fast_sleep):
await asyncio.wait_for(
runner._kanban_notifier_watcher(interval=1),
timeout=10.0,
)
fake_adapter.send.assert_called_once()
conn = kb.connect()
try:
subs = kb.list_notify_subs(conn, tid)
finally:
conn.close()
assert subs == []