component pubsub: PEP implementation:

New implementations of XEP-0355 and XEP-0356 are integrated to handle PEP. The
implementation is not complete yet, as auto-subscribe and presence permissions are not
implemented yet.

rel 476
This commit is contained in:
Goffi 2026-04-14 23:16:18 +02:00
commit 81bd3dcf01
2 changed files with 244 additions and 153 deletions

View file

@ -42,19 +42,34 @@ from libervia.backend.plugins.plugin_xep_0496 import XEP_0496
@fixture(autouse=True)
def setup_xep_0496(host, client):
"""Set up XEP-0496 plugin instance for pubsub tests.
def prepare_for_tests(host, client):
"""Set up important data for testing the pubsub component.
This autouse fixture creates a real XEP_0496 instance so that the actual
permission-checking logic is tested rather than mocked behavior.
It also links the client to the host so PubsubResource can access the plugin.
This creates a real XEP_0496 instance so that the actual permission-checking logic is
tested rather than mocked behavior.
It also links the client to the host so PubsubResource can access the plugin, and mark
it as a component to reflect real workflow.
"""
xep_0496 = XEP_0496(host)
host.plugins["XEP-0496"] = xep_0496
client.is_component = True
client.host = host
return xep_0496
@fixture
def pubsub_resource(client):
"""Create a PubsubResource with proper mocking.
This fixture creates a PubsubResource with a mock service that has
xep_0355.is_pep configured to return False by default (since
pubsub.test.example is not a PEP service).
"""
mock_service = MagicMock(client=client)
mock_service.component.xep_0355.is_pep.return_value = False
return PubsubResource(mock_service)
def make_pubsub_request(
sender: jid.JID,
nodeIdentifier: str | None = None,
@ -68,6 +83,7 @@ def make_pubsub_request(
maxItems: int | None = None,
nodeType: str | None = None,
notify: bool = False,
recipient: jid.JID | None = None,
) -> pubsub.PubSubRequest:
"""Helper to create a PubSubRequest for testing."""
request = pubsub.PubSubRequest()
@ -83,6 +99,7 @@ def make_pubsub_request(
request.maxItems = maxItems
request.nodeType = nodeType
request.notify = notify
request.recipient = recipient
return request
@ -132,17 +149,17 @@ class TestPubsubResourceCreate:
"""Tests for node creation."""
@ed
async def test_creates_node_with_owner_affiliation(self, host, client):
async def test_creates_node_with_owner_affiliation(self, host, pubsub_resource):
"""creating a node sets the creator as owner"""
resource = PubsubResource(MagicMock(client=client))
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
recipient=pubsub_resource.service.client.pubsub_service,
)
host.memory.storage.set_pubsub_node = AsyncMock()
await resource._create(request)
await pubsub_resource._create(request)
# Verify that the creator is set as owner
call_args = host.memory.storage.set_pubsub_node.call_args
@ -153,14 +170,16 @@ class TestPubsubResourceCreate:
assert affiliations[0].affiliation == Affiliation.owner
@ed
async def test_generates_node_id_if_not_provided(self, host, client):
async def test_generates_node_id_if_not_provided(self, host, pubsub_resource):
"""creating a node without ID generates one"""
resource = PubsubResource(MagicMock(client=client))
request = make_pubsub_request(sender=jid.JID("user@test.example"))
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
recipient=pubsub_resource.service.client.pubsub_service,
)
host.memory.storage.set_pubsub_node = AsyncMock()
await resource._create(request)
await pubsub_resource._create(request)
# Verify a node ID was generated and used
call_args = host.memory.storage.set_pubsub_node.call_args
@ -172,14 +191,14 @@ class TestPubsubResourceCreate:
assert node_id.startswith("generic/")
@ed
async def test_raises_conflict_if_node_exists(self, host, client):
async def test_raises_conflict_if_node_exists(self, host, pubsub_resource):
"""creating an existing node raises conflict"""
from libervia.backend.core.exceptions import ConflictError
resource = PubsubResource(MagicMock(client=client))
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="existing_node",
recipient=pubsub_resource.service.client.pubsub_service,
)
# The ConflictError is generated by storage, so we actually check that the
@ -187,16 +206,16 @@ class TestPubsubResourceCreate:
host.memory.storage.set_pubsub_node = AsyncMock(side_effect=ConflictError())
with raises(StanzaError, match="conflict"):
await resource._create(request)
await pubsub_resource._create(request)
class TestPubsubResourcePublish:
"""Tests for item publishing."""
@ed
async def test_rejects_empty_items(self, host, client):
async def test_rejects_empty_items(self, host, client, pubsub_resource):
"""publishing empty items raises bad-request"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -207,9 +226,9 @@ class TestPubsubResourcePublish:
await resource._publish(request)
@ed
async def test_rejects_nonexistent_node(self, host, client):
async def test_rejects_nonexistent_node(self, host, client, pubsub_resource):
"""publishing to nonexistent node raises item_not_found"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="nonexistent_node",
@ -222,9 +241,11 @@ class TestPubsubResourcePublish:
await resource._publish(request)
@ed
async def test_publishers_model_requires_publisher_affiliation(self, host, client):
async def test_publishers_model_requires_publisher_affiliation(
self, host, client, pubsub_resource
):
"""publishers model requires publisher or owner affiliation"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -244,9 +265,9 @@ class TestPubsubResourcePublish:
await resource._publish(request)
@ed
async def test_publishers_model_allows_owner(self, host, client):
async def test_publishers_model_allows_owner(self, host, client, pubsub_resource):
"""publishers model allows owners to publish"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",
@ -268,9 +289,9 @@ class TestPubsubResourcePublish:
host.memory.storage.cache_pubsub_items.assert_called_once()
@ed
async def test_publishers_model_allows_publisher(self, host, client):
async def test_publishers_model_allows_publisher(self, host, client, pubsub_resource):
"""publishers model allows publishers to publish"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("publisher@test.example"),
nodeIdentifier="test_node",
@ -292,9 +313,11 @@ class TestPubsubResourcePublish:
host.memory.storage.cache_pubsub_items.assert_called_once()
@ed
async def test_subscribers_model_requires_subscription(self, host, client):
async def test_subscribers_model_requires_subscription(
self, host, client, pubsub_resource
):
"""subscribers model requires subscription to publish"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -314,9 +337,11 @@ class TestPubsubResourcePublish:
await resource._publish(request)
@ed
async def test_subscribers_model_allows_subscribed_member(self, host, client):
async def test_subscribers_model_allows_subscribed_member(
self, host, client, pubsub_resource
):
"""subscribers model allows subscribed members to publish"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -339,9 +364,9 @@ class TestPubsubResourcePublish:
host.memory.storage.cache_pubsub_items.assert_called_once()
@ed
async def test_generates_item_id_if_missing(self, host, client):
async def test_generates_item_id_if_missing(self, host, client, pubsub_resource):
"""publishing an item without ID generates one"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
item = make_item_element("") # Empty ID
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
@ -370,9 +395,9 @@ class TestPubsubResourcePublish:
assert len(items_data[0].getAttribute("id")) > 0
@ed
async def test_sets_publisher_attribute(self, host, client):
async def test_sets_publisher_attribute(self, host, client, pubsub_resource):
"""publishing sets the publisher attribute on items"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
item = make_item_element("item1")
request = make_pubsub_request(
sender=jid.JID("user@test.example/resource"),
@ -405,9 +430,9 @@ class TestPubsubResourceSubscribe:
"""Tests for subscription management."""
@ed
async def test_rejects_subscribing_for_others(self, host, client):
async def test_rejects_subscribing_for_others(self, host, client, pubsub_resource):
"""subscribing for another user raises forbidden"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -418,9 +443,9 @@ class TestPubsubResourceSubscribe:
await resource._subscribe(request)
@ed
async def test_rejects_nonexistent_node(self, host, client):
async def test_rejects_nonexistent_node(self, host, client, pubsub_resource):
"""subscribing to nonexistent node raises item_not_found"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="nonexistent_node",
@ -433,9 +458,9 @@ class TestPubsubResourceSubscribe:
await resource._subscribe(request)
@ed
async def test_rejects_outcast_users(self, host, client):
async def test_rejects_outcast_users(self, host, client, pubsub_resource):
"""outcast users cannot subscribe"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("outcast@test.example"),
nodeIdentifier="test_node",
@ -454,9 +479,9 @@ class TestPubsubResourceSubscribe:
await resource._subscribe(request)
@ed
async def test_open_model_allows_anyone(self, host, client):
async def test_open_model_allows_anyone(self, host, client, pubsub_resource):
"""open access model allows anyone to subscribe"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -481,9 +506,11 @@ class TestPubsubResourceSubscribe:
)
@ed
async def test_whitelist_model_requires_membership(self, host, client):
async def test_whitelist_model_requires_membership(
self, host, client, pubsub_resource
):
"""whitelist access model requires member affiliation"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -501,9 +528,9 @@ class TestPubsubResourceSubscribe:
await resource._subscribe(request)
@ed
async def test_whitelist_model_allows_member(self, host, client):
async def test_whitelist_model_allows_member(self, host, client, pubsub_resource):
"""whitelist access model allows members to subscribe"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("member@test.example"),
nodeIdentifier="test_node",
@ -531,9 +558,9 @@ class TestPubsubResourceSubscribe:
)
@ed
async def test_rejects_duplicate_pending(self, host, client):
async def test_rejects_duplicate_pending(self, host, client, pubsub_resource):
"""subscribing when already pending raises not-authorized"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -558,9 +585,9 @@ class TestPubsubResourceUnsubscribe:
"""Tests for unsubscription."""
@ed
async def test_rejects_unsubscribing_for_others(self, host, client):
async def test_rejects_unsubscribing_for_others(self, host, client, pubsub_resource):
"""unsubscribing for another user raises forbidden"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -571,9 +598,9 @@ class TestPubsubResourceUnsubscribe:
await resource._unsubscribe(request)
@ed
async def test_rejects_nonexistent_node(self, host, client):
async def test_rejects_nonexistent_node(self, host, client, pubsub_resource):
"""unsubscribing from nonexistent node raises item_not_found"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="nonexistent_node",
@ -586,9 +613,9 @@ class TestPubsubResourceUnsubscribe:
await resource._unsubscribe(request)
@ed
async def test_removes_subscription(self, host, client):
async def test_removes_subscription(self, host, client, pubsub_resource):
"""unsubscribing removes the subscription"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -617,9 +644,9 @@ class TestPubsubResourceItems:
"""Tests for item retrieval."""
@ed
async def test_rejects_nonexistent_node(self, host, client):
async def test_rejects_nonexistent_node(self, host, client, pubsub_resource):
"""retrieving items from nonexistent node raises item_not_found"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="nonexistent_node",
@ -631,9 +658,9 @@ class TestPubsubResourceItems:
await resource._items(request)
@ed
async def test_open_model_allows_anyone(self, host, client):
async def test_open_model_allows_anyone(self, host, client, pubsub_resource):
"""open access model allows anyone to retrieve items"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -651,9 +678,11 @@ class TestPubsubResourceItems:
host.memory.storage.get_items.assert_called_once()
@ed
async def test_whitelist_model_rejects_non_members(self, host, client):
async def test_whitelist_model_rejects_non_members(
self, host, client, pubsub_resource
):
"""whitelist access model rejects non-members"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -670,9 +699,9 @@ class TestPubsubResourceItems:
await resource._items(request)
@ed
async def test_whitelist_model_allows_member(self, host, client):
async def test_whitelist_model_allows_member(self, host, client, pubsub_resource):
"""whitelist access model allows members to retrieve items"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("member@test.example"),
nodeIdentifier="test_node",
@ -697,9 +726,9 @@ class TestPubsubResourceRetract:
"""Tests for item retraction."""
@ed
async def test_rejects_empty_identifiers(self, host, client):
async def test_rejects_empty_identifiers(self, host, client, pubsub_resource):
"""retracting without item identifiers raises bad-request"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -710,9 +739,9 @@ class TestPubsubResourceRetract:
await resource._retract(request)
@ed
async def test_rejects_nonexistent_node(self, host, client):
async def test_rejects_nonexistent_node(self, host, client, pubsub_resource):
"""retracting from nonexistent node raises item_not_found"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="nonexistent_node",
@ -725,9 +754,9 @@ class TestPubsubResourceRetract:
await resource._retract(request)
@ed
async def test_owner_can_retract_any_item(self, host, client):
async def test_owner_can_retract_any_item(self, host, client, pubsub_resource):
"""owners can retract any item from their node"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",
@ -760,9 +789,9 @@ class TestPubsubResourceRetract:
assert call_args.args[1] == ["item1"]
@ed
async def test_publisher_can_retract_any_item(self, host, client):
async def test_publisher_can_retract_any_item(self, host, client, pubsub_resource):
"""publishers can retract any item from their node"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("publisher@test.example"),
nodeIdentifier="test_node",
@ -794,9 +823,9 @@ class TestPubsubResourceRetract:
assert call_args.args[1] == ["item1"]
@ed
async def test_user_can_only_retract_own_items(self, host, client):
async def test_user_can_only_retract_own_items(self, host, client, pubsub_resource):
"""non-owners can only retract their own items"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -824,9 +853,9 @@ class TestPubsubResourceRetract:
await resource._retract(request)
@ed
async def test_user_can_retract_own_items(self, host, client):
async def test_user_can_retract_own_items(self, host, client, pubsub_resource):
"""users can retract their own items"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -863,9 +892,9 @@ class TestPubsubResourcePurge:
"""Tests for node purging."""
@ed
async def test_rejects_nonexistent_node(self, host, client):
async def test_rejects_nonexistent_node(self, host, client, pubsub_resource):
"""purging nonexistent node raises item_not_found"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="nonexistent_node",
@ -877,9 +906,9 @@ class TestPubsubResourcePurge:
await resource._purge(request)
@ed
async def test_only_owners_can_purge(self, host, client):
async def test_only_owners_can_purge(self, host, client, pubsub_resource):
"""only owners can purge a node"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -898,9 +927,9 @@ class TestPubsubResourcePurge:
await resource._purge(request)
@ed
async def test_owner_can_purge(self, host, client):
async def test_owner_can_purge(self, host, client, pubsub_resource):
"""owners can purge their node"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",
@ -929,9 +958,9 @@ class TestPubsubResourceDelete:
"""Tests for node deletion."""
@ed
async def test_rejects_nonexistent_node(self, host, client):
async def test_rejects_nonexistent_node(self, host, client, pubsub_resource):
"""deleting nonexistent node raises item_not_found"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="nonexistent_node",
@ -943,9 +972,9 @@ class TestPubsubResourceDelete:
await resource._delete(request)
@ed
async def test_only_owners_can_delete(self, host, client):
async def test_only_owners_can_delete(self, host, client, pubsub_resource):
"""only owners can delete a node"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -964,9 +993,9 @@ class TestPubsubResourceDelete:
await resource._delete(request)
@ed
async def test_owner_can_delete(self, host, client):
async def test_owner_can_delete(self, host, client, pubsub_resource):
"""owners can delete their node"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",
@ -995,9 +1024,9 @@ class TestPubsubResourceConfigure:
"""Tests for node configuration."""
@ed
async def test_only_owners_can_get_config(self, host, client):
async def test_only_owners_can_get_config(self, host, client, pubsub_resource):
"""only owners can get node configuration"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -1016,9 +1045,9 @@ class TestPubsubResourceConfigure:
await resource._configureGet(request)
@ed
async def test_owner_can_get_config(self, host, client):
async def test_owner_can_get_config(self, host, client, pubsub_resource):
"""owners can get node configuration"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",
@ -1041,9 +1070,9 @@ class TestPubsubResourceConfigure:
assert result["pubsub#publish_model"] == "subscribers"
@ed
async def test_only_owners_can_set_config(self, host, client):
async def test_only_owners_can_set_config(self, host, client, pubsub_resource):
"""only owners can set node configuration"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -1063,9 +1092,9 @@ class TestPubsubResourceConfigure:
await resource._configureSet(request)
@ed
async def test_owner_can_set_config(self, host, client):
async def test_owner_can_set_config(self, host, client, pubsub_resource):
"""owners can set node configuration"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",
@ -1098,9 +1127,9 @@ class TestPubsubResourceAffiliations:
"""Tests for affiliation management."""
@ed
async def test_only_owners_can_get_affiliations(self, host, client):
async def test_only_owners_can_get_affiliations(self, host, client, pubsub_resource):
"""only owners can retrieve all affiliations"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -1119,9 +1148,9 @@ class TestPubsubResourceAffiliations:
await resource._affiliationsGet(request)
@ed
async def test_only_owners_can_set_affiliations(self, host, client):
async def test_only_owners_can_set_affiliations(self, host, client, pubsub_resource):
"""only owners can set affiliations"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -1141,9 +1170,9 @@ class TestPubsubResourceAffiliations:
await resource._affiliationsSet(request)
@ed
async def test_owner_cannot_demote_self(self, host, client):
async def test_owner_cannot_demote_self(self, host, client, pubsub_resource):
"""owners cannot change their own affiliation to non-owner"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",
@ -1167,9 +1196,9 @@ class TestPubsubResourceSubscriptionsGetSet:
"""Tests for subscription management by owners."""
@ed
async def test_only_owners_can_get_subscriptions(self, host, client):
async def test_only_owners_can_get_subscriptions(self, host, client, pubsub_resource):
"""only owners can retrieve all subscriptions"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -1188,9 +1217,9 @@ class TestPubsubResourceSubscriptionsGetSet:
await resource._subscriptionsGet(request)
@ed
async def test_only_owners_can_set_subscriptions(self, host, client):
async def test_only_owners_can_set_subscriptions(self, host, client, pubsub_resource):
"""only owners can set subscriptions"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("user@test.example"),
nodeIdentifier="test_node",
@ -1216,9 +1245,9 @@ class TestPubsubResourceSubscriptionsGetSet:
await resource._subscriptionsSet(request)
@ed
async def test_owner_can_set_subscriptions(self, host, client):
async def test_owner_can_set_subscriptions(self, host, client, pubsub_resource):
"""owners can set subscriptions for entities"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",
@ -1252,9 +1281,9 @@ class TestPubsubResourceSubscriptionsGetSet:
)
@ed
async def test_cannot_subscribe_outcast(self, host, client):
async def test_cannot_subscribe_outcast(self, host, client, pubsub_resource):
"""owners cannot subscribe outcast entities"""
resource = PubsubResource(MagicMock(client=client))
resource = pubsub_resource
request = make_pubsub_request(
sender=jid.JID("owner@test.example"),
nodeIdentifier="test_node",