tests (unit/AP gateway): tests for item repeat/announce and noticed/like conversion:

Add tests for

- XMPP blog post repeat => AP Announce conversion and vice versa
- XMPP pubsub `noticed` attachment => AP like conversion and vice versa

rel 370
This commit is contained in:
Goffi 2022-07-22 15:45:33 +02:00
commit 155c249884

View file

@ -17,35 +17,37 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from copy import deepcopy
from unittest.mock import MagicMock, AsyncMock, patch, DEFAULT
from urllib import parse
from functools import partial
from typing import Dict, Union
import io
import json
from typing import Any, Dict, Optional, Union
from unittest.mock import AsyncMock, DEFAULT, MagicMock, patch
from urllib import parse
import pytest
from pytest_twisted import ensureDeferred as ed
from treq.response import _Response as TReqResponse
from twisted.internet import defer
from twisted.web.server import Request
from twisted.words.protocols.jabber import jid
from twisted.words.protocols.jabber.error import StanzaError
from twisted.web.server import Request
from twisted.words.xish import domish
from wokkel import rsm, pubsub
from treq.response import _Response as TReqResponse
from wokkel import pubsub, rsm
from sat.core import exceptions
from sat.core.constants import Const as C
from sat.memory.sqla_mapping import SubscriptionState
from sat.plugins import plugin_comp_ap_gateway
from sat.plugins.plugin_comp_ap_gateway import constants as ap_const
from sat.plugins.plugin_comp_ap_gateway import TYPE_ACTOR
from sat.plugins.plugin_comp_ap_gateway.http_server import HTTPServer
from sat.plugins.plugin_xep_0277 import NS_ATOM
from sat.plugins.plugin_xep_0422 import NS_FASTEN
from sat.plugins.plugin_xep_0424 import NS_MESSAGE_RETRACT
from sat.plugins.plugin_xep_0465 import NS_PPS
from sat.tools.utils import xmpp_date
from sat.tools import xml_tools
from sat.tools.common import uri as xmpp_uri
from sat.plugins.plugin_comp_ap_gateway import TYPE_ACTOR
from sat.memory.sqla_mapping import SubscriptionState
from sat.tools.utils import xmpp_date
TEST_BASE_URL = "https://example.org"
@ -362,6 +364,13 @@ XMPP_ITEMS = [
for i in range(1, 5)
]
TEST_USER_DATA = AP_REQUESTS[f"{TEST_BASE_URL}/users/{TEST_USER}"]
OUTBOX_FIRST_PAGE = f"{TEST_BASE_URL}/users/{TEST_USER}/outbox?page=true"
TEST_AP_ITEMS = AP_REQUESTS[OUTBOX_FIRST_PAGE]["orderedItems"]
# request on an item ID must return the ID
for item in TEST_AP_ITEMS:
AP_REQUESTS[item["id"]] = item
async def mock_ap_get(url):
return deepcopy(AP_REQUESTS[url])
@ -649,11 +658,21 @@ class TestActivityPubGateway:
"</title>"
)
def ap_request_params(self, ap_gateway, type_=None, url=None, query_data=None):
def ap_request_params(
self,
ap_gateway,
type_: Optional[str] = None,
url: Optional[str] = None,
doc: Optional[Any] = None,
query_data: Optional[dict] = None,
signing_actor: Optional[str] = None
) -> Dict[str, Any]:
"""Generate parameters for HTTPAPGServer's AP*Request
@param type_: one of the AP query type (e.g. "outbox")
@param url: URL to query (mutually exclusif with type_)
@param doc: if set, a document to embed in content of the request (will be
converted to JSON)
@param query_data: query data as returned by parse.parse_qs
@return dict with kw params to use
"""
@ -676,6 +695,9 @@ class TestActivityPubGateway:
request = Request(MagicMock())
request.path = path.encode()
request.uri = uri.encode()
if doc is not None:
request.content = io.BytesIO(json.dumps(doc).encode())
ap_url = parse.urljoin(
f"https://{ap_gateway.public_url}",
path
@ -686,7 +708,7 @@ class TestActivityPubGateway:
"node": None,
"ap_account": test_jid.full(),
"ap_url": ap_url,
"signing_actor": None
"signing_actor": signing_actor
}
if type_ == "outbox" and query_data:
kwargs["query_data"] = query_data
@ -1350,3 +1372,220 @@ class TestActivityPubGateway:
"name": f"{TEST_AP_ACCOUNT}"
}
assert expected_mention in ap_object["tag"]
@ed
async def test_xmpp_repeat_to_ap_announce(self, ap_gateway, monkeypatch):
"""XEP-0272 post repeat is converted to AP Announce activity"""
monkeypatch.setattr(plugin_comp_ap_gateway.treq, "get", mock_ap_get)
monkeypatch.setattr(plugin_comp_ap_gateway.treq, "json_content", mock_treq_json)
monkeypatch.setattr(ap_gateway, "apGet", mock_ap_get)
# JID repeated AP actor (also the recipient of the message)
recipient_jid = ap_gateway.getLocalJIDFromAccount(TEST_AP_ACCOUNT)
# repeated item
ap_item = TEST_AP_ITEMS[0]
ap_item_url = xmpp_uri.buildXMPPUri(
"pubsub",
path=recipient_jid.full(),
node=ap_gateway._m.namespace,
item=ap_item["id"]
)
item_elt = xml_tools.parse(f"""
<item id="123" publisher="{TEST_JID}/res.123">
<entry xmlns="http://www.w3.org/2005/Atom">
<title type="text">test message 1</title>
<title type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<p>test message 1</p>
</div>
</title>
<author>
<name>test_user</name>
<uri>xmpp:{recipient_jid}</uri>
</author>
<updated>2022-07-21T14:38:53Z</updated>
<published>2022-07-21T14:38:53Z</published>
<id>{ap_item["id"]}</id>
<link href="{ap_item_url}" rel="via"/>
</entry>
</item>
""")
item_elt.uri = pubsub.NS_PUBSUB_EVENT
with patch.object(ap_gateway, "signAndPost") as signAndPost:
signAndPost.return_value.code = 202
await ap_gateway.convertAndPostItems(
ap_gateway.client,
TEST_AP_ACCOUNT,
TEST_JID,
ap_gateway._m.namespace,
[item_elt]
)
assert signAndPost.called
url, actor_id, doc = signAndPost.call_args.args
assert url == TEST_USER_DATA["inbox"]
assert actor_id == ap_gateway.buildAPURL(ap_const.TYPE_ACTOR, TEST_JID.userhost())
assert doc["type"] == "Announce"
assert ap_const.NS_AP_PUBLIC in doc["to"]
assert doc["object"] == ap_item["id"]
@ed
async def test_ap_announce_to_xmpp_repeat(self, ap_gateway, monkeypatch):
"""AP Announce activity is converted to XEP-0272 post repeat"""
monkeypatch.setattr(plugin_comp_ap_gateway.treq, "get", mock_ap_get)
monkeypatch.setattr(plugin_comp_ap_gateway.treq, "json_content", mock_treq_json)
monkeypatch.setattr(ap_gateway, "apGet", mock_ap_get)
xmpp_actor_id = ap_gateway.buildAPURL(ap_const.TYPE_ACTOR, TEST_JID.userhost())
# announced item
xmpp_item = XMPP_ITEMS[0]
xmpp_item_url = ap_gateway.buildAPURL(
ap_const.TYPE_ITEM, TEST_JID.userhost(), xmpp_item["id"]
)
announce = {
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Announce",
"actor": TEST_AP_ACTOR_ID,
"cc": [
xmpp_actor_id,
TEST_USER_DATA["followers"]
],
"id": "https://example.org/announce/123",
"object": xmpp_item_url,
"published": "2022-07-22T09:24:12Z",
"to": [ap_const.NS_AP_PUBLIC]
}
with patch.object(ap_gateway.host.memory.storage, "getItems") as getItems:
mock_pubsub_item = MagicMock
mock_pubsub_item.data = xmpp_item
getItems.return_value = ([mock_pubsub_item], {})
with patch.object(
ap_gateway.host.memory.storage,
"cachePubsubItems") as cachePubsubItems:
await ap_gateway.server.resource.handleAnnounceActivity(
Request(MagicMock()),
announce,
None,
None,
None,
"",
TEST_AP_ACTOR_ID
)
assert cachePubsubItems.called
# the microblog data put in cache correspond to the item sent to subscribers
__, __, __, [mb_data] = cachePubsubItems.call_args.args
extra = mb_data["extra"]
assert "repeated" in extra
repeated = extra["repeated"]
assert repeated["by"] == ap_gateway.getLocalJIDFromAccount(TEST_AP_ACCOUNT).full()
xmpp_item_xmpp_url = xmpp_uri.buildXMPPUri(
"pubsub",
path=TEST_JID.full(),
node=ap_gateway._m.namespace,
item=xmpp_item["id"]
)
assert repeated["uri"] == xmpp_item_xmpp_url
@ed
async def test_xmpp_attachment_noticed_to_ap_like(self, ap_gateway, monkeypatch):
"""Pubsub-attachments ``noticed`` is converted to AP Like activity"""
monkeypatch.setattr(plugin_comp_ap_gateway.treq, "get", mock_ap_get)
monkeypatch.setattr(plugin_comp_ap_gateway.treq, "json_content", mock_treq_json)
monkeypatch.setattr(ap_gateway, "apGet", mock_ap_get)
recipient_jid = ap_gateway.getLocalJIDFromAccount(TEST_AP_ACCOUNT)
# noticed item
ap_item = TEST_AP_ITEMS[0]
ap_item_url = xmpp_uri.buildXMPPUri(
"pubsub",
path=recipient_jid.full(),
node=ap_gateway._m.namespace,
item=ap_item["id"]
)
attachment_node = ap_gateway._pa.getAttachmentNodeName(
recipient_jid,
ap_gateway._m.namespace,
ap_item["id"]
)
item_elt = xml_tools.parse(f"""
<item id="{TEST_JID.userhost()}" published="{TEST_JID.userhostJID()}">
<attachments xmlns="urn:xmpp:pubsub-attachments:0">
<noticed timestamp="2022-07-22T12:29:45Z"/>
</attachments>
</item>
""")
item_elt.uri = pubsub.NS_PUBSUB_EVENT
items_event = pubsub.ItemsEvent(
TEST_JID,
recipient_jid,
attachment_node,
[item_elt],
{}
)
with patch.object(ap_gateway, "signAndPost") as signAndPost:
signAndPost.return_value.code = 202
await ap_gateway._itemsReceived(
ap_gateway.client,
items_event
)
assert signAndPost.called
url, actor_id, doc = signAndPost.call_args.args
assert url == TEST_USER_DATA["inbox"]
assert actor_id == ap_gateway.buildAPURL(ap_const.TYPE_ACTOR, TEST_JID.userhost())
assert doc["type"] == "Like"
assert ap_const.NS_AP_PUBLIC in doc["to"]
assert doc["object"] == ap_item["id"]
@ed
async def test_ap_like_to_xmpp_noticed_attachment(self, ap_gateway, monkeypatch):
"""AP Like activity is converted to ``noticed`` attachment"""
monkeypatch.setattr(plugin_comp_ap_gateway.treq, "get", mock_ap_get)
monkeypatch.setattr(plugin_comp_ap_gateway.treq, "json_content", mock_treq_json)
monkeypatch.setattr(ap_gateway, "apGet", mock_ap_get)
xmpp_actor_id = ap_gateway.buildAPURL(ap_const.TYPE_ACTOR, TEST_JID.userhost())
# liked item
xmpp_item = XMPP_ITEMS[0]
xmpp_item_url = ap_gateway.buildAPURL(
ap_const.TYPE_ITEM, TEST_JID.userhost(), xmpp_item["id"]
)
like = {
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Like",
"actor": TEST_AP_ACTOR_ID,
"cc": [
xmpp_actor_id,
TEST_USER_DATA["followers"]
],
"id": "https://example.org/like/123",
"object": xmpp_item_url,
"published": "2022-07-22T09:24:12Z",
"to": [ap_const.NS_AP_PUBLIC]
}
with patch.object(ap_gateway.host.memory.storage, "getItems") as getItems:
getItems.return_value = ([], {})
with patch.object(ap_gateway._p, "sendItems") as sendItems:
await ap_gateway.server.resource.APInboxRequest(
**self.ap_request_params(
ap_gateway,
"inbox",
doc=like,
signing_actor=TEST_AP_ACTOR_ID
)
)
assert sendItems.called
si_client, si_service, si_node, [si_item] = sendItems.call_args.args
assert si_client.jid == ap_gateway.getLocalJIDFromAccount(TEST_AP_ACCOUNT)
assert si_service == TEST_JID
assert si_node == ap_gateway._pa.getAttachmentNodeName(
TEST_JID, ap_gateway._m.namespace, xmpp_item["id"]
)
[parsed_item] = ap_gateway._pa.items2attachmentData(si_client, [si_item])
assert parsed_item["from"] == si_client.jid.full()
assert "noticed" in parsed_item
assert parsed_item["noticed"]["noticed"] == True