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)
This commit is contained in:
parent
0c9b7dd407
commit
06eab1b007
1 changed files with 53 additions and 0 deletions
53
tests/test_req_filters.py
Normal file
53
tests/test_req_filters.py
Normal 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."]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue