Port upstream tests and rebuilt NIP-09 handling #7

Merged
padreug merged 6 commits from test/port-upstream-tests into main 2026-09-13 16:56:18 +00:00
Showing only changes of commit 06eab1b007 - Show all commits

fix: keep every filter of a multi-filter REQ

_handle_request dropped the subscription's existing filters before
adding each filter of a REQ, so a REQ carrying several filters ended
up with only its last one registered. Remove the old filters once per
REQ instead, before the loop, since a REQ replaces the subscription as
a whole.

Also invert _can_add_filter so its name matches what it returns. The
old version returned "limit exceeded" and the caller tested for that,
so behaviour is unchanged; the tests pin it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013Tbyw6FwjhEJg3gHfPHxWt
(cherry picked from commit 37331b14847cfb5d43f8e97b36a6f52d9b86abae)
Patrick Mulligan 2026-09-13 16:35:29 +02:00 • committed by Padreug

53
tests/test_req_filters.py Normal file
View file

@ -0,0 +1,53 @@
from unittest.mock import AsyncMock, MagicMock
import pytest
from ..relay.client_connection import NostrClientConnection
from ..relay.relay import RelaySpec
RELAY_ID = "relay_req_filters"
def _connection(spec: RelaySpec | None = None) -> NostrClientConnection:
conn = NostrClientConnection(relay_id=RELAY_ID, websocket=MagicMock())
conn.get_client_config = lambda: spec or RelaySpec()
conn._send_msg = AsyncMock() # type: ignore[method-assign]
return conn
def _subscriptions(conn: NostrClientConnection) -> list[str | None]:
return [f.subscription_id for f in conn.filters]
@pytest.mark.asyncio
async def test_multi_filter_req_keeps_every_filter():
conn = _connection()
await conn._handle_message(["REQ", "sub", {"kinds": [1]}, {"kinds": [3]}])
assert _subscriptions(conn) == ["sub", "sub"]
assert sorted(f.kinds for f in conn.filters) == [[1], [3]]
@pytest.mark.asyncio
async def test_new_req_replaces_the_subscription():
conn = _connection()
await conn._handle_message(["REQ", "sub", {"kinds": [1]}, {"kinds": [3]}])
await conn._handle_message(["REQ", "other", {"kinds": [7]}])
await conn._handle_message(["REQ", "sub", {"kinds": [0]}])
assert _subscriptions(conn) == ["other", "sub"]
assert [f.kinds for f in conn.filters] == [[7], [0]]
@pytest.mark.asyncio
async def test_filter_cap_is_enforced():
conn = _connection(RelaySpec(maxClientFilters=2))
await conn._handle_message(["REQ", "a", {"kinds": [1]}])
await conn._handle_message(["REQ", "b", {"kinds": [1]}])
responses = await conn._handle_message(["REQ", "c", {"kinds": [1]}])
assert _subscriptions(conn) == ["a", "b"]
assert responses == [["NOTICE", "Maximum number of filters (2) exceeded."]]