summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorAlexander Strizhakov <alex.strizhakov@gmail.com>2021-02-03 16:09:28 +0300
committerAlexander Strizhakov <alex.strizhakov@gmail.com>2021-03-25 13:03:40 +0300
commit3ec1dbd9223aa44205e90967175f07cc532501ab (patch)
treec25eed18a5f38b2feb63cb7a889a1c110c0c8f98 /test
parentcaadde3b04cf4c6509cc0841a338503e646221a0 (diff)
downloadpleroma-3ec1dbd9223aa44205e90967175f07cc532501ab.tar.gz
pleroma-3ec1dbd9223aa44205e90967175f07cc532501ab.zip
Let pins federate
- save object ids on pin, instead of activity ids - pins federation - removed pinned_activities field from the users table - activityPub endpoint for user pins - pulling remote users pins
Diffstat (limited to 'test')
-rw-r--r--test/fixtures/collections/featured.json39
-rw-r--r--test/fixtures/masto_pin.json41
-rw-r--r--test/fixtures/statuses/note.json27
-rw-r--r--test/fixtures/users_mock/masto_featured.json18
-rw-r--r--test/fixtures/users_mock/user.json41
-rw-r--r--test/pleroma/user_test.exs45
-rw-r--r--test/pleroma/web/activity_pub/activity_pub_controller_test.exs105
-rw-r--r--test/pleroma/web/activity_pub/activity_pub_test.exs77
-rw-r--r--test/pleroma/web/activity_pub/transmogrifier_test.exs74
-rw-r--r--test/pleroma/web/common_api_test.exs60
-rw-r--r--test/pleroma/web/mastodon_api/controllers/status_controller_test.exs32
-rw-r--r--test/pleroma/web/mastodon_api/views/status_view_test.exs3
-rw-r--r--test/pleroma/web/twitter_api/remote_follow_controller_test.exs30
-rw-r--r--test/support/factory.ex6
-rw-r--r--test/support/http_request_mock.ex23
15 files changed, 601 insertions, 20 deletions
diff --git a/test/fixtures/collections/featured.json b/test/fixtures/collections/featured.json
new file mode 100644
index 000000000..56f8f56fa
--- /dev/null
+++ b/test/fixtures/collections/featured.json
@@ -0,0 +1,39 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://{{domain}}/schemas/litepub-0.1.jsonld",
+ {
+ "@language": "und"
+ }
+ ],
+ "id": "https://{{domain}}/users/{{nickname}}/collections/featured",
+ "orderedItems": [
+ {
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://{{domain}}/schemas/litepub-0.1.jsonld",
+ {
+ "@language": "und"
+ }
+ ],
+ "actor": "https://{{domain}}/users/{{nickname}}",
+ "attachment": [],
+ "attributedTo": "https://{{domain}}/users/{{nickname}}",
+ "cc": [
+ "https://{{domain}}/users/{{nickname}}/followers"
+ ],
+ "content": "",
+ "id": "https://{{domain}}/objects/{{object_id}}",
+ "published": "2021-02-12T15:13:43.915429Z",
+ "sensitive": false,
+ "source": "",
+ "summary": "",
+ "tag": [],
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "type": "Note"
+ }
+ ],
+ "type": "OrderedCollection"
+}
diff --git a/test/fixtures/masto_pin.json b/test/fixtures/masto_pin.json
new file mode 100644
index 000000000..e57a34375
--- /dev/null
+++ b/test/fixtures/masto_pin.json
@@ -0,0 +1,41 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ {
+ "Emoji": "toot:Emoji",
+ "Hashtag": "as:Hashtag",
+ "PropertyValue": "schema:PropertyValue",
+ "alsoKnownAs": {
+ "@id": "as:alsoKnownAs",
+ "@type": "@id"
+ },
+ "atomUri": "ostatus:atomUri",
+ "conversation": "ostatus:conversation",
+ "featured": {
+ "@id": "toot:featured",
+ "@type": "@id"
+ },
+ "focalPoint": {
+ "@container": "@list",
+ "@id": "toot:focalPoint"
+ },
+ "inReplyToAtomUri": "ostatus:inReplyToAtomUri",
+ "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+ "movedTo": {
+ "@id": "as:movedTo",
+ "@type": "@id"
+ },
+ "ostatus": "http://ostatus.org#",
+ "schema": "http://schema.org#",
+ "sensitive": "as:sensitive",
+ "toot": "http://joinmastodon.org/ns#",
+ "value": "schema:value"
+ }
+ ],
+ "id": "https://example.com/users/nickname/statuses/{{id}}",
+ "actor": "https://example.com/users/nickname",
+ "object": "https://example.com/users/nickname/statuses/101355175004496751",
+ "target": "https://example.com/users/nickname/collections/featured",
+ "type": "{{type}}"
+}
diff --git a/test/fixtures/statuses/note.json b/test/fixtures/statuses/note.json
new file mode 100644
index 000000000..41735cbc5
--- /dev/null
+++ b/test/fixtures/statuses/note.json
@@ -0,0 +1,27 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://example.com/schemas/litepub-0.1.jsonld",
+ {
+ "@language": "und"
+ }
+ ],
+ "actor": "https://example.com/users/{{nickname}}",
+ "attachment": [],
+ "attributedTo": "https://example.com/users/{{nickname}}",
+ "cc": [
+ "https://example.com/users/{{nickname}}/followers"
+ ],
+ "content": "Content",
+ "context": "https://example.com/contexts/e4b180e1-7403-477f-aeb4-de57e7a3fe7f",
+ "conversation": "https://example.com/contexts/e4b180e1-7403-477f-aeb4-de57e7a3fe7f",
+ "id": "https://example.com/objects/{{object_id}}",
+ "published": "2019-12-15T22:00:05.279583Z",
+ "sensitive": false,
+ "summary": "",
+ "tag": [],
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "type": "Note"
+}
diff --git a/test/fixtures/users_mock/masto_featured.json b/test/fixtures/users_mock/masto_featured.json
new file mode 100644
index 000000000..646a343ad
--- /dev/null
+++ b/test/fixtures/users_mock/masto_featured.json
@@ -0,0 +1,18 @@
+{
+ "@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"
+ }
+ ],
+ "id": "https://{{domain}}/users/{{nickname}}/collections/featured",
+ "type": "OrderedCollection",
+ "totalItems": 0,
+ "orderedItems": []
+}
diff --git a/test/fixtures/users_mock/user.json b/test/fixtures/users_mock/user.json
new file mode 100644
index 000000000..da2483d02
--- /dev/null
+++ b/test/fixtures/users_mock/user.json
@@ -0,0 +1,41 @@
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://example.com/schemas/litepub-0.1.jsonld",
+ {
+ "@language": "und"
+ }
+ ],
+ "attachment": [],
+ "endpoints": {
+ "oauthAuthorizationEndpoint": "https://example.com/oauth/authorize",
+ "oauthRegistrationEndpoint": "https://example.com/api/v1/apps",
+ "oauthTokenEndpoint": "https://example.com/oauth/token",
+ "sharedInbox": "https://example.com/inbox"
+ },
+ "followers": "https://example.com/users/{{nickname}}/followers",
+ "following": "https://example.com/users/{{nickname}}/following",
+ "icon": {
+ "type": "Image",
+ "url": "https://example.com/media/4e914f5b84e4a259a3f6c2d2edc9ab642f2ab05f3e3d9c52c81fc2d984b3d51e.jpg"
+ },
+ "id": "https://example.com/users/{{nickname}}",
+ "image": {
+ "type": "Image",
+ "url": "https://example.com/media/f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg?name=f739efddefeee49c6e67e947c4811fdc911785c16ae43da4c3684051fbf8da6a.jpg"
+ },
+ "inbox": "https://example.com/users/{{nickname}}/inbox",
+ "manuallyApprovesFollowers": false,
+ "name": "{{nickname}}",
+ "outbox": "https://example.com/users/{{nickname}}/outbox",
+ "preferredUsername": "{{nickname}}",
+ "publicKey": {
+ "id": "https://example.com/users/{{nickname}}#main-key",
+ "owner": "https://example.com/users/{{nickname}}",
+ "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5DLtwGXNZElJyxFGfcVc\nXANhaMadj/iYYQwZjOJTV9QsbtiNBeIK54PJrYuU0/0YIdrvS1iqheX5IwXRhcwa\nhm3ZyLz7XeN9st7FBni4BmZMBtMpxAuYuu5p/jbWy13qAiYOhPreCx0wrWgm/lBD\n9mkgaxIxPooBE0S4ZWEJIDIV1Vft3AWcRUyWW1vIBK0uZzs6GYshbQZB952S0yo4\nFzI1hABGHncH8UvuFauh4EZ8tY7/X5I0pGRnDOcRN1dAht5w5yTA+6r5kebiFQjP\nIzN/eCO/a9Flrj9YGW7HDNtjSOH0A31PLRGlJtJO3yK57dnf5ppyCZGfL4emShQo\ncQIDAQAB\n-----END PUBLIC KEY-----\n\n"
+ },
+ "summary": "your friendly neighborhood pleroma developer<br>I like cute things and distributed systems, and really hate delete and redrafts",
+ "tag": [],
+ "type": "Person",
+ "url": "https://example.com/users/{{nickname}}"
+}
diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs
index 6f5bcab57..d81c1b8eb 100644
--- a/test/pleroma/user_test.exs
+++ b/test/pleroma/user_test.exs
@@ -2338,4 +2338,49 @@ defmodule Pleroma.UserTest do
assert User.active_user_count(6) == 3
assert User.active_user_count(1) == 1
end
+
+ describe "pins" do
+ setup do
+ user = insert(:user)
+
+ [user: user, object_id: object_id_from_created_activity(user)]
+ end
+
+ test "unique pins", %{user: user, object_id: object_id} do
+ assert {:ok, %{pinned_objects: %{^object_id => pinned_at1} = pins} = updated_user} =
+ User.add_pinned_object_id(user, object_id)
+
+ assert Enum.count(pins) == 1
+
+ assert {:ok, %{pinned_objects: %{^object_id => pinned_at2} = pins}} =
+ User.add_pinned_object_id(updated_user, object_id)
+
+ assert pinned_at1 == pinned_at2
+
+ assert Enum.count(pins) == 1
+ end
+
+ test "respects max_pinned_statuses limit", %{user: user, object_id: object_id} do
+ clear_config([:instance, :max_pinned_statuses], 1)
+ {:ok, updated} = User.add_pinned_object_id(user, object_id)
+
+ object_id2 = object_id_from_created_activity(user)
+
+ {:error, %{errors: errors}} = User.add_pinned_object_id(updated, object_id2)
+ assert Keyword.has_key?(errors, :pinned_objects)
+ end
+
+ test "remove_pinned_object_id/2", %{user: user, object_id: object_id} do
+ assert {:ok, updated} = User.add_pinned_object_id(user, object_id)
+
+ {:ok, after_remove} = User.remove_pinned_object_id(updated, object_id)
+ assert after_remove.pinned_objects == %{}
+ end
+ end
+
+ defp object_id_from_created_activity(user) do
+ %{id: id} = insert(:note_activity, user: user)
+ %{object: %{data: %{"id" => object_id}}} = Activity.get_by_id_with_object(id)
+ object_id
+ end
end
diff --git a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
index 19e04d472..a9cbf90c3 100644
--- a/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_controller_test.exs
@@ -636,6 +636,86 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> post("/inbox", non_create_data)
|> json_response(400)
end
+
+ test "accepts Add/Remove activities", %{conn: conn} do
+ object_id = "c61d6733-e256-4fe1-ab13-1e369789423f"
+
+ status =
+ File.read!("test/fixtures/statuses/note.json")
+ |> String.replace("{{nickname}}", "lain")
+ |> String.replace("{{object_id}}", object_id)
+
+ object_url = "https://example.com/objects/#{object_id}"
+
+ user =
+ File.read!("test/fixtures/users_mock/user.json")
+ |> String.replace("{{nickname}}", "lain")
+
+ actor = "https://example.com/users/lain"
+
+ Tesla.Mock.mock(fn
+ %{
+ method: :get,
+ url: ^object_url
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: status,
+ headers: [{"content-type", "application/activity+json"}]
+ }
+
+ %{
+ method: :get,
+ url: ^actor
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: user,
+ headers: [{"content-type", "application/activity+json"}]
+ }
+ end)
+
+ data = %{
+ "id" => "https://example.com/objects/d61d6733-e256-4fe1-ab13-1e369789423f",
+ "actor" => actor,
+ "object" => object_url,
+ "target" => "https://example.com/users/lain/collections/featured",
+ "type" => "Add",
+ "to" => [Pleroma.Constants.as_public()]
+ }
+
+ assert "ok" ==
+ conn
+ |> assign(:valid_signature, true)
+ |> put_req_header("content-type", "application/activity+json")
+ |> post("/inbox", data)
+ |> json_response(200)
+
+ ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
+ assert Activity.get_by_ap_id(data["id"])
+ user = User.get_cached_by_ap_id(data["actor"])
+ assert user.pinned_objects[data["object"]]
+
+ data = %{
+ "id" => "https://example.com/objects/d61d6733-e256-4fe1-ab13-1e369789423d",
+ "actor" => actor,
+ "object" => object_url,
+ "target" => "https://example.com/users/lain/collections/featured",
+ "type" => "Remove",
+ "to" => [Pleroma.Constants.as_public()]
+ }
+
+ assert "ok" ==
+ conn
+ |> assign(:valid_signature, true)
+ |> put_req_header("content-type", "application/activity+json")
+ |> post("/inbox", data)
+ |> json_response(200)
+
+ ObanHelpers.perform(all_enqueued(worker: ReceiverWorker))
+ user = refresh_record(user)
+ refute user.pinned_objects[data["object"]]
+ end
end
describe "/users/:nickname/inbox" do
@@ -1772,4 +1852,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|> json_response(403)
end
end
+
+ test "pinned collection", %{conn: conn} do
+ clear_config([:instance, :max_pinned_statuses], 2)
+ user = insert(:user)
+ objects = insert_list(2, :note, user: user)
+
+ Enum.reduce(objects, user, fn %{data: %{"id" => object_id}}, user ->
+ {:ok, updated} = User.add_pinned_object_id(user, object_id)
+ updated
+ end)
+
+ %{nickname: nickname, featured_address: featured_address, pinned_objects: pinned_objects} =
+ refresh_record(user)
+
+ %{"id" => ^featured_address, "orderedItems" => items} =
+ conn
+ |> get("/users/#{nickname}/collections/featured")
+ |> json_response(200)
+
+ object_ids = Enum.map(items, & &1["id"])
+
+ assert Enum.all?(pinned_objects, fn {obj_id, _} ->
+ obj_id in object_ids
+ end)
+ end
end
diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs
index c7fa452f7..081d00d45 100644
--- a/test/pleroma/web/activity_pub/activity_pub_test.exs
+++ b/test/pleroma/web/activity_pub/activity_pub_test.exs
@@ -235,6 +235,83 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
"url" => [%{"href" => "https://jk.nipponalba.scot/images/profile.jpg"}]
}
end
+
+ test "fetches user featured collection" do
+ ap_id = "https://example.com/users/lain"
+
+ featured_url = "https://example.com/users/lain/collections/featured"
+
+ user_data =
+ "test/fixtures/users_mock/user.json"
+ |> File.read!()
+ |> String.replace("{{nickname}}", "lain")
+ |> Jason.decode!()
+ |> Map.put("featured", featured_url)
+ |> Jason.encode!()
+
+ object_id = Ecto.UUID.generate()
+
+ featured_data =
+ "test/fixtures/collections/featured.json"
+ |> File.read!()
+ |> String.replace("{{domain}}", "example.com")
+ |> String.replace("{{nickname}}", "lain")
+ |> String.replace("{{object_id}}", object_id)
+
+ object_url = "https://example.com/objects/#{object_id}"
+
+ object_data =
+ "test/fixtures/statuses/note.json"
+ |> File.read!()
+ |> String.replace("{{object_id}}", object_id)
+ |> String.replace("{{nickname}}", "lain")
+
+ Tesla.Mock.mock(fn
+ %{
+ method: :get,
+ url: ^ap_id
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: user_data,
+ headers: [{"content-type", "application/activity+json"}]
+ }
+
+ %{
+ method: :get,
+ url: ^featured_url
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: featured_data,
+ headers: [{"content-type", "application/activity+json"}]
+ }
+ end)
+
+ Tesla.Mock.mock_global(fn
+ %{
+ method: :get,
+ url: ^object_url
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: object_data,
+ headers: [{"content-type", "application/activity+json"}]
+ }
+ end)
+
+ {:ok, user} = ActivityPub.make_user_from_ap_id(ap_id)
+ Process.sleep(50)
+
+ assert user.featured_address == featured_url
+ assert Map.has_key?(user.pinned_objects, object_url)
+
+ in_db = Pleroma.User.get_by_ap_id(ap_id)
+ assert in_db.featured_address == featured_url
+ assert Map.has_key?(user.pinned_objects, object_url)
+
+ assert %{data: %{"id" => ^object_url}} = Object.get_by_ap_id(object_url)
+ end
end
test "it fetches the appropriate tag-restricted posts" do
diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs
index 4c3fcb44a..28d7e1e3c 100644
--- a/test/pleroma/web/activity_pub/transmogrifier_test.exs
+++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs
@@ -6,6 +6,8 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
use Oban.Testing, repo: Pleroma.Repo
use Pleroma.DataCase
+ require Pleroma.Constants
+
alias Pleroma.Activity
alias Pleroma.Object
alias Pleroma.Tests.ObanHelpers
@@ -106,6 +108,78 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
assert activity.data["target"] == new_user.ap_id
assert activity.data["type"] == "Move"
end
+
+ test "it accepts Add/Remove activities" do
+ user =
+ "test/fixtures/users_mock/user.json"
+ |> File.read!()
+ |> String.replace("{{nickname}}", "lain")
+
+ object_id = "c61d6733-e256-4fe1-ab13-1e369789423f"
+
+ object =
+ "test/fixtures/statuses/note.json"
+ |> File.read!()
+ |> String.replace("{{nickname}}", "lain")
+ |> String.replace("{{object_id}}", object_id)
+
+ object_url = "https://example.com/objects/#{object_id}"
+
+ actor = "https://example.com/users/lain"
+
+ Tesla.Mock.mock(fn
+ %{
+ method: :get,
+ url: ^actor
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: user,
+ headers: [{"content-type", "application/activity+json"}]
+ }
+
+ %{
+ method: :get,
+ url: ^object_url
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: object,
+ headers: [{"content-type", "application/activity+json"}]
+ }
+ end)
+
+ message = %{
+ "id" => "https://example.com/objects/d61d6733-e256-4fe1-ab13-1e369789423f",
+ "actor" => actor,
+ "object" => object_url,
+ "target" => "https://example.com/users/lain/collections/featured",
+ "type" => "Add",
+ "to" => [Pleroma.Constants.as_public()],
+ "cc" => ["https://example.com/users/lain/followers"]
+ }
+
+ assert {:ok, activity} = Transmogrifier.handle_incoming(message)
+ assert activity.data == message
+ user = User.get_cached_by_ap_id(actor)
+ assert user.pinned_objects[object_url]
+
+ remove = %{
+ "id" => "http://localhost:400/objects/d61d6733-e256-4fe1-ab13-1e369789423d",
+ "actor" => actor,
+ "object" => object_url,
+ "target" => "http://example.com/users/lain/collections/featured",
+ "type" => "Remove",
+ "to" => [Pleroma.Constants.as_public()],
+ "cc" => ["https://example.com/users/lain/followers"]
+ }
+
+ assert {:ok, activity} = Transmogrifier.handle_incoming(remove)
+ assert activity.data == remove
+
+ user = refresh_record(user)
+ refute user.pinned_objects[object_url]
+ end
end
describe "prepare outgoing" do
diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs
index 6619f8fc8..fa55c2832 100644
--- a/test/pleroma/web/common_api_test.exs
+++ b/test/pleroma/web/common_api_test.exs
@@ -827,13 +827,17 @@ defmodule Pleroma.Web.CommonAPITest do
[user: user, activity: activity]
end
+ test "activity not found error", %{user: user} do
+ assert {:error, :not_found} = CommonAPI.pin("id", user)
+ end
+
test "pin status", %{user: user, activity: activity} do
assert {:ok, ^activity} = CommonAPI.pin(activity.id, user)
- id = activity.id
+ %{data: %{"id" => object_id}} = Object.normalize(activity)
user = refresh_record(user)
- assert %User{pinned_activities: [^id]} = user
+ assert user.pinned_objects |> Map.keys() == [object_id]
end
test "pin poll", %{user: user} do
@@ -845,10 +849,11 @@ defmodule Pleroma.Web.CommonAPITest do
assert {:ok, ^activity} = CommonAPI.pin(activity.id, user)
- id = activity.id
+ %{data: %{"id" => object_id}} = Object.normalize(activity)
+
user = refresh_record(user)
- assert %User{pinned_activities: [^id]} = user
+ assert user.pinned_objects |> Map.keys() == [object_id]
end
test "unlisted statuses can be pinned", %{user: user} do
@@ -859,7 +864,7 @@ defmodule Pleroma.Web.CommonAPITest do
test "only self-authored can be pinned", %{activity: activity} do
user = insert(:user)
- assert {:error, "Could not pin"} = CommonAPI.pin(activity.id, user)
+ assert {:error, :ownership_error} = CommonAPI.pin(activity.id, user)
end
test "max pinned statuses", %{user: user, activity: activity_one} do
@@ -869,8 +874,12 @@ defmodule Pleroma.Web.CommonAPITest do
user = refresh_record(user)
- assert {:error, "You have already pinned the maximum number of statuses"} =
- CommonAPI.pin(activity_two.id, user)
+ assert {:error, :pinned_statuses_limit_reached} = CommonAPI.pin(activity_two.id, user)
+ end
+
+ test "only public can be pinned", %{user: user} do
+ {:ok, activity} = CommonAPI.post(user, %{status: "private status", visibility: "private"})
+ {:error, :visibility_error} = CommonAPI.pin(activity.id, user)
end
test "unpin status", %{user: user, activity: activity} do
@@ -884,7 +893,7 @@ defmodule Pleroma.Web.CommonAPITest do
user = refresh_record(user)
- assert %User{pinned_activities: []} = user
+ assert user.pinned_objects == %{}
end
test "should unpin when deleting a status", %{user: user, activity: activity} do
@@ -896,7 +905,40 @@ defmodule Pleroma.Web.CommonAPITest do
user = refresh_record(user)
- assert %User{pinned_activities: []} = user
+ assert user.pinned_objects == %{}
+ end
+
+ test "ephemeral activity won't be deleted if was pinned", %{user: user} do
+ {:ok, activity} = CommonAPI.post(user, %{status: "Hello!", expires_in: 601})
+
+ assert Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id)
+
+ {:ok, _activity} = CommonAPI.pin(activity.id, user)
+ refute Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id)
+
+ user = refresh_record(user)
+ {:ok, _} = CommonAPI.unpin(activity.id, user)
+
+ # recreates expiration job on unpin
+ assert Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity.id)
+ end
+
+ test "ephemeral activity deletion job won't be deleted on pinning error", %{
+ user: user,
+ activity: activity
+ } do
+ clear_config([:instance, :max_pinned_statuses], 1)
+
+ {:ok, _activity} = CommonAPI.pin(activity.id, user)
+
+ {:ok, activity2} = CommonAPI.post(user, %{status: "another status", expires_in: 601})
+
+ assert Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity2.id)
+
+ user = refresh_record(user)
+ {:error, :pinned_statuses_limit_reached} = CommonAPI.pin(activity2.id, user)
+
+ assert Pleroma.Workers.PurgeExpiredActivity.get_expiration(activity2.id)
end
end
diff --git a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
index f616f405e..e0d642910 100644
--- a/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/pleroma/web/mastodon_api/controllers/status_controller_test.exs
@@ -1223,6 +1223,13 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> json_response_and_validate_schema(200)
end
+ test "non authenticated user", %{activity: activity} do
+ assert build_conn()
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses/#{activity.id}/pin")
+ |> json_response(403) == %{"error" => "Invalid credentials."}
+ end
+
test "/pin: returns 400 error when activity is not public", %{conn: conn, user: user} do
{:ok, dm} = CommonAPI.post(user, %{status: "test", visibility: "direct"})
@@ -1231,7 +1238,18 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> put_req_header("content-type", "application/json")
|> post("/api/v1/statuses/#{dm.id}/pin")
- assert json_response_and_validate_schema(conn, 400) == %{"error" => "Could not pin"}
+ assert json_response_and_validate_schema(conn, 422) == %{
+ "error" => "Non-public status cannot be pinned"
+ }
+ end
+
+ test "pin by another user", %{activity: activity} do
+ %{conn: conn} = oauth_access(["write:accounts"])
+
+ assert conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses/#{activity.id}/pin")
+ |> json_response(422) == %{"error" => "Someone else's status cannot be pinned"}
end
test "unpin status", %{conn: conn, user: user, activity: activity} do
@@ -1252,13 +1270,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
|> json_response_and_validate_schema(200)
end
- test "/unpin: returns 400 error when activity is not exist", %{conn: conn} do
- conn =
- conn
- |> put_req_header("content-type", "application/json")
- |> post("/api/v1/statuses/1/unpin")
-
- assert json_response_and_validate_schema(conn, 400) == %{"error" => "Could not unpin"}
+ test "/unpin: returns 404 error when activity doesn't exist", %{conn: conn} do
+ assert conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/statuses/1/unpin")
+ |> json_response_and_validate_schema(404) == %{"error" => "Record not found"}
end
test "max pinned statuses", %{conn: conn, user: user, activity: activity_one} do
diff --git a/test/pleroma/web/mastodon_api/views/status_view_test.exs b/test/pleroma/web/mastodon_api/views/status_view_test.exs
index 4172cc294..fbea25079 100644
--- a/test/pleroma/web/mastodon_api/views/status_view_test.exs
+++ b/test/pleroma/web/mastodon_api/views/status_view_test.exs
@@ -286,7 +286,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
direct_conversation_id: nil,
thread_muted: false,
emoji_reactions: [],
- parent_visible: false
+ parent_visible: false,
+ pinned_at: nil
}
}
diff --git a/test/pleroma/web/twitter_api/remote_follow_controller_test.exs b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
index f389c272b..fa3b29006 100644
--- a/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
+++ b/test/pleroma/web/twitter_api/remote_follow_controller_test.exs
@@ -27,6 +27,16 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
body: File.read!("test/fixtures/tesla_mock/status.emelie.json")
}
+ %{method: :get, url: "https://mastodon.social/users/emelie/collections/featured"} ->
+ %Tesla.Env{
+ status: 200,
+ headers: [{"content-type", "application/activity+json"}],
+ body:
+ File.read!("test/fixtures/users_mock/masto_featured.json")
+ |> String.replace("{{domain}}", "mastodon.social")
+ |> String.replace("{{nickname}}", "emelie")
+ }
+
%{method: :get, url: "https://mastodon.social/users/emelie"} ->
%Tesla.Env{
status: 200,
@@ -52,6 +62,16 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
headers: [{"content-type", "application/activity+json"}],
body: File.read!("test/fixtures/tesla_mock/emelie.json")
}
+
+ %{method: :get, url: "https://mastodon.social/users/emelie/collections/featured"} ->
+ %Tesla.Env{
+ status: 200,
+ headers: [{"content-type", "application/activity+json"}],
+ body:
+ File.read!("test/fixtures/users_mock/masto_featured.json")
+ |> String.replace("{{domain}}", "mastodon.social")
+ |> String.replace("{{nickname}}", "emelie")
+ }
end)
response =
@@ -70,6 +90,16 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowControllerTest do
headers: [{"content-type", "application/activity+json"}],
body: File.read!("test/fixtures/tesla_mock/emelie.json")
}
+
+ %{method: :get, url: "https://mastodon.social/users/emelie/collections/featured"} ->
+ %Tesla.Env{
+ status: 200,
+ headers: [{"content-type", "application/activity+json"}],
+ body:
+ File.read!("test/fixtures/users_mock/masto_featured.json")
+ |> String.replace("{{domain}}", "mastodon.social")
+ |> String.replace("{{nickname}}", "emelie")
+ }
end)
user = insert(:user)
diff --git a/test/support/factory.ex b/test/support/factory.ex
index af4fff45b..883cedf3c 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -48,13 +48,15 @@ defmodule Pleroma.Factory do
%{
ap_id: ap_id,
follower_address: ap_id <> "/followers",
- following_address: ap_id <> "/following"
+ following_address: ap_id <> "/following",
+ featured_address: ap_id <> "/collections/featured"
}
else
%{
ap_id: User.ap_id(user),
follower_address: User.ap_followers(user),
- following_address: User.ap_following(user)
+ following_address: User.ap_following(user),
+ featured_address: User.ap_featured_collection(user)
}
end
diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex
index eb692fab5..9e9f1c86c 100644
--- a/test/support/http_request_mock.ex
+++ b/test/support/http_request_mock.ex
@@ -89,6 +89,18 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://mastodon.sdf.org/users/rinpatch/collections/featured", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ File.read!("test/fixtures/users_mock/masto_featured.json")
+ |> String.replace("{{domain}}", "mastodon.sdf.org")
+ |> String.replace("{{nickname}}", "rinpatch"),
+ headers: [{"content-type", "application/activity+json"}]
+ }}
+ end
+
def get("https://patch.cx/objects/tesla_mock/poll_attachment", _, _, _) do
{:ok,
%Tesla.Env{
@@ -905,6 +917,17 @@ defmodule HttpRequestMock do
}}
end
+ def get("https://mastodon.social/users/lambadalambda/collections/featured", _, _, _) do
+ {:ok,
+ %Tesla.Env{
+ status: 200,
+ body:
+ File.read!("test/fixtures/users_mock/masto_featured.json")
+ |> String.replace("{{domain}}", "mastodon.social")
+ |> String.replace("{{nickname}}", "lambadalambda")
+ }}
+ end
+
def get("https://apfed.club/channel/indio", _, _, _) do
{:ok,
%Tesla.Env{