fix FCM push notifications
This commit is contained in:
1 parent
560d9c19b3
commit
d801a18db5
4 files changed
+177
-6
No files matched your search
@@ -1729,6 +1729,79 @@ async def test_push_skipped_when_backend_unconfigured(adapter):
|
||||
assert fake.calls == []
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_push_deferred_while_turn_active_flushed_on_stop_typing(adapter):
|
||||
"""Turn-aware push: while the agent's turn is in flight (typing on) and
|
||||
the device is offline, intermediate status messages park without a push;
|
||||
the turn-end (stop_typing) flushes ONE push with the latest (final)
|
||||
message. Regression: a long research turn pushed every status report."""
|
||||
fake = _FakePush()
|
||||
adapter._push = fake
|
||||
adapter._devices.upsert(DEVICE_ID, "Test", {}, fcm_token="tok-1")
|
||||
|
||||
await adapter.send_typing("default") # turn starts
|
||||
await adapter.send("default", "researching XXXX", metadata={"notify": True})
|
||||
assert fake.calls == [] # intermediate: held back
|
||||
await adapter.send(
|
||||
"default", "found XXX, cross-referencing", metadata={"notify": True}
|
||||
)
|
||||
assert fake.calls == [] # still held back; latest replaces the pending
|
||||
await adapter.send("default", "done, findings ready", metadata={"notify": True})
|
||||
assert fake.calls == []
|
||||
|
||||
await adapter.stop_typing("default") # turn ends
|
||||
assert len(fake.calls) == 1
|
||||
call = fake.calls[0]
|
||||
assert call["chat_id"] == "default"
|
||||
assert call["data"]["kind"] == "message"
|
||||
assert "done, findings ready" in call["body"]
|
||||
# All frames are parked in the outbox for sync catch-up.
|
||||
assert adapter._outbox.latest_cursor() == 3
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_deferred_push_dropped_when_device_comes_online(adapter, ws_client):
|
||||
"""If the device reconnects mid-turn it syncs the parked frames, so the
|
||||
turn-end flush must not push a duplicate."""
|
||||
ws, _ = ws_client
|
||||
fake = _FakePush()
|
||||
adapter._push = fake
|
||||
adapter._devices.upsert(DEVICE_ID, "Test", {}, fcm_token="tok-1")
|
||||
|
||||
await adapter.send_typing("default")
|
||||
await adapter.send("default", "intermediate", metadata={"notify": True})
|
||||
assert fake.calls == []
|
||||
# Device reconnects mid-turn (SSE open -> on_device_online clears the
|
||||
# pending push); the parked frame arrives via the event stream.
|
||||
frames = await recv_until(ws, lambda f: f.get("type") == "message")
|
||||
assert frames[-1]["payload"]["text"] == "intermediate"
|
||||
await adapter.stop_typing("default")
|
||||
assert fake.calls == []
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_high_priority_notification_pushes_immediately_during_turn(plugin, adapter):
|
||||
"""Approval/clarify/cron notifications need user action: they push
|
||||
immediately even while a turn is in flight and the device is offline."""
|
||||
fake = _FakePush()
|
||||
adapter._push = fake
|
||||
adapter._devices.upsert(DEVICE_ID, "Test", {}, fcm_token="tok-1")
|
||||
|
||||
await adapter.send_typing("default")
|
||||
await adapter._broadcast_or_log(
|
||||
"default",
|
||||
plugin.protocol.notification(
|
||||
"default", plugin.protocol.NOTIF_APPROVAL, "Approve", "run rm -rf?"
|
||||
),
|
||||
)
|
||||
assert len(fake.calls) == 1
|
||||
assert fake.calls[0]["priority"] == "high"
|
||||
assert fake.calls[0]["data"]["kind"] == "approval"
|
||||
|
||||
|
||||
# ── M5: fcm.register ───────────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user