Merge branch 'develop' into feature/digest-email
This commit is contained in:
commit
6ef145b4fc
73 changed files with 2589 additions and 518 deletions
1
test/fixtures/httpoison_mock/emelie.json
vendored
Normal file
1
test/fixtures/httpoison_mock/emelie.json
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1",{"manuallyApprovesFollowers":"as:manuallyApprovesFollowers","toot":"http://joinmastodon.org/ns#","featured":{"@id":"toot:featured","@type":"@id"},"alsoKnownAs":{"@id":"as:alsoKnownAs","@type":"@id"},"movedTo":{"@id":"as:movedTo","@type":"@id"},"schema":"http://schema.org#","PropertyValue":"schema:PropertyValue","value":"schema:value","Hashtag":"as:Hashtag","Emoji":"toot:Emoji","IdentityProof":"toot:IdentityProof","focalPoint":{"@container":"@list","@id":"toot:focalPoint"}}],"id":"https://mastodon.social/users/emelie","type":"Person","following":"https://mastodon.social/users/emelie/following","followers":"https://mastodon.social/users/emelie/followers","inbox":"https://mastodon.social/users/emelie/inbox","outbox":"https://mastodon.social/users/emelie/outbox","featured":"https://mastodon.social/users/emelie/collections/featured","preferredUsername":"emelie","name":"emelie 🎨","summary":"\u003cp\u003e23 / \u003ca href=\"https://mastodon.social/tags/sweden\" class=\"mention hashtag\" rel=\"tag\"\u003e#\u003cspan\u003eSweden\u003c/span\u003e\u003c/a\u003e / \u003ca href=\"https://mastodon.social/tags/artist\" class=\"mention hashtag\" rel=\"tag\"\u003e#\u003cspan\u003eArtist\u003c/span\u003e\u003c/a\u003e / \u003ca href=\"https://mastodon.social/tags/equestrian\" class=\"mention hashtag\" rel=\"tag\"\u003e#\u003cspan\u003eEquestrian\u003c/span\u003e\u003c/a\u003e / \u003ca href=\"https://mastodon.social/tags/gamedev\" class=\"mention hashtag\" rel=\"tag\"\u003e#\u003cspan\u003eGameDev\u003c/span\u003e\u003c/a\u003e\u003c/p\u003e\u003cp\u003eIf I ain\u0026apos;t spending time with my pets, I\u0026apos;m probably drawing. 🐴 🐱 🐰\u003c/p\u003e","url":"https://mastodon.social/@emelie","manuallyApprovesFollowers":false,"publicKey":{"id":"https://mastodon.social/users/emelie#main-key","owner":"https://mastodon.social/users/emelie","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu3CWs1oAJPE3ZJ9sj6Ut\n/Mu+mTE7MOijsQc8/6c73XVVuhIEomiozJIH7l8a7S1n5SYL4UuiwcubSOi7u1bb\nGpYnp5TYhN+Cxvq/P80V4/ncNIPSQzS49it7nSLeG5pA21lGPDA44huquES1un6p\n9gSmbTwngVX9oe4MYuUeh0Z7vijjU13Llz1cRq/ZgPQPgfz+2NJf+VeXnvyDZDYx\nZPVBBlrMl3VoGbu0M5L8SjY35559KCZ3woIvqRolcoHXfgvJMdPcJgSZVYxlCw3d\nA95q9jQcn6s87CPSUs7bmYEQCrDVn5m5NER5TzwBmP4cgJl9AaDVWQtRd4jFZNTx\nlQIDAQAB\n-----END PUBLIC KEY-----\n"},"tag":[{"type":"Hashtag","href":"https://mastodon.social/explore/sweden","name":"#sweden"},{"type":"Hashtag","href":"https://mastodon.social/explore/gamedev","name":"#gamedev"},{"type":"Hashtag","href":"https://mastodon.social/explore/artist","name":"#artist"},{"type":"Hashtag","href":"https://mastodon.social/explore/equestrian","name":"#equestrian"}],"attachment":[{"type":"PropertyValue","name":"Ko-fi","value":"\u003ca href=\"https://ko-fi.com/emeliepng\" rel=\"me nofollow noopener\" target=\"_blank\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003eko-fi.com/emeliepng\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e"},{"type":"PropertyValue","name":"Instagram","value":"\u003ca href=\"https://www.instagram.com/emelie_png/\" rel=\"me nofollow noopener\" target=\"_blank\"\u003e\u003cspan class=\"invisible\"\u003ehttps://www.\u003c/span\u003e\u003cspan class=\"\"\u003einstagram.com/emelie_png/\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e"},{"type":"PropertyValue","name":"Carrd","value":"\u003ca href=\"https://emelie.carrd.co/\" rel=\"me nofollow noopener\" target=\"_blank\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003eemelie.carrd.co/\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e"},{"type":"PropertyValue","name":"Artstation","value":"\u003ca href=\"https://emiri.artstation.com\" rel=\"me nofollow noopener\" target=\"_blank\"\u003e\u003cspan class=\"invisible\"\u003ehttps://\u003c/span\u003e\u003cspan class=\"\"\u003eemiri.artstation.com\u003c/span\u003e\u003cspan class=\"invisible\"\u003e\u003c/span\u003e\u003c/a\u003e"}],"endpoints":{"sharedInbox":"https://mastodon.social/inbox"},"icon":{"type":"Image","mediaType":"image/png","url":"https://files.mastodon.social/accounts/avatars/000/015/657/original/e7163f98280da1a4.png"},"image":{"type":"Image","mediaType":"image/png","url":"https://files.mastodon.social/accounts/headers/000/015/657/original/847f331f3dd9e38b.png"}}
|
||||
64
test/fixtures/httpoison_mock/rinpatch.json
vendored
Normal file
64
test/fixtures/httpoison_mock/rinpatch.json
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
"https://w3id.org/security/v1",
|
||||
{
|
||||
"manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"featured": {
|
||||
"@id": "toot:featured",
|
||||
"@type": "@id"
|
||||
},
|
||||
"alsoKnownAs": {
|
||||
"@id": "as:alsoKnownAs",
|
||||
"@type": "@id"
|
||||
},
|
||||
"movedTo": {
|
||||
"@id": "as:movedTo",
|
||||
"@type": "@id"
|
||||
},
|
||||
"schema": "http://schema.org#",
|
||||
"PropertyValue": "schema:PropertyValue",
|
||||
"value": "schema:value",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"Emoji": "toot:Emoji",
|
||||
"IdentityProof": "toot:IdentityProof",
|
||||
"focalPoint": {
|
||||
"@container": "@list",
|
||||
"@id": "toot:focalPoint"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://mastodon.sdf.org/users/rinpatch",
|
||||
"type": "Person",
|
||||
"following": "https://mastodon.sdf.org/users/rinpatch/following",
|
||||
"followers": "https://mastodon.sdf.org/users/rinpatch/followers",
|
||||
"inbox": "https://mastodon.sdf.org/users/rinpatch/inbox",
|
||||
"outbox": "https://mastodon.sdf.org/users/rinpatch/outbox",
|
||||
"featured": "https://mastodon.sdf.org/users/rinpatch/collections/featured",
|
||||
"preferredUsername": "rinpatch",
|
||||
"name": "rinpatch",
|
||||
"summary": "<p>umu</p>",
|
||||
"url": "https://mastodon.sdf.org/@rinpatch",
|
||||
"manuallyApprovesFollowers": false,
|
||||
"publicKey": {
|
||||
"id": "https://mastodon.sdf.org/users/rinpatch#main-key",
|
||||
"owner": "https://mastodon.sdf.org/users/rinpatch",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1vbhYKDopb5xzfJB2TZY\n0ZvgxqdAhbSKKkQC5Q2b0ofhvueDy2AuZTnVk1/BbHNlqKlwhJUSpA6LiTZVvtcc\nMn6cmSaJJEg30gRF5GARP8FMcuq8e2jmceiW99NnUX17MQXsddSf2JFUwD0rUE8H\nBsgD7UzE9+zlA/PJOTBO7fvBEz9PTQ3r4sRMTJVFvKz2MU/U+aRNTuexRKMMPnUw\nfp6VWh1F44VWJEQOs4tOEjGiQiMQh5OfBk1w2haT3vrDbQvq23tNpUP1cRomLUtx\nEBcGKi5DMMBzE1RTVT1YUykR/zLWlA+JSmw7P6cWtsHYZovs8dgn8Po3X//6N+ng\nTQIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||
},
|
||||
"tag": [],
|
||||
"attachment": [],
|
||||
"endpoints": {
|
||||
"sharedInbox": "https://mastodon.sdf.org/inbox"
|
||||
},
|
||||
"icon": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/jpeg",
|
||||
"url": "https://mastodon.sdf.org/system/accounts/avatars/000/067/580/original/bf05521bf711b7a0.jpg?1533238802"
|
||||
},
|
||||
"image": {
|
||||
"type": "Image",
|
||||
"mediaType": "image/gif",
|
||||
"url": "https://mastodon.sdf.org/system/accounts/headers/000/067/580/original/a99b987e798f7063.gif?1533278217"
|
||||
}
|
||||
}
|
||||
99
test/fixtures/mastodon-question-activity.json
vendored
Normal file
99
test/fixtures/mastodon-question-activity.json
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
{
|
||||
"@context": [
|
||||
"https://www.w3.org/ns/activitystreams",
|
||||
{
|
||||
"ostatus": "http://ostatus.org#",
|
||||
"atomUri": "ostatus:atomUri",
|
||||
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
|
||||
"conversation": "ostatus:conversation",
|
||||
"sensitive": "as:sensitive",
|
||||
"Hashtag": "as:Hashtag",
|
||||
"toot": "http://joinmastodon.org/ns#",
|
||||
"Emoji": "toot:Emoji",
|
||||
"focalPoint": {
|
||||
"@container": "@list",
|
||||
"@id": "toot:focalPoint"
|
||||
}
|
||||
}
|
||||
],
|
||||
"id": "https://mastodon.sdf.org/users/rinpatch/statuses/102070944809637304/activity",
|
||||
"type": "Create",
|
||||
"actor": "https://mastodon.sdf.org/users/rinpatch",
|
||||
"published": "2019-05-10T09:03:36Z",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://mastodon.sdf.org/users/rinpatch/followers"
|
||||
],
|
||||
"object": {
|
||||
"id": "https://mastodon.sdf.org/users/rinpatch/statuses/102070944809637304",
|
||||
"type": "Question",
|
||||
"summary": null,
|
||||
"inReplyTo": null,
|
||||
"published": "2019-05-10T09:03:36Z",
|
||||
"url": "https://mastodon.sdf.org/@rinpatch/102070944809637304",
|
||||
"attributedTo": "https://mastodon.sdf.org/users/rinpatch",
|
||||
"to": [
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
],
|
||||
"cc": [
|
||||
"https://mastodon.sdf.org/users/rinpatch/followers"
|
||||
],
|
||||
"sensitive": false,
|
||||
"atomUri": "https://mastodon.sdf.org/users/rinpatch/statuses/102070944809637304",
|
||||
"inReplyToAtomUri": null,
|
||||
"conversation": "tag:mastodon.sdf.org,2019-05-10:objectId=15095122:objectType=Conversation",
|
||||
"content": "<p>Why is Tenshi eating a corndog so cute?</p>",
|
||||
"contentMap": {
|
||||
"en": "<p>Why is Tenshi eating a corndog so cute?</p>"
|
||||
},
|
||||
"endTime": "2019-05-11T09:03:36Z",
|
||||
"closed": "2019-05-11T09:03:36Z",
|
||||
"attachment": [],
|
||||
"tag": [],
|
||||
"replies": {
|
||||
"id": "https://mastodon.sdf.org/users/rinpatch/statuses/102070944809637304/replies",
|
||||
"type": "Collection",
|
||||
"first": {
|
||||
"type": "CollectionPage",
|
||||
"partOf": "https://mastodon.sdf.org/users/rinpatch/statuses/102070944809637304/replies",
|
||||
"items": []
|
||||
}
|
||||
},
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "Note",
|
||||
"name": "Dunno",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"totalItems": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"name": "Everyone knows that!",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"totalItems": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"name": "25 char limit is dumb",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"totalItems": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Note",
|
||||
"name": "I can't even fit a funny",
|
||||
"replies": {
|
||||
"type": "Collection",
|
||||
"totalItems": 1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
16
test/fixtures/mastodon-vote.json
vendored
Normal file
16
test/fixtures/mastodon-vote.json
vendored
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"@context": "https://www.w3.org/ns/activitystreams",
|
||||
"actor": "https://mastodon.sdf.org/users/rinpatch",
|
||||
"id": "https://mastodon.sdf.org/users/rinpatch#votes/387/activity",
|
||||
"nickname": "rin",
|
||||
"object": {
|
||||
"attributedTo": "https://mastodon.sdf.org/users/rinpatch",
|
||||
"id": "https://mastodon.sdf.org/users/rinpatch#votes/387",
|
||||
"inReplyTo": "https://testing.uguu.ltd/objects/9d300947-2dcb-445d-8978-9a3b4b84fa14",
|
||||
"name": "suya..",
|
||||
"to": "https://testing.uguu.ltd/users/rin",
|
||||
"type": "Note"
|
||||
},
|
||||
"to": "https://testing.uguu.ltd/users/rin",
|
||||
"type": "Create"
|
||||
}
|
||||
8
test/fixtures/rich_media/ogp-missing-data.html
vendored
Normal file
8
test/fixtures/rich_media/ogp-missing-data.html
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<html prefix="og: http://ogp.me/ns#">
|
||||
<head>
|
||||
<title>Pleroma</title>
|
||||
<meta property="og:title" content="Pleroma" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="https://pleroma.social/" />
|
||||
</head>
|
||||
</html>
|
||||
1
test/fixtures/rich_media/ogp.html
vendored
1
test/fixtures/rich_media/ogp.html
vendored
|
|
@ -5,5 +5,6 @@
|
|||
<meta property="og:type" content="video.movie" />
|
||||
<meta property="og:url" content="http://www.imdb.com/title/tt0117500/" />
|
||||
<meta property="og:image" content="http://ia.media-imdb.com/images/rock.jpg" />
|
||||
<meta property="og:description" content="Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.">
|
||||
</head>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -80,33 +80,6 @@ defmodule Pleroma.NotificationTest do
|
|||
assert nil == Notification.create_notification(activity, muter)
|
||||
end
|
||||
|
||||
test "it disables notifications from people on remote instances" do
|
||||
user = insert(:user, info: %{notification_settings: %{"remote" => false}})
|
||||
other_user = insert(:user)
|
||||
|
||||
create_activity = %{
|
||||
"@context" => "https://www.w3.org/ns/activitystreams",
|
||||
"type" => "Create",
|
||||
"to" => ["https://www.w3.org/ns/activitystreams#Public"],
|
||||
"actor" => other_user.ap_id,
|
||||
"object" => %{
|
||||
"type" => "Note",
|
||||
"content" => "Hi @#{user.nickname}",
|
||||
"attributedTo" => other_user.ap_id
|
||||
}
|
||||
}
|
||||
|
||||
{:ok, %{local: false} = activity} = Transmogrifier.handle_incoming(create_activity)
|
||||
assert nil == Notification.create_notification(activity, user)
|
||||
end
|
||||
|
||||
test "it disables notifications from people on the local instance" do
|
||||
user = insert(:user, info: %{notification_settings: %{"local" => false}})
|
||||
other_user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(other_user, %{"status" => "hey @#{user.nickname}"})
|
||||
assert nil == Notification.create_notification(activity, user)
|
||||
end
|
||||
|
||||
test "it disables notifications from followers" do
|
||||
follower = insert(:user)
|
||||
followed = insert(:user, info: %{notification_settings: %{"followers" => false}})
|
||||
|
|
@ -115,6 +88,13 @@ defmodule Pleroma.NotificationTest do
|
|||
assert nil == Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
test "it disables notifications from non-followers" do
|
||||
follower = insert(:user)
|
||||
followed = insert(:user, info: %{notification_settings: %{"non_followers" => false}})
|
||||
{:ok, activity} = CommonAPI.post(follower, %{"status" => "hey @#{followed.nickname}"})
|
||||
assert nil == Notification.create_notification(activity, followed)
|
||||
end
|
||||
|
||||
test "it disables notifications from people the user follows" do
|
||||
follower = insert(:user, info: %{notification_settings: %{"follows" => false}})
|
||||
followed = insert(:user)
|
||||
|
|
@ -124,6 +104,13 @@ defmodule Pleroma.NotificationTest do
|
|||
assert nil == Notification.create_notification(activity, follower)
|
||||
end
|
||||
|
||||
test "it disables notifications from people the user does not follow" do
|
||||
follower = insert(:user, info: %{notification_settings: %{"non_follows" => false}})
|
||||
followed = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(followed, %{"status" => "hey @#{follower.nickname}"})
|
||||
assert nil == Notification.create_notification(activity, follower)
|
||||
end
|
||||
|
||||
test "it doesn't create a notification for user if he is the activity author" do
|
||||
activity = insert(:note_activity)
|
||||
author = User.get_cached_by_ap_id(activity.data["actor"])
|
||||
|
|
|
|||
|
|
@ -52,6 +52,14 @@ defmodule HttpRequestMock do
|
|||
}}
|
||||
end
|
||||
|
||||
def get("https://mastodon.sdf.org/users/rinpatch", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/httpoison_mock/rinpatch.json")
|
||||
}}
|
||||
end
|
||||
|
||||
def get(
|
||||
"https://mastodon.social/.well-known/webfinger?resource=https://mastodon.social/users/emelie",
|
||||
_,
|
||||
|
|
@ -728,6 +736,14 @@ defmodule HttpRequestMock do
|
|||
{:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/ogp.html")}}
|
||||
end
|
||||
|
||||
def get("http://example.com/ogp-missing-data", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{
|
||||
status: 200,
|
||||
body: File.read!("test/fixtures/rich_media/ogp-missing-data.html")
|
||||
}}
|
||||
end
|
||||
|
||||
def get("http://example.com/malformed", _, _, _) do
|
||||
{:ok,
|
||||
%Tesla.Env{status: 200, body: File.read!("test/fixtures/rich_media/malformed-data.html")}}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ObjectView
|
||||
alias Pleroma.Web.ActivityPub.UserView
|
||||
alias Pleroma.Web.ActivityPub.Utils
|
||||
|
||||
setup_all do
|
||||
Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end)
|
||||
|
|
@ -234,13 +235,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
end
|
||||
|
||||
describe "/users/:nickname/inbox" do
|
||||
test "it inserts an incoming activity into the database", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
setup do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("bcc", [user.ap_id])
|
||||
|
||||
[data: data]
|
||||
end
|
||||
|
||||
test "it inserts an incoming activity into the database", %{conn: conn, data: data} do
|
||||
user = insert(:user)
|
||||
data = Map.put(data, "bcc", [user.ap_id])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|
|
@ -253,16 +258,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert Activity.get_by_ap_id(data["id"])
|
||||
end
|
||||
|
||||
test "it accepts messages from actors that are followed by the user", %{conn: conn} do
|
||||
test "it accepts messages from actors that are followed by the user", %{
|
||||
conn: conn,
|
||||
data: data
|
||||
} do
|
||||
recipient = insert(:user)
|
||||
actor = insert(:user, %{ap_id: "http://mastodon.example.org/users/actor"})
|
||||
|
||||
{:ok, recipient} = User.follow(recipient, actor)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
object =
|
||||
data["object"]
|
||||
|> Map.put("attributedTo", actor.ap_id)
|
||||
|
|
@ -309,13 +313,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert response(conn, 200) =~ note_activity.data["object"]["content"]
|
||||
end
|
||||
|
||||
test "it clears `unreachable` federation status of the sender", %{conn: conn} do
|
||||
test "it clears `unreachable` federation status of the sender", %{conn: conn, data: data} do
|
||||
user = insert(:user)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|> Map.put("bcc", [user.ap_id])
|
||||
data = Map.put(data, "bcc", [user.ap_id])
|
||||
|
||||
sender_host = URI.parse(data["actor"]).host
|
||||
Instances.set_consistently_unreachable(sender_host)
|
||||
|
|
@ -330,6 +330,47 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert "ok" == json_response(conn, 200)
|
||||
assert Instances.reachable?(sender_host)
|
||||
end
|
||||
|
||||
test "it removes all follower collections but actor's", %{conn: conn} do
|
||||
[actor, recipient] = insert_pair(:user)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/activitypub-client-post-activity.json")
|
||||
|> Poison.decode!()
|
||||
|
||||
object = Map.put(data["object"], "attributedTo", actor.ap_id)
|
||||
|
||||
data =
|
||||
data
|
||||
|> Map.put("id", Utils.generate_object_id())
|
||||
|> Map.put("actor", actor.ap_id)
|
||||
|> Map.put("object", object)
|
||||
|> Map.put("cc", [
|
||||
recipient.follower_address,
|
||||
actor.follower_address
|
||||
])
|
||||
|> Map.put("to", [
|
||||
recipient.ap_id,
|
||||
recipient.follower_address,
|
||||
"https://www.w3.org/ns/activitystreams#Public"
|
||||
])
|
||||
|
||||
conn
|
||||
|> assign(:valid_signature, true)
|
||||
|> put_req_header("content-type", "application/activity+json")
|
||||
|> post("/users/#{recipient.nickname}/inbox", data)
|
||||
|> json_response(200)
|
||||
|
||||
activity = Activity.get_by_ap_id(data["id"])
|
||||
|
||||
assert activity.id
|
||||
assert actor.follower_address in activity.recipients
|
||||
assert actor.follower_address in activity.data["cc"]
|
||||
|
||||
refute recipient.follower_address in activity.recipients
|
||||
refute recipient.follower_address in activity.data["cc"]
|
||||
refute recipient.follower_address in activity.data["to"]
|
||||
end
|
||||
end
|
||||
|
||||
describe "/users/:nickname/outbox" do
|
||||
|
|
|
|||
|
|
@ -1186,4 +1186,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
def data_uri do
|
||||
File.read!("test/fixtures/avatar_data_uri")
|
||||
end
|
||||
|
||||
describe "fetch_activities_bounded" do
|
||||
test "fetches private posts for followed users" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "thought I looked cute might delete later :3",
|
||||
"visibility" => "private"
|
||||
})
|
||||
|
||||
[result] = ActivityPub.fetch_activities_bounded([user.follower_address], [])
|
||||
assert result.id == activity.id
|
||||
end
|
||||
|
||||
test "fetches only public posts for other users" do
|
||||
user = insert(:user)
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "#cofe", "visibility" => "public"})
|
||||
|
||||
{:ok, _private_activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "why is tenshi eating a corndog so cute?",
|
||||
"visibility" => "private"
|
||||
})
|
||||
|
||||
[result] = ActivityPub.fetch_activities_bounded([], [user.follower_address])
|
||||
assert result.id == activity.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -113,6 +113,55 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
assert Enum.at(object.data["tag"], 2) == "moo"
|
||||
end
|
||||
|
||||
test "it works for incoming questions" do
|
||||
data = File.read!("test/fixtures/mastodon-question-activity.json") |> Poison.decode!()
|
||||
|
||||
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
assert Enum.all?(object.data["oneOf"], fn choice ->
|
||||
choice["name"] in [
|
||||
"Dunno",
|
||||
"Everyone knows that!",
|
||||
"25 char limit is dumb",
|
||||
"I can't even fit a funny"
|
||||
]
|
||||
end)
|
||||
end
|
||||
|
||||
test "it rewrites Note votes to Answers and increments vote counters on question activities" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "suya...",
|
||||
"poll" => %{"options" => ["suya", "suya.", "suya.."], "expires_in" => 10}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-vote.json")
|
||||
|> Poison.decode!()
|
||||
|> Kernel.put_in(["to"], user.ap_id)
|
||||
|> Kernel.put_in(["object", "inReplyTo"], object.data["id"])
|
||||
|> Kernel.put_in(["object", "to"], user.ap_id)
|
||||
|
||||
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
|
||||
answer_object = Object.normalize(activity)
|
||||
assert answer_object.data["type"] == "Answer"
|
||||
object = Object.get_by_ap_id(object.data["id"])
|
||||
|
||||
assert Enum.any?(
|
||||
object.data["oneOf"],
|
||||
fn
|
||||
%{"name" => "suya..", "replies" => %{"totalItems" => 1}} -> true
|
||||
_ -> false
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
test "it works for incoming notices with contentMap" do
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-post-activity-contentmap.json") |> Poison.decode!()
|
||||
|
|
@ -1209,4 +1258,85 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
|||
{:ok, _} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
end
|
||||
end
|
||||
|
||||
test "Rewrites Answers to Notes" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, poll_activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "suya...",
|
||||
"poll" => %{"options" => ["suya", "suya.", "suya.."], "expires_in" => 10}
|
||||
})
|
||||
|
||||
poll_object = Object.normalize(poll_activity)
|
||||
# TODO: Replace with CommonAPI vote creation when implemented
|
||||
data =
|
||||
File.read!("test/fixtures/mastodon-vote.json")
|
||||
|> Poison.decode!()
|
||||
|> Kernel.put_in(["to"], user.ap_id)
|
||||
|> Kernel.put_in(["object", "inReplyTo"], poll_object.data["id"])
|
||||
|> Kernel.put_in(["object", "to"], user.ap_id)
|
||||
|
||||
{:ok, %Activity{local: false} = activity} = Transmogrifier.handle_incoming(data)
|
||||
{:ok, data} = Transmogrifier.prepare_outgoing(activity.data)
|
||||
|
||||
assert data["object"]["type"] == "Note"
|
||||
end
|
||||
|
||||
describe "fix_explicit_addressing" do
|
||||
setup do
|
||||
user = insert(:user)
|
||||
[user: user]
|
||||
end
|
||||
|
||||
test "moves non-explicitly mentioned actors to cc", %{user: user} do
|
||||
explicitly_mentioned_actors = [
|
||||
"https://pleroma.gold/users/user1",
|
||||
"https://pleroma.gold/user2"
|
||||
]
|
||||
|
||||
object = %{
|
||||
"actor" => user.ap_id,
|
||||
"to" => explicitly_mentioned_actors ++ ["https://social.beepboop.ga/users/dirb"],
|
||||
"cc" => [],
|
||||
"tag" =>
|
||||
Enum.map(explicitly_mentioned_actors, fn href ->
|
||||
%{"type" => "Mention", "href" => href}
|
||||
end)
|
||||
}
|
||||
|
||||
fixed_object = Transmogrifier.fix_explicit_addressing(object)
|
||||
assert Enum.all?(explicitly_mentioned_actors, &(&1 in fixed_object["to"]))
|
||||
refute "https://social.beepboop.ga/users/dirb" in fixed_object["to"]
|
||||
assert "https://social.beepboop.ga/users/dirb" in fixed_object["cc"]
|
||||
end
|
||||
|
||||
test "does not move actor's follower collection to cc", %{user: user} do
|
||||
object = %{
|
||||
"actor" => user.ap_id,
|
||||
"to" => [user.follower_address],
|
||||
"cc" => []
|
||||
}
|
||||
|
||||
fixed_object = Transmogrifier.fix_explicit_addressing(object)
|
||||
assert user.follower_address in fixed_object["to"]
|
||||
refute user.follower_address in fixed_object["cc"]
|
||||
end
|
||||
|
||||
test "removes recipient's follower collection from cc", %{user: user} do
|
||||
recipient = insert(:user)
|
||||
|
||||
object = %{
|
||||
"actor" => user.ap_id,
|
||||
"to" => [recipient.ap_id, "https://www.w3.org/ns/activitystreams#Public"],
|
||||
"cc" => [user.follower_address, recipient.follower_address]
|
||||
}
|
||||
|
||||
fixed_object = Transmogrifier.fix_explicit_addressing(object)
|
||||
|
||||
assert user.follower_address in fixed_object["cc"]
|
||||
refute recipient.follower_address in fixed_object["cc"]
|
||||
refute recipient.follower_address in fixed_object["to"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -117,4 +117,8 @@ defmodule Pleroma.Web.ActivityPub.VisibilityTest do
|
|||
assert Visibility.get_visibility(direct) == "direct"
|
||||
assert Visibility.get_visibility(unlisted) == "unlisted"
|
||||
end
|
||||
|
||||
test "get_visibility with directMessage flag" do
|
||||
assert Visibility.get_visibility(%{data: %{"directMessage" => true}}) == "direct"
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -437,27 +437,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
user = insert(:user, local: false, tags: ["foo", "bar"])
|
||||
conn = get(conn, "/api/pleroma/admin/users?page=1")
|
||||
|
||||
users =
|
||||
[
|
||||
%{
|
||||
"deactivated" => admin.info.deactivated,
|
||||
"id" => admin.id,
|
||||
"nickname" => admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"local" => true,
|
||||
"tags" => []
|
||||
},
|
||||
%{
|
||||
"deactivated" => user.info.deactivated,
|
||||
"id" => user.id,
|
||||
"nickname" => user.nickname,
|
||||
"roles" => %{"admin" => false, "moderator" => false},
|
||||
"local" => false,
|
||||
"tags" => ["foo", "bar"]
|
||||
}
|
||||
]
|
||||
|> Enum.sort_by(& &1["nickname"])
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"count" => 2,
|
||||
"page_size" => 50,
|
||||
"users" => [
|
||||
%{
|
||||
"deactivated" => admin.info.deactivated,
|
||||
"id" => admin.id,
|
||||
"nickname" => admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"local" => true,
|
||||
"tags" => []
|
||||
},
|
||||
%{
|
||||
"deactivated" => user.info.deactivated,
|
||||
"id" => user.id,
|
||||
"nickname" => user.nickname,
|
||||
"roles" => %{"admin" => false, "moderator" => false},
|
||||
"local" => false,
|
||||
"tags" => ["foo", "bar"]
|
||||
}
|
||||
]
|
||||
"users" => users
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -659,35 +663,39 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|> assign(:user, admin)
|
||||
|> get("/api/pleroma/admin/users?filters=local")
|
||||
|
||||
users =
|
||||
[
|
||||
%{
|
||||
"deactivated" => user.info.deactivated,
|
||||
"id" => user.id,
|
||||
"nickname" => user.nickname,
|
||||
"roles" => %{"admin" => false, "moderator" => false},
|
||||
"local" => true,
|
||||
"tags" => []
|
||||
},
|
||||
%{
|
||||
"deactivated" => admin.info.deactivated,
|
||||
"id" => admin.id,
|
||||
"nickname" => admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"local" => true,
|
||||
"tags" => []
|
||||
},
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => old_admin.id,
|
||||
"local" => true,
|
||||
"nickname" => old_admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"tags" => []
|
||||
}
|
||||
]
|
||||
|> Enum.sort_by(& &1["nickname"])
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"count" => 3,
|
||||
"page_size" => 50,
|
||||
"users" => [
|
||||
%{
|
||||
"deactivated" => user.info.deactivated,
|
||||
"id" => user.id,
|
||||
"nickname" => user.nickname,
|
||||
"roles" => %{"admin" => false, "moderator" => false},
|
||||
"local" => true,
|
||||
"tags" => []
|
||||
},
|
||||
%{
|
||||
"deactivated" => admin.info.deactivated,
|
||||
"id" => admin.id,
|
||||
"nickname" => admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"local" => true,
|
||||
"tags" => []
|
||||
},
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => old_admin.id,
|
||||
"local" => true,
|
||||
"nickname" => old_admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"tags" => []
|
||||
}
|
||||
]
|
||||
"users" => users
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -698,27 +706,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
conn = get(conn, "/api/pleroma/admin/users?filters=is_admin")
|
||||
|
||||
users =
|
||||
[
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => admin.id,
|
||||
"nickname" => admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"local" => admin.local,
|
||||
"tags" => []
|
||||
},
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => second_admin.id,
|
||||
"nickname" => second_admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"local" => second_admin.local,
|
||||
"tags" => []
|
||||
}
|
||||
]
|
||||
|> Enum.sort_by(& &1["nickname"])
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"count" => 2,
|
||||
"page_size" => 50,
|
||||
"users" => [
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => admin.id,
|
||||
"nickname" => admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"local" => admin.local,
|
||||
"tags" => []
|
||||
},
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => second_admin.id,
|
||||
"nickname" => second_admin.nickname,
|
||||
"roles" => %{"admin" => true, "moderator" => false},
|
||||
"local" => second_admin.local,
|
||||
"tags" => []
|
||||
}
|
||||
]
|
||||
"users" => users
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -753,27 +765,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
|
|||
|
||||
conn = get(conn, "/api/pleroma/admin/users?tags[]=first&tags[]=second")
|
||||
|
||||
users =
|
||||
[
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => user1.id,
|
||||
"nickname" => user1.nickname,
|
||||
"roles" => %{"admin" => false, "moderator" => false},
|
||||
"local" => user1.local,
|
||||
"tags" => ["first"]
|
||||
},
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => user2.id,
|
||||
"nickname" => user2.nickname,
|
||||
"roles" => %{"admin" => false, "moderator" => false},
|
||||
"local" => user2.local,
|
||||
"tags" => ["second"]
|
||||
}
|
||||
]
|
||||
|> Enum.sort_by(& &1["nickname"])
|
||||
|
||||
assert json_response(conn, 200) == %{
|
||||
"count" => 2,
|
||||
"page_size" => 50,
|
||||
"users" => [
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => user1.id,
|
||||
"nickname" => user1.nickname,
|
||||
"roles" => %{"admin" => false, "moderator" => false},
|
||||
"local" => user1.local,
|
||||
"tags" => ["first"]
|
||||
},
|
||||
%{
|
||||
"deactivated" => false,
|
||||
"id" => user2.id,
|
||||
"nickname" => user2.nickname,
|
||||
"roles" => %{"admin" => false, "moderator" => false},
|
||||
"local" => user2.local,
|
||||
"tags" => ["second"]
|
||||
}
|
||||
]
|
||||
"users" => users
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -78,10 +78,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
user = insert(:user)
|
||||
|
||||
notification_settings = %{
|
||||
"remote" => true,
|
||||
"local" => true,
|
||||
"followers" => true,
|
||||
"follows" => true
|
||||
"follows" => true,
|
||||
"non_follows" => true,
|
||||
"non_followers" => true
|
||||
}
|
||||
|
||||
privacy = user.info.default_scope
|
||||
|
|
|
|||
|
|
@ -146,6 +146,103 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
|||
refute id == third_id
|
||||
end
|
||||
|
||||
describe "posting polls" do
|
||||
test "posting a poll", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
time = NaiveDateTime.utc_now()
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "Who is the #bestgrill?",
|
||||
"poll" => %{"options" => ["Rei", "Asuka", "Misato"], "expires_in" => 420}
|
||||
})
|
||||
|
||||
response = json_response(conn, 200)
|
||||
|
||||
assert Enum.all?(response["poll"]["options"], fn %{"title" => title} ->
|
||||
title in ["Rei", "Asuka", "Misato"]
|
||||
end)
|
||||
|
||||
assert NaiveDateTime.diff(NaiveDateTime.from_iso8601!(response["poll"]["expires_at"]), time) in 420..430
|
||||
refute response["poll"]["expred"]
|
||||
end
|
||||
|
||||
test "option limit is enforced", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
limit = Pleroma.Config.get([:instance, :poll_limits, :max_options])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "desu~",
|
||||
"poll" => %{"options" => Enum.map(0..limit, fn _ -> "desu" end), "expires_in" => 1}
|
||||
})
|
||||
|
||||
%{"error" => error} = json_response(conn, 422)
|
||||
assert error == "Poll can't contain more than #{limit} options"
|
||||
end
|
||||
|
||||
test "option character limit is enforced", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
limit = Pleroma.Config.get([:instance, :poll_limits, :max_option_chars])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "...",
|
||||
"poll" => %{
|
||||
"options" => [Enum.reduce(0..limit, "", fn _, acc -> acc <> "." end)],
|
||||
"expires_in" => 1
|
||||
}
|
||||
})
|
||||
|
||||
%{"error" => error} = json_response(conn, 422)
|
||||
assert error == "Poll options cannot be longer than #{limit} characters each"
|
||||
end
|
||||
|
||||
test "minimal date limit is enforced", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
limit = Pleroma.Config.get([:instance, :poll_limits, :min_expiration])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "imagine arbitrary limits",
|
||||
"poll" => %{
|
||||
"options" => ["this post was made by pleroma gang"],
|
||||
"expires_in" => limit - 1
|
||||
}
|
||||
})
|
||||
|
||||
%{"error" => error} = json_response(conn, 422)
|
||||
assert error == "Expiration date is too soon"
|
||||
end
|
||||
|
||||
test "maximum date limit is enforced", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
limit = Pleroma.Config.get([:instance, :poll_limits, :max_expiration])
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/statuses", %{
|
||||
"status" => "imagine arbitrary limits",
|
||||
"poll" => %{
|
||||
"options" => ["this post was made by pleroma gang"],
|
||||
"expires_in" => limit + 1
|
||||
}
|
||||
})
|
||||
|
||||
%{"error" => error} = json_response(conn, 422)
|
||||
assert error == "Expiration date is too far in the future"
|
||||
end
|
||||
end
|
||||
|
||||
test "posting a sensitive status", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
|
|
@ -317,12 +414,13 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
|||
test "Conversations", %{conn: conn} do
|
||||
user_one = insert(:user)
|
||||
user_two = insert(:user)
|
||||
user_three = insert(:user)
|
||||
|
||||
{:ok, user_two} = User.follow(user_two, user_one)
|
||||
|
||||
{:ok, direct} =
|
||||
CommonAPI.post(user_one, %{
|
||||
"status" => "Hi @#{user_two.nickname}!",
|
||||
"status" => "Hi @#{user_two.nickname}, @#{user_three.nickname}!",
|
||||
"visibility" => "direct"
|
||||
})
|
||||
|
||||
|
|
@ -348,7 +446,10 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
|||
}
|
||||
] = response
|
||||
|
||||
account_ids = Enum.map(res_accounts, & &1["id"])
|
||||
assert length(res_accounts) == 2
|
||||
assert user_two.id in account_ids
|
||||
assert user_three.id in account_ids
|
||||
assert is_binary(res_id)
|
||||
assert unread == true
|
||||
assert res_last_status["id"] == direct.id
|
||||
|
|
@ -2538,7 +2639,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
|||
"stats" => _,
|
||||
"thumbnail" => _,
|
||||
"languages" => _,
|
||||
"registrations" => _
|
||||
"registrations" => _,
|
||||
"poll_limits" => _
|
||||
} = result
|
||||
|
||||
assert email == from_config_email
|
||||
|
|
@ -2684,33 +2786,50 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
|||
|> post("/api/v1/statuses/#{activity_two.id}/pin")
|
||||
|> json_response(400)
|
||||
end
|
||||
end
|
||||
|
||||
test "Status rich-media Card", %{conn: conn, user: user} do
|
||||
describe "cards" do
|
||||
setup do
|
||||
Pleroma.Config.put([:rich_media, :enabled], true)
|
||||
|
||||
on_exit(fn ->
|
||||
Pleroma.Config.put([:rich_media, :enabled], false)
|
||||
end)
|
||||
|
||||
user = insert(:user)
|
||||
%{user: user}
|
||||
end
|
||||
|
||||
test "returns rich-media card", %{conn: conn, user: user} do
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "http://example.com/ogp"})
|
||||
|
||||
card_data = %{
|
||||
"image" => "http://ia.media-imdb.com/images/rock.jpg",
|
||||
"provider_name" => "www.imdb.com",
|
||||
"provider_url" => "http://www.imdb.com",
|
||||
"title" => "The Rock",
|
||||
"type" => "link",
|
||||
"url" => "http://www.imdb.com/title/tt0117500/",
|
||||
"description" =>
|
||||
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
|
||||
"pleroma" => %{
|
||||
"opengraph" => %{
|
||||
"image" => "http://ia.media-imdb.com/images/rock.jpg",
|
||||
"title" => "The Rock",
|
||||
"type" => "video.movie",
|
||||
"url" => "http://www.imdb.com/title/tt0117500/",
|
||||
"description" =>
|
||||
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}/card")
|
||||
|> json_response(200)
|
||||
|
||||
assert response == %{
|
||||
"image" => "http://ia.media-imdb.com/images/rock.jpg",
|
||||
"provider_name" => "www.imdb.com",
|
||||
"provider_url" => "http://www.imdb.com",
|
||||
"title" => "The Rock",
|
||||
"type" => "link",
|
||||
"url" => "http://www.imdb.com/title/tt0117500/",
|
||||
"description" => nil,
|
||||
"pleroma" => %{
|
||||
"opengraph" => %{
|
||||
"image" => "http://ia.media-imdb.com/images/rock.jpg",
|
||||
"title" => "The Rock",
|
||||
"type" => "video.movie",
|
||||
"url" => "http://www.imdb.com/title/tt0117500/"
|
||||
}
|
||||
}
|
||||
}
|
||||
assert response == card_data
|
||||
|
||||
# works with private posts
|
||||
{:ok, activity} =
|
||||
|
|
@ -2722,9 +2841,33 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
|||
|> get("/api/v1/statuses/#{activity.id}/card")
|
||||
|> json_response(200)
|
||||
|
||||
assert response_two == response
|
||||
assert response_two == card_data
|
||||
end
|
||||
|
||||
Pleroma.Config.put([:rich_media, :enabled], false)
|
||||
test "replaces missing description with an empty string", %{conn: conn, user: user} do
|
||||
{:ok, activity} = CommonAPI.post(user, %{"status" => "http://example.com/ogp-missing-data"})
|
||||
|
||||
response =
|
||||
conn
|
||||
|> get("/api/v1/statuses/#{activity.id}/card")
|
||||
|> json_response(:ok)
|
||||
|
||||
assert response == %{
|
||||
"type" => "link",
|
||||
"title" => "Pleroma",
|
||||
"description" => "",
|
||||
"image" => nil,
|
||||
"provider_name" => "pleroma.social",
|
||||
"provider_url" => "https://pleroma.social",
|
||||
"url" => "https://pleroma.social/",
|
||||
"pleroma" => %{
|
||||
"opengraph" => %{
|
||||
"title" => "Pleroma",
|
||||
"type" => "website",
|
||||
"url" => "https://pleroma.social/"
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -2811,31 +2954,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
|||
end
|
||||
end
|
||||
|
||||
test "flavours switching (Pleroma Extension)", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
get_old_flavour =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/api/v1/pleroma/flavour")
|
||||
|
||||
assert "glitch" == json_response(get_old_flavour, 200)
|
||||
|
||||
set_flavour =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/pleroma/flavour/vanilla")
|
||||
|
||||
assert "vanilla" == json_response(set_flavour, 200)
|
||||
|
||||
get_new_flavour =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/pleroma/flavour/vanilla")
|
||||
|
||||
assert json_response(set_flavour, 200) == json_response(get_new_flavour, 200)
|
||||
end
|
||||
|
||||
describe "reports" do
|
||||
setup do
|
||||
reporter = insert(:user)
|
||||
|
|
@ -3421,4 +3539,124 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
|
|||
assert json_response(conn, 403) == %{"error" => "Rate limit exceeded."}
|
||||
end
|
||||
end
|
||||
|
||||
describe "GET /api/v1/polls/:id" do
|
||||
test "returns poll entity for object id", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "Pleroma does",
|
||||
"poll" => %{"options" => ["what Mastodon't", "n't what Mastodoes"], "expires_in" => 20}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, user)
|
||||
|> get("/api/v1/polls/#{object.id}")
|
||||
|
||||
response = json_response(conn, 200)
|
||||
id = object.id
|
||||
assert %{"id" => ^id, "expired" => false, "multiple" => false} = response
|
||||
end
|
||||
|
||||
test "does not expose polls for private statuses", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "Pleroma does",
|
||||
"poll" => %{"options" => ["what Mastodon't", "n't what Mastodoes"], "expires_in" => 20},
|
||||
"visibility" => "private"
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, other_user)
|
||||
|> get("/api/v1/polls/#{object.id}")
|
||||
|
||||
assert json_response(conn, 404)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST /api/v1/polls/:id/votes" do
|
||||
test "votes are added to the poll", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "A very delicious sandwich",
|
||||
"poll" => %{
|
||||
"options" => ["Lettuce", "Grilled Bacon", "Tomato"],
|
||||
"expires_in" => 20,
|
||||
"multiple" => true
|
||||
}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
conn =
|
||||
conn
|
||||
|> assign(:user, other_user)
|
||||
|> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1, 2]})
|
||||
|
||||
assert json_response(conn, 200)
|
||||
object = Object.get_by_id(object.id)
|
||||
|
||||
assert Enum.all?(object.data["anyOf"], fn %{"replies" => %{"totalItems" => total_items}} ->
|
||||
total_items == 1
|
||||
end)
|
||||
end
|
||||
|
||||
test "author can't vote", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "Am I cute?",
|
||||
"poll" => %{"options" => ["Yes", "No"], "expires_in" => 20}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
assert conn
|
||||
|> assign(:user, user)
|
||||
|> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [1]})
|
||||
|> json_response(422) == %{"error" => "Poll's author can't vote"}
|
||||
|
||||
object = Object.get_by_id(object.id)
|
||||
|
||||
refute Enum.at(object.data["oneOf"], 1)["replies"]["totalItems"] == 1
|
||||
end
|
||||
|
||||
test "does not allow multiple choices on a single-choice question", %{conn: conn} do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "The glass is",
|
||||
"poll" => %{"options" => ["half empty", "half full"], "expires_in" => 20}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
assert conn
|
||||
|> assign(:user, other_user)
|
||||
|> post("/api/v1/polls/#{object.id}/votes", %{"choices" => [0, 1]})
|
||||
|> json_response(422) == %{"error" => "Too many choices"}
|
||||
|
||||
object = Object.get_by_id(object.id)
|
||||
|
||||
refute Enum.any?(object.data["oneOf"], fn %{"replies" => %{"totalItems" => total_items}} ->
|
||||
total_items == 1
|
||||
end)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
muted: false,
|
||||
pinned: false,
|
||||
sensitive: false,
|
||||
poll: nil,
|
||||
spoiler_text: HtmlSanitizeEx.basic_html(note.data["object"]["summary"]),
|
||||
visibility: "public",
|
||||
media_attachments: [],
|
||||
|
|
@ -341,4 +342,106 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
|||
StatusView.render("card.json", %{page_url: page_url, rich_media: card})
|
||||
end
|
||||
end
|
||||
|
||||
describe "poll view" do
|
||||
test "renders a poll" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "Is Tenshi eating a corndog cute?",
|
||||
"poll" => %{
|
||||
"options" => ["absolutely!", "sure", "yes", "why are you even asking?"],
|
||||
"expires_in" => 20
|
||||
}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
expected = %{
|
||||
emojis: [],
|
||||
expired: false,
|
||||
id: object.id,
|
||||
multiple: false,
|
||||
options: [
|
||||
%{title: "absolutely!", votes_count: 0},
|
||||
%{title: "sure", votes_count: 0},
|
||||
%{title: "yes", votes_count: 0},
|
||||
%{title: "why are you even asking?", votes_count: 0}
|
||||
],
|
||||
voted: false,
|
||||
votes_count: 0
|
||||
}
|
||||
|
||||
result = StatusView.render("poll.json", %{object: object})
|
||||
expires_at = result.expires_at
|
||||
result = Map.delete(result, :expires_at)
|
||||
|
||||
assert result == expected
|
||||
|
||||
expires_at = NaiveDateTime.from_iso8601!(expires_at)
|
||||
assert NaiveDateTime.diff(expires_at, NaiveDateTime.utc_now()) in 15..20
|
||||
end
|
||||
|
||||
test "detects if it is multiple choice" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "Which Mastodon developer is your favourite?",
|
||||
"poll" => %{
|
||||
"options" => ["Gargron", "Eugen"],
|
||||
"expires_in" => 20,
|
||||
"multiple" => true
|
||||
}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
assert %{multiple: true} = StatusView.render("poll.json", %{object: object})
|
||||
end
|
||||
|
||||
test "detects emoji" do
|
||||
user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "What's with the smug face?",
|
||||
"poll" => %{
|
||||
"options" => [":blank: sip", ":blank::blank: sip", ":blank::blank::blank: sip"],
|
||||
"expires_in" => 20
|
||||
}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
assert %{emojis: [%{shortcode: "blank"}]} =
|
||||
StatusView.render("poll.json", %{object: object})
|
||||
end
|
||||
|
||||
test "detects vote status" do
|
||||
user = insert(:user)
|
||||
other_user = insert(:user)
|
||||
|
||||
{:ok, activity} =
|
||||
CommonAPI.post(user, %{
|
||||
"status" => "Which input devices do you use?",
|
||||
"poll" => %{
|
||||
"options" => ["mouse", "trackball", "trackpoint"],
|
||||
"multiple" => true,
|
||||
"expires_in" => 20
|
||||
}
|
||||
})
|
||||
|
||||
object = Object.normalize(activity)
|
||||
|
||||
{:ok, _, object} = CommonAPI.vote(other_user, object, [1, 2])
|
||||
|
||||
result = StatusView.render("poll.json", %{object: object, for: other_user})
|
||||
|
||||
assert result[:voted] == true
|
||||
assert Enum.at(result[:options], 1)[:votes_count] == 1
|
||||
assert Enum.at(result[:options], 2)[:votes_count] == 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,11 +6,7 @@ defmodule Pleroma.Web.FederatingPlugTest do
|
|||
use Pleroma.Web.ConnCase
|
||||
|
||||
test "returns and halt the conn when federating is disabled" do
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:federating, false)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :federating], false)
|
||||
|
||||
conn =
|
||||
build_conn()
|
||||
|
|
@ -19,11 +15,7 @@ defmodule Pleroma.Web.FederatingPlugTest do
|
|||
assert conn.status == 404
|
||||
assert conn.halted
|
||||
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:federating, true)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :federating], true)
|
||||
end
|
||||
|
||||
test "does nothing when federating is enabled" do
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ defmodule Pleroma.Web.RichMedia.ParserTest do
|
|||
%{
|
||||
image: "http://ia.media-imdb.com/images/rock.jpg",
|
||||
title: "The Rock",
|
||||
description:
|
||||
"Directed by Michael Bay. With Sean Connery, Nicolas Cage, Ed Harris, John Spencer.",
|
||||
type: "video.movie",
|
||||
url: "http://www.imdb.com/title/tt0117500/"
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -144,41 +144,25 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
|||
end
|
||||
|
||||
test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:public, false)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :public], false)
|
||||
|
||||
conn
|
||||
|> get("/api/statuses/public_timeline.json")
|
||||
|> json_response(403)
|
||||
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:public, true)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :public], true)
|
||||
end
|
||||
|
||||
test "returns 200 to authenticated request when the instance is not public",
|
||||
%{conn: conn, user: user} do
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:public, false)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :public], false)
|
||||
|
||||
conn
|
||||
|> with_credentials(user.nickname, "test")
|
||||
|> get("/api/statuses/public_timeline.json")
|
||||
|> json_response(200)
|
||||
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:public, true)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :public], true)
|
||||
end
|
||||
|
||||
test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
|
||||
|
|
@ -214,41 +198,25 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|
|||
setup [:valid_user]
|
||||
|
||||
test "returns 403 to unauthenticated request when the instance is not public", %{conn: conn} do
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:public, false)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :public], false)
|
||||
|
||||
conn
|
||||
|> get("/api/statuses/public_and_external_timeline.json")
|
||||
|> json_response(403)
|
||||
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:public, true)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :public], true)
|
||||
end
|
||||
|
||||
test "returns 200 to authenticated request when the instance is not public",
|
||||
%{conn: conn, user: user} do
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:public, false)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :public], false)
|
||||
|
||||
conn
|
||||
|> with_credentials(user.nickname, "test")
|
||||
|> get("/api/statuses/public_and_external_timeline.json")
|
||||
|> json_response(200)
|
||||
|
||||
instance =
|
||||
Application.get_env(:pleroma, :instance)
|
||||
|> Keyword.put(:public, true)
|
||||
|
||||
Application.put_env(:pleroma, :instance, instance)
|
||||
Pleroma.Config.put([:instance, :public], true)
|
||||
end
|
||||
|
||||
test "returns 200 to unauthenticated request when the instance is public", %{conn: conn} do
|
||||
|
|
|
|||
|
|
@ -102,7 +102,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
conn
|
||||
|> assign(:user, user)
|
||||
|> put("/api/pleroma/notification_settings", %{
|
||||
"remote" => false,
|
||||
"followers" => false,
|
||||
"bar" => 1
|
||||
})
|
||||
|
|
@ -110,8 +109,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
|
|||
|
||||
user = Repo.get(User, user.id)
|
||||
|
||||
assert %{"remote" => false, "local" => true, "followers" => false, "follows" => true} ==
|
||||
user.info.notification_settings
|
||||
assert %{
|
||||
"followers" => false,
|
||||
"follows" => true,
|
||||
"non_follows" => true,
|
||||
"non_followers" => true
|
||||
} == user.info.notification_settings
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -112,9 +112,11 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
|
|||
as_user = UserView.render("show.json", %{user: user, for: user})
|
||||
assert as_user["default_scope"] == user.info.default_scope
|
||||
assert as_user["no_rich_text"] == user.info.no_rich_text
|
||||
assert as_user["pleroma"]["notification_settings"] == user.info.notification_settings
|
||||
as_stranger = UserView.render("show.json", %{user: user})
|
||||
refute as_stranger["default_scope"]
|
||||
refute as_stranger["no_rich_text"]
|
||||
refute as_stranger["pleroma"]["notification_settings"]
|
||||
end
|
||||
|
||||
test "A user for a given other follower", %{user: user} do
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue