Merge branch 'develop' into phoenix1.7

This commit is contained in:
Mark Felder 2023-11-07 16:05:04 -05:00
commit a0e08c6ec2
251 changed files with 6494 additions and 1976 deletions

View file

@ -0,0 +1 @@
{"version":"2.0","software":{"name":"mastodon","version":"4.1.0"},"protocols":["activitypub"],"services":{"outbound":[],"inbound":[]},"usage":{"users":{"total":971090,"activeMonth":167218,"activeHalfyear":384808},"localPosts":52071541},"openRegistrations":true,"metadata":{}}

View file

@ -0,0 +1 @@
{"links":[{"rel":"http://nodeinfo.diaspora.software/ns/schema/2.0","href":"https://mastodon.example.org/nodeinfo/2.0"}]}

View file

@ -0,0 +1,54 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"ostatus": "http://ostatus.org#",
"atomUri": "ostatus:atomUri",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"sensitive": "as:sensitive",
"toot": "http://joinmastodon.org/ns#",
"votersCount": "toot:votersCount",
"fedibird": "http://fedibird.com/ns#",
"quoteUri": "fedibird:quoteUri",
"expiry": "fedibird:expiry"
}
],
"id": "https://fedibird.com/users/noellabo/statuses/107712183700212249",
"type": "Note",
"summary": null,
"inReplyTo": null,
"published": "2022-01-30T15:44:50Z",
"url": "https://fedibird.com/@noellabo/107712183700212249",
"attributedTo": "https://fedibird.com/users/noellabo",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://fedibird.com/users/noellabo/followers"
],
"sensitive": false,
"atomUri": "https://fedibird.com/users/noellabo/statuses/107712183700212249",
"inReplyToAtomUri": null,
"conversation": "tag:fedibird.com,2022-01-30:objectId=107712183700170473:objectType=Conversation",
"context": "https://fedibird.com/contexts/107712183700170473",
"quoteUri": "https://unnerv.jp/users/UN_NERV/statuses/107712176849067434",
"_misskey_quote": "https://unnerv.jp/users/UN_NERV/statuses/107712176849067434",
"_misskey_content": "揺れていたようだ",
"content": "<p>揺れていたようだ<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"UN_NERV@unnerv.jp\" data-status-id=\"107712177062934465\" href=\"https://unnerv.jp/@UN_NERV/107712176849067434\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">unnerv.jp/@UN_NERV/10771217684</span><span class=\"invisible\">9067434</span></a></span></p>",
"contentMap": {
"ja": "<p>揺れていたようだ<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"UN_NERV@unnerv.jp\" data-status-id=\"107712177062934465\" href=\"https://unnerv.jp/@UN_NERV/107712176849067434\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">unnerv.jp/@UN_NERV/10771217684</span><span class=\"invisible\">9067434</span></a></span></p>"
},
"attachment": [],
"tag": [],
"replies": {
"id": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies?only_other_accounts=true&page=true",
"partOf": "https://fedibird.com/users/noellabo/statuses/107712183700212249/replies",
"items": []
}
}
}

View file

@ -0,0 +1,52 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"ostatus": "http://ostatus.org#",
"atomUri": "ostatus:atomUri",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"sensitive": "as:sensitive",
"toot": "http://joinmastodon.org/ns#",
"votersCount": "toot:votersCount",
"expiry": "toot:expiry"
}
],
"id": "https://fedibird.com/users/noellabo/statuses/107663670404015196",
"type": "Note",
"summary": null,
"inReplyTo": null,
"published": "2022-01-22T02:07:16Z",
"url": "https://fedibird.com/@noellabo/107663670404015196",
"attributedTo": "https://fedibird.com/users/noellabo",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://fedibird.com/users/noellabo/followers"
],
"sensitive": false,
"atomUri": "https://fedibird.com/users/noellabo/statuses/107663670404015196",
"inReplyToAtomUri": null,
"conversation": "tag:fedibird.com,2022-01-22:objectId=107663670404038002:objectType=Conversation",
"context": "https://fedibird.com/contexts/107663670404038002",
"quoteURL": "https://misskey.io/notes/8vsn2izjwh",
"_misskey_quote": "https://misskey.io/notes/8vsn2izjwh",
"_misskey_content": "いつの生まれだシトリン",
"content": "<p>いつの生まれだシトリン<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"Citrine@misskey.io\" data-status-id=\"107663207194225003\" href=\"https://misskey.io/notes/8vsn2izjwh\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">misskey.io/notes/8vsn2izjwh</span><span class=\"invisible\"></span></a></span></p>",
"contentMap": {
"ja": "<p>いつの生まれだシトリン<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"Citrine@misskey.io\" data-status-id=\"107663207194225003\" href=\"https://misskey.io/notes/8vsn2izjwh\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"\">misskey.io/notes/8vsn2izjwh</span><span class=\"invisible\"></span></a></span></p>"
},
"attachment": [],
"tag": [],
"replies": {
"id": "https://fedibird.com/users/noellabo/statuses/107663670404015196/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://fedibird.com/users/noellabo/statuses/107663670404015196/replies?only_other_accounts=true&page=true",
"partOf": "https://fedibird.com/users/noellabo/statuses/107663670404015196/replies",
"items": []
}
}
}

View file

@ -0,0 +1,54 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"ostatus": "http://ostatus.org#",
"atomUri": "ostatus:atomUri",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"sensitive": "as:sensitive",
"toot": "http://joinmastodon.org/ns#",
"votersCount": "toot:votersCount",
"fedibird": "http://fedibird.com/ns#",
"quoteUri": "fedibird:quoteUri",
"expiry": "fedibird:expiry"
}
],
"id": "https://fedibird.com/users/noellabo/statuses/107699335988346142",
"type": "Note",
"summary": null,
"inReplyTo": null,
"published": "2022-01-28T09:17:30Z",
"url": "https://fedibird.com/@noellabo/107699335988346142",
"attributedTo": "https://fedibird.com/users/noellabo",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://fedibird.com/users/noellabo/followers"
],
"sensitive": false,
"atomUri": "https://fedibird.com/users/noellabo/statuses/107699335988346142",
"inReplyToAtomUri": null,
"conversation": "tag:fedibird.com,2022-01-28:objectId=107699335988345290:objectType=Conversation",
"context": "https://fedibird.com/contexts/107699335988345290",
"quoteUri": "https://fedibird.com/users/yamako/statuses/107699333438289729",
"_misskey_quote": "https://fedibird.com/users/yamako/statuses/107699333438289729",
"_misskey_content": "美味しそう",
"content": "<p>美味しそう<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"yamako\" data-status-id=\"107699333438289729\" href=\"https://fedibird.com/@yamako/107699333438289729\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">fedibird.com/@yamako/107699333</span><span class=\"invisible\">438289729</span></a></span></p>",
"contentMap": {
"ja": "<p>美味しそう<span class=\"quote-inline\"><br/>QT: <a class=\"status-url-link\" data-status-account-acct=\"yamako\" data-status-id=\"107699333438289729\" href=\"https://fedibird.com/@yamako/107699333438289729\" rel=\"nofollow noopener noreferrer\" target=\"_blank\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">fedibird.com/@yamako/107699333</span><span class=\"invisible\">438289729</span></a></span></p>"
},
"attachment": [],
"tag": [],
"replies": {
"id": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies?only_other_accounts=true&page=true",
"partOf": "https://fedibird.com/users/noellabo/statuses/107699335988346142/replies",
"items": []
}
}
}

View file

@ -0,0 +1,17 @@
{
"@context": "https://www.w3.org/ns/activitystreams",
"type": "Note",
"content": "This is a quote:<br>RE: https://server.example/objects/123",
"tag": [
{
"type": "Link",
"mediaType": "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
"href": "https://server.example/objects/123",
"name": "RE: https://server.example/objects/123"
}
],
"id": "https://server.example/objects/1",
"to": "https://server.example/users/1",
"attributedTo": "https://server.example/users/1",
"actor": "https://server.example/users/1"
}

View file

@ -0,0 +1,46 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"sensitive": "as:sensitive",
"Hashtag": "as:Hashtag",
"quoteUrl": "as:quoteUrl",
"toot": "http://joinmastodon.org/ns#",
"Emoji": "toot:Emoji",
"featured": "toot:featured",
"discoverable": "toot:discoverable",
"schema": "http://schema.org#",
"PropertyValue": "schema:PropertyValue",
"value": "schema:value",
"misskey": "https://misskey.io/ns#",
"_misskey_content": "misskey:_misskey_content",
"_misskey_quote": "misskey:_misskey_quote",
"_misskey_reaction": "misskey:_misskey_reaction",
"_misskey_votes": "misskey:_misskey_votes",
"_misskey_talk": "misskey:_misskey_talk",
"isCat": "misskey:isCat",
"vcard": "http://www.w3.org/2006/vcard/ns#"
}
],
"id": "https://misskey.io/notes/8vs6ylpfez",
"type": "Note",
"attributedTo": "https://misskey.io/users/7rkrarq81i",
"summary": null,
"content": "<p><span>投稿者の設定によるね<br>Fanboxについても投稿者によっては過去の投稿は高額なプランに移動してることがある<br><br>RE: </span><a href=\"https://misskey.io/notes/8vs6wxufd0\">https://misskey.io/notes/8vs6wxufd0</a></p>",
"_misskey_content": "投稿者の設定によるね\nFanboxについても投稿者によっては過去の投稿は高額なプランに移動してることがある",
"_misskey_quote": "https://misskey.io/notes/8vs6wxufd0",
"quoteUrl": "https://misskey.io/notes/8vs6wxufd0",
"published": "2022-01-21T16:38:30.243Z",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://misskey.io/users/7rkrarq81i/followers"
],
"inReplyTo": null,
"attachment": [],
"sensitive": false,
"tag": []
}

View file

@ -0,0 +1,64 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"sensitive": "as:sensitive",
"Hashtag": "as:Hashtag",
"quoteUrl": "as:quoteUrl",
"toot": "http://joinmastodon.org/ns#",
"Emoji": "toot:Emoji",
"featured": "toot:featured",
"discoverable": "toot:discoverable",
"schema": "http://schema.org#",
"PropertyValue": "schema:PropertyValue",
"value": "schema:value",
"misskey": "https://misskey.io/ns#",
"_misskey_content": "misskey:_misskey_content",
"_misskey_quote": "misskey:_misskey_quote",
"_misskey_reaction": "misskey:_misskey_reaction",
"_misskey_votes": "misskey:_misskey_votes",
"_misskey_talk": "misskey:_misskey_talk",
"isCat": "misskey:isCat",
"vcard": "http://www.w3.org/2006/vcard/ns#"
}
],
"type": "Person",
"id": "https://misskey.io/users/83ssedkv53",
"inbox": "https://misskey.io/users/83ssedkv53/inbox",
"outbox": "https://misskey.io/users/83ssedkv53/outbox",
"followers": "https://misskey.io/users/83ssedkv53/followers",
"following": "https://misskey.io/users/83ssedkv53/following",
"sharedInbox": "https://misskey.io/inbox",
"endpoints": {
"sharedInbox": "https://misskey.io/inbox"
},
"url": "https://misskey.io/@aimu",
"preferredUsername": "aimu",
"name": "あいむ",
"summary": "<p><span>わずかな作曲要素 巣穴で独り言<br>Twitter </span><a href=\"https://twitter.com/aimu_53\">https://twitter.com/aimu_53</a><span><br>Soundcloud </span><a href=\"https://soundcloud.com/aimu-53\">https://soundcloud.com/aimu-53</a></p>",
"icon": {
"type": "Image",
"url": "https://s3.arkjp.net/misskey/webpublic-3f7e93c0-34f5-443c-acc0-f415cb2342b4.jpg",
"sensitive": false,
"name": null
},
"image": {
"type": "Image",
"url": "https://s3.arkjp.net/misskey/webpublic-2db63d1d-490b-488b-ab62-c93c285f26b6.png",
"sensitive": false,
"name": null
},
"tag": [],
"manuallyApprovesFollowers": false,
"discoverable": true,
"publicKey": {
"id": "https://misskey.io/users/83ssedkv53#main-key",
"type": "Key",
"owner": "https://misskey.io/users/83ssedkv53",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1ylhePJ6qGHmwHSBP17b\nIosxGaiFKvgDBgZdm8vzvKeRSqJV9uLHfZL3pO/Zt02EwaZd2GohZAtBZEF8DbMA\n3s93WAesvyGF9mjGrYYKlhp/glwyrrrbf+RdD0DLtyDwRRlrxp3pS2lLmv5Tp1Zl\npH+UKpOnNrpQqjHI5P+lEc9bnflzbRrX+UiyLNsVAP80v4wt7SZfT/telrU6mDru\n998UdfhUo7bDKeDsHG1PfLpyhhtfdoZub4kBpkyacHiwAd+CdCjR54Eu7FDwVK3p\nY3JcrT2q5stgMqN1m4QgSL4XAADIotWwDYttTJejM1n9dr+6VWv5bs0F2Q/6gxOp\nu5DQZLk4Q+64U4LWNox6jCMOq3fYe0g7QalJIHnanYQQo+XjoH6S1Aw64gQ3Ip2Y\nZBmZREAOR7GMFVDPFnVnsbCHnIAv16TdgtLgQBAihkWEUuPqITLi8PMu6kMr3uyq\nYkObEfH0TNTcqaiVpoXv791GZLEUV5ROl0FSUANLNkHZZv29xZ5JDOBOR1rNBLyH\ngVtW8rpszYqOXwzX23hh4WsVXfB7YgNvIijwjiaWbzsecleaENGEnLNMiVKVumTj\nmtyTeFJpH0+OaSrUYpemRRJizmqIjklKsNwUEwUb2WcUUg92o56T2obrBkooabZe\nwgSXSKTOcjsR/ju7+AuIyvkCAwEAAQ==\n-----END PUBLIC KEY-----\n"
},
"isCat": true,
"vcard:bday": "5353-05-03"
}

View file

@ -0,0 +1,44 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1",
{
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
"sensitive": "as:sensitive",
"Hashtag": "as:Hashtag",
"quoteUrl": "as:quoteUrl",
"toot": "http://joinmastodon.org/ns#",
"Emoji": "toot:Emoji",
"featured": "toot:featured",
"discoverable": "toot:discoverable",
"schema": "http://schema.org#",
"PropertyValue": "schema:PropertyValue",
"value": "schema:value",
"misskey": "https://misskey.io/ns#",
"_misskey_content": "misskey:_misskey_content",
"_misskey_quote": "misskey:_misskey_quote",
"_misskey_reaction": "misskey:_misskey_reaction",
"_misskey_votes": "misskey:_misskey_votes",
"_misskey_talk": "misskey:_misskey_talk",
"isCat": "misskey:isCat",
"vcard": "http://www.w3.org/2006/vcard/ns#"
}
],
"id": "https://misskey.io/notes/8vs6wxufd0",
"type": "Note",
"attributedTo": "https://misskey.io/users/83ssedkv53",
"summary": null,
"content": "<p><span>Fantiaこれできないように過去のやつは従量課金だった気がする</span></p>",
"_misskey_content": "Fantiaこれできないように過去のやつは従量課金だった気がする",
"published": "2022-01-21T16:37:12.663Z",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://misskey.io/users/83ssedkv53/followers"
],
"inReplyTo": null,
"attachment": [],
"sensitive": false,
"tag": []
}

View file

@ -0,0 +1 @@
{"version":"2.1","software":{"name":"wildebeest","version":"0.0.1","repository":"https://github.com/cloudflare/wildebeest"},"protocols":["activitypub"],"usage":{"users":{"total":1,"activeMonth":1,"activeHalfyear":1}},"openRegistrations":false,"metadata":{"upstream":{"name":"mastodon","version":"3.5.1"}}}

View file

@ -0,0 +1 @@
{"links":[{"rel":"http://nodeinfo.diaspora.software/ns/schema/2.0","href":"https://wildebeest.example.org/nodeinfo/2.0"},{"rel":"http://nodeinfo.diaspora.software/ns/schema/2.1","href":"https://wildebeest.example.org/nodeinfo/2.1"}]}

15
test/fixtures/xml_billion_laughs.xml vendored Normal file
View file

@ -0,0 +1,15 @@
<?xml version="1.0"?>
<!DOCTYPE lolz [
<!ENTITY lol "lol">
<!ELEMENT lolz (#PCDATA)>
<!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">
<!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">
<!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">
<!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">
<!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">
<!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">
<!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">
<!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">
<!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">
]>
<lolz>&lol9;</lolz>

View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]>
<stockCheck><productId>&xxe;</productId></stockCheck>

View file

@ -10,13 +10,15 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
describe "load/2" do
test "loads release defaults config and warns about non-existent runtime config" do
ExUnit.CaptureIO.capture_io(fn ->
merged = ReleaseRuntimeProvider.load([], [])
merged = ReleaseRuntimeProvider.load([], config_path: "/var/empty/config.exs")
assert merged == Pleroma.Config.Holder.release_defaults()
end) =~
"!!! Config path is not declared! Please ensure it exists and that PLEROMA_CONFIG_PATH is unset or points to an existing file"
end
test "merged runtime config" do
assert :ok == File.chmod!("test/fixtures/config/temp.secret.exs", 0o640)
merged =
ReleaseRuntimeProvider.load([], config_path: "test/fixtures/config/temp.secret.exs")
@ -25,6 +27,8 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
end
test "merged exported config" do
assert :ok == File.chmod!("test/fixtures/config/temp.exported_from_db.secret.exs", 0o640)
ExUnit.CaptureIO.capture_io(fn ->
merged =
ReleaseRuntimeProvider.load([],
@ -37,6 +41,9 @@ defmodule Pleroma.Config.ReleaseRuntimeProviderTest do
end
test "runtime config is merged with exported config" do
assert :ok == File.chmod!("test/fixtures/config/temp.secret.exs", 0o640)
assert :ok == File.chmod!("test/fixtures/config/temp.exported_from_db.secret.exs", 0o640)
merged =
ReleaseRuntimeProvider.load([],
config_path: "test/fixtures/config/temp.secret.exs",

View file

@ -0,0 +1,25 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.BareUriTest do
use Pleroma.DataCase, async: true
alias Pleroma.EctoType.ActivityPub.ObjectValidators.BareUri
test "diaspora://" do
text = "diaspora://alice@fediverse.example/post/deadbeefdeadbeefdeadbeefdeadbeef"
assert {:ok, text} = BareUri.cast(text)
end
test "nostr:" do
text = "nostr:note1gwdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
assert {:ok, text} = BareUri.cast(text)
end
test "errors for non-URIs" do
assert :error == SafeText.cast(1)
assert :error == SafeText.cast("foo")
assert :error == SafeText.cast("foo bar")
end
end

View file

@ -90,4 +90,8 @@ defmodule Pleroma.Emoji.PackTest do
assert updated_pack.files_count == 1
end
test "load_pack/1 ignores path traversal in a forged pack name", %{pack: pack} do
assert {:ok, ^pack} = Pack.load_pack("../../../../../dump_pack")
end
end

View file

@ -161,6 +161,66 @@ defmodule Pleroma.Instances.InstanceTest do
end
end
describe "get_or_update_metadata/1" do
test "Scrapes Wildebeest NodeInfo" do
Tesla.Mock.mock(fn
%{url: "https://wildebeest.example.org/.well-known/nodeinfo"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/wildebeest-well-known-nodeinfo.json")
}
%{url: "https://wildebeest.example.org/nodeinfo/2.1"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/wildebeest-nodeinfo21.json")
}
end)
expected = %{
software_name: "wildebeest",
software_repository: "https://github.com/cloudflare/wildebeest",
software_version: "0.0.1"
}
assert expected ==
Instance.get_or_update_metadata(URI.parse("https://wildebeest.example.org/"))
expected = %Pleroma.Instances.Instance.Pleroma.Instances.Metadata{
software_name: "wildebeest",
software_repository: "https://github.com/cloudflare/wildebeest",
software_version: "0.0.1"
}
assert expected ==
Repo.get_by(Pleroma.Instances.Instance, %{host: "wildebeest.example.org"}).metadata
end
test "Scrapes Mastodon NodeInfo" do
Tesla.Mock.mock(fn
%{url: "https://mastodon.example.org/.well-known/nodeinfo"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/mastodon-well-known-nodeinfo.json")
}
%{url: "https://mastodon.example.org/nodeinfo/2.0"} ->
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/mastodon-nodeinfo20.json")
}
end)
expected = %{
software_name: "mastodon",
software_version: "4.1.0"
}
assert expected ==
Instance.get_or_update_metadata(URI.parse("https://mastodon.example.org/"))
end
end
test "delete_users_and_activities/1 deletes remote instance users and activities" do
[mario, luigi, _peach, wario] =
users = [

View file

@ -31,9 +31,22 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
WebsocketClient.start_link(self(), path, headers)
end
defp decode_json(json) do
with {:ok, %{"event" => event, "payload" => payload_text}} <- Jason.decode(json),
{:ok, payload} <- Jason.decode(payload_text) do
{:ok, %{"event" => event, "payload" => payload}}
end
end
# Turns atom keys to strings
defp atom_key_to_string(json) do
json
|> Jason.encode!()
|> Jason.decode!()
end
test "refuses invalid requests" do
capture_log(fn ->
assert {:error, %WebSockex.RequestError{code: 404}} = start_socket()
assert {:error, %WebSockex.RequestError{code: 404}} = start_socket("?stream=ncjdk")
Process.sleep(30)
end)
@ -49,6 +62,10 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
end)
end
test "allows unified stream" do
assert {:ok, _} = start_socket()
end
test "allows public streams without authentication" do
assert {:ok, _} = start_socket("?stream=public")
assert {:ok, _} = start_socket("?stream=public:local")
@ -70,12 +87,143 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
view_json =
Pleroma.Web.MastodonAPI.StatusView.render("show.json", activity: activity, for: nil)
|> Jason.encode!()
|> Jason.decode!()
|> atom_key_to_string()
assert json == view_json
end
describe "subscribing via WebSocket" do
test "can subscribe" do
user = insert(:user)
{:ok, pid} = start_socket()
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "success"}
}} = decode_json(raw_json)
{:ok, activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
assert_receive {:text, raw_json}, 1_000
assert {:ok, json} = Jason.decode(raw_json)
assert "update" == json["event"]
assert json["payload"]
assert {:ok, json} = Jason.decode(json["payload"])
view_json =
Pleroma.Web.MastodonAPI.StatusView.render("show.json", activity: activity, for: nil)
|> Jason.encode!()
|> Jason.decode!()
assert json == view_json
end
test "can subscribe to multiple streams" do
user = insert(:user)
{:ok, pid} = start_socket()
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "success"}
}} = decode_json(raw_json)
WebsocketClient.send_text(
pid,
%{type: "subscribe", stream: "hashtag", tag: "mew"} |> Jason.encode!()
)
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "success"}
}} = decode_json(raw_json)
{:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber #mew"})
assert_receive {:text, raw_json}, 1_000
assert {:ok, %{"stream" => stream1}} = Jason.decode(raw_json)
assert_receive {:text, raw_json}, 1_000
assert {:ok, %{"stream" => stream2}} = Jason.decode(raw_json)
streams = [stream1, stream2]
assert ["hashtag", "mew"] in streams
assert ["public"] in streams
end
test "won't double subscribe" do
user = insert(:user)
{:ok, pid} = start_socket()
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "success"}
}} = decode_json(raw_json)
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "ignored"}
}} = decode_json(raw_json)
{:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
assert_receive {:text, _}, 1_000
refute_receive {:text, _}, 1_000
end
test "rejects invalid streams" do
{:ok, pid} = start_socket()
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "nonsense"} |> Jason.encode!())
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "error", "error" => "bad_topic"}
}} = decode_json(raw_json)
end
test "can unsubscribe" do
user = insert(:user)
{:ok, pid} = start_socket()
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "public"} |> Jason.encode!())
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "success"}
}} = decode_json(raw_json)
WebsocketClient.send_text(pid, %{type: "unsubscribe", stream: "public"} |> Jason.encode!())
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "unsubscribe", "result" => "success"}
}} = decode_json(raw_json)
{:ok, _activity} = CommonAPI.post(user, %{status: "nice echo chamber"})
refute_receive {:text, _}, 1_000
end
end
describe "with a valid user token" do
setup do
{:ok, app} =
@ -131,6 +279,124 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
end)
end
test "accepts valid token on client-sent event", %{token: token} do
assert {:ok, pid} = start_socket()
WebsocketClient.send_text(
pid,
%{type: "pleroma:authenticate", token: token.token} |> Jason.encode!()
)
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "pleroma:authenticate", "result" => "success"}
}} = decode_json(raw_json)
WebsocketClient.send_text(pid, %{type: "subscribe", stream: "user"} |> Jason.encode!())
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "success"}
}} = decode_json(raw_json)
end
test "rejects invalid token on client-sent event" do
assert {:ok, pid} = start_socket()
WebsocketClient.send_text(
pid,
%{type: "pleroma:authenticate", token: "Something else"} |> Jason.encode!()
)
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{
"type" => "pleroma:authenticate",
"result" => "error",
"error" => "unauthorized"
}
}} = decode_json(raw_json)
end
test "rejects new authenticate request if already logged-in", %{token: token} do
assert {:ok, pid} = start_socket()
WebsocketClient.send_text(
pid,
%{type: "pleroma:authenticate", token: token.token} |> Jason.encode!()
)
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "pleroma:authenticate", "result" => "success"}
}} = decode_json(raw_json)
WebsocketClient.send_text(
pid,
%{type: "pleroma:authenticate", token: "Something else"} |> Jason.encode!()
)
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{
"type" => "pleroma:authenticate",
"result" => "error",
"error" => "already_authenticated"
}
}} = decode_json(raw_json)
end
test "accepts the 'list' stream", %{token: token, user: user} do
posting_user = insert(:user)
{:ok, list} = Pleroma.List.create("test", user)
Pleroma.List.follow(list, posting_user)
assert {:ok, _} = start_socket("?stream=list&access_token=#{token.token}&list=#{list.id}")
assert {:ok, pid} = start_socket("?access_token=#{token.token}")
WebsocketClient.send_text(
pid,
%{type: "subscribe", stream: "list", list: list.id} |> Jason.encode!()
)
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "success"}
}} = decode_json(raw_json)
WebsocketClient.send_text(
pid,
%{type: "subscribe", stream: "list", list: to_string(list.id)} |> Jason.encode!()
)
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "pleroma:respond",
"payload" => %{"type" => "subscribe", "result" => "ignored"}
}} = decode_json(raw_json)
end
test "disconnect when token is revoked", %{app: app, user: user, token: token} do
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
@ -146,5 +412,85 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
assert_receive {:close, _}
refute_receive {:close, _}
end
test "receives private statuses", %{user: reading_user, token: token} do
user = insert(:user)
CommonAPI.follow(reading_user, user)
{:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
{:ok, activity} =
CommonAPI.post(user, %{status: "nice echo chamber", visibility: "private"})
assert_receive {:text, raw_json}, 1_000
assert {:ok, json} = Jason.decode(raw_json)
assert "update" == json["event"]
assert json["payload"]
assert {:ok, json} = Jason.decode(json["payload"])
view_json =
Pleroma.Web.MastodonAPI.StatusView.render("show.json",
activity: activity,
for: reading_user
)
|> Jason.encode!()
|> Jason.decode!()
assert json == view_json
end
test "receives edits", %{user: reading_user, token: token} do
user = insert(:user)
CommonAPI.follow(reading_user, user)
{:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
{:ok, activity} =
CommonAPI.post(user, %{status: "nice echo chamber", visibility: "private"})
assert_receive {:text, _raw_json}, 1_000
{:ok, _} = CommonAPI.update(user, activity, %{status: "mew mew", visibility: "private"})
assert_receive {:text, raw_json}, 1_000
activity = Pleroma.Activity.normalize(activity)
view_json =
Pleroma.Web.MastodonAPI.StatusView.render("show.json",
activity: activity,
for: reading_user
)
|> Jason.encode!()
|> Jason.decode!()
assert {:ok, %{"event" => "status.update", "payload" => ^view_json}} = decode_json(raw_json)
end
test "receives notifications", %{user: reading_user, token: token} do
user = insert(:user)
CommonAPI.follow(reading_user, user)
{:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
{:ok, %Pleroma.Activity{id: activity_id} = _activity} =
CommonAPI.post(user, %{
status: "nice echo chamber @#{reading_user.nickname}",
visibility: "private"
})
assert_receive {:text, raw_json}, 1_000
assert {:ok,
%{
"event" => "notification",
"payload" => %{
"status" => %{
"id" => ^activity_id
}
}
}} = decode_json(raw_json)
end
end
end

View file

@ -252,7 +252,7 @@ defmodule Pleroma.NotificationTest do
task =
Task.async(fn ->
{:ok, _topic} = Streamer.get_topic_and_add_socket("user", user, oauth_token)
assert_receive {:render_with_user, _, _, _}, 4_000
assert_receive {:render_with_user, _, _, _, _}, 4_000
end)
task_user_notification =
@ -260,7 +260,7 @@ defmodule Pleroma.NotificationTest do
{:ok, _topic} =
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
assert_receive {:render_with_user, _, _, _}, 4_000
assert_receive {:render_with_user, _, _, _, _}, 4_000
end)
activity = insert(:note_activity)

View file

@ -39,7 +39,7 @@ defmodule Pleroma.User.BackupTest do
assert_enqueued(worker: BackupWorker, args: args)
backup = Backup.get(args["backup_id"])
assert %Backup{user_id: ^user_id, processed: false, file_size: 0} = backup
assert %Backup{user_id: ^user_id, processed: false, file_size: 0, state: :pending} = backup
end
test "it return an error if the export limit is over" do
@ -59,7 +59,30 @@ defmodule Pleroma.User.BackupTest do
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
assert {:ok, backup} = perform_job(BackupWorker, args)
assert backup.file_size > 0
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id} = backup
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id, state: :complete} = backup
delete_job_args = %{"op" => "delete", "backup_id" => backup_id}
assert_enqueued(worker: BackupWorker, args: delete_job_args)
assert {:ok, backup} = perform_job(BackupWorker, delete_job_args)
refute Backup.get(backup_id)
email = Pleroma.Emails.UserEmail.backup_is_ready_email(backup)
assert_email_sent(
to: {user.name, user.email},
html_body: email.html_body
)
end
test "it updates states of the backup" do
clear_config([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
%{id: user_id} = user = insert(:user)
assert {:ok, %Oban.Job{args: %{"backup_id" => backup_id} = args}} = Backup.create(user)
assert {:ok, backup} = perform_job(BackupWorker, args)
assert backup.file_size > 0
assert %Backup{id: ^backup_id, processed: true, user_id: ^user_id, state: :complete} = backup
delete_job_args = %{"op" => "delete", "backup_id" => backup_id}
@ -148,7 +171,7 @@ defmodule Pleroma.User.BackupTest do
Bookmark.create(user.id, status3.id)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
assert {:ok, path} = Backup.export(backup)
assert {:ok, path} = Backup.export(backup, self())
assert {:ok, zipfile} = :zip.zip_open(String.to_charlist(path), [:memory])
assert {:ok, {'actor.json', json}} = :zip.zip_get('actor.json', zipfile)
@ -230,6 +253,73 @@ defmodule Pleroma.User.BackupTest do
File.rm!(path)
end
test "it counts the correct number processed" do
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
Enum.map(1..120, fn i ->
{:ok, status} = CommonAPI.post(user, %{status: "status #{i}"})
CommonAPI.favorite(user, status.id)
Bookmark.create(user.id, status.id)
end)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
{:ok, backup} = Backup.process(backup)
assert backup.processed_number == 1 + 120 + 120 + 120
Backup.delete(backup)
end
test "it handles errors" do
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
Enum.map(1..120, fn i ->
{:ok, _status} = CommonAPI.post(user, %{status: "status #{i}"})
end)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
with_mock Pleroma.Web.ActivityPub.Transmogrifier,
[:passthrough],
prepare_outgoing: fn data ->
object =
data["object"]
|> Pleroma.Object.normalize(fetch: false)
|> Map.get(:data)
data = data |> Map.put("object", object)
if String.contains?(data["object"]["content"], "119"),
do: raise(%Postgrex.Error{}),
else: {:ok, data}
end do
{:ok, backup} = Backup.process(backup)
assert backup.processed
assert backup.state == :complete
assert backup.processed_number == 1 + 119
Backup.delete(backup)
end
end
test "it handles unrecoverable exceptions" do
user = insert(:user, %{nickname: "cofe", name: "Cofe", ap_id: "http://cofe.io/users/cofe"})
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
with_mock Backup, [:passthrough], do_process: fn _, _ -> raise "mock exception" end do
{:error, %{backup: backup, reason: :exit}} = Backup.process(backup)
assert backup.state == :failed
end
with_mock Backup, [:passthrough], do_process: fn _, _ -> Process.sleep(:timer.seconds(32)) end do
{:error, %{backup: backup, reason: :timeout}} = Backup.process(backup)
assert backup.state == :failed
end
end
describe "it uploads and deletes a backup archive" do
setup do
clear_config([Pleroma.Upload, :base_url], "https://s3.amazonaws.com")
@ -246,7 +336,7 @@ defmodule Pleroma.User.BackupTest do
Bookmark.create(user.id, status3.id)
assert {:ok, backup} = user |> Backup.new() |> Repo.insert()
assert {:ok, path} = Backup.export(backup)
assert {:ok, path} = Backup.export(backup, self())
[path: path, backup: backup]
end

View file

@ -1844,7 +1844,6 @@ defmodule Pleroma.UserTest do
confirmation_token: "qqqq",
domain_blocks: ["lain.com"],
is_active: false,
ap_enabled: true,
is_moderator: true,
is_admin: true,
mascot: %{"a" => "b"},
@ -1885,7 +1884,6 @@ defmodule Pleroma.UserTest do
confirmation_token: nil,
domain_blocks: [],
is_active: false,
ap_enabled: false,
is_moderator: false,
is_admin: false,
mascot: nil,
@ -2473,8 +2471,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
following_address: "http://localhost:4001/users/masto_closed/following",
ap_enabled: true
following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0
@ -2495,8 +2492,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
following_address: "http://localhost:4001/users/masto_closed/following",
ap_enabled: true
following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0
@ -2517,8 +2513,7 @@ defmodule Pleroma.UserTest do
insert(:user,
local: false,
follower_address: "http://localhost:4001/users/masto_closed/followers",
following_address: "http://localhost:4001/users/masto_closed/following",
ap_enabled: true
following_address: "http://localhost:4001/users/masto_closed/following"
)
assert other_user.following_count == 0

View file

@ -575,7 +575,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
user =
insert(:user,
ap_id: "https://mastodon.example.org/users/raymoo",
ap_enabled: true,
local: false,
last_refreshed_at: nil
)

View file

@ -174,7 +174,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
assert user.ap_id == user_id
assert user.nickname == "admin@mastodon.example.org"
assert user.ap_enabled
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
end
@ -2653,4 +2652,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
{:ok, user} = ActivityPub.make_user_from_ap_id("https://princess.cat/users/mewmew")
assert user.name == " "
end
test "pin_data_from_featured_collection will ignore unsupported values" do
assert %{} ==
ActivityPub.pin_data_from_featured_collection(%{
"type" => "OrderedCollection",
"first" => "https://social.example/users/alice/collections/featured?page=true"
})
end
end

View file

@ -44,5 +44,34 @@ defmodule Pleroma.Web.ActivityPub.BuilderTest do
assert {:ok, ^expected, []} = Builder.note(draft)
end
test "quote post" do
user = insert(:user)
note = insert(:note)
draft = %ActivityDraft{
user: user,
context: "2hu",
content_html: "<h1>This is :moominmamma: note</h1>",
quote_post: note,
extra: %{}
}
expected = %{
"actor" => user.ap_id,
"attachment" => [],
"content" => "<h1>This is :moominmamma: note</h1>",
"context" => "2hu",
"sensitive" => false,
"type" => "Note",
"quoteUrl" => note.data["id"],
"cc" => [],
"summary" => nil,
"tag" => [],
"to" => []
}
assert {:ok, ^expected, []} = Builder.note(draft)
end
end
end

View file

@ -0,0 +1,425 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.EmojiPolicyTest do
use Pleroma.DataCase
require Pleroma.Constants
alias Pleroma.Web.ActivityPub.MRF
alias Pleroma.Web.ActivityPub.MRF.EmojiPolicy
setup do: clear_config(:mrf_emoji)
setup do
clear_config([:mrf_emoji], %{
remove_url: [],
remove_shortcode: [],
federated_timeline_removal_url: [],
federated_timeline_removal_shortcode: []
})
end
@emoji_tags [
%{
"icon" => %{
"type" => "Image",
"url" => "https://example.org/emoji/biribiri/mikoto_smile2.png"
},
"id" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
"name" => ":mikoto_smile2:",
"type" => "Emoji",
"updated" => "1970-01-01T00:00:00Z"
},
%{
"icon" => %{
"type" => "Image",
"url" => "https://example.org/emoji/biribiri/mikoto_smile3.png"
},
"id" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
"name" => ":mikoto_smile3:",
"type" => "Emoji",
"updated" => "1970-01-01T00:00:00Z"
},
%{
"icon" => %{
"type" => "Image",
"url" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
},
"id" => "https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
"name" => ":nekomimi_girl_emoji_007:",
"type" => "Emoji",
"updated" => "1970-01-01T00:00:00Z"
},
%{
"icon" => %{
"type" => "Image",
"url" => "https://example.org/test.png"
},
"id" => "https://example.org/test.png",
"name" => ":test:",
"type" => "Emoji",
"updated" => "1970-01-01T00:00:00Z"
}
]
@misc_tags [%{"type" => "Placeholder"}]
@user_data %{
"type" => "Person",
"id" => "https://example.org/placeholder",
"name" => "lol",
"tag" => @emoji_tags ++ @misc_tags
}
@status_data %{
"type" => "Create",
"object" => %{
"type" => "Note",
"id" => "https://example.org/placeholder",
"content" => "lol",
"tag" => @emoji_tags ++ @misc_tags,
"emoji" => %{
"mikoto_smile2" => "https://example.org/emoji/biribiri/mikoto_smile2.png",
"mikoto_smile3" => "https://example.org/emoji/biribiri/mikoto_smile3.png",
"nekomimi_girl_emoji_007" =>
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png",
"test" => "https://example.org/test.png"
},
"to" => ["https://example.org/self", Pleroma.Constants.as_public()],
"cc" => ["https://example.org/someone"]
},
"to" => ["https://example.org/self", Pleroma.Constants.as_public()],
"cc" => ["https://example.org/someone"]
}
@status_data_with_history %{
"type" => "Create",
"object" =>
@status_data["object"]
|> Map.merge(%{
"formerRepresentations" => %{
"type" => "OrderedCollection",
"orderedItems" => [@status_data["object"] |> Map.put("content", "older")],
"totalItems" => 1
}
}),
"to" => ["https://example.org/self", Pleroma.Constants.as_public()],
"cc" => ["https://example.org/someone"]
}
@emoji_react_data %{
"type" => "EmojiReact",
"tag" => [@emoji_tags |> Enum.at(3)],
"object" => "https://example.org/someobject",
"to" => ["https://example.org/self"],
"cc" => ["https://example.org/someone"]
}
@emoji_react_data_matching_regex %{
"type" => "EmojiReact",
"tag" => [@emoji_tags |> Enum.at(1)],
"object" => "https://example.org/someobject",
"to" => ["https://example.org/self"],
"cc" => ["https://example.org/someone"]
}
@emoji_react_data_matching_nothing %{
"type" => "EmojiReact",
"tag" => [@emoji_tags |> Enum.at(2)],
"object" => "https://example.org/someobject",
"to" => ["https://example.org/self"],
"cc" => ["https://example.org/someone"]
}
@emoji_react_data_unicode %{
"type" => "EmojiReact",
"content" => "😍",
"object" => "https://example.org/someobject",
"to" => ["https://example.org/self"],
"cc" => ["https://example.org/someone"]
}
describe "remove_url" do
setup do
clear_config([:mrf_emoji, :remove_url], [
"https://example.org/test.png",
~r{/biribiri/mikoto_smile[23]\.png},
"nekomimi_girl_emoji"
])
:ok
end
test "processes user" do
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
assert %{"tag" => ^expected_tags} = filtered
end
test "processes status" do
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
expected_emoji = %{
"nekomimi_girl_emoji_007" =>
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
}
assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
end
test "processes status with history" do
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
expected_emoji = %{
"nekomimi_girl_emoji_007" =>
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
}
assert %{
"object" => %{
"tag" => ^expected_tags,
"emoji" => ^expected_emoji,
"formerRepresentations" => %{"orderedItems" => [item]}
}
} = filtered
assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
end
test "processes updates" do
{:ok, filtered} =
MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
expected_emoji = %{
"nekomimi_girl_emoji_007" =>
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
}
assert %{
"object" => %{
"tag" => ^expected_tags,
"emoji" => ^expected_emoji,
"formerRepresentations" => %{"orderedItems" => [item]}
}
} = filtered
assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
end
test "processes EmojiReact" do
assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
MRF.filter_one(EmojiPolicy, @emoji_react_data)
assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
assert {:ok, @emoji_react_data_matching_nothing} ==
MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
assert {:ok, @emoji_react_data_unicode} ==
MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
end
end
describe "remove_shortcode" do
setup do
clear_config([:mrf_emoji, :remove_shortcode], [
"test",
~r{mikoto_s},
"nekomimi_girl_emoji"
])
:ok
end
test "processes user" do
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @user_data)
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
assert %{"tag" => ^expected_tags} = filtered
end
test "processes status" do
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
expected_emoji = %{
"nekomimi_girl_emoji_007" =>
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
}
assert %{"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}} = filtered
end
test "processes status with history" do
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data_with_history)
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
expected_emoji = %{
"nekomimi_girl_emoji_007" =>
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
}
assert %{
"object" => %{
"tag" => ^expected_tags,
"emoji" => ^expected_emoji,
"formerRepresentations" => %{"orderedItems" => [item]}
}
} = filtered
assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
end
test "processes updates" do
{:ok, filtered} =
MRF.filter_one(EmojiPolicy, @status_data_with_history |> Map.put("type", "Update"))
expected_tags = [@emoji_tags |> Enum.at(2)] ++ @misc_tags
expected_emoji = %{
"nekomimi_girl_emoji_007" =>
"https://example.org/emoji/nekomimi_girl_emoji/nekomimi_girl_emoji_007.png"
}
assert %{
"object" => %{
"tag" => ^expected_tags,
"emoji" => ^expected_emoji,
"formerRepresentations" => %{"orderedItems" => [item]}
}
} = filtered
assert %{"tag" => ^expected_tags, "emoji" => ^expected_emoji} = item
end
test "processes EmojiReact" do
assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
MRF.filter_one(EmojiPolicy, @emoji_react_data)
assert {:reject, "[EmojiPolicy] Rejected for having disallowed emoji"} ==
MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_regex)
assert {:ok, @emoji_react_data_matching_nothing} ==
MRF.filter_one(EmojiPolicy, @emoji_react_data_matching_nothing)
assert {:ok, @emoji_react_data_unicode} ==
MRF.filter_one(EmojiPolicy, @emoji_react_data_unicode)
end
end
describe "federated_timeline_removal_url" do
setup do
clear_config([:mrf_emoji, :federated_timeline_removal_url], [
"https://example.org/test.png",
~r{/biribiri/mikoto_smile[23]\.png},
"nekomimi_girl_emoji"
])
:ok
end
test "processes status" do
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data)
expected_tags = @status_data["object"]["tag"]
expected_emoji = @status_data["object"]["emoji"]
expected_to = ["https://example.org/self"]
expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
assert %{
"to" => ^expected_to,
"cc" => ^expected_cc,
"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
} = filtered
end
test "ignore updates" do
{:ok, filtered} = MRF.filter_one(EmojiPolicy, @status_data |> Map.put("type", "Update"))
expected_tags = @status_data["object"]["tag"]
expected_emoji = @status_data["object"]["emoji"]
expected_to = ["https://example.org/self", Pleroma.Constants.as_public()]
expected_cc = ["https://example.org/someone"]
assert %{
"to" => ^expected_to,
"cc" => ^expected_cc,
"object" => %{"tag" => ^expected_tags, "emoji" => ^expected_emoji}
} = filtered
end
test "processes status with history" do
status =
@status_data_with_history
|> put_in(["object", "tag"], @misc_tags)
|> put_in(["object", "emoji"], %{})
{:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
expected_tags = @status_data["object"]["tag"]
expected_emoji = @status_data["object"]["emoji"]
expected_to = ["https://example.org/self"]
expected_cc = [Pleroma.Constants.as_public(), "https://example.org/someone"]
assert %{
"to" => ^expected_to,
"cc" => ^expected_cc,
"object" => %{
"formerRepresentations" => %{
"orderedItems" => [%{"tag" => ^expected_tags, "emoji" => ^expected_emoji}]
}
}
} = filtered
end
end
describe "edge cases" do
setup do
clear_config([:mrf_emoji, :remove_url], [
"https://example.org/test.png",
~r{/biribiri/mikoto_smile[23]\.png},
"nekomimi_girl_emoji"
])
:ok
end
test "non-statuses" do
answer = @status_data |> put_in(["object", "type"], "Answer")
{:ok, filtered} = MRF.filter_one(EmojiPolicy, answer)
assert filtered == answer
end
test "without tag" do
status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["tag"]))
{:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
refute Map.has_key?(filtered["object"], "tag")
end
test "without emoji" do
status = @status_data |> Map.put("object", Map.drop(@status_data["object"], ["emoji"]))
{:ok, filtered} = MRF.filter_one(EmojiPolicy, status)
refute Map.has_key?(filtered["object"], "emoji")
end
end
end

View file

@ -256,4 +256,55 @@ defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContentTest do
}
}} = MRF.filter_one(ForceMentionsInContent, activity)
end
test "don't add duplicate mentions for mastodon or misskey posts" do
[zero, rogerick, greg] = [
insert(:user,
ap_id: "https://pleroma.example.com/users/zero",
uri: "https://pleroma.example.com/users/zero",
nickname: "zero@pleroma.example.com",
local: false
),
insert(:user,
ap_id: "https://misskey.example.com/users/104ab42f11",
uri: "https://misskey.example.com/@rogerick",
nickname: "rogerick@misskey.example.com",
local: false
),
insert(:user,
ap_id: "https://mastodon.example.com/users/greg",
uri: "https://mastodon.example.com/@greg",
nickname: "greg@mastodon.example.com",
local: false
)
]
{:ok, post} = CommonAPI.post(rogerick, %{status: "eugh"})
inline_mentions = [
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{rogerick.id}\" href=\"#{rogerick.ap_id}\" rel=\"ugc\">@<span>rogerick</span></a></span>",
"<span class=\"h-card\"><a class=\"u-url mention\" data-user=\"#{greg.id}\" href=\"#{greg.uri}\" rel=\"ugc\">@<span>greg</span></a></span>"
]
activity = %{
"type" => "Create",
"actor" => zero.ap_id,
"object" => %{
"type" => "Note",
"actor" => zero.ap_id,
"content" => "#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm",
"to" => [
rogerick.ap_id,
greg.ap_id,
Constants.as_public()
],
"inReplyTo" => Object.normalize(post).data["id"]
}
}
{:ok, %{"object" => %{"content" => filtered}}} = ForceMentionsInContent.filter(activity)
assert filtered ==
"#{Enum.at(inline_mentions, 0)} #{Enum.at(inline_mentions, 1)} erm"
end
end

View file

@ -0,0 +1,112 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicyTest do
alias Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy
use Pleroma.DataCase
test "adds quote URL to post content" do
quote_url = "https://gleasonator.com/objects/1234"
activity = %{
"type" => "Create",
"actor" => "https://gleasonator.com/users/alex",
"object" => %{
"type" => "Note",
"content" => "Nice post",
"quoteUrl" => quote_url
}
}
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
assert filtered ==
"Nice post<span class=\"quote-inline\"><br/><br/><bdi>RT:</bdi> <a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a></span>"
end
test "adds quote URL to post content, custom template" do
clear_config([:mrf_inline_quote, :template], "{url}'s quoting")
quote_url = "https://gleasonator.com/objects/1234"
activity = %{
"type" => "Create",
"actor" => "https://gleasonator.com/users/alex",
"object" => %{
"type" => "Note",
"content" => "Nice post",
"quoteUrl" => quote_url
}
}
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
assert filtered ==
"Nice post<span class=\"quote-inline\"><br/><br/><a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a>'s quoting</span>"
end
test "doesn't add line breaks to markdown posts" do
quote_url = "https://gleasonator.com/objects/1234"
activity = %{
"type" => "Create",
"actor" => "https://gleasonator.com/users/alex",
"object" => %{
"type" => "Note",
"content" => "<p>Nice post</p>",
"quoteUrl" => quote_url
}
}
{:ok, %{"object" => %{"content" => filtered}}} = InlineQuotePolicy.filter(activity)
assert filtered ==
"<p>Nice post<span class=\"quote-inline\"><br/><br/><bdi>RT:</bdi> <a href=\"https://gleasonator.com/objects/1234\">https://gleasonator.com/objects/1234</a></span></p>"
end
test "ignores Misskey quote posts" do
object = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
activity = %{
"type" => "Create",
"actor" => "https://misskey.io/users/7rkrarq81i",
"object" => object
}
{:ok, filtered} = InlineQuotePolicy.filter(activity)
assert filtered == activity
end
test "ignores Fedibird quote posts" do
object = File.read!("test/fixtures/quote_post/fedibird_quote_post.json") |> Jason.decode!()
# Normally the ObjectValidator will fix this before it reaches MRF
object = Map.put(object, "quoteUrl", object["quoteURL"])
activity = %{
"type" => "Create",
"actor" => "https://fedibird.com/users/noellabo",
"object" => object
}
{:ok, filtered} = InlineQuotePolicy.filter(activity)
assert filtered == activity
end
test "skips objects which already have an .inline-quote span" do
object =
File.read!("test/fixtures/quote_post/fedibird_quote_mismatched.json") |> Jason.decode!()
# Normally the ObjectValidator will fix this before it reaches MRF
object = Map.put(object, "quoteUrl", object["quoteUri"])
activity = %{
"type" => "Create",
"actor" => "https://fedibird.com/users/noellabo",
"object" => object
}
{:ok, filtered} = InlineQuotePolicy.filter(activity)
assert filtered == activity
end
end

View file

@ -0,0 +1,73 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicyTest do
alias Pleroma.Web.ActivityPub.MRF.QuoteToLinkTagPolicy
use Pleroma.DataCase
require Pleroma.Constants
test "Add quote url to Link tag" do
quote_url = "https://gleasonator.com/objects/1234"
activity = %{
"type" => "Create",
"actor" => "https://gleasonator.com/users/alex",
"object" => %{
"type" => "Note",
"content" => "Nice post",
"quoteUrl" => quote_url
}
}
{:ok, %{"object" => object}} = QuoteToLinkTagPolicy.filter(activity)
assert object["tag"] == [
%{
"type" => "Link",
"href" => quote_url,
"mediaType" => Pleroma.Constants.activity_json_canonical_mime_type()
}
]
end
test "Add quote url to Link tag, append to the end" do
quote_url = "https://gleasonator.com/objects/1234"
activity = %{
"type" => "Create",
"actor" => "https://gleasonator.com/users/alex",
"object" => %{
"type" => "Note",
"content" => "Nice post",
"quoteUrl" => quote_url,
"tag" => [%{"type" => "Hashtag", "name" => "#foo"}]
}
}
{:ok, %{"object" => object}} = QuoteToLinkTagPolicy.filter(activity)
assert [_, tag] = object["tag"]
assert tag == %{
"type" => "Link",
"href" => quote_url,
"mediaType" => Pleroma.Constants.activity_json_canonical_mime_type()
}
end
test "Bypass posts without quoteUrl" do
activity = %{
"type" => "Create",
"actor" => "https://gleasonator.com/users/alex",
"object" => %{
"type" => "Note",
"content" => "Nice post"
}
}
assert {:ok, ^activity} = QuoteToLinkTagPolicy.filter(activity)
end
end

View file

@ -0,0 +1,19 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2023 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.UtilsTest do
use Pleroma.DataCase, async: true
alias Pleroma.Web.ActivityPub.MRF.Utils
describe "describe_regex_or_string/1" do
test "describes regex" do
assert "~r/foo/i" == Utils.describe_regex_or_string(~r/foo/i)
end
test "returns string as-is" do
assert "foo" == Utils.describe_regex_or_string("foo")
end
end
end

View file

@ -116,4 +116,53 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.ArticleNotePageValidatorTest
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note)
end
test "Fedibird quote post" do
insert(:user, ap_id: "https://fedibird.com/users/noellabo")
data = File.read!("test/fixtures/quote_post/fedibird_quote_post.json") |> Jason.decode!()
cng = ArticleNotePageValidator.cast_and_validate(data)
assert cng.valid?
assert cng.changes.quoteUrl == "https://misskey.io/notes/8vsn2izjwh"
end
test "Fedibird quote post with quoteUri field" do
insert(:user, ap_id: "https://fedibird.com/users/noellabo")
data = File.read!("test/fixtures/quote_post/fedibird_quote_uri.json") |> Jason.decode!()
cng = ArticleNotePageValidator.cast_and_validate(data)
assert cng.valid?
assert cng.changes.quoteUrl == "https://fedibird.com/users/yamako/statuses/107699333438289729"
end
test "Misskey quote post" do
insert(:user, ap_id: "https://misskey.io/users/7rkrarq81i")
data = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
cng = ArticleNotePageValidator.cast_and_validate(data)
assert cng.valid?
assert cng.changes.quoteUrl == "https://misskey.io/notes/8vs6wxufd0"
end
test "Parse tag as quote" do
# https://codeberg.org/fediverse/fep/src/branch/main/fep/e232/fep-e232.md
insert(:user, ap_id: "https://server.example/users/1")
data = File.read!("test/fixtures/quote_post/fep-e232-tag-example.json") |> Jason.decode!()
cng = ArticleNotePageValidator.cast_and_validate(data)
assert cng.valid?
assert cng.changes.quoteUrl == "https://server.example/objects/123"
assert Enum.at(cng.changes.tag, 0).changes == %{
type: "Link",
mediaType: "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
href: "https://server.example/objects/123",
name: "RE: https://server.example/objects/123"
}
end
end

View file

@ -276,8 +276,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
inbox: "https://domain.com/users/nick1/inbox",
ap_enabled: true
inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@ -313,8 +312,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
inbox: "https://domain.com/users/nick1/inbox",
ap_enabled: true
inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@ -348,8 +346,7 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
follower =
insert(:user, %{
local: false,
inbox: "https://domain.com/users/nick1/inbox",
ap_enabled: true
inbox: "https://domain.com/users/nick1/inbox"
})
actor = insert(:user, follower_address: follower.ap_id)
@ -382,15 +379,13 @@ defmodule Pleroma.Web.ActivityPub.PublisherTest do
fetcher =
insert(:user,
local: false,
inbox: "https://domain.com/users/nick1/inbox",
ap_enabled: true
inbox: "https://domain.com/users/nick1/inbox"
)
another_fetcher =
insert(:user,
local: false,
inbox: "https://domain2.com/users/nick1/inbox",
ap_enabled: true
inbox: "https://domain2.com/users/nick1/inbox"
)
actor = insert(:user)

View file

@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Tests.ObanHelpers
alias Pleroma.User
alias Pleroma.Web.ActivityPub.Transmogrifier
alias Pleroma.Web.ActivityPub.Utils
@ -124,7 +123,7 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert activity.data["context"] == object.data["context"]
end
test "it drops link tags" do
test "it keeps link tags" do
insert(:user, ap_id: "https://example.org/users/alice")
message = File.read!("test/fixtures/fep-e232.json") |> Jason.decode!()
@ -132,10 +131,29 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert {:ok, activity} = Transmogrifier.handle_incoming(message)
object = Object.normalize(activity)
assert length(object.data["tag"]) == 1
assert [%{"type" => "Mention"}, %{"type" => "Link"}] = object.data["tag"]
end
tag = object.data["tag"] |> List.first()
assert tag["type"] == "Mention"
test "it accepts quote posts" do
insert(:user, ap_id: "https://misskey.io/users/7rkrarq81i")
object = File.read!("test/fixtures/quote_post/misskey_quote_post.json") |> Jason.decode!()
message = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"type" => "Create",
"actor" => "https://misskey.io/users/7rkrarq81i",
"object" => object
}
assert {:ok, activity} = Transmogrifier.handle_incoming(message)
# Object was created in the database
object = Object.normalize(activity)
assert object.data["quoteUrl"] == "https://misskey.io/notes/8vs6wxufd0"
# It fetched the quoted post
assert Object.normalize("https://misskey.io/notes/8vs6wxufd0")
end
end
@ -351,68 +369,19 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
}
} = prepared["object"]
end
end
describe "user upgrade" do
test "it upgrades a user to activitypub" do
user =
insert(:user, %{
nickname: "rye@niu.moe",
local: false,
ap_id: "https://niu.moe/users/rye",
follower_address: User.ap_followers(%User{nickname: "rye@niu.moe"})
})
test "it prepares a quote post" do
user = insert(:user)
user_two = insert(:user)
Pleroma.FollowingRelationship.follow(user_two, user, :follow_accept)
{:ok, quoted_post} = CommonAPI.post(user, %{status: "hey"})
{:ok, quote_post} = CommonAPI.post(user, %{status: "hey", quote_id: quoted_post.id})
{:ok, activity} = CommonAPI.post(user, %{status: "test"})
{:ok, unrelated_activity} = CommonAPI.post(user_two, %{status: "test"})
assert "http://localhost:4001/users/rye@niu.moe/followers" in activity.recipients
{:ok, modified} = Transmogrifier.prepare_outgoing(quote_post.data)
user = User.get_cached_by_id(user.id)
assert user.note_count == 1
%{data: %{"id" => quote_id}} = Object.normalize(quoted_post)
{:ok, user} = Transmogrifier.upgrade_user_from_ap_id("https://niu.moe/users/rye")
ObanHelpers.perform_all()
assert user.ap_enabled
assert user.note_count == 1
assert user.follower_address == "https://niu.moe/users/rye/followers"
assert user.following_address == "https://niu.moe/users/rye/following"
user = User.get_cached_by_id(user.id)
assert user.note_count == 1
activity = Activity.get_by_id(activity.id)
assert user.follower_address in activity.recipients
assert %{
"url" => [
%{
"href" =>
"https://cdn.niu.moe/accounts/avatars/000/033/323/original/fd7f8ae0b3ffedc9.jpeg"
}
]
} = user.avatar
assert %{
"url" => [
%{
"href" =>
"https://cdn.niu.moe/accounts/headers/000/033/323/original/850b3448fa5fd477.png"
}
]
} = user.banner
refute "..." in activity.recipients
unrelated_activity = Activity.get_by_id(unrelated_activity.id)
refute user.follower_address in unrelated_activity.recipients
user_two = User.get_cached_by_id(user_two.id)
assert User.following?(user_two, user)
refute "..." in User.following(user_two)
assert modified["object"]["quoteUrl"] == quote_id
assert modified["object"]["quoteUri"] == quote_id
end
end

View file

@ -123,6 +123,7 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
})
%{
reporter: reporter,
id: report_id,
second_report_id: second_report_id
}
@ -266,6 +267,26 @@ defmodule Pleroma.Web.AdminAPI.ReportControllerTest do
assert ModerationLog.get_log_entry_message(second_log_entry) ==
"@#{admin.nickname} updated report ##{second_report_id} (on user @#{second_activity.user_actor.nickname}) with 'closed' state"
end
test "works if reporter is deactivated", %{
conn: conn,
id: id,
reporter: reporter
} do
Pleroma.User.set_activation(reporter, false)
conn
|> put_req_header("content-type", "application/json")
|> patch("/api/pleroma/admin/reports", %{
"reports" => [
%{"state" => "resolved", "id" => id}
]
})
|> json_response_and_validate_schema(:no_content)
activity = Activity.get_by_id_with_user_actor(id)
assert activity.data["state"] == "resolved"
end
end
describe "GET /api/pleroma/admin/reports" do

View file

@ -0,0 +1,33 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.CommonAPI.ActivityDraftTest do
use Pleroma.DataCase
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.CommonAPI.ActivityDraft
import Pleroma.Factory
test "create/2 with a quote post" do
user = insert(:user)
another_user = insert(:user)
{:ok, direct} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
{:ok, private} = CommonAPI.post(user, %{status: ".", visibility: "private"})
{:ok, unlisted} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
{:ok, local} = CommonAPI.post(user, %{status: ".", visibility: "local"})
{:ok, public} = CommonAPI.post(user, %{status: ".", visibility: "public"})
{:error, _} = ActivityDraft.create(user, %{status: "nice", quote_id: direct.id})
{:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: private.id})
{:error, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: private.id})
{:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: unlisted.id})
{:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: unlisted.id})
{:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: local.id})
{:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: local.id})
{:ok, _} = ActivityDraft.create(user, %{status: "nice", quote_id: public.id})
{:ok, _} = ActivityDraft.create(another_user, %{status: "nice", quote_id: public.id})
end
end

View file

@ -200,7 +200,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
{result, _, []} = Utils.format_input(code, "text/markdown")
assert result ==
~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo whats up?</p>]
~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what&#39;s up?</p>]
end
test "remote mentions" do
@ -211,7 +211,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
{result, _, []} = Utils.format_input(code, "text/markdown")
assert result ==
~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo whats up?</p>]
~s[<p><span class="h-card"><a class="u-url mention" data-user="#{mario.id}" href="#{mario.ap_id}" rel="ugc">@<span>mario</span></a></span> <span class="h-card"><a class="u-url mention" data-user="#{luigi.id}" href="#{luigi.ap_id}" rel="ugc">@<span>luigi</span></a></span> yo what&#39;s up?</p>]
end
test "raw HTML" do
@ -229,7 +229,7 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
test "blockquote" do
code = ~s[> whoms't are you quoting?]
{result, [], []} = Utils.format_input(code, "text/markdown")
assert result == "<blockquote><p>whomst are you quoting?</p></blockquote>"
assert result == "<blockquote><p>whoms&#39;t are you quoting?</p></blockquote>"
end
test "code" do
@ -586,41 +586,61 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
end
end
describe "attachments_from_ids_descs/2" do
describe "attachments_from_ids_descs/3" do
test "returns [] when attachment ids is empty" do
assert Utils.attachments_from_ids_descs([], "{}") == []
assert Utils.attachments_from_ids_descs([], "{}", nil) == []
end
test "returns list attachments with desc" do
object = insert(:note)
user = insert(:user)
object = insert(:attachment, %{user: user})
desc = Jason.encode!(%{object.id => "test-desc"})
assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc) == [
assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc, user) == [
Map.merge(object.data, %{"name" => "test-desc"})
]
end
end
describe "attachments_from_ids/1" do
describe "attachments_from_ids/2" do
test "returns attachments with descs" do
object = insert(:note)
user = insert(:user)
object = insert(:attachment, %{user: user})
desc = Jason.encode!(%{object.id => "test-desc"})
assert Utils.attachments_from_ids(%{
media_ids: ["#{object.id}"],
descriptions: desc
}) == [
assert Utils.attachments_from_ids(
%{
media_ids: ["#{object.id}"],
descriptions: desc
},
user
) == [
Map.merge(object.data, %{"name" => "test-desc"})
]
end
test "returns attachments without descs" do
object = insert(:note)
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}) == [object.data]
user = insert(:user)
object = insert(:attachment, %{user: user})
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user) == [object.data]
end
test "returns [] when not pass media_ids" do
assert Utils.attachments_from_ids(%{}) == []
assert Utils.attachments_from_ids(%{}, nil) == []
end
test "returns [] when media_ids not belong to current user" do
user = insert(:user)
user2 = insert(:user)
object = insert(:attachment, %{user: user})
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user2) == []
end
test "checks that the object is of upload type" do
object = insert(:note)
assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, nil) == []
end
end

View file

@ -279,6 +279,24 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} ==
CommonAPI.post_chat_message(author, recipient, "GNO/Linux")
end
test "it reject messages with attachments not belonging to user" do
author = insert(:user)
not_author = insert(:user)
recipient = author
attachment = insert(:attachment, %{user: not_author})
{:error, message} =
CommonAPI.post_chat_message(
author,
recipient,
"123",
media_id: attachment.id
)
assert message == :forbidden
end
end
describe "unblocking" do
@ -393,6 +411,20 @@ defmodule Pleroma.Web.CommonAPITest do
refute Activity.get_by_id(post.id)
end
test "it allows privileged users to delete banned user's posts" do
clear_config([:instance, :moderator_privileges], [:messages_delete])
user = insert(:user)
moderator = insert(:user, is_moderator: true)
{:ok, post} = CommonAPI.post(user, %{status: "namu amida butsu"})
User.set_activation(user, false)
assert {:ok, delete} = CommonAPI.delete(post.id, moderator)
assert delete.local
refute Activity.get_by_id(post.id)
end
end
test "favoriting race condition" do
@ -764,6 +796,65 @@ defmodule Pleroma.Web.CommonAPITest do
scheduled_at: expires_at
)
end
test "it allows quote posting" do
user = insert(:user)
{:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"})
{:ok, quote_post} = CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id})
quoted = Object.normalize(quoted)
quote_post = Object.normalize(quote_post)
assert quote_post.data["quoteUrl"] == quoted.data["id"]
# The OP is not mentioned
refute quoted.data["actor"] in quote_post.data["to"]
end
test "quote posting with explicit addressing doesn't mention the OP" do
user = insert(:user)
{:ok, quoted} = CommonAPI.post(user, %{status: "Hello world"})
{:ok, quote_post} =
CommonAPI.post(user, %{status: "nice post", quote_id: quoted.id, to: []})
assert Object.normalize(quote_post).data["to"] == [Pleroma.Constants.as_public()]
end
test "quote posting visibility" do
user = insert(:user)
another_user = insert(:user)
{:ok, direct} = CommonAPI.post(user, %{status: ".", visibility: "direct"})
{:ok, private} = CommonAPI.post(user, %{status: ".", visibility: "private"})
{:ok, unlisted} = CommonAPI.post(user, %{status: ".", visibility: "unlisted"})
{:ok, local} = CommonAPI.post(user, %{status: ".", visibility: "local"})
{:ok, public} = CommonAPI.post(user, %{status: ".", visibility: "public"})
{:error, _} = CommonAPI.post(user, %{status: "nice", quote_id: direct.id})
{:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: private.id})
{:error, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: private.id})
{:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: unlisted.id})
{:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: unlisted.id})
{:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: local.id})
{:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: local.id})
{:ok, _} = CommonAPI.post(user, %{status: "nice", quote_id: public.id})
{:ok, _} = CommonAPI.post(another_user, %{status: "nice", quote_id: public.id})
end
test "it properly mentions punycode domain" do
user = insert(:user)
_mentioned_user =
insert(:user, ap_id: "https://xn--i2raa.com/users/yyy", nickname: "yyy@xn--i2raa.com")
{:ok, activity} =
CommonAPI.post(user, %{status: "hey @yyy@xn--i2raa.com", content_type: "text/markdown"})
assert "https://xn--i2raa.com/users/yyy" in Object.normalize(activity).data["to"]
end
end
describe "reactions" do
@ -1339,7 +1430,7 @@ defmodule Pleroma.Web.CommonAPITest do
test "cancels a pending follow for a remote user" do
follower = insert(:user)
followed = insert(:user, is_locked: true, local: false, ap_enabled: true)
followed = insert(:user, is_locked: true, local: false)
assert {:ok, follower, followed, %{id: activity_id, data: %{"state" => "pending"}}} =
CommonAPI.follow(follower, followed)

View file

@ -78,16 +78,14 @@ defmodule Pleroma.Web.FederatorTest do
local: false,
nickname: "nick1@domain.com",
ap_id: "https://domain.com/users/nick1",
inbox: inbox1,
ap_enabled: true
inbox: inbox1
})
insert(:user, %{
local: false,
nickname: "nick2@domain2.com",
ap_id: "https://domain2.com/users/nick2",
inbox: inbox2,
ap_enabled: true
inbox: inbox2
})
dt = NaiveDateTime.utc_now()

View file

@ -125,6 +125,28 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
)
end
test "posting a quote post", %{conn: conn} do
user = insert(:user)
{:ok, %{id: activity_id} = activity} = CommonAPI.post(user, %{status: "yolo"})
%{data: %{"id" => quote_url}} = Object.normalize(activity)
conn =
conn
|> put_req_header("content-type", "application/json")
|> post("/api/v1/statuses", %{
"status" => "indeed",
"quote_id" => activity_id
})
assert %{
"id" => id,
"pleroma" => %{"quote" => %{"id" => ^activity_id}, "quote_url" => ^quote_url}
} = json_response_and_validate_schema(conn, 200)
assert Activity.get_by_id(id)
end
test "it fails to create a status if `expires_in` is less or equal than an hour", %{
conn: conn
} do
@ -771,6 +793,49 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
{:ok, local: local, remote: remote}
end
defp local_and_remote_context_activities do
local_user_1 = insert(:user)
local_user_2 = insert(:user)
remote_user = insert(:user, local: false)
{:ok, %{id: id1, data: %{"context" => context}}} =
CommonAPI.post(local_user_1, %{status: "post"})
{:ok, %{id: id2} = post} =
CommonAPI.post(local_user_2, %{status: "local reply", in_reply_to_status_id: id1})
params = %{
"@context" => "https://www.w3.org/ns/activitystreams",
"actor" => remote_user.ap_id,
"type" => "Create",
"context" => context,
"id" => "#{remote_user.ap_id}/activities/1",
"inReplyTo" => post.data["id"],
"object" => %{
"type" => "Note",
"content" => "remote reply",
"context" => context,
"id" => "#{remote_user.ap_id}/objects/1",
"attributedTo" => remote_user.ap_id,
"to" => [
local_user_1.ap_id,
local_user_2.ap_id,
"https://www.w3.org/ns/activitystreams#Public"
]
},
"to" => [
local_user_1.ap_id,
local_user_2.ap_id,
"https://www.w3.org/ns/activitystreams#Public"
]
}
{:ok, job} = Pleroma.Web.Federator.incoming_ap_doc(params)
{:ok, remote_activity} = ObanHelpers.perform(job)
%{locals: [id1, id2], remote: remote_activity.id, context: context}
end
describe "status with restrict unauthenticated activities for local and remote" do
setup do: local_and_remote_activities()
@ -957,6 +1022,230 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
end
end
describe "getting status contexts restricted unauthenticated for local and remote" do
setup do: local_and_remote_context_activities()
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
test "if user is unauthenticated", %{conn: conn, locals: [post_id, _]} do
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
assert json_response_and_validate_schema(res_conn, 200) == %{
"ancestors" => [],
"descendants" => []
}
end
test "if user is unauthenticated reply", %{conn: conn, locals: [_, reply_id]} do
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
assert json_response_and_validate_schema(res_conn, 200) == %{
"ancestors" => [],
"descendants" => []
}
end
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
%{"ancestors" => [], "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert reply_id in descendant_ids
assert remote_reply_id in descendant_ids
end
test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
%{"ancestors" => ancestors, "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids =
ancestors
|> Enum.map(& &1["id"])
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
end
describe "getting status contexts restricted unauthenticated for local" do
setup do: local_and_remote_context_activities()
setup do: clear_config([:restrict_unauthenticated, :activities, :local], true)
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], false)
test "if user is unauthenticated", %{
conn: conn,
locals: [post_id, reply_id],
remote: remote_reply_id
} do
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
%{"ancestors" => [], "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert reply_id not in descendant_ids
assert remote_reply_id in descendant_ids
end
test "if user is unauthenticated reply", %{
conn: conn,
locals: [post_id, reply_id],
remote: remote_reply_id
} do
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
%{"ancestors" => ancestors, "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids =
ancestors
|> Enum.map(& &1["id"])
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert post_id not in ancestor_ids
assert remote_reply_id in descendant_ids
end
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
%{"ancestors" => [], "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert reply_id in descendant_ids
assert remote_reply_id in descendant_ids
end
test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
%{"ancestors" => ancestors, "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids =
ancestors
|> Enum.map(& &1["id"])
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
end
describe "getting status contexts restricted unauthenticated for remote" do
setup do: local_and_remote_context_activities()
setup do: clear_config([:restrict_unauthenticated, :activities, :local], false)
setup do: clear_config([:restrict_unauthenticated, :activities, :remote], true)
test "if user is unauthenticated", %{
conn: conn,
locals: [post_id, reply_id],
remote: remote_reply_id
} do
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
%{"ancestors" => [], "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert reply_id in descendant_ids
assert remote_reply_id not in descendant_ids
end
test "if user is unauthenticated reply", %{
conn: conn,
locals: [post_id, reply_id],
remote: remote_reply_id
} do
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
%{"ancestors" => ancestors, "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids =
ancestors
|> Enum.map(& &1["id"])
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert post_id in ancestor_ids
assert remote_reply_id not in descendant_ids
end
test "if user is authenticated", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{post_id}/context")
%{"ancestors" => [], "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
reply_ids =
descendants
|> Enum.map(& &1["id"])
assert reply_id in reply_ids
assert remote_reply_id in reply_ids
end
test "if user is authenticated reply", %{locals: [post_id, reply_id], remote: remote_reply_id} do
%{conn: conn} = oauth_access(["read"])
res_conn = get(conn, "/api/v1/statuses/#{reply_id}/context")
%{"ancestors" => ancestors, "descendants" => descendants} =
json_response_and_validate_schema(res_conn, 200)
ancestor_ids =
ancestors
|> Enum.map(& &1["id"])
descendant_ids =
descendants
|> Enum.map(& &1["id"])
assert post_id in ancestor_ids
assert remote_reply_id in descendant_ids
end
end
describe "deleting a status" do
test "when you created it" do
%{user: author, conn: conn} = oauth_access(["write:statuses"])
@ -1018,6 +1307,27 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
refute Activity.get_by_id(activity.id)
end
test "when you're privileged and the user is banned", %{conn: conn} do
clear_config([:instance, :moderator_privileges], [:messages_delete])
posting_user = insert(:user, is_active: false)
refute posting_user.is_active
activity = insert(:note_activity, user: posting_user)
user = insert(:user, is_moderator: true)
res_conn =
conn
|> assign(:user, user)
|> assign(:token, insert(:oauth_token, user: user, scopes: ["write:statuses"]))
|> delete("/api/v1/statuses/#{activity.id}")
assert %{} = json_response_and_validate_schema(res_conn, 200)
assert ModerationLog |> Repo.one() |> ModerationLog.get_log_entry_message() ==
"@#{user.nickname} deleted status ##{activity.id}"
refute Activity.get_by_id(activity.id)
end
end
describe "reblogging" do

View file

@ -97,6 +97,42 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
assert user.raw_bio == raw_bio
end
test "updating bio honours bio limit", %{conn: conn} do
bio_limit = Config.get([:instance, :user_bio_length], 5000)
raw_bio = String.duplicate(".", bio_limit + 1)
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"note" => raw_bio})
assert %{"error" => "Bio is too long"} = json_response_and_validate_schema(conn, 413)
end
test "updating name honours name limit", %{conn: conn} do
name_limit = Config.get([:instance, :user_name_length], 100)
name = String.duplicate(".", name_limit + 1)
conn = patch(conn, "/api/v1/accounts/update_credentials", %{"display_name" => name})
assert %{"error" => "Name is too long"} = json_response_and_validate_schema(conn, 413)
end
test "when both name and bio exceeds the limit, display name error", %{conn: conn} do
name_limit = Config.get([:instance, :user_name_length], 100)
bio_limit = Config.get([:instance, :user_bio_length], 5000)
name = String.duplicate(".", name_limit + 1)
raw_bio = String.duplicate(".", bio_limit + 1)
conn =
patch(conn, "/api/v1/accounts/update_credentials", %{
"display_name" => name,
"note" => raw_bio
})
assert %{"error" => "Name is too long"} = json_response_and_validate_schema(conn, 413)
end
test "updates the user's locking status", %{conn: conn} do
conn = patch(conn, "/api/v1/accounts/update_credentials", %{locked: "true"})
@ -595,17 +631,17 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
fields = [%{"name" => "foo", "value" => long_value}]
assert %{"error" => "Invalid request"} ==
assert %{"error" => "One or more field entries are too long"} ==
conn
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|> json_response_and_validate_schema(403)
|> json_response_and_validate_schema(413)
fields = [%{"name" => long_name, "value" => "bar"}]
assert %{"error" => "Invalid request"} ==
assert %{"error" => "One or more field entries are too long"} ==
conn
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|> json_response_and_validate_schema(403)
|> json_response_and_validate_schema(413)
clear_config([:instance, :max_account_fields], 1)
@ -614,10 +650,10 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
%{"name" => "link", "value" => "cofe.io"}
]
assert %{"error" => "Invalid request"} ==
assert %{"error" => "Too many field entries"} ==
conn
|> patch("/api/v1/accounts/update_credentials", %{"fields_attributes" => fields})
|> json_response_and_validate_schema(403)
|> json_response_and_validate_schema(413)
end
end

View file

@ -48,7 +48,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do
id: to_string(scheduled_activity.id),
media_attachments:
%{media_ids: [upload.id]}
|> Utils.attachments_from_ids()
|> Utils.attachments_from_ids(user)
|> Enum.map(&StatusView.render("attachment.json", %{attachment: &1})),
params: %{
in_reply_to_id: to_string(activity.id),

View file

@ -326,6 +326,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
conversation_id: convo_id,
context: object_data["context"],
in_reply_to_account_acct: nil,
quote: nil,
quote_id: nil,
quote_url: nil,
quote_visible: false,
content: %{"text/plain" => HTML.strip_tags(object_data["content"])},
spoiler_text: %{"text/plain" => HTML.strip_tags(object_data["summary"])},
expires_at: nil,
@ -422,6 +426,88 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
assert status.in_reply_to_id == to_string(note.id)
end
test "a quote post" do
post = insert(:note_activity)
user = insert(:user)
{:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id})
{:ok, quoted_quote_post} = CommonAPI.post(user, %{status: "yo", quote_id: quote_post.id})
status = StatusView.render("show.json", %{activity: quoted_quote_post})
assert status.pleroma.quote.id == to_string(quote_post.id)
assert status.pleroma.quote_id == to_string(quote_post.id)
assert status.pleroma.quote_url == Object.normalize(quote_post).data["id"]
assert status.pleroma.quote_visible
# Quotes don't go more than one level deep
refute status.pleroma.quote.pleroma.quote
assert status.pleroma.quote.pleroma.quote_id == to_string(post.id)
assert status.pleroma.quote.pleroma.quote_url == Object.normalize(post).data["id"]
assert status.pleroma.quote.pleroma.quote_visible
# In an index
[status] = StatusView.render("index.json", %{activities: [quoted_quote_post], as: :activity})
assert status.pleroma.quote.id == to_string(quote_post.id)
end
test "quoted private post" do
user = insert(:user)
# Insert a private post
private = insert(:followers_only_note_activity, user: user)
private_object = Object.normalize(private)
# Create a public post quoting the private post
quote_private =
insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => private_object.data["id"]}))
status = StatusView.render("show.json", %{activity: quote_private})
# The quote isn't rendered
refute status.pleroma.quote
assert status.pleroma.quote_url == private_object.data["id"]
refute status.pleroma.quote_visible
# After following the user, the quote is rendered
follower = insert(:user)
CommonAPI.follow(follower, user)
status = StatusView.render("show.json", %{activity: quote_private, for: follower})
assert status.pleroma.quote.id == to_string(private.id)
assert status.pleroma.quote_visible
end
test "quoted direct message" do
# Insert a direct message
direct = insert(:direct_note_activity)
direct_object = Object.normalize(direct)
# Create a public post quoting the direct message
quote_direct =
insert(:note_activity, note: insert(:note, data: %{"quoteUrl" => direct_object.data["id"]}))
status = StatusView.render("show.json", %{activity: quote_direct})
# The quote isn't rendered
refute status.pleroma.quote
assert status.pleroma.quote_url == direct_object.data["id"]
refute status.pleroma.quote_visible
end
test "repost of quote post" do
post = insert(:note_activity)
user = insert(:user)
{:ok, quote_post} = CommonAPI.post(user, %{status: "he", quote_id: post.id})
{:ok, repost} = CommonAPI.repeat(quote_post.id, user)
[status] = StatusView.render("index.json", %{activities: [repost], as: :activity})
assert status.reblog.pleroma.quote.id == to_string(post.id)
end
test "contains mentions" do
user = insert(:user)
mentioned = insert(:user)

View file

@ -54,35 +54,6 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
} = get(conn, "/proxy/hhgfh/eeee/fff")
end
test "it returns a 302 for invalid host", %{conn: conn} do
new_proxy_base = "http://mp.localhost/"
%{scheme: new_proxy_scheme, host: new_proxy_host, port: new_proxy_port} =
URI.parse(new_proxy_base)
clear_config([:media_proxy, :base_url], new_proxy_base)
proxy_url =
MediaProxy.encode_url("https://pleroma.social/logo.jpeg")
|> URI.parse()
|> Map.put(:host, "wronghost")
|> URI.to_string()
expected_url =
URI.parse(proxy_url)
|> Map.put(:host, new_proxy_host)
|> Map.put(:port, new_proxy_port)
|> Map.put(:scheme, new_proxy_scheme)
|> URI.to_string()
with_mock Pleroma.ReverseProxy,
call: fn _conn, _url, _opts -> %Conn{status: :success} end do
conn = get(conn, proxy_url)
assert redirected_to(conn, 302) == expected_url
end
end
test "redirects to valid url when filename is invalidated", %{conn: conn, url: url} do
invalid_url = String.replace(url, "test.png", "test-file.png")
response = get(conn, invalid_url)

View file

@ -182,7 +182,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
{:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
{:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
{:meta, [name: "twitter:card", content: "summary_large_image"], []},
{:meta, [name: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
{:meta, [name: "twitter:image", content: "https://pleroma.gov/tenshi.png"], []},
{:meta, [name: "twitter:image:alt", content: ""], []},
{:meta, [name: "twitter:player:width", content: "1280"], []},
{:meta, [name: "twitter:player:height", content: "1024"], []},
{:meta, [name: "twitter:card", content: "player"], []},

View file

@ -15,4 +15,43 @@ defmodule Pleroma.Web.PleromaAPI.BackupViewTest do
result = BackupView.render("show.json", backup: backup)
assert result.id == backup.id
end
test "it renders the state and processed_number" do
user = insert(:user)
backup = Backup.new(user)
result = BackupView.render("show.json", backup: backup)
assert result.state == to_string(backup.state)
assert result.processed_number == backup.processed_number
end
test "it renders failed state with legacy records" do
backup = %Backup{
id: 0,
content_type: "application/zip",
file_name: "dummy",
file_size: 1,
state: :invalid,
processed: true,
processed_number: 1,
inserted_at: NaiveDateTime.utc_now()
}
result = BackupView.render("show.json", backup: backup)
assert result.state == "complete"
backup = %Backup{
id: 0,
content_type: "application/zip",
file_name: "dummy",
file_size: 1,
state: :invalid,
processed: false,
processed_number: 1,
inserted_at: NaiveDateTime.utc_now()
}
result = BackupView.render("show.json", backup: backup)
assert result.state == "failed"
end
end

View file

@ -24,7 +24,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatMessageReferenceViewTest do
filename: "an_image.jpg"
}
{:ok, upload} = ActivityPub.upload(file, actor: user.ap_id)
{:ok, upload} = ActivityPub.upload(file, actor: recipient.ap_id)
{:ok, activity} =
CommonAPI.post_chat_message(user, recipient, "kippis :firefox:", idempotency_key: "123")

View file

@ -40,30 +40,4 @@ defmodule Pleroma.Web.Plugs.UploadedMediaPlugTest do
&(&1 == {"content-disposition", ~s[inline; filename="\\"cofe\\".gif"]})
)
end
test "denies access to media if wrong Host", %{
attachment_url: attachment_url
} do
conn = get(build_conn(), attachment_url)
assert conn.status == 200
new_media_base = "http://media.localhost:8080"
%{scheme: new_media_scheme, host: new_media_host, port: new_media_port} =
URI.parse(new_media_base)
clear_config([Pleroma.Upload, :base_url], new_media_base)
conn = get(build_conn(), attachment_url)
expected_url =
URI.parse(attachment_url)
|> Map.put(:host, new_media_host)
|> Map.put(:port, new_media_port)
|> Map.put(:scheme, new_media_scheme)
|> URI.to_string()
assert redirected_to(conn, 302) == expected_url
end
end

View file

@ -22,6 +22,10 @@ defmodule Pleroma.Web.StreamerTest do
setup do: clear_config([:instance, :skip_thread_containment])
describe "get_topic/_ (unauthenticated)" do
test "allows no stream" do
assert {:ok, nil} = Streamer.get_topic(nil, nil, nil)
end
test "allows public" do
assert {:ok, "public"} = Streamer.get_topic("public", nil, nil)
assert {:ok, "public:local"} = Streamer.get_topic("public:local", nil, nil)
@ -242,7 +246,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user, oauth_token)
{:ok, activity} = CommonAPI.post(user, %{status: "hey"})
assert_receive {:render_with_user, _, _, ^activity}
assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(user, activity)
end
@ -253,7 +257,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity} = CommonAPI.post(other_user, %{status: "hey"})
{:ok, announce} = CommonAPI.repeat(activity.id, user)
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce, _}
refute Streamer.filtered_by_user?(user, announce)
end
@ -306,7 +310,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, %Pleroma.Activity{data: _data, local: false} = announce} =
Pleroma.Web.ActivityPub.Transmogrifier.handle_incoming(data)
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce}
assert_receive {:render_with_user, Pleroma.Web.StreamerView, "update.json", ^announce, _}
refute Streamer.filtered_by_user?(user, announce)
end
@ -318,7 +322,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user, oauth_token)
Streamer.stream("user", notify)
assert_receive {:render_with_user, _, _, ^notify}
assert_receive {:render_with_user, _, _, ^notify, _}
refute Streamer.filtered_by_user?(user, notify)
end
@ -330,7 +334,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
Streamer.stream("user:notification", notify)
assert_receive {:render_with_user, _, _, ^notify}
assert_receive {:render_with_user, _, _, ^notify, _}
refute Streamer.filtered_by_user?(user, notify)
end
@ -351,7 +355,12 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:pleroma_chat", user, oauth_token)
Streamer.stream("user:pleroma_chat", {user, cm_ref})
text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
text =
StreamerView.render(
"chat_update.json",
%{chat_message_reference: cm_ref},
"user:pleroma_chat:#{user.id}"
)
assert text =~ "hey cirno"
assert_receive {:text, ^text}
@ -369,7 +378,12 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user, oauth_token)
Streamer.stream("user", {user, cm_ref})
text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref})
text =
StreamerView.render(
"chat_update.json",
%{chat_message_reference: cm_ref},
"user:#{user.id}"
)
assert text =~ "hey cirno"
assert_receive {:text, ^text}
@ -390,7 +404,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
Streamer.stream("user:notification", notify)
assert_receive {:render_with_user, _, _, ^notify}
assert_receive {:render_with_user, _, _, ^notify, _}
refute Streamer.filtered_by_user?(user, notify)
end
@ -436,7 +450,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
{:ok, favorite_activity} = CommonAPI.favorite(user2, activity.id)
assert_receive {:render_with_user, _, "notification.json", notif}
assert_receive {:render_with_user, _, "notification.json", notif, _}
assert notif.activity.id == favorite_activity.id
refute Streamer.filtered_by_user?(user, notif)
end
@ -465,7 +479,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user:notification", user, oauth_token)
{:ok, _follower, _followed, follow_activity} = CommonAPI.follow(user2, user)
assert_receive {:render_with_user, _, "notification.json", notif}
assert_receive {:render_with_user, _, "notification.json", notif, _}
assert notif.activity.id == follow_activity.id
refute Streamer.filtered_by_user?(user, notif)
end
@ -530,7 +544,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, edited} = CommonAPI.update(sender, activity, %{status: "mew mew"})
create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"])
assert_receive {:render_with_user, _, "status_update.json", ^create}
assert_receive {:render_with_user, _, "status_update.json", ^create, _}
refute Streamer.filtered_by_user?(user, edited)
end
@ -541,7 +555,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, edited} = CommonAPI.update(user, activity, %{status: "mew mew"})
create = Pleroma.Activity.get_create_by_object_ap_id_with_object(activity.object.data["id"])
assert_receive {:render_with_user, _, "status_update.json", ^create}
assert_receive {:render_with_user, _, "status_update.json", ^create, _}
refute Streamer.filtered_by_user?(user, edited)
end
end
@ -554,7 +568,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
{:ok, activity} = CommonAPI.post(other_user, %{status: "Test"})
assert_receive {:render_with_user, _, _, ^activity}
assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(other_user, activity)
end
@ -654,7 +668,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
Streamer.stream("public", activity)
assert_receive {:render_with_user, _, _, ^activity}
assert_receive {:render_with_user, _, _, ^activity, _}
assert Streamer.filtered_by_user?(user, activity)
end
@ -676,7 +690,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
Streamer.stream("public", activity)
assert_receive {:render_with_user, _, _, ^activity}
assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(user, activity)
end
@ -699,7 +713,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
Streamer.stream("public", activity)
assert_receive {:render_with_user, _, _, ^activity}
assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(user, activity)
end
end
@ -713,7 +727,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("public", user, oauth_token)
{:ok, activity} = CommonAPI.post(blocked_user, %{status: "Test"})
assert_receive {:render_with_user, _, _, ^activity}
assert_receive {:render_with_user, _, _, ^activity, _}
assert Streamer.filtered_by_user?(user, activity)
end
@ -730,17 +744,17 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity_one} = CommonAPI.post(friend, %{status: "hey! @#{blockee.nickname}"})
assert_receive {:render_with_user, _, _, ^activity_one}
assert_receive {:render_with_user, _, _, ^activity_one, _}
assert Streamer.filtered_by_user?(blocker, activity_one)
{:ok, activity_two} = CommonAPI.post(blockee, %{status: "hey! @#{friend.nickname}"})
assert_receive {:render_with_user, _, _, ^activity_two}
assert_receive {:render_with_user, _, _, ^activity_two, _}
assert Streamer.filtered_by_user?(blocker, activity_two)
{:ok, activity_three} = CommonAPI.post(blockee, %{status: "hey! @#{blocker.nickname}"})
assert_receive {:render_with_user, _, _, ^activity_three}
assert_receive {:render_with_user, _, _, ^activity_three, _}
assert Streamer.filtered_by_user?(blocker, activity_three)
end
end
@ -801,7 +815,7 @@ defmodule Pleroma.Web.StreamerTest do
visibility: "private"
})
assert_receive {:render_with_user, _, _, ^activity}
assert_receive {:render_with_user, _, _, ^activity, _}
refute Streamer.filtered_by_user?(user_a, activity)
end
end
@ -819,7 +833,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user1, user1_token)
{:ok, announce_activity} = CommonAPI.repeat(create_activity.id, user2)
assert_receive {:render_with_user, _, _, ^announce_activity}
assert_receive {:render_with_user, _, _, ^announce_activity, _}
assert Streamer.filtered_by_user?(user1, announce_activity)
end
@ -835,7 +849,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user1, user1_token)
{:ok, _announce_activity} = CommonAPI.repeat(create_activity.id, user2)
assert_receive {:render_with_user, _, "notification.json", notif}
assert_receive {:render_with_user, _, "notification.json", notif, _}
assert Streamer.filtered_by_user?(user1, notif)
end
@ -851,7 +865,7 @@ defmodule Pleroma.Web.StreamerTest do
Streamer.get_topic_and_add_socket("user", user1, user1_token)
{:ok, _favorite_activity} = CommonAPI.favorite(user2, create_activity.id)
assert_receive {:render_with_user, _, "notification.json", notif}
assert_receive {:render_with_user, _, "notification.json", notif, _}
refute Streamer.filtered_by_user?(user1, notif)
end
end
@ -866,7 +880,7 @@ defmodule Pleroma.Web.StreamerTest do
{:ok, activity} = CommonAPI.post(user, %{status: "super hot take"})
{:ok, _} = CommonAPI.add_mute(user2, activity)
assert_receive {:render_with_user, _, _, ^activity}
assert_receive {:render_with_user, _, _, ^activity, _}
assert Streamer.filtered_by_user?(user2, activity)
end
end
@ -908,7 +922,7 @@ defmodule Pleroma.Web.StreamerTest do
})
create_activity_id = create_activity.id
assert_receive {:render_with_user, _, _, ^create_activity}
assert_receive {:render_with_user, _, _, ^create_activity, _}
assert_receive {:text, received_conversation1}
assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
@ -943,8 +957,8 @@ defmodule Pleroma.Web.StreamerTest do
visibility: "direct"
})
assert_receive {:render_with_user, _, _, ^create_activity}
assert_receive {:render_with_user, _, _, ^create_activity2}
assert_receive {:render_with_user, _, _, ^create_activity, _}
assert_receive {:render_with_user, _, _, ^create_activity2, _}
assert_receive {:text, received_conversation1}
assert %{"event" => "conversation", "payload" => _} = Jason.decode!(received_conversation1)
assert_receive {:text, received_conversation1}
@ -973,7 +987,7 @@ defmodule Pleroma.Web.StreamerTest do
receive do
{StreamerTest, :ready} ->
assert_receive {:render_with_user, _, "update.json", _}
assert_receive {:render_with_user, _, "update.json", _, _}
receive do
{StreamerTest, :revoked} -> finalize.()

View file

@ -180,5 +180,28 @@ defmodule Pleroma.Web.WebFingerTest do
{:ok, _data} = WebFinger.finger("pekorino@pawoo.net")
end
test "refuses to process XML remote entities" do
Tesla.Mock.mock(fn
%{
url: "https://pawoo.net/.well-known/webfinger?resource=acct:pekorino@pawoo.net"
} ->
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/xml_external_entities.xml"),
headers: [{"content-type", "application/xrd+xml"}]
}}
%{url: "https://pawoo.net/.well-known/host-meta"} ->
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta")
}}
end)
assert :error = WebFinger.finger("pekorino@pawoo.net")
end
end
end

View file

@ -0,0 +1,15 @@
defmodule Pleroma.Web.XMLTest do
use Pleroma.DataCase, async: true
alias Pleroma.Web.XML
test "refuses to parse any entities from XML" do
data = File.read!("test/fixtures/xml_billion_laughs.xml")
assert(:error == XML.parse_document(data))
end
test "refuses to load external entities from XML" do
data = File.read!("test/fixtures/xml_external_entities.xml")
assert(:error == XML.parse_document(data))
end
end

View file

@ -120,9 +120,6 @@ defmodule Pleroma.Web.ConnCase do
Mox.verify_on_exit!()
{:ok,
conn:
Phoenix.ConnTest.build_conn()
|> Map.put(:host, Pleroma.Web.Endpoint.host())}
{:ok, conn: Phoenix.ConnTest.build_conn()}
end
end

View file

@ -50,7 +50,6 @@ defmodule Pleroma.Factory do
last_refreshed_at: NaiveDateTime.utc_now(),
notification_settings: %Pleroma.User.NotificationSetting{},
multi_factor_authentication_settings: %Pleroma.MFA.Settings{},
ap_enabled: true,
keys: pem
}

View file

@ -1380,6 +1380,15 @@ defmodule HttpRequestMock do
}}
end
def get("https://misskey.io/users/83ssedkv53", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/aimu@misskey.io.json"),
headers: activitypub_object_headers()
}}
end
def get("https://gleasonator.com/users/macgirvin", _, _, _) do
{:ok,
%Tesla.Env{
@ -1446,6 +1455,15 @@ defmodule HttpRequestMock do
}}
end
def get("https://misskey.io/notes/8vs6wxufd0", _, _, _) do
{:ok,
%Tesla.Env{
status: 200,
body: File.read!("test/fixtures/tesla_mock/misskey.io_8vs6wxufd0.json"),
headers: activitypub_object_headers()
}}
end
def get(url, query, body, headers) do
{:error,
"Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{inspect(headers)}"}