comparison tests/unit/test_ap-gateway.py @ 3994:69d970f974ff

component AP gateway: don't percent-encode `@`: Mastodon doesn't like when "@" is percent-encoded (because it doesn't do it, and it checks that the URL matches the ID without taking care of percent-encoding).
author Goffi <goffi@goffi.org>
date Fri, 10 Feb 2023 17:20:02 +0100
parents acc9dfc8ba8d
children 524856bd7b19
comparison
equal deleted inserted replaced
3993:722c25818778 3994:69d970f974ff
253 f"{TEST_BASE_URL}/users/{TEST_USER}/following?page=1": { 253 f"{TEST_BASE_URL}/users/{TEST_USER}/following?page=1": {
254 "@context": "https://www.w3.org/ns/activitystreams", 254 "@context": "https://www.w3.org/ns/activitystreams",
255 "id": f"{TEST_BASE_URL}/users/{TEST_USER}/following?page=1", 255 "id": f"{TEST_BASE_URL}/users/{TEST_USER}/following?page=1",
256 "orderedItems": [ 256 "orderedItems": [
257 f"{TEST_BASE_URL}/users/ext_user", 257 f"{TEST_BASE_URL}/users/ext_user",
258 f"https://{PUBLIC_URL}/_ap/{TYPE_ACTOR}/local_user%40{PUBLIC_URL}", 258 f"https://{PUBLIC_URL}/_ap/{TYPE_ACTOR}/local_user@{PUBLIC_URL}",
259 ], 259 ],
260 "partOf": "{TEST_BASE_URL}/users/{TEST_USER}/following", 260 "partOf": "{TEST_BASE_URL}/users/{TEST_USER}/following",
261 "totalItems": 2, 261 "totalItems": 2,
262 "type": "OrderedCollectionPage", 262 "type": "OrderedCollectionPage",
263 }, 263 },
271 f"{TEST_BASE_URL}/users/{TEST_USER}/followers?page=1": { 271 f"{TEST_BASE_URL}/users/{TEST_USER}/followers?page=1": {
272 "@context": "https://www.w3.org/ns/activitystreams", 272 "@context": "https://www.w3.org/ns/activitystreams",
273 "id": f"{TEST_BASE_URL}/users/{TEST_USER}/followers?page=1", 273 "id": f"{TEST_BASE_URL}/users/{TEST_USER}/followers?page=1",
274 "orderedItems": [ 274 "orderedItems": [
275 f"{TEST_BASE_URL}/users/ext_user", 275 f"{TEST_BASE_URL}/users/ext_user",
276 f"https://{PUBLIC_URL}/_ap/{TYPE_ACTOR}/local_user%40{PUBLIC_URL}", 276 f"https://{PUBLIC_URL}/_ap/{TYPE_ACTOR}/local_user@{PUBLIC_URL}",
277 ], 277 ],
278 "partOf": "{TEST_BASE_URL}/users/{TEST_USER}/followers", 278 "partOf": "{TEST_BASE_URL}/users/{TEST_USER}/followers",
279 "totalItems": 2, 279 "totalItems": 2,
280 "type": "OrderedCollectionPage", 280 "type": "OrderedCollectionPage",
281 }, 281 },
641 @param query_data: query data as returned by parse.parse_qs 641 @param query_data: query data as returned by parse.parse_qs
642 @return dict with kw params to use 642 @return dict with kw params to use
643 """ 643 """
644 assert type_ and url is None or url and type_ is None 644 assert type_ and url is None or url and type_ is None
645 if type_ is not None: 645 if type_ is not None:
646 path = f"_ap/{type_}/some_user%40test.example" 646 path = f"_ap/{type_}/some_user@test.example"
647 else: 647 else:
648 url_parsed = parse.urlparse(url) 648 url_parsed = parse.urlparse(url)
649 path = url_parsed.path.lstrip("/") 649 path = url_parsed.path.lstrip("/")
650 type_ = path.split("/")[1] 650 type_ = path.split("/")[1]
651 if query_data is None: 651 if query_data is None:
683 monkeypatch.setattr(ap_gateway._p, "getItems", mock_getItems) 683 monkeypatch.setattr(ap_gateway._p, "getItems", mock_getItems)
684 outbox = await ap_gateway.server.resource.APOutboxRequest( 684 outbox = await ap_gateway.server.resource.APOutboxRequest(
685 **self.ap_request_params(ap_gateway, "outbox") 685 **self.ap_request_params(ap_gateway, "outbox")
686 ) 686 )
687 assert outbox["@context"] == ["https://www.w3.org/ns/activitystreams"] 687 assert outbox["@context"] == ["https://www.w3.org/ns/activitystreams"]
688 assert outbox["id"] == "https://test.example/_ap/outbox/some_user%40test.example" 688 assert outbox["id"] == "https://test.example/_ap/outbox/some_user@test.example"
689 assert outbox["totalItems"] == len(XMPP_ITEMS) 689 assert outbox["totalItems"] == len(XMPP_ITEMS)
690 assert outbox["type"] == "OrderedCollection" 690 assert outbox["type"] == "OrderedCollection"
691 assert outbox["first"] 691 assert outbox["first"]
692 assert outbox["last"] 692 assert outbox["last"]
693 693
695 **self.ap_request_params(ap_gateway, url=outbox["first"]) 695 **self.ap_request_params(ap_gateway, url=outbox["first"])
696 ) 696 )
697 assert first_page["@context"] == ["https://www.w3.org/ns/activitystreams"] 697 assert first_page["@context"] == ["https://www.w3.org/ns/activitystreams"]
698 assert ( 698 assert (
699 first_page["id"] 699 first_page["id"]
700 == "https://test.example/_ap/outbox/some_user%40test.example?page=first" 700 == "https://test.example/_ap/outbox/some_user@test.example?page=first"
701 ) 701 )
702 assert first_page["type"] == "OrderedCollectionPage" 702 assert first_page["type"] == "OrderedCollectionPage"
703 assert first_page["partOf"] == outbox["id"] 703 assert first_page["partOf"] == outbox["id"]
704 assert len(first_page["orderedItems"]) == len(XMPP_ITEMS) 704 assert len(first_page["orderedItems"]) == len(XMPP_ITEMS)
705 first_item = first_page["orderedItems"][0] 705 first_item = first_page["orderedItems"][0]
706 assert first_item["@context"] == ["https://www.w3.org/ns/activitystreams"] 706 assert first_item["@context"] == ["https://www.w3.org/ns/activitystreams"]
707 assert ( 707 assert (
708 first_item["id"] == "https://test.example/_ap/item/some_user%40test.example/4" 708 first_item["id"] == "https://test.example/_ap/item/some_user@test.example/4"
709 ) 709 )
710 assert ( 710 assert (
711 first_item["actor"] 711 first_item["actor"]
712 == "https://test.example/_ap/actor/some_user%40test.example" 712 == "https://test.example/_ap/actor/some_user@test.example"
713 ) 713 )
714 assert first_item["type"] == "Create" 714 assert first_item["type"] == "Create"
715 first_item_obj = first_item["object"] 715 first_item_obj = first_item["object"]
716 assert first_item_obj["id"] == first_item["id"] 716 assert first_item_obj["id"] == first_item["id"]
717 assert first_item_obj["type"] == "Note" 717 assert first_item_obj["type"] == "Note"
792 **self.ap_request_params(ap_gateway, "following") 792 **self.ap_request_params(ap_gateway, "following")
793 ) 793 )
794 assert following["@context"] == ["https://www.w3.org/ns/activitystreams"] 794 assert following["@context"] == ["https://www.w3.org/ns/activitystreams"]
795 assert ( 795 assert (
796 following["id"] 796 following["id"]
797 == "https://test.example/_ap/following/some_user%40test.example" 797 == "https://test.example/_ap/following/some_user@test.example"
798 ) 798 )
799 assert following["totalItems"] == len(subscriptions) 799 assert following["totalItems"] == len(subscriptions)
800 assert following["type"] == "OrderedCollection" 800 assert following["type"] == "OrderedCollection"
801 assert following.get("first") 801 assert following.get("first")
802 802
830 **self.ap_request_params(ap_gateway, "followers") 830 **self.ap_request_params(ap_gateway, "followers")
831 ) 831 )
832 assert followers["@context"] == ["https://www.w3.org/ns/activitystreams"] 832 assert followers["@context"] == ["https://www.w3.org/ns/activitystreams"]
833 assert ( 833 assert (
834 followers["id"] 834 followers["id"]
835 == "https://test.example/_ap/followers/some_user%40test.example" 835 == "https://test.example/_ap/followers/some_user@test.example"
836 ) 836 )
837 assert followers["totalItems"] == len(subscribers) 837 assert followers["totalItems"] == len(subscribers)
838 assert followers["type"] == "OrderedCollection" 838 assert followers["type"] == "OrderedCollection"
839 assert followers.get("first") 839 assert followers.get("first")
840 840
859 } 859 }
860 with patch.object(ap_gateway, "signAndPost") as signAndPost: 860 with patch.object(ap_gateway, "signAndPost") as signAndPost:
861 await ap_gateway.onMessage(ap_gateway.client, mess_data) 861 await ap_gateway.onMessage(ap_gateway.client, mess_data)
862 url, actor_id, doc = signAndPost.call_args[0] 862 url, actor_id, doc = signAndPost.call_args[0]
863 assert url == "https://example.org/users/test_user/inbox" 863 assert url == "https://example.org/users/test_user/inbox"
864 assert actor_id == "https://test.example/_ap/actor/some_user%40test.example" 864 assert actor_id == "https://test.example/_ap/actor/some_user@test.example"
865 obj = doc["object"] 865 obj = doc["object"]
866 assert doc["@context"] == ["https://www.w3.org/ns/activitystreams"] 866 assert doc["@context"] == ["https://www.w3.org/ns/activitystreams"]
867 assert doc["actor"] == "https://test.example/_ap/actor/some_user%40test.example" 867 assert doc["actor"] == "https://test.example/_ap/actor/some_user@test.example"
868 assert obj["type"] == "Note" 868 assert obj["type"] == "Note"
869 assert obj["content"] == "This is a test message." 869 assert obj["content"] == "This is a test message."
870 assert obj["attributedTo"] == ( 870 assert obj["attributedTo"] == (
871 "https://test.example/_ap/actor/some_user%40test.example" 871 "https://test.example/_ap/actor/some_user@test.example"
872 ) 872 )
873 # we must have a direct message, thus the item must be only addressed to destinee 873 # we must have a direct message, thus the item must be only addressed to destinee
874 # ("to" attribute of the message), and the "Public" namespace must not be set 874 # ("to" attribute of the message), and the "Public" namespace must not be set
875 assert doc["to"] == ["https://example.org/users/test_user"] 875 assert doc["to"] == ["https://example.org/users/test_user"]
876 assert obj["to"] == ["https://example.org/users/test_user"] 876 assert obj["to"] == ["https://example.org/users/test_user"]
1667 1667
1668 ap_item = await ap_gateway.ap_events.event_data_2_ap_item(event_data, TEST_JID) 1668 ap_item = await ap_gateway.ap_events.event_data_2_ap_item(event_data, TEST_JID)
1669 ap_object = ap_item["object"] 1669 ap_object = ap_item["object"]
1670 actor_id = ( 1670 actor_id = (
1671 "https://test.example/_ap/actor/" 1671 "https://test.example/_ap/actor/"
1672 "___urn.3Axmpp.3Aevents.3A0---some_user%40test.example" 1672 "___urn.3Axmpp.3Aevents.3A0---some_user@test.example"
1673 ) 1673 )
1674 event_id = ( 1674 event_id = (
1675 "https://test.example/_ap/item/" 1675 "https://test.example/_ap/item/"
1676 "___urn.3Axmpp.3Aevents.3A0---some_user%40test.example/event_123" 1676 "___urn.3Axmpp.3Aevents.3A0---some_user@test.example/event_123"
1677 ) 1677 )
1678 assert ap_object["name"] == "test event" 1678 assert ap_object["name"] == "test event"
1679 assert ap_object["actor"] == actor_id 1679 assert ap_object["actor"] == actor_id
1680 assert ap_object["attributedTo"] == actor_id 1680 assert ap_object["attributedTo"] == actor_id
1681 assert ap_object["type"] == "Event" 1681 assert ap_object["type"] == "Event"
1698 assert ap_item["type"] == "Create" 1698 assert ap_item["type"] == "Create"
1699 1699
1700 @ed 1700 @ed
1701 async def test_ap_event_2_xmpp_event(self, ap_gateway): 1701 async def test_ap_event_2_xmpp_event(self, ap_gateway):
1702 """AP events are converted to XMPP events""" 1702 """AP events are converted to XMPP events"""
1703 test_actor = "___urn.3Axmpp.3Aevents.3A0---some_user%40test.example" 1703 test_actor = "___urn.3Axmpp.3Aevents.3A0---some_user@test.example"
1704 ap_object = { 1704 ap_object = {
1705 "actor": f"https://test.example/_ap/actor/{test_actor}", 1705 "actor": f"https://test.example/_ap/actor/{test_actor}",
1706 "attachment": [ 1706 "attachment": [
1707 { 1707 {
1708 "mediaType": "image/jpeg", 1708 "mediaType": "image/jpeg",