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:
parent
2cee9c9519
commit
155c249884
1 changed files with 250 additions and 11 deletions
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue