From 5c028b8f92aacb296afbd59130d848883f0c3a10 Mon Sep 17 00:00:00 2001 From: Sachin Joshi Date: Fri, 17 May 2019 12:20:31 +0545 Subject: user creation admin api will create multiple users --- test/web/admin_api/admin_api_controller_test.exs | 83 ++++++++++++++++++++++-- 1 file changed, 79 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 6c1897b5a..a0c9fd56f 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -31,12 +31,87 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do |> assign(:user, admin) |> put_req_header("accept", "application/json") |> post("/api/pleroma/admin/users", %{ - "nickname" => "lain", - "email" => "lain@example.org", - "password" => "test" + "users" => [ + %{ + "nickname" => "lain", + "email" => "lain@example.org", + "password" => "test" + } + ] }) - assert json_response(conn, 200) == "lain" + assert json_response(conn, 200) == [ + %{ + "code" => 201, + "data" => %{ + "email" => "lain@example.org", + "nickname" => "lain" + }, + "type" => "success" + } + ] + end + + test "Cannot create user with exisiting email" do + admin = insert(:user, info: %{is_admin: true}) + user = insert(:user) + + conn = + build_conn() + |> assign(:user, admin) + |> put_req_header("accept", "application/json") + |> post("/api/pleroma/admin/users", %{ + "users" => [ + %{ + "nickname" => "lain", + "email" => user.email, + "password" => "test" + } + ] + }) + + assert json_response(conn, 200) == [ + %{ + "code" => 409, + "data" => %{ + "email" => user.email, + "nickname" => "lain" + }, + "error" => "email has already been taken", + "type" => "error" + } + ] + end + + test "Cannot create user with exisiting nickname" do + admin = insert(:user, info: %{is_admin: true}) + user = insert(:user) + + conn = + build_conn() + |> assign(:user, admin) + |> put_req_header("accept", "application/json") + |> post("/api/pleroma/admin/users", %{ + "users" => [ + %{ + "nickname" => user.nickname, + "email" => "someuser@plerama.social", + "password" => "test" + } + ] + }) + + assert json_response(conn, 200) == [ + %{ + "code" => 409, + "data" => %{ + "email" => "someuser@plerama.social", + "nickname" => user.nickname + }, + "error" => "nickname has already been taken", + "type" => "error" + } + ] end end -- cgit v1.2.3 From 5534d4c67675901ab272ee47355ad43dfae99033 Mon Sep 17 00:00:00 2001 From: Sachin Joshi Date: Sat, 1 Jun 2019 11:17:53 +0545 Subject: make bulk user creation from admin works as a transaction --- test/web/admin_api/admin_api_controller_test.exs | 66 ++++++++++++++++++++++-- 1 file changed, 63 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index a0c9fd56f..019905137 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -36,18 +36,31 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "nickname" => "lain", "email" => "lain@example.org", "password" => "test" + }, + %{ + "nickname" => "lain2", + "email" => "lain2@example.org", + "password" => "test" } ] }) assert json_response(conn, 200) == [ %{ - "code" => 201, + "code" => 200, "data" => %{ "email" => "lain@example.org", "nickname" => "lain" }, "type" => "success" + }, + %{ + "code" => 200, + "data" => %{ + "email" => "lain2@example.org", + "nickname" => "lain2" + }, + "type" => "success" } ] end @@ -70,7 +83,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do ] }) - assert json_response(conn, 200) == [ + assert json_response(conn, 409) == [ %{ "code" => 409, "data" => %{ @@ -101,7 +114,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do ] }) - assert json_response(conn, 200) == [ + assert json_response(conn, 409) == [ %{ "code" => 409, "data" => %{ @@ -113,6 +126,53 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do } ] end + + test "Multiple user creation works in transaction" do + admin = insert(:user, info: %{is_admin: true}) + user = insert(:user) + + conn = + build_conn() + |> assign(:user, admin) + |> put_req_header("accept", "application/json") + |> post("/api/pleroma/admin/users", %{ + "users" => [ + %{ + "nickname" => "newuser", + "email" => "newuser@pleroma.social", + "password" => "test" + }, + %{ + "nickname" => "lain", + "email" => user.email, + "password" => "test" + } + ] + }) + + assert json_response(conn, 409) == [ + %{ + "code" => 409, + "data" => %{ + "email" => user.email, + "nickname" => "lain" + }, + "error" => "email has already been taken", + "type" => "error" + }, + %{ + "code" => 409, + "data" => %{ + "email" => "newuser@pleroma.social", + "nickname" => "newuser" + }, + "error" => "", + "type" => "error" + } + ] + + assert User.get_by_nickname("newuser") === nil + end end describe "/api/pleroma/admin/users/:nickname" do -- cgit v1.2.3 From e394fc2eefdd7a4c7edd5fb3c04b445215d4a86c Mon Sep 17 00:00:00 2001 From: Sachin Joshi Date: Sun, 2 Jun 2019 09:48:45 +0545 Subject: fix the flaky test for users creation by admin --- test/web/admin_api/admin_api_controller_test.exs | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) (limited to 'test') diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 9721a4034..86b160246 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -47,24 +47,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do ] }) - assert json_response(conn, 200) == [ - %{ - "code" => 200, - "data" => %{ - "email" => "lain@example.org", - "nickname" => "lain" - }, - "type" => "success" - }, - %{ - "code" => 200, - "data" => %{ - "email" => "lain2@example.org", - "nickname" => "lain2" - }, - "type" => "success" - } - ] + response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type")) + assert response == ["success", "success"] end test "Cannot create user with exisiting email" do -- cgit v1.2.3 From 8ba7a151adf77c5cc47d6e1364a6078cc4bdef98 Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Mon, 22 Jul 2019 16:45:54 +0200 Subject: Cleanup: fix a comment --- test/web/mastodon_api/mastodon_api_controller_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index ce2e44499..b5279412f 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -405,7 +405,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do assert %{"visibility" => "direct"} = status assert status["url"] != direct.data["id"] - # User should be able to see his own direct message + # User should be able to see their own direct message res_conn = build_conn() |> assign(:user, user_one) -- cgit v1.2.3 From 666514194a325e2463c05bae516b89d7c5f59316 Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Mon, 22 Jul 2019 14:16:20 +0200 Subject: Add activity expirations table Add a table to store activity expirations. An activity can have zero or one expirations. The expiration has a scheduled_at field which stores the time at which the activity should expire and be deleted. --- test/activity_expiration_test.exs | 21 +++++++++++++++++++++ test/activity_test.exs | 9 +++++++++ test/support/factory.ex | 19 ++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 test/activity_expiration_test.exs (limited to 'test') diff --git a/test/activity_expiration_test.exs b/test/activity_expiration_test.exs new file mode 100644 index 000000000..20566a186 --- /dev/null +++ b/test/activity_expiration_test.exs @@ -0,0 +1,21 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.ActivityExpirationTest do + use Pleroma.DataCase + alias Pleroma.ActivityExpiration + import Pleroma.Factory + + test "finds activities due to be deleted only" do + activity = insert(:note_activity) + expiration_due = insert(:expiration_in_the_past, %{activity_id: activity.id}) + activity2 = insert(:note_activity) + insert(:expiration_in_the_future, %{activity_id: activity2.id}) + + expirations = ActivityExpiration.due_expirations() + + assert length(expirations) == 1 + assert hd(expirations) == expiration_due + end +end diff --git a/test/activity_test.exs b/test/activity_test.exs index b27f6fd36..785c4b3cf 100644 --- a/test/activity_test.exs +++ b/test/activity_test.exs @@ -164,4 +164,13 @@ defmodule Pleroma.ActivityTest do Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated) end end + + test "add an activity with an expiration" do + activity = insert(:note_activity) + insert(:expiration_in_the_future, %{activity_id: activity.id}) + + Pleroma.ActivityExpiration + |> where([a], a.activity_id == ^activity.id) + |> Repo.one!() + end end diff --git a/test/support/factory.ex b/test/support/factory.ex index c751546ce..7b52b1328 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -1,5 +1,5 @@ # Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors +# Copyright © 2017-2019 Pleroma Authors # SPDX-License-Identifier: AGPL-3.0-only defmodule Pleroma.Factory do @@ -142,6 +142,23 @@ defmodule Pleroma.Factory do |> Map.merge(attrs) end + defp expiration_offset_by_minutes(attrs, minutes) do + %Pleroma.ActivityExpiration{} + |> Map.merge(attrs) + |> Map.put( + :scheduled_at, + NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(minutes), :millisecond) + ) + end + + def expiration_in_the_past_factory(attrs \\ %{}) do + expiration_offset_by_minutes(attrs, -60) + end + + def expiration_in_the_future_factory(attrs \\ %{}) do + expiration_offset_by_minutes(attrs, 60) + end + def article_activity_factory do article = insert(:article) -- cgit v1.2.3 From 378f5f0fbe21c2533719fed9afe8313586fda5d5 Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Mon, 22 Jul 2019 14:18:58 +0200 Subject: Add activity expiration worker This is a worker that runs every minute and deletes expired activities. It's based heavily on the scheduled activities worker. --- test/activity_expiration_worker_test.exs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 test/activity_expiration_worker_test.exs (limited to 'test') diff --git a/test/activity_expiration_worker_test.exs b/test/activity_expiration_worker_test.exs new file mode 100644 index 000000000..939d912f1 --- /dev/null +++ b/test/activity_expiration_worker_test.exs @@ -0,0 +1,17 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.ActivityExpirationWorkerTest do + use Pleroma.DataCase + alias Pleroma.Activity + import Pleroma.Factory + + test "deletes an activity" do + activity = insert(:note_activity) + expiration = insert(:expiration_in_the_past, %{activity_id: activity.id}) + Pleroma.ActivityExpirationWorker.perform(:execute, expiration.id) + + refute Repo.get(Activity, activity.id) + end +end -- cgit v1.2.3 From 704960b3c135d2e050308c68f5ccf5d7b7df40f8 Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Mon, 22 Jul 2019 16:46:20 +0200 Subject: Add support for activity expiration to common and Masto API The "expires_at" parameter accepts an ISO8601-formatted date which defines when the activity will expire. At this point the API will not give you any feedback about if your post will expire or not. --- test/support/factory.ex | 10 ++++++---- test/web/common_api/common_api_test.exs | 17 +++++++++++++++++ .../web/mastodon_api/mastodon_api_controller_test.exs | 19 +++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) (limited to 'test') diff --git a/test/support/factory.ex b/test/support/factory.ex index 7b52b1328..63fe3a66d 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -143,12 +143,14 @@ defmodule Pleroma.Factory do end defp expiration_offset_by_minutes(attrs, minutes) do + scheduled_at = + NaiveDateTime.utc_now() + |> NaiveDateTime.add(:timer.minutes(minutes), :millisecond) + |> NaiveDateTime.truncate(:second) + %Pleroma.ActivityExpiration{} |> Map.merge(attrs) - |> Map.put( - :scheduled_at, - NaiveDateTime.add(NaiveDateTime.utc_now(), :timer.minutes(minutes), :millisecond) - ) + |> Map.put(:scheduled_at, scheduled_at) end def expiration_in_the_past_factory(attrs \\ %{}) do diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index 16b3f121d..210314a4a 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -160,6 +160,23 @@ defmodule Pleroma.Web.CommonAPITest do Pleroma.Config.put([:instance, :limit], limit) end + + test "it can handle activities that expire" do + user = insert(:user) + + expires_at = + NaiveDateTime.utc_now() + |> NaiveDateTime.truncate(:second) + |> NaiveDateTime.add(1_000_000, :second) + + expires_at_iso8601 = expires_at |> NaiveDateTime.to_iso8601() + + assert {:ok, activity} = + CommonAPI.post(user, %{"status" => "chai", "expires_at" => expires_at_iso8601}) + + assert expiration = Pleroma.ActivityExpiration.get_by_activity_id(activity.id) + assert expiration.scheduled_at == expires_at + end end describe "reactions" do diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index b5279412f..24482a4a2 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -7,6 +7,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do alias Ecto.Changeset alias Pleroma.Activity + alias Pleroma.ActivityExpiration alias Pleroma.Notification alias Pleroma.Object alias Pleroma.Repo @@ -151,6 +152,24 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do assert %{"id" => third_id} = json_response(conn_three, 200) refute id == third_id + + # An activity that will expire: + expires_at = + NaiveDateTime.utc_now() + |> NaiveDateTime.add(:timer.minutes(120), :millisecond) + |> NaiveDateTime.truncate(:second) + + conn_four = + conn + |> post("api/v1/statuses", %{ + "status" => "oolong", + "expires_at" => expires_at + }) + + assert %{"id" => fourth_id} = json_response(conn_four, 200) + assert activity = Activity.get_by_id(fourth_id) + assert expiration = ActivityExpiration.get_by_activity_id(fourth_id) + assert expiration.scheduled_at == expires_at end test "replying to a status", %{conn: conn} do -- cgit v1.2.3 From 36012ef6c1dfea2489e61063e14783fa3fb52700 Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Tue, 23 Jul 2019 16:33:45 +0200 Subject: Require that ephemeral posts live for at least one hour If we didn't put some kind of lifetime requirement on these, I guess you could annoy people by sending large numbers of ephemeral posts that provoke notifications but then disappear before anyone can read them. --- test/activity_expiration_test.exs | 6 ++++++ test/support/factory.ex | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/activity_expiration_test.exs b/test/activity_expiration_test.exs index 20566a186..4948fae16 100644 --- a/test/activity_expiration_test.exs +++ b/test/activity_expiration_test.exs @@ -18,4 +18,10 @@ defmodule Pleroma.ActivityExpirationTest do assert length(expirations) == 1 assert hd(expirations) == expiration_due end + + test "denies expirations that don't live long enough" do + activity = insert(:note_activity) + now = NaiveDateTime.utc_now() + assert {:error, _} = ActivityExpiration.create(activity, now) + end end diff --git a/test/support/factory.ex b/test/support/factory.ex index 63fe3a66d..7a2ddcada 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -158,7 +158,7 @@ defmodule Pleroma.Factory do end def expiration_in_the_future_factory(attrs \\ %{}) do - expiration_offset_by_minutes(attrs, 60) + expiration_offset_by_minutes(attrs, 61) end def article_activity_factory do -- cgit v1.2.3 From 3cb471ec0688b81c8ef37dd27f2b82e6c858431f Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Wed, 24 Jul 2019 12:43:20 +0200 Subject: Expose expires_at datetime in mastoAPI only for the activity actor In the "pleroma" section of the MastoAPI for status activities you can see an expires_at item that states when the activity will expire, or nothing if the activity will not expire. The expires_at date is only visible to the person who posted the activity. This is the conservative approach in case some attacker decides to write a logger for expiring posts. However, in the future of OCAP, signed requests, and all that stuff, this attack might not be that likely. Some other pleroma dev should remove the restriction in the code at that time, if they're satisfied with the security implications of doing so. --- test/web/mastodon_api/mastodon_api_controller_test.exs | 3 ++- test/web/mastodon_api/status_view_test.exs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index 24482a4a2..e59908979 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -166,10 +166,11 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do "expires_at" => expires_at }) - assert %{"id" => fourth_id} = json_response(conn_four, 200) + assert fourth_response = %{"id" => fourth_id} = json_response(conn_four, 200) assert activity = Activity.get_by_id(fourth_id) assert expiration = ActivityExpiration.get_by_activity_id(fourth_id) assert expiration.scheduled_at == expires_at + assert fourth_response["pleroma"]["expires_at"] == NaiveDateTime.to_iso8601(expires_at) end test "replying to a status", %{conn: conn} do diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs index 3447c5b1f..073c69659 100644 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@ -133,7 +133,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do conversation_id: convo_id, in_reply_to_account_acct: nil, content: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["content"])}, - spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["summary"])} + spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["summary"])}, + expires_at: nil } } -- cgit v1.2.3 From 2981821db834448bf9b2ba26590314e36201664c Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Wed, 24 Jul 2019 16:51:09 +0200 Subject: squash! Expose expires_at datetime in mastoAPI only for the activity actor NOTE: rewrite the commit msg --- test/web/mastodon_api/mastodon_api_controller_test.exs | 2 +- test/web/mastodon_api/status_view_test.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index e59908979..a9d38c06e 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -170,7 +170,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do assert activity = Activity.get_by_id(fourth_id) assert expiration = ActivityExpiration.get_by_activity_id(fourth_id) assert expiration.scheduled_at == expires_at - assert fourth_response["pleroma"]["expires_at"] == NaiveDateTime.to_iso8601(expires_at) + assert fourth_response["pleroma"]["expires_in"] > 0 end test "replying to a status", %{conn: conn} do diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs index 073c69659..eb0874ab2 100644 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@ -134,7 +134,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do in_reply_to_account_acct: nil, content: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["content"])}, spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["summary"])}, - expires_at: nil + expires_in: nil } } -- cgit v1.2.3 From 2c83eb0b157b2f574f55341e9171f0b5ab7bd3b2 Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Wed, 24 Jul 2019 17:09:59 +0200 Subject: Revert "squash! Expose expires_at datetime in mastoAPI only for the activity actor" This reverts commit 2981821db834448bf9b2ba26590314e36201664c. --- test/web/mastodon_api/mastodon_api_controller_test.exs | 2 +- test/web/mastodon_api/status_view_test.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'test') diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index a9d38c06e..e59908979 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -170,7 +170,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do assert activity = Activity.get_by_id(fourth_id) assert expiration = ActivityExpiration.get_by_activity_id(fourth_id) assert expiration.scheduled_at == expires_at - assert fourth_response["pleroma"]["expires_in"] > 0 + assert fourth_response["pleroma"]["expires_at"] == NaiveDateTime.to_iso8601(expires_at) end test "replying to a status", %{conn: conn} do diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs index eb0874ab2..073c69659 100644 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@ -134,7 +134,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do in_reply_to_account_acct: nil, content: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["content"])}, spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["summary"])}, - expires_in: nil + expires_at: nil } } -- cgit v1.2.3 From 0e2b5a3e6aed7947909c2a1ff1618403546f1572 Mon Sep 17 00:00:00 2001 From: Mike Verdone Date: Wed, 24 Jul 2019 17:25:11 +0200 Subject: WIP --- test/web/mastodon_api/mastodon_api_controller_test.exs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index e59908979..fbe0ab375 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -154,23 +154,27 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do refute id == third_id # An activity that will expire: - expires_at = - NaiveDateTime.utc_now() - |> NaiveDateTime.add(:timer.minutes(120), :millisecond) - |> NaiveDateTime.truncate(:second) + expires_in = 120 conn_four = conn |> post("api/v1/statuses", %{ "status" => "oolong", - "expires_at" => expires_at + "expires_in" => expires_in }) assert fourth_response = %{"id" => fourth_id} = json_response(conn_four, 200) assert activity = Activity.get_by_id(fourth_id) assert expiration = ActivityExpiration.get_by_activity_id(fourth_id) - assert expiration.scheduled_at == expires_at - assert fourth_response["pleroma"]["expires_at"] == NaiveDateTime.to_iso8601(expires_at) + + estimated_expires_at = + NaiveDateTime.utc_now() + |> NaiveDateTime.add(:timer.minutes(expires_in), :millisecond) + |> NaiveDateTime.truncate(:second) + + # This assert will fail if the test takes longer than a minute. I sure hope it never does: + assert abs(NaiveDateTime.diff(expiration.scheduled_at, estimated_expires_at, :second)) < 60 + assert fourth_response["pleroma"]["expires_at"] == NaiveDateTime.to_iso8601(expiration.scheduled_at) end test "replying to a status", %{conn: conn} do -- cgit v1.2.3 From 64bfb41c553a45855e86737298185c1395bbb350 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Thu, 22 Aug 2019 06:57:55 +0300 Subject: fixed unfollow for relay actor --- .../activity_pub/activity_pub_controller_test.exs | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'test') diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index 77f5e39fa..cf71066fd 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -12,6 +12,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do alias Pleroma.Web.ActivityPub.ObjectView alias Pleroma.Web.ActivityPub.UserView alias Pleroma.Web.ActivityPub.Utils + alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.CommonAPI setup_all do @@ -593,6 +594,34 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do end end + describe "/relay/followers" do + test "it returns relay followers", %{conn: conn} do + relay_actor = Relay.get_actor() + user = insert(:user) + User.follow(user, relay_actor) + + result = + conn + |> assign(:relay, true) + |> get("/relay/followers") + |> json_response(200) + + assert result["first"]["orderedItems"] == [user.ap_id] + end + end + + describe "/relay/following" do + test "it returns relay following", %{conn: conn} do + result = + conn + |> assign(:relay, true) + |> get("/relay/following") + |> json_response(200) + + assert result["first"]["orderedItems"] == [] + end + end + describe "/users/:nickname/followers" do test "it returns the followers in a collection", %{conn: conn} do user = insert(:user) -- cgit v1.2.3 From 399ca9133b67725242f76093103e9909e2337e72 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Thu, 22 Aug 2019 21:32:40 +0300 Subject: fix test --- test/web/activity_pub/activity_pub_controller_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test') diff --git a/test/web/activity_pub/activity_pub_controller_test.exs b/test/web/activity_pub/activity_pub_controller_test.exs index cf71066fd..5192e734f 100644 --- a/test/web/activity_pub/activity_pub_controller_test.exs +++ b/test/web/activity_pub/activity_pub_controller_test.exs @@ -10,9 +10,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do alias Pleroma.Object alias Pleroma.User alias Pleroma.Web.ActivityPub.ObjectView + alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.ActivityPub.UserView alias Pleroma.Web.ActivityPub.Utils - alias Pleroma.Web.ActivityPub.Relay alias Pleroma.Web.CommonAPI setup_all do -- cgit v1.2.3 From 73bcbf4fa3bcac7e3ef04049ae6e5768baa6b1d8 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Fri, 23 Aug 2019 21:17:14 +0300 Subject: add tests --- test/signature_test.exs | 14 ++++++++++++++ test/tasks/relay_test.exs | 4 +++- test/web/activity_pub/relay_test.exs | 3 +++ 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/signature_test.exs b/test/signature_test.exs index 26337eaf9..d5bf63d7d 100644 --- a/test/signature_test.exs +++ b/test/signature_test.exs @@ -8,6 +8,7 @@ defmodule Pleroma.SignatureTest do import ExUnit.CaptureLog import Pleroma.Factory import Tesla.Mock + import Mock alias Pleroma.Signature @@ -114,4 +115,17 @@ defmodule Pleroma.SignatureTest do "https://example.com/users/1234" end end + + describe "signed_date" do + test "it returns formatted current date" do + with_mock(NaiveDateTime, utc_now: fn -> ~N[2019-08-23 18:11:24.822233] end) do + assert Signature.signed_date() == "Fri, 23 Aug 2019 18:11:24 GMT" + end + end + + test "it returns formatted date" do + assert Signature.signed_date(~N[2019-08-23 08:11:24.822233]) == + "Fri, 23 Aug 2019 08:11:24 GMT" + end + end end diff --git a/test/tasks/relay_test.exs b/test/tasks/relay_test.exs index 0d341c8d6..7bde56606 100644 --- a/test/tasks/relay_test.exs +++ b/test/tasks/relay_test.exs @@ -50,7 +50,8 @@ defmodule Mix.Tasks.Pleroma.RelayTest do %User{ap_id: follower_id} = local_user = Relay.get_actor() target_user = User.get_cached_by_ap_id(target_instance) follow_activity = Utils.fetch_latest_follow(local_user, target_user) - + User.follow(local_user, target_user) + assert "#{target_instance}/followers" in refresh_record(local_user).following Mix.Tasks.Pleroma.Relay.run(["unfollow", target_instance]) cancelled_activity = Activity.get_by_ap_id(follow_activity.data["id"]) @@ -67,6 +68,7 @@ defmodule Mix.Tasks.Pleroma.RelayTest do assert undo_activity.data["type"] == "Undo" assert undo_activity.data["actor"] == local_user.ap_id assert undo_activity.data["object"] == cancelled_activity.data + refute "#{target_instance}/followers" in refresh_record(local_user).following end end diff --git a/test/web/activity_pub/relay_test.exs b/test/web/activity_pub/relay_test.exs index e10b808f7..aeef91cda 100644 --- a/test/web/activity_pub/relay_test.exs +++ b/test/web/activity_pub/relay_test.exs @@ -43,12 +43,15 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do user = insert(:user) service_actor = Relay.get_actor() ActivityPub.follow(service_actor, user) + Pleroma.User.follow(service_actor, user) + assert "#{user.ap_id}/followers" in refresh_record(service_actor).following assert {:ok, %Activity{} = activity} = Relay.unfollow(user.ap_id) assert activity.actor == "#{Pleroma.Web.Endpoint.url()}/relay" assert user.ap_id in activity.recipients assert activity.data["type"] == "Undo" assert activity.data["actor"] == service_actor.ap_id assert activity.data["to"] == [user.ap_id] + refute "#{user.ap_id}/followers" in refresh_record(service_actor).following end end -- cgit v1.2.3 From 654d291b6d151bc372bca849ce0b42f723e2bd94 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Sat, 24 Aug 2019 17:41:53 +0300 Subject: update tests --- test/web/activity_pub/relay_test.exs | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'test') diff --git a/test/web/activity_pub/relay_test.exs b/test/web/activity_pub/relay_test.exs index aeef91cda..4f7d592a6 100644 --- a/test/web/activity_pub/relay_test.exs +++ b/test/web/activity_pub/relay_test.exs @@ -11,6 +11,7 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do alias Pleroma.Web.ActivityPub.Relay import Pleroma.Factory + import Mock test "gets an actor for the relay" do user = Relay.get_actor() @@ -56,6 +57,8 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do end describe "publish/1" do + clear_config([:instance, :federating]) + test "returns error when activity not `Create` type" do activity = insert(:like_activity) assert Relay.publish(activity) == {:error, "Not implemented"} @@ -66,13 +69,44 @@ defmodule Pleroma.Web.ActivityPub.RelayTest do assert Relay.publish(activity) == {:error, false} end - test "returns announce activity" do + test "returns error when object is unknown" do + activity = + insert(:note_activity, + data: %{ + "type" => "Create", + "object" => "http://mastodon.example.org/eee/99541947525187367" + } + ) + + assert Relay.publish(activity) == {:error, nil} + end + + test_with_mock "returns announce activity and publish to federate", + Pleroma.Web.Federator, + [:passthrough], + [] do + Pleroma.Config.put([:instance, :federating], true) + service_actor = Relay.get_actor() + note = insert(:note_activity) + assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note) + assert activity.data["type"] == "Announce" + assert activity.data["actor"] == service_actor.ap_id + assert activity.data["object"] == obj.data["id"] + assert called(Pleroma.Web.Federator.publish(activity, 5)) + end + + test_with_mock "returns announce activity and not publish to federate", + Pleroma.Web.Federator, + [:passthrough], + [] do + Pleroma.Config.put([:instance, :federating], false) service_actor = Relay.get_actor() note = insert(:note_activity) assert {:ok, %Activity{} = activity, %Object{} = obj} = Relay.publish(note) assert activity.data["type"] == "Announce" assert activity.data["actor"] == service_actor.ap_id assert activity.data["object"] == obj.data["id"] + refute called(Pleroma.Web.Federator.publish(activity, 5)) end end end -- cgit v1.2.3 From efb8818e9ee280b53eac17699e8114e8af82b03b Mon Sep 17 00:00:00 2001 From: lain Date: Sat, 24 Aug 2019 17:22:48 +0200 Subject: Activity Expiration: Switch to 'expires_in' system. --- test/web/common_api/common_api_test.exs | 4 +--- test/web/mastodon_api/mastodon_api_controller_test.exs | 9 ++++++--- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs index 5fda91438..f28a66090 100644 --- a/test/web/common_api/common_api_test.exs +++ b/test/web/common_api/common_api_test.exs @@ -213,10 +213,8 @@ defmodule Pleroma.Web.CommonAPITest do |> NaiveDateTime.truncate(:second) |> NaiveDateTime.add(1_000_000, :second) - expires_at_iso8601 = expires_at |> NaiveDateTime.to_iso8601() - assert {:ok, activity} = - CommonAPI.post(user, %{"status" => "chai", "expires_at" => expires_at_iso8601}) + CommonAPI.post(user, %{"status" => "chai", "expires_in" => 1_000_000}) assert expiration = Pleroma.ActivityExpiration.get_by_activity_id(activity.id) assert expiration.scheduled_at == expires_at diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index c05c39db6..6fcdc19aa 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -153,7 +153,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do refute id == third_id # An activity that will expire: - expires_in = 120 + # 2 hours + expires_in = 120 * 60 conn_four = conn @@ -168,12 +169,14 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do estimated_expires_at = NaiveDateTime.utc_now() - |> NaiveDateTime.add(:timer.minutes(expires_in), :millisecond) + |> NaiveDateTime.add(expires_in) |> NaiveDateTime.truncate(:second) # This assert will fail if the test takes longer than a minute. I sure hope it never does: assert abs(NaiveDateTime.diff(expiration.scheduled_at, estimated_expires_at, :second)) < 60 - assert fourth_response["pleroma"]["expires_at"] == NaiveDateTime.to_iso8601(expiration.scheduled_at) + + assert fourth_response["pleroma"]["expires_at"] == + NaiveDateTime.to_iso8601(expiration.scheduled_at) end test "replying to a status", %{conn: conn} do -- cgit v1.2.3 From 18668447d268524e39d9cc8812805053ef9c186e Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 25 Aug 2019 07:10:22 +0200 Subject: HttpRequestMock: Log mock errors as warnings --- test/support/http_request_mock.ex | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 3adb5ba3b..00f4660c1 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -17,9 +17,14 @@ defmodule HttpRequestMock do with {:ok, res} <- apply(__MODULE__, method, [url, query, body, headers]) do res else - {_, _r} = error -> - # Logger.warn(r) - error + error -> + error = error + + with {:error, message} <- error do + Logger.warn(message) + end + + {_, _r} = error end end -- cgit v1.2.3 From e22737ffb5f7e7c567802e2bcef5520e2759e734 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 25 Aug 2019 07:33:46 +0200 Subject: HttpRequestMock: Improve non-implemented error message --- test/support/http_request_mock.ex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'test') diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 00f4660c1..320244c75 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -975,7 +975,7 @@ defmodule HttpRequestMock do def get(url, query, body, headers) do {:error, - "Not implemented the mock response for get #{inspect(url)}, #{query}, #{inspect(body)}, #{ + "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{ inspect(headers) }"} end @@ -1037,7 +1037,10 @@ defmodule HttpRequestMock do }} end - def post(url, _query, _body, _headers) do - {:error, "Not implemented the mock response for post #{inspect(url)}"} + def post(url, query, body, headers) do + {:error, + "Mock response not implemented for POST #{inspect(url)}, #{query}, #{inspect(body)}, #{ + inspect(headers) + }"} end end -- cgit v1.2.3 From 211e1637705266bebd33735d4bb1809c0326f707 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 25 Aug 2019 08:03:25 +0200 Subject: Implement missing mocks for rel=me --- test/support/http_request_mock.ex | 16 ++++++++++++++++ test/web/rel_me_test.exs | 29 ++--------------------------- 2 files changed, 18 insertions(+), 27 deletions(-) (limited to 'test') diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 320244c75..c308e5a36 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -973,6 +973,22 @@ defmodule HttpRequestMock do }} end + def get("http://example.com/rel_me/anchor", _, _, _) do + {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor.html")}} + end + + def get("http://example.com/rel_me/anchor_nofollow", _, _, _) do + {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor_nofollow.html")}} + end + + def get("http://example.com/rel_me/link", _, _, _) do + {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_link.html")}} + end + + def get("http://example.com/rel_me/null", _, _, _) do + {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_null.html")}} + end + def get(url, query, body, headers) do {:error, "Mock response not implemented for GET #{inspect(url)}, #{query}, #{inspect(body)}, #{ diff --git a/test/web/rel_me_test.exs b/test/web/rel_me_test.exs index 85515c432..2251fed16 100644 --- a/test/web/rel_me_test.exs +++ b/test/web/rel_me_test.exs @@ -5,33 +5,8 @@ defmodule Pleroma.Web.RelMeTest do use ExUnit.Case, async: true - setup do - Tesla.Mock.mock(fn - %{ - method: :get, - url: "http://example.com/rel_me/anchor" - } -> - %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor.html")} - - %{ - method: :get, - url: "http://example.com/rel_me/anchor_nofollow" - } -> - %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_anchor_nofollow.html")} - - %{ - method: :get, - url: "http://example.com/rel_me/link" - } -> - %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_link.html")} - - %{ - method: :get, - url: "http://example.com/rel_me/null" - } -> - %Tesla.Env{status: 200, body: File.read!("test/fixtures/rel_me_null.html")} - end) - + setup_all do + Tesla.Mock.mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) :ok end -- cgit v1.2.3 From f3b12662731fa8d1aa458ea16fb4bcb176b77744 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 25 Aug 2019 08:48:38 +0200 Subject: user_test.exs: fix rel=me tests --- test/user_test.exs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'test') diff --git a/test/user_test.exs b/test/user_test.exs index 661ffc0b3..2cbc1f525 100644 --- a/test/user_test.exs +++ b/test/user_test.exs @@ -1253,18 +1253,18 @@ defmodule Pleroma.UserTest do end test "Adds rel=me on linkbacked urls" do - user = insert(:user, ap_id: "http://social.example.org/users/lain") + user = insert(:user, ap_id: "https://social.example.org/users/lain") - bio = "http://example.org/rel_me/null" + bio = "http://example.com/rel_me/null" expected_text = "#{bio}" assert expected_text == User.parse_bio(bio, user) - bio = "http://example.org/rel_me/link" - expected_text = "#{bio}" + bio = "http://example.com/rel_me/link" + expected_text = "#{bio}" assert expected_text == User.parse_bio(bio, user) - bio = "http://example.org/rel_me/anchor" - expected_text = "#{bio}" + bio = "http://example.com/rel_me/anchor" + expected_text = "#{bio}" assert expected_text == User.parse_bio(bio, user) end end -- cgit v1.2.3 From 20c3f613d8574d67b1e5a47bf41f324101183398 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 25 Aug 2019 08:55:29 +0200 Subject: HttpRequestMock: Remove useless `error = error` --- test/support/http_request_mock.ex | 2 -- 1 file changed, 2 deletions(-) (limited to 'test') diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 320244c75..314b20a45 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -18,8 +18,6 @@ defmodule HttpRequestMock do res else error -> - error = error - with {:error, message} <- error do Logger.warn(message) end -- cgit v1.2.3 From d74efde94e3526b45dc9b31d9d48ffce14203ffa Mon Sep 17 00:00:00 2001 From: kPherox Date: Mon, 26 Aug 2019 02:00:41 +0900 Subject: Update test for custom profile fields --- test/web/activity_pub/transmogrifier_test.exs | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'test') diff --git a/test/web/activity_pub/transmogrifier_test.exs b/test/web/activity_pub/transmogrifier_test.exs index 629c76c97..0661d5d7c 100644 --- a/test/web/activity_pub/transmogrifier_test.exs +++ b/test/web/activity_pub/transmogrifier_test.exs @@ -563,6 +563,14 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do %{"name" => "foo", "value" => "updated"}, %{"name" => "foo1", "value" => "updated"} ] + + update_data = put_in(update_data, ["object", "attachment"], []) + + {:ok, _} = Transmogrifier.handle_incoming(update_data) + + user = User.get_cached_by_ap_id(user.ap_id) + + assert User.Info.fields(user.info) == [] end test "it works for incoming update activities which lock the account" do -- cgit v1.2.3 From 37dd3867bb0439e4a2717eb780a1837196fcef00 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Sun, 25 Aug 2019 19:39:37 +0000 Subject: Log admin/moderator actions --- test/moderation_log_test.exs | 301 +++++++++++++++++++++++ test/web/admin_api/admin_api_controller_test.exs | 241 ++++++++++++++++-- 2 files changed, 527 insertions(+), 15 deletions(-) create mode 100644 test/moderation_log_test.exs (limited to 'test') diff --git a/test/moderation_log_test.exs b/test/moderation_log_test.exs new file mode 100644 index 000000000..c78708471 --- /dev/null +++ b/test/moderation_log_test.exs @@ -0,0 +1,301 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.ModerationLogTest do + alias Pleroma.Activity + alias Pleroma.ModerationLog + + use Pleroma.DataCase + + import Pleroma.Factory + + describe "user moderation" do + setup do + admin = insert(:user, info: %{is_admin: true}) + moderator = insert(:user, info: %{is_moderator: true}) + subject1 = insert(:user) + subject2 = insert(:user) + + [admin: admin, moderator: moderator, subject1: subject1, subject2: subject2] + end + + test "logging user deletion by moderator", %{moderator: moderator, subject1: subject1} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + subject: subject1, + action: "delete" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} deleted user @#{subject1.nickname}" + end + + test "logging user creation by moderator", %{ + moderator: moderator, + subject1: subject1, + subject2: subject2 + } do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + subjects: [subject1, subject2], + action: "create" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} created users: @#{subject1.nickname}, @#{subject2.nickname}" + end + + test "logging user follow by admin", %{admin: admin, subject1: subject1, subject2: subject2} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: admin, + followed: subject1, + follower: subject2, + action: "follow" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{admin.nickname} made @#{subject2.nickname} follow @#{subject1.nickname}" + end + + test "logging user unfollow by admin", %{admin: admin, subject1: subject1, subject2: subject2} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: admin, + followed: subject1, + follower: subject2, + action: "unfollow" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{admin.nickname} made @#{subject2.nickname} unfollow @#{subject1.nickname}" + end + + test "logging user tagged by admin", %{admin: admin, subject1: subject1, subject2: subject2} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: admin, + nicknames: [subject1.nickname, subject2.nickname], + tags: ["foo", "bar"], + action: "tag" + }) + + log = Repo.one(ModerationLog) + + users = + [subject1.nickname, subject2.nickname] + |> Enum.map(&"@#{&1}") + |> Enum.join(", ") + + tags = ["foo", "bar"] |> Enum.join(", ") + + assert ModerationLog.get_log_entry_message(log) == + "@#{admin.nickname} added tags: #{tags} to users: #{users}" + end + + test "logging user untagged by admin", %{admin: admin, subject1: subject1, subject2: subject2} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: admin, + nicknames: [subject1.nickname, subject2.nickname], + tags: ["foo", "bar"], + action: "untag" + }) + + log = Repo.one(ModerationLog) + + users = + [subject1.nickname, subject2.nickname] + |> Enum.map(&"@#{&1}") + |> Enum.join(", ") + + tags = ["foo", "bar"] |> Enum.join(", ") + + assert ModerationLog.get_log_entry_message(log) == + "@#{admin.nickname} removed tags: #{tags} from users: #{users}" + end + + test "logging user grant by moderator", %{moderator: moderator, subject1: subject1} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + subject: subject1, + action: "grant", + permission: "moderator" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} made @#{subject1.nickname} moderator" + end + + test "logging user revoke by moderator", %{moderator: moderator, subject1: subject1} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + subject: subject1, + action: "revoke", + permission: "moderator" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} revoked moderator role from @#{subject1.nickname}" + end + + test "logging relay follow", %{moderator: moderator} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + action: "relay_follow", + target: "https://example.org/relay" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} followed relay: https://example.org/relay" + end + + test "logging relay unfollow", %{moderator: moderator} do + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + action: "relay_unfollow", + target: "https://example.org/relay" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} unfollowed relay: https://example.org/relay" + end + + test "logging report update", %{moderator: moderator} do + report = %Activity{ + id: "9m9I1F4p8ftrTP6QTI", + data: %{ + "type" => "Flag", + "state" => "resolved" + } + } + + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + action: "report_update", + subject: report + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} updated report ##{report.id} with 'resolved' state" + end + + test "logging report response", %{moderator: moderator} do + report = %Activity{ + id: "9m9I1F4p8ftrTP6QTI", + data: %{ + "type" => "Note" + } + } + + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + action: "report_response", + subject: report, + text: "look at this" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} responded with 'look at this' to report ##{report.id}" + end + + test "logging status sensitivity update", %{moderator: moderator} do + note = insert(:note_activity) + + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + action: "status_update", + subject: note, + sensitive: "true", + visibility: nil + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} updated status ##{note.id}, set sensitive: 'true'" + end + + test "logging status visibility update", %{moderator: moderator} do + note = insert(:note_activity) + + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + action: "status_update", + subject: note, + sensitive: nil, + visibility: "private" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} updated status ##{note.id}, set visibility: 'private'" + end + + test "logging status sensitivity & visibility update", %{moderator: moderator} do + note = insert(:note_activity) + + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + action: "status_update", + subject: note, + sensitive: "true", + visibility: "private" + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} updated status ##{note.id}, set sensitive: 'true', visibility: 'private'" + end + + test "logging status deletion", %{moderator: moderator} do + note = insert(:note_activity) + + {:ok, _} = + ModerationLog.insert_log(%{ + actor: moderator, + action: "status_delete", + subject_id: note.id + }) + + log = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log) == + "@#{moderator.nickname} deleted status ##{note.id}" + end + end +end diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index ab829d6bd..1afdb6a50 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -7,6 +7,8 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do alias Pleroma.Activity alias Pleroma.HTML + alias Pleroma.ModerationLog + alias Pleroma.Repo alias Pleroma.User alias Pleroma.UserInviteToken alias Pleroma.Web.CommonAPI @@ -24,6 +26,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do |> put_req_header("accept", "application/json") |> delete("/api/pleroma/admin/users?nickname=#{user.nickname}") + log_entry = Repo.one(ModerationLog) + + assert log_entry.data["subject"]["nickname"] == user.nickname + assert log_entry.data["action"] == "delete" + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} deleted user @#{user.nickname}" + assert json_response(conn, 200) == user.nickname end @@ -51,6 +61,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do response = json_response(conn, 200) |> Enum.map(&Map.get(&1, "type")) assert response == ["success", "success"] + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} created users: @lain2, @lain" end test "Cannot create user with exisiting email" do @@ -218,6 +233,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do follower = User.get_cached_by_id(follower.id) assert User.following?(follower, user) + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} made @#{follower.nickname} follow @#{user.nickname}" end end @@ -241,6 +261,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do follower = User.get_cached_by_id(follower.id) refute User.following?(follower, user) + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} made @#{follower.nickname} unfollow @#{user.nickname}" end end @@ -261,17 +286,30 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do }&tags[]=foo&tags[]=bar" ) - %{conn: conn, user1: user1, user2: user2, user3: user3} + %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3} end test "it appends specified tags to users with specified nicknames", %{ conn: conn, + admin: admin, user1: user1, user2: user2 } do assert json_response(conn, :no_content) assert User.get_cached_by_id(user1.id).tags == ["x", "foo", "bar"] assert User.get_cached_by_id(user2.id).tags == ["y", "foo", "bar"] + + log_entry = Repo.one(ModerationLog) + + users = + [user1.nickname, user2.nickname] + |> Enum.map(&"@#{&1}") + |> Enum.join(", ") + + tags = ["foo", "bar"] |> Enum.join(", ") + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} added tags: #{tags} to users: #{users}" end test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do @@ -297,17 +335,30 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do }&tags[]=x&tags[]=z" ) - %{conn: conn, user1: user1, user2: user2, user3: user3} + %{conn: conn, admin: admin, user1: user1, user2: user2, user3: user3} end test "it removes specified tags from users with specified nicknames", %{ conn: conn, + admin: admin, user1: user1, user2: user2 } do assert json_response(conn, :no_content) assert User.get_cached_by_id(user1.id).tags == [] assert User.get_cached_by_id(user2.id).tags == ["y"] + + log_entry = Repo.one(ModerationLog) + + users = + [user1.nickname, user2.nickname] + |> Enum.map(&"@#{&1}") + |> Enum.join(", ") + + tags = ["x", "z"] |> Enum.join(", ") + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} removed tags: #{tags} from users: #{users}" end test "it does not modify tags of not specified users", %{conn: conn, user3: user3} do @@ -345,6 +396,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) == %{ "is_admin" => true } + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} made @#{user.nickname} admin" end test "/:right DELETE, can remove from a permission group" do @@ -360,6 +416,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) == %{ "is_admin" => false } + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} revoked admin role from @#{user.nickname}" end end @@ -372,10 +433,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do |> assign(:user, admin) |> put_req_header("accept", "application/json") - %{conn: conn} + %{conn: conn, admin: admin} end - test "deactivates the user", %{conn: conn} do + test "deactivates the user", %{conn: conn, admin: admin} do user = insert(:user) conn = @@ -385,9 +446,14 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do user = User.get_cached_by_id(user.id) assert user.info.deactivated == true assert json_response(conn, :no_content) + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} deactivated user @#{user.nickname}" end - test "activates the user", %{conn: conn} do + test "activates the user", %{conn: conn, admin: admin} do user = insert(:user, info: %{deactivated: true}) conn = @@ -397,6 +463,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do user = User.get_cached_by_id(user.id) assert user.info.deactivated == false assert json_response(conn, :no_content) + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} activated user @#{user.nickname}" end test "returns 403 when requested by a non-admin", %{conn: conn} do @@ -987,6 +1058,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "avatar" => User.avatar_url(user) |> MediaProxy.url(), "display_name" => HTML.strip_tags(user.name || user.nickname) } + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} deactivated user @#{user.nickname}" end describe "GET /api/pleroma/admin/users/invite_token" do @@ -1172,25 +1248,35 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do "status_ids" => [activity.id] }) - %{conn: assign(conn, :user, admin), id: report_id} + %{conn: assign(conn, :user, admin), id: report_id, admin: admin} end - test "mark report as resolved", %{conn: conn, id: id} do + test "mark report as resolved", %{conn: conn, id: id, admin: admin} do response = conn |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "resolved"}) |> json_response(:ok) assert response["state"] == "resolved" + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} updated report ##{id} with 'resolved' state" end - test "closes report", %{conn: conn, id: id} do + test "closes report", %{conn: conn, id: id, admin: admin} do response = conn |> put("/api/pleroma/admin/reports/#{id}", %{"state" => "closed"}) |> json_response(:ok) assert response["state"] == "closed" + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} updated report ##{id} with 'closed' state" end test "returns 400 when state is unknown", %{conn: conn, id: id} do @@ -1321,14 +1407,15 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do end end + # describe "POST /api/pleroma/admin/reports/:id/respond" do setup %{conn: conn} do admin = insert(:user, info: %{is_admin: true}) - %{conn: assign(conn, :user, admin)} + %{conn: assign(conn, :user, admin), admin: admin} end - test "returns created dm", %{conn: conn} do + test "returns created dm", %{conn: conn, admin: admin} do [reporter, target_user] = insert_pair(:user) activity = insert(:note_activity, user: target_user) @@ -1351,6 +1438,13 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert reporter.nickname in recipients assert response["content"] == "I will check it out" assert response["visibility"] == "direct" + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} responded with 'I will check it out' to report ##{ + response["id"] + }" end test "returns 400 when status is missing", %{conn: conn} do @@ -1374,10 +1468,10 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do admin = insert(:user, info: %{is_admin: true}) activity = insert(:note_activity) - %{conn: assign(conn, :user, admin), id: activity.id} + %{conn: assign(conn, :user, admin), id: activity.id, admin: admin} end - test "toggle sensitive flag", %{conn: conn, id: id} do + test "toggle sensitive flag", %{conn: conn, id: id, admin: admin} do response = conn |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "true"}) @@ -1385,6 +1479,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert response["sensitive"] + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} updated status ##{id}, set sensitive: 'true'" + response = conn |> put("/api/pleroma/admin/statuses/#{id}", %{"sensitive" => "false"}) @@ -1393,7 +1492,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do refute response["sensitive"] end - test "change visibility flag", %{conn: conn, id: id} do + test "change visibility flag", %{conn: conn, id: id, admin: admin} do response = conn |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "public"}) @@ -1401,6 +1500,11 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert response["visibility"] == "public" + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} updated status ##{id}, set visibility: 'public'" + response = conn |> put("/api/pleroma/admin/statuses/#{id}", %{"visibility" => "private"}) @@ -1430,15 +1534,20 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do admin = insert(:user, info: %{is_admin: true}) activity = insert(:note_activity) - %{conn: assign(conn, :user, admin), id: activity.id} + %{conn: assign(conn, :user, admin), id: activity.id, admin: admin} end - test "deletes status", %{conn: conn, id: id} do + test "deletes status", %{conn: conn, id: id, admin: admin} do conn |> delete("/api/pleroma/admin/statuses/#{id}") |> json_response(:ok) refute Activity.get_by_id(id) + + log_entry = Repo.one(ModerationLog) + + assert ModerationLog.get_log_entry_message(log_entry) == + "@#{admin.nickname} deleted status ##{id}" end test "returns error when status is not exist", %{conn: conn} do @@ -2139,6 +2248,108 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do assert json_response(conn, 200) |> length() == 5 end end + + describe "GET /api/pleroma/admin/moderation_log" do + setup %{conn: conn} do + admin = insert(:user, info: %{is_admin: true}) + + %{conn: assign(conn, :user, admin), admin: admin} + end + + test "returns the log", %{conn: conn, admin: admin} do + Repo.insert(%ModerationLog{ + data: %{ + actor: %{ + "id" => admin.id, + "nickname" => admin.nickname, + "type" => "user" + }, + action: "relay_follow", + target: "https://example.org/relay" + }, + inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second) + }) + + Repo.insert(%ModerationLog{ + data: %{ + actor: %{ + "id" => admin.id, + "nickname" => admin.nickname, + "type" => "user" + }, + action: "relay_unfollow", + target: "https://example.org/relay" + }, + inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second) + }) + + conn = get(conn, "/api/pleroma/admin/moderation_log") + + response = json_response(conn, 200) + [first_entry, second_entry] = response + + assert response |> length() == 2 + assert first_entry["data"]["action"] == "relay_unfollow" + + assert first_entry["message"] == + "@#{admin.nickname} unfollowed relay: https://example.org/relay" + + assert second_entry["data"]["action"] == "relay_follow" + + assert second_entry["message"] == + "@#{admin.nickname} followed relay: https://example.org/relay" + end + + test "returns the log with pagination", %{conn: conn, admin: admin} do + Repo.insert(%ModerationLog{ + data: %{ + actor: %{ + "id" => admin.id, + "nickname" => admin.nickname, + "type" => "user" + }, + action: "relay_follow", + target: "https://example.org/relay" + }, + inserted_at: NaiveDateTime.truncate(~N[2017-08-15 15:47:06.597036], :second) + }) + + Repo.insert(%ModerationLog{ + data: %{ + actor: %{ + "id" => admin.id, + "nickname" => admin.nickname, + "type" => "user" + }, + action: "relay_unfollow", + target: "https://example.org/relay" + }, + inserted_at: NaiveDateTime.truncate(~N[2017-08-16 15:47:06.597036], :second) + }) + + conn1 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=1") + + response1 = json_response(conn1, 200) + [first_entry] = response1 + + assert response1 |> length() == 1 + assert first_entry["data"]["action"] == "relay_unfollow" + + assert first_entry["message"] == + "@#{admin.nickname} unfollowed relay: https://example.org/relay" + + conn2 = get(conn, "/api/pleroma/admin/moderation_log?page_size=1&page=2") + + response2 = json_response(conn2, 200) + [second_entry] = response2 + + assert response2 |> length() == 1 + assert second_entry["data"]["action"] == "relay_follow" + + assert second_entry["message"] == + "@#{admin.nickname} followed relay: https://example.org/relay" + end + end end # Needed for testing -- cgit v1.2.3 From 3b1b631c2aedc8e359c296b11237fa4f6edd31e5 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 26 Aug 2019 18:59:57 +0700 Subject: Add validation in Pleroma.List.create/2 --- test/list_test.exs | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'test') diff --git a/test/list_test.exs b/test/list_test.exs index f39033d02..8efba75ea 100644 --- a/test/list_test.exs +++ b/test/list_test.exs @@ -15,6 +15,13 @@ defmodule Pleroma.ListTest do assert title == "title" end + test "validates title" do + user = insert(:user) + + assert {:error, changeset} = Pleroma.List.create("", user) + assert changeset.errors == [title: {"can't be blank", [validation: :required]}] + end + test "getting a list not belonging to the user" do user = insert(:user) other_user = insert(:user) -- cgit v1.2.3 From 30510ade0e2f813413c5599245adc4dae8c7ffd8 Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 26 Aug 2019 19:37:54 +0700 Subject: Extract MastodonAPIController's list actions into MastodonAPI.ListController; Add more tests --- .../controllers/list_controller_test.exs | 166 +++++++++++++++++++++ test/web/mastodon_api/list_view_test.exs | 22 --- .../mastodon_api/mastodon_api_controller_test.exs | 101 +------------ test/web/mastodon_api/views/list_view_test.exs | 32 ++++ 4 files changed, 199 insertions(+), 122 deletions(-) create mode 100644 test/web/mastodon_api/controllers/list_controller_test.exs delete mode 100644 test/web/mastodon_api/list_view_test.exs create mode 100644 test/web/mastodon_api/views/list_view_test.exs (limited to 'test') diff --git a/test/web/mastodon_api/controllers/list_controller_test.exs b/test/web/mastodon_api/controllers/list_controller_test.exs new file mode 100644 index 000000000..093506309 --- /dev/null +++ b/test/web/mastodon_api/controllers/list_controller_test.exs @@ -0,0 +1,166 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.ListControllerTest do + use Pleroma.Web.ConnCase + + alias Pleroma.Repo + + import Pleroma.Factory + + test "creating a list", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> post("/api/v1/lists", %{"title" => "cuties"}) + + assert %{"title" => title} = json_response(conn, 200) + assert title == "cuties" + end + + test "renders error for invalid params", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> post("/api/v1/lists", %{"title" => nil}) + + assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity) + end + + test "listing a user's lists", %{conn: conn} do + user = insert(:user) + + conn + |> assign(:user, user) + |> post("/api/v1/lists", %{"title" => "cuties"}) + + conn + |> assign(:user, user) + |> post("/api/v1/lists", %{"title" => "cofe"}) + + conn = + conn + |> assign(:user, user) + |> get("/api/v1/lists") + + assert [ + %{"id" => _, "title" => "cofe"}, + %{"id" => _, "title" => "cuties"} + ] = json_response(conn, :ok) + end + + test "adding users to a list", %{conn: conn} do + user = insert(:user) + other_user = insert(:user) + {:ok, list} = Pleroma.List.create("name", user) + + conn = + conn + |> assign(:user, user) + |> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + + assert %{} == json_response(conn, 200) + %Pleroma.List{following: following} = Pleroma.List.get(list.id, user) + assert following == [other_user.follower_address] + end + + test "removing users from a list", %{conn: conn} do + user = insert(:user) + other_user = insert(:user) + third_user = insert(:user) + {:ok, list} = Pleroma.List.create("name", user) + {:ok, list} = Pleroma.List.follow(list, other_user) + {:ok, list} = Pleroma.List.follow(list, third_user) + + conn = + conn + |> assign(:user, user) + |> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + + assert %{} == json_response(conn, 200) + %Pleroma.List{following: following} = Pleroma.List.get(list.id, user) + assert following == [third_user.follower_address] + end + + test "listing users in a list", %{conn: conn} do + user = insert(:user) + other_user = insert(:user) + {:ok, list} = Pleroma.List.create("name", user) + {:ok, list} = Pleroma.List.follow(list, other_user) + + conn = + conn + |> assign(:user, user) + |> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) + + assert [%{"id" => id}] = json_response(conn, 200) + assert id == to_string(other_user.id) + end + + test "retrieving a list", %{conn: conn} do + user = insert(:user) + {:ok, list} = Pleroma.List.create("name", user) + + conn = + conn + |> assign(:user, user) + |> get("/api/v1/lists/#{list.id}") + + assert %{"id" => id} = json_response(conn, 200) + assert id == to_string(list.id) + end + + test "renders 404 if list is not found", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> get("/api/v1/lists/666") + + assert %{"error" => "List not found"} = json_response(conn, :not_found) + end + + test "renaming a list", %{conn: conn} do + user = insert(:user) + {:ok, list} = Pleroma.List.create("name", user) + + conn = + conn + |> assign(:user, user) + |> put("/api/v1/lists/#{list.id}", %{"title" => "newname"}) + + assert %{"title" => name} = json_response(conn, 200) + assert name == "newname" + end + + test "validates title when renaming a list", %{conn: conn} do + user = insert(:user) + {:ok, list} = Pleroma.List.create("name", user) + + conn = + conn + |> assign(:user, user) + |> put("/api/v1/lists/#{list.id}", %{"title" => " "}) + + assert %{"error" => "can't be blank"} == json_response(conn, :unprocessable_entity) + end + + test "deleting a list", %{conn: conn} do + user = insert(:user) + {:ok, list} = Pleroma.List.create("name", user) + + conn = + conn + |> assign(:user, user) + |> delete("/api/v1/lists/#{list.id}") + + assert %{} = json_response(conn, 200) + assert is_nil(Repo.get(Pleroma.List, list.id)) + end +end diff --git a/test/web/mastodon_api/list_view_test.exs b/test/web/mastodon_api/list_view_test.exs deleted file mode 100644 index 73143467f..000000000 --- a/test/web/mastodon_api/list_view_test.exs +++ /dev/null @@ -1,22 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.ListViewTest do - use Pleroma.DataCase - import Pleroma.Factory - alias Pleroma.Web.MastodonAPI.ListView - - test "Represent a list" do - user = insert(:user) - title = "mortal enemies" - {:ok, list} = Pleroma.List.create(title, user) - - expected = %{ - id: to_string(list.id), - title: title - } - - assert expected == ListView.render("list.json", %{list: list}) - end -end diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index 6fcdc19aa..4fd0a5aeb 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -927,106 +927,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do end end - describe "lists" do - test "creating a list", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> post("/api/v1/lists", %{"title" => "cuties"}) - - assert %{"title" => title} = json_response(conn, 200) - assert title == "cuties" - end - - test "adding users to a list", %{conn: conn} do - user = insert(:user) - other_user = insert(:user) - {:ok, list} = Pleroma.List.create("name", user) - - conn = - conn - |> assign(:user, user) - |> post("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) - - assert %{} == json_response(conn, 200) - %Pleroma.List{following: following} = Pleroma.List.get(list.id, user) - assert following == [other_user.follower_address] - end - - test "removing users from a list", %{conn: conn} do - user = insert(:user) - other_user = insert(:user) - third_user = insert(:user) - {:ok, list} = Pleroma.List.create("name", user) - {:ok, list} = Pleroma.List.follow(list, other_user) - {:ok, list} = Pleroma.List.follow(list, third_user) - - conn = - conn - |> assign(:user, user) - |> delete("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) - - assert %{} == json_response(conn, 200) - %Pleroma.List{following: following} = Pleroma.List.get(list.id, user) - assert following == [third_user.follower_address] - end - - test "listing users in a list", %{conn: conn} do - user = insert(:user) - other_user = insert(:user) - {:ok, list} = Pleroma.List.create("name", user) - {:ok, list} = Pleroma.List.follow(list, other_user) - - conn = - conn - |> assign(:user, user) - |> get("/api/v1/lists/#{list.id}/accounts", %{"account_ids" => [other_user.id]}) - - assert [%{"id" => id}] = json_response(conn, 200) - assert id == to_string(other_user.id) - end - - test "retrieving a list", %{conn: conn} do - user = insert(:user) - {:ok, list} = Pleroma.List.create("name", user) - - conn = - conn - |> assign(:user, user) - |> get("/api/v1/lists/#{list.id}") - - assert %{"id" => id} = json_response(conn, 200) - assert id == to_string(list.id) - end - - test "renaming a list", %{conn: conn} do - user = insert(:user) - {:ok, list} = Pleroma.List.create("name", user) - - conn = - conn - |> assign(:user, user) - |> put("/api/v1/lists/#{list.id}", %{"title" => "newname"}) - - assert %{"title" => name} = json_response(conn, 200) - assert name == "newname" - end - - test "deleting a list", %{conn: conn} do - user = insert(:user) - {:ok, list} = Pleroma.List.create("name", user) - - conn = - conn - |> assign(:user, user) - |> delete("/api/v1/lists/#{list.id}") - - assert %{} = json_response(conn, 200) - assert is_nil(Repo.get(Pleroma.List, list.id)) - end - + describe "list timelines" do test "list timeline", %{conn: conn} do user = insert(:user) other_user = insert(:user) diff --git a/test/web/mastodon_api/views/list_view_test.exs b/test/web/mastodon_api/views/list_view_test.exs new file mode 100644 index 000000000..fb00310b9 --- /dev/null +++ b/test/web/mastodon_api/views/list_view_test.exs @@ -0,0 +1,32 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.ListViewTest do + use Pleroma.DataCase + import Pleroma.Factory + alias Pleroma.Web.MastodonAPI.ListView + + test "show" do + user = insert(:user) + title = "mortal enemies" + {:ok, list} = Pleroma.List.create(title, user) + + expected = %{ + id: to_string(list.id), + title: title + } + + assert expected == ListView.render("show.json", %{list: list}) + end + + test "index" do + user = insert(:user) + + {:ok, list} = Pleroma.List.create("my list", user) + {:ok, list2} = Pleroma.List.create("cofe", user) + + assert [%{id: _, title: "my list"}, %{id: _, title: "cofe"}] = + ListView.render("index.json", lists: [list, list2]) + end +end -- cgit v1.2.3 From 019ced055836b3d01ea95865549478dc5cdb3c0e Mon Sep 17 00:00:00 2001 From: Egor Kislitsyn Date: Mon, 26 Aug 2019 19:34:43 +0700 Subject: Move test/web/mastodon_api/*_test.exs to test/web/mastodon_api/controllers and test/web/mastodon_api/views --- test/web/mastodon_api/account_view_test.exs | 389 -------------- .../update_credentials_test.exs | 369 +++++++++++++ .../controllers/search_controller_test.exs | 285 ++++++++++ .../controllers/subscription_controller_test.exs | 192 +++++++ test/web/mastodon_api/conversation_view_test.exs | 34 -- .../update_credentials_test.exs | 369 ------------- test/web/mastodon_api/notification_view_test.exs | 104 ---- .../mastodon_api/push_subscription_view_test.exs | 23 - .../mastodon_api/scheduled_activity_view_test.exs | 68 --- test/web/mastodon_api/search_controller_test.exs | 285 ---------- test/web/mastodon_api/status_view_test.exs | 584 --------------------- .../mastodon_api/subscription_controller_test.exs | 192 ------- test/web/mastodon_api/views/account_view_test.exs | 389 ++++++++++++++ .../mastodon_api/views/conversation_view_test.exs | 34 ++ .../mastodon_api/views/notification_view_test.exs | 104 ++++ .../views/push_subscription_view_test.exs | 23 + .../views/scheduled_activity_view_test.exs | 68 +++ test/web/mastodon_api/views/status_view_test.exs | 584 +++++++++++++++++++++ 18 files changed, 2048 insertions(+), 2048 deletions(-) delete mode 100644 test/web/mastodon_api/account_view_test.exs create mode 100644 test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs create mode 100644 test/web/mastodon_api/controllers/search_controller_test.exs create mode 100644 test/web/mastodon_api/controllers/subscription_controller_test.exs delete mode 100644 test/web/mastodon_api/conversation_view_test.exs delete mode 100644 test/web/mastodon_api/mastodon_api_controller/update_credentials_test.exs delete mode 100644 test/web/mastodon_api/notification_view_test.exs delete mode 100644 test/web/mastodon_api/push_subscription_view_test.exs delete mode 100644 test/web/mastodon_api/scheduled_activity_view_test.exs delete mode 100644 test/web/mastodon_api/search_controller_test.exs delete mode 100644 test/web/mastodon_api/status_view_test.exs delete mode 100644 test/web/mastodon_api/subscription_controller_test.exs create mode 100644 test/web/mastodon_api/views/account_view_test.exs create mode 100644 test/web/mastodon_api/views/conversation_view_test.exs create mode 100644 test/web/mastodon_api/views/notification_view_test.exs create mode 100644 test/web/mastodon_api/views/push_subscription_view_test.exs create mode 100644 test/web/mastodon_api/views/scheduled_activity_view_test.exs create mode 100644 test/web/mastodon_api/views/status_view_test.exs (limited to 'test') diff --git a/test/web/mastodon_api/account_view_test.exs b/test/web/mastodon_api/account_view_test.exs deleted file mode 100644 index 1d8b28339..000000000 --- a/test/web/mastodon_api/account_view_test.exs +++ /dev/null @@ -1,389 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.AccountViewTest do - use Pleroma.DataCase - import Pleroma.Factory - alias Pleroma.User - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.MastodonAPI.AccountView - - test "Represent a user account" do - source_data = %{ - "tag" => [ - %{ - "type" => "Emoji", - "icon" => %{"url" => "/file.png"}, - "name" => ":karjalanpiirakka:" - } - ] - } - - background_image = %{ - "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}] - } - - user = - insert(:user, %{ - info: %{ - note_count: 5, - follower_count: 3, - source_data: source_data, - background: background_image - }, - nickname: "shp@shitposter.club", - name: ":karjalanpiirakka: shp", - bio: "valid html", - inserted_at: ~N[2017-08-15 15:47:06.597036] - }) - - expected = %{ - id: to_string(user.id), - username: "shp", - acct: user.nickname, - display_name: user.name, - locked: false, - created_at: "2017-08-15T15:47:06.000Z", - followers_count: 3, - following_count: 0, - statuses_count: 5, - note: "valid html", - url: user.ap_id, - avatar: "http://localhost:4001/images/avi.png", - avatar_static: "http://localhost:4001/images/avi.png", - header: "http://localhost:4001/images/banner.png", - header_static: "http://localhost:4001/images/banner.png", - emojis: [ - %{ - "static_url" => "/file.png", - "url" => "/file.png", - "shortcode" => "karjalanpiirakka", - "visible_in_picker" => false - } - ], - fields: [], - bot: false, - source: %{ - note: "valid html", - sensitive: false, - pleroma: %{}, - fields: [] - }, - pleroma: %{ - background_image: "https://example.com/images/asuka_hospital.png", - confirmation_pending: false, - tags: [], - is_admin: false, - is_moderator: false, - hide_favorites: true, - hide_followers: false, - hide_follows: false, - relationship: %{}, - skip_thread_containment: false - } - } - - assert expected == AccountView.render("account.json", %{user: user}) - end - - test "Represent the user account for the account owner" do - user = insert(:user) - - notification_settings = %{ - "followers" => true, - "follows" => true, - "non_follows" => true, - "non_followers" => true - } - - privacy = user.info.default_scope - - assert %{ - pleroma: %{notification_settings: ^notification_settings}, - source: %{privacy: ^privacy} - } = AccountView.render("account.json", %{user: user, for: user}) - end - - test "Represent a Service(bot) account" do - user = - insert(:user, %{ - info: %{note_count: 5, follower_count: 3, source_data: %{"type" => "Service"}}, - nickname: "shp@shitposter.club", - inserted_at: ~N[2017-08-15 15:47:06.597036] - }) - - expected = %{ - id: to_string(user.id), - username: "shp", - acct: user.nickname, - display_name: user.name, - locked: false, - created_at: "2017-08-15T15:47:06.000Z", - followers_count: 3, - following_count: 0, - statuses_count: 5, - note: user.bio, - url: user.ap_id, - avatar: "http://localhost:4001/images/avi.png", - avatar_static: "http://localhost:4001/images/avi.png", - header: "http://localhost:4001/images/banner.png", - header_static: "http://localhost:4001/images/banner.png", - emojis: [], - fields: [], - bot: true, - source: %{ - note: user.bio, - sensitive: false, - pleroma: %{}, - fields: [] - }, - pleroma: %{ - background_image: nil, - confirmation_pending: false, - tags: [], - is_admin: false, - is_moderator: false, - hide_favorites: true, - hide_followers: false, - hide_follows: false, - relationship: %{}, - skip_thread_containment: false - } - } - - assert expected == AccountView.render("account.json", %{user: user}) - end - - test "Represent a deactivated user for an admin" do - admin = insert(:user, %{info: %{is_admin: true}}) - deactivated_user = insert(:user, %{info: %{deactivated: true}}) - represented = AccountView.render("account.json", %{user: deactivated_user, for: admin}) - assert represented[:pleroma][:deactivated] == true - end - - test "Represent a smaller mention" do - user = insert(:user) - - expected = %{ - id: to_string(user.id), - acct: user.nickname, - username: user.nickname, - url: user.ap_id - } - - assert expected == AccountView.render("mention.json", %{user: user}) - end - - describe "relationship" do - test "represent a relationship for the following and followed user" do - user = insert(:user) - other_user = insert(:user) - - {:ok, user} = User.follow(user, other_user) - {:ok, other_user} = User.follow(other_user, user) - {:ok, other_user} = User.subscribe(user, other_user) - {:ok, user} = User.mute(user, other_user, true) - {:ok, user} = CommonAPI.hide_reblogs(user, other_user) - - expected = %{ - id: to_string(other_user.id), - following: true, - followed_by: true, - blocking: false, - blocked_by: false, - muting: true, - muting_notifications: true, - subscribing: true, - requested: false, - domain_blocking: false, - showing_reblogs: false, - endorsed: false - } - - assert expected == - AccountView.render("relationship.json", %{user: user, target: other_user}) - end - - test "represent a relationship for the blocking and blocked user" do - user = insert(:user) - other_user = insert(:user) - - {:ok, user} = User.follow(user, other_user) - {:ok, other_user} = User.subscribe(user, other_user) - {:ok, user} = User.block(user, other_user) - {:ok, other_user} = User.block(other_user, user) - - expected = %{ - id: to_string(other_user.id), - following: false, - followed_by: false, - blocking: true, - blocked_by: true, - muting: false, - muting_notifications: false, - subscribing: false, - requested: false, - domain_blocking: false, - showing_reblogs: true, - endorsed: false - } - - assert expected == - AccountView.render("relationship.json", %{user: user, target: other_user}) - end - - test "represent a relationship for the user blocking a domain" do - user = insert(:user) - other_user = insert(:user, ap_id: "https://bad.site/users/other_user") - - {:ok, user} = User.block_domain(user, "bad.site") - - assert %{domain_blocking: true, blocking: false} = - AccountView.render("relationship.json", %{user: user, target: other_user}) - end - - test "represent a relationship for the user with a pending follow request" do - user = insert(:user) - other_user = insert(:user, %{info: %User.Info{locked: true}}) - - {:ok, user, other_user, _} = CommonAPI.follow(user, other_user) - user = User.get_cached_by_id(user.id) - other_user = User.get_cached_by_id(other_user.id) - - expected = %{ - id: to_string(other_user.id), - following: false, - followed_by: false, - blocking: false, - blocked_by: false, - muting: false, - muting_notifications: false, - subscribing: false, - requested: true, - domain_blocking: false, - showing_reblogs: true, - endorsed: false - } - - assert expected == - AccountView.render("relationship.json", %{user: user, target: other_user}) - end - end - - test "represent an embedded relationship" do - user = - insert(:user, %{ - info: %{note_count: 5, follower_count: 0, source_data: %{"type" => "Service"}}, - nickname: "shp@shitposter.club", - inserted_at: ~N[2017-08-15 15:47:06.597036] - }) - - other_user = insert(:user) - {:ok, other_user} = User.follow(other_user, user) - {:ok, other_user} = User.block(other_user, user) - {:ok, _} = User.follow(insert(:user), user) - - expected = %{ - id: to_string(user.id), - username: "shp", - acct: user.nickname, - display_name: user.name, - locked: false, - created_at: "2017-08-15T15:47:06.000Z", - followers_count: 1, - following_count: 0, - statuses_count: 5, - note: user.bio, - url: user.ap_id, - avatar: "http://localhost:4001/images/avi.png", - avatar_static: "http://localhost:4001/images/avi.png", - header: "http://localhost:4001/images/banner.png", - header_static: "http://localhost:4001/images/banner.png", - emojis: [], - fields: [], - bot: true, - source: %{ - note: user.bio, - sensitive: false, - pleroma: %{}, - fields: [] - }, - pleroma: %{ - background_image: nil, - confirmation_pending: false, - tags: [], - is_admin: false, - is_moderator: false, - hide_favorites: true, - hide_followers: false, - hide_follows: false, - relationship: %{ - id: to_string(user.id), - following: false, - followed_by: false, - blocking: true, - blocked_by: false, - subscribing: false, - muting: false, - muting_notifications: false, - requested: false, - domain_blocking: false, - showing_reblogs: true, - endorsed: false - }, - skip_thread_containment: false - } - } - - assert expected == AccountView.render("account.json", %{user: user, for: other_user}) - end - - test "returns the settings store if the requesting user is the represented user and it's requested specifically" do - user = insert(:user, %{info: %User.Info{pleroma_settings_store: %{fe: "test"}}}) - - result = - AccountView.render("account.json", %{user: user, for: user, with_pleroma_settings: true}) - - assert result.pleroma.settings_store == %{:fe => "test"} - - result = AccountView.render("account.json", %{user: user, with_pleroma_settings: true}) - assert result.pleroma[:settings_store] == nil - - result = AccountView.render("account.json", %{user: user, for: user}) - assert result.pleroma[:settings_store] == nil - end - - test "sanitizes display names" do - user = insert(:user, name: " username ") - result = AccountView.render("account.json", %{user: user}) - refute result.display_name == " username " - end - - describe "hiding follows/following" do - test "shows when follows/following are hidden and sets follower/following count to 0" do - user = insert(:user, info: %{hide_followers: true, hide_follows: true}) - other_user = insert(:user) - {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user) - {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) - - assert %{ - followers_count: 0, - following_count: 0, - pleroma: %{hide_follows: true, hide_followers: true} - } = AccountView.render("account.json", %{user: user}) - end - - test "shows actual follower/following count to the account owner" do - user = insert(:user, info: %{hide_followers: true, hide_follows: true}) - other_user = insert(:user) - {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user) - {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) - - assert %{ - followers_count: 1, - following_count: 1 - } = AccountView.render("account.json", %{user: user, for: user}) - end - end -end diff --git a/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs b/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs new file mode 100644 index 000000000..87ee82050 --- /dev/null +++ b/test/web/mastodon_api/controllers/mastodon_api_controller/update_credentials_test.exs @@ -0,0 +1,369 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do + alias Pleroma.Repo + alias Pleroma.User + + use Pleroma.Web.ConnCase + + import Pleroma.Factory + clear_config([:instance, :max_account_fields]) + + describe "updating credentials" do + test "sets user settings in a generic way", %{conn: conn} do + user = insert(:user) + + res_conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{ + "pleroma_settings_store" => %{ + pleroma_fe: %{ + theme: "bla" + } + } + }) + + assert user = json_response(res_conn, 200) + assert user["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}} + + user = Repo.get(User, user["id"]) + + res_conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{ + "pleroma_settings_store" => %{ + masto_fe: %{ + theme: "bla" + } + } + }) + + assert user = json_response(res_conn, 200) + + assert user["pleroma"]["settings_store"] == + %{ + "pleroma_fe" => %{"theme" => "bla"}, + "masto_fe" => %{"theme" => "bla"} + } + + user = Repo.get(User, user["id"]) + + res_conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{ + "pleroma_settings_store" => %{ + masto_fe: %{ + theme: "blub" + } + } + }) + + assert user = json_response(res_conn, 200) + + assert user["pleroma"]["settings_store"] == + %{ + "pleroma_fe" => %{"theme" => "bla"}, + "masto_fe" => %{"theme" => "blub"} + } + end + + test "updates the user's bio", %{conn: conn} do + user = insert(:user) + user2 = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{ + "note" => "I drink #cofe with @#{user2.nickname}" + }) + + assert user = json_response(conn, 200) + + assert user["note"] == + ~s(I drink with @) <> user2.nickname <> ~s() + end + + test "updates the user's locking status", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{locked: "true"}) + + assert user = json_response(conn, 200) + assert user["locked"] == true + end + + test "updates the user's default scope", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{default_scope: "cofe"}) + + assert user = json_response(conn, 200) + assert user["source"]["privacy"] == "cofe" + end + + test "updates the user's hide_followers status", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{hide_followers: "true"}) + + assert user = json_response(conn, 200) + assert user["pleroma"]["hide_followers"] == true + end + + test "updates the user's skip_thread_containment option", %{conn: conn} do + user = insert(:user) + + response = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"}) + |> json_response(200) + + assert response["pleroma"]["skip_thread_containment"] == true + assert refresh_record(user).info.skip_thread_containment + end + + test "updates the user's hide_follows status", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{hide_follows: "true"}) + + assert user = json_response(conn, 200) + assert user["pleroma"]["hide_follows"] == true + end + + test "updates the user's hide_favorites status", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{hide_favorites: "true"}) + + assert user = json_response(conn, 200) + assert user["pleroma"]["hide_favorites"] == true + end + + test "updates the user's show_role status", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{show_role: "false"}) + + assert user = json_response(conn, 200) + assert user["source"]["pleroma"]["show_role"] == false + end + + test "updates the user's no_rich_text status", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{no_rich_text: "true"}) + + assert user = json_response(conn, 200) + assert user["source"]["pleroma"]["no_rich_text"] == true + end + + test "updates the user's name", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"}) + + assert user = json_response(conn, 200) + assert user["display_name"] == "markorepairs" + end + + test "updates the user's avatar", %{conn: conn} do + user = insert(:user) + + new_avatar = %Plug.Upload{ + content_type: "image/jpg", + path: Path.absname("test/fixtures/image.jpg"), + filename: "an_image.jpg" + } + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar}) + + assert user_response = json_response(conn, 200) + assert user_response["avatar"] != User.avatar_url(user) + end + + test "updates the user's banner", %{conn: conn} do + user = insert(:user) + + new_header = %Plug.Upload{ + content_type: "image/jpg", + path: Path.absname("test/fixtures/image.jpg"), + filename: "an_image.jpg" + } + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{"header" => new_header}) + + assert user_response = json_response(conn, 200) + assert user_response["header"] != User.banner_url(user) + end + + test "updates the user's background", %{conn: conn} do + user = insert(:user) + + new_header = %Plug.Upload{ + content_type: "image/jpg", + path: Path.absname("test/fixtures/image.jpg"), + filename: "an_image.jpg" + } + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{ + "pleroma_background_image" => new_header + }) + + assert user_response = json_response(conn, 200) + assert user_response["pleroma"]["background_image"] + end + + test "requires 'write' permission", %{conn: conn} do + token1 = insert(:oauth_token, scopes: ["read"]) + token2 = insert(:oauth_token, scopes: ["write", "follow"]) + + for token <- [token1, token2] do + conn = + conn + |> put_req_header("authorization", "Bearer #{token.token}") + |> patch("/api/v1/accounts/update_credentials", %{}) + + if token == token1 do + assert %{"error" => "Insufficient permissions: write."} == json_response(conn, 403) + else + assert json_response(conn, 200) + end + end + end + + test "updates profile emojos", %{conn: conn} do + user = insert(:user) + + note = "*sips :blank:*" + name = "I am :firefox:" + + conn = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{ + "note" => note, + "display_name" => name + }) + + assert json_response(conn, 200) + + conn = + conn + |> get("/api/v1/accounts/#{user.id}") + + assert user = json_response(conn, 200) + + assert user["note"] == note + assert user["display_name"] == name + assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user["emojis"] + end + + test "update fields", %{conn: conn} do + user = insert(:user) + + fields = [ + %{"name" => "foo", "value" => ""}, + %{"name" => "link", "value" => "cofe.io"} + ] + + account = + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{"fields" => fields}) + |> json_response(200) + + assert account["fields"] == [ + %{"name" => "foo", "value" => "bar"}, + %{"name" => "link", "value" => "cofe.io"} + ] + + assert account["source"]["fields"] == [ + %{ + "name" => "foo", + "value" => "" + }, + %{"name" => "link", "value" => "cofe.io"} + ] + + name_limit = Pleroma.Config.get([:instance, :account_field_name_length]) + value_limit = Pleroma.Config.get([:instance, :account_field_value_length]) + + long_value = Enum.map(0..value_limit, fn _ -> "x" end) |> Enum.join() + + fields = [%{"name" => "foo", "value" => long_value}] + + assert %{"error" => "Invalid request"} == + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{"fields" => fields}) + |> json_response(403) + + long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join() + + fields = [%{"name" => long_name, "value" => "bar"}] + + assert %{"error" => "Invalid request"} == + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{"fields" => fields}) + |> json_response(403) + + Pleroma.Config.put([:instance, :max_account_fields], 1) + + fields = [ + %{"name" => "foo", "value" => "bar"}, + %{"name" => "link", "value" => "cofe.io"} + ] + + assert %{"error" => "Invalid request"} == + conn + |> assign(:user, user) + |> patch("/api/v1/accounts/update_credentials", %{"fields" => fields}) + |> json_response(403) + end + end +end diff --git a/test/web/mastodon_api/controllers/search_controller_test.exs b/test/web/mastodon_api/controllers/search_controller_test.exs new file mode 100644 index 000000000..49c79ff0a --- /dev/null +++ b/test/web/mastodon_api/controllers/search_controller_test.exs @@ -0,0 +1,285 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do + use Pleroma.Web.ConnCase + + alias Pleroma.Object + alias Pleroma.Web + alias Pleroma.Web.CommonAPI + import Pleroma.Factory + import ExUnit.CaptureLog + import Tesla.Mock + import Mock + + setup do + mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) + :ok + end + + describe ".search2" do + test "it returns empty result if user or status search return undefined error", %{conn: conn} do + with_mocks [ + {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]}, + {Pleroma.Activity, [], [search: fn _u, _q, _o -> raise "Oops" end]} + ] do + capture_log(fn -> + results = + conn + |> get("/api/v2/search", %{"q" => "2hu"}) + |> json_response(200) + + assert results["accounts"] == [] + assert results["statuses"] == [] + end) =~ + "[error] Elixir.Pleroma.Web.MastodonAPI.SearchController search error: %RuntimeError{message: \"Oops\"}" + end + end + + test "search", %{conn: conn} do + user = insert(:user) + user_two = insert(:user, %{nickname: "shp@shitposter.club"}) + user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu private"}) + + {:ok, _activity} = + CommonAPI.post(user, %{ + "status" => "This is about 2hu, but private", + "visibility" => "private" + }) + + {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"}) + + conn = get(conn, "/api/v2/search", %{"q" => "2hu #private"}) + + assert results = json_response(conn, 200) + + [account | _] = results["accounts"] + assert account["id"] == to_string(user_three.id) + + assert results["hashtags"] == [ + %{"name" => "private", "url" => "#{Web.base_url()}/tag/private"} + ] + + [status] = results["statuses"] + assert status["id"] == to_string(activity.id) + end + end + + describe ".account_search" do + test "account search", %{conn: conn} do + user = insert(:user) + user_two = insert(:user, %{nickname: "shp@shitposter.club"}) + user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) + + results = + conn + |> assign(:user, user) + |> get("/api/v1/accounts/search", %{"q" => "shp"}) + |> json_response(200) + + result_ids = for result <- results, do: result["acct"] + + assert user_two.nickname in result_ids + assert user_three.nickname in result_ids + + results = + conn + |> assign(:user, user) + |> get("/api/v1/accounts/search", %{"q" => "2hu"}) + |> json_response(200) + + result_ids = for result <- results, do: result["acct"] + + assert user_three.nickname in result_ids + end + + test "returns account if query contains a space", %{conn: conn} do + user = insert(:user, %{nickname: "shp@shitposter.club"}) + + results = + conn + |> assign(:user, user) + |> get("/api/v1/accounts/search", %{"q" => "shp@shitposter.club xxx "}) + |> json_response(200) + + assert length(results) == 1 + end + end + + describe ".search" do + test "it returns empty result if user or status search return undefined error", %{conn: conn} do + with_mocks [ + {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]}, + {Pleroma.Activity, [], [search: fn _u, _q, _o -> raise "Oops" end]} + ] do + capture_log(fn -> + results = + conn + |> get("/api/v1/search", %{"q" => "2hu"}) + |> json_response(200) + + assert results["accounts"] == [] + assert results["statuses"] == [] + end) =~ + "[error] Elixir.Pleroma.Web.MastodonAPI.SearchController search error: %RuntimeError{message: \"Oops\"}" + end + end + + test "search", %{conn: conn} do + user = insert(:user) + user_two = insert(:user, %{nickname: "shp@shitposter.club"}) + user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) + + {:ok, _activity} = + CommonAPI.post(user, %{ + "status" => "This is about 2hu, but private", + "visibility" => "private" + }) + + {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"}) + + conn = + conn + |> get("/api/v1/search", %{"q" => "2hu"}) + + assert results = json_response(conn, 200) + + [account | _] = results["accounts"] + assert account["id"] == to_string(user_three.id) + + assert results["hashtags"] == [] + + [status] = results["statuses"] + assert status["id"] == to_string(activity.id) + end + + test "search fetches remote statuses", %{conn: conn} do + capture_log(fn -> + conn = + conn + |> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"}) + + assert results = json_response(conn, 200) + + [status] = results["statuses"] + + assert status["uri"] == + "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment" + end) + end + + test "search doesn't show statuses that it shouldn't", %{conn: conn} do + {:ok, activity} = + CommonAPI.post(insert(:user), %{ + "status" => "This is about 2hu, but private", + "visibility" => "private" + }) + + capture_log(fn -> + conn = + conn + |> get("/api/v1/search", %{"q" => Object.normalize(activity).data["id"]}) + + assert results = json_response(conn, 200) + + [] = results["statuses"] + end) + end + + test "search fetches remote accounts", %{conn: conn} do + user = insert(:user) + + conn = + conn + |> assign(:user, user) + |> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "true"}) + + assert results = json_response(conn, 200) + [account] = results["accounts"] + assert account["acct"] == "shp@social.heldscal.la" + end + + test "search doesn't fetch remote accounts if resolve is false", %{conn: conn} do + conn = + conn + |> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "false"}) + + assert results = json_response(conn, 200) + assert [] == results["accounts"] + end + + test "search with limit and offset", %{conn: conn} do + user = insert(:user) + _user_two = insert(:user, %{nickname: "shp@shitposter.club"}) + _user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) + + {:ok, _activity1} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) + {:ok, _activity2} = CommonAPI.post(user, %{"status" => "This is also about 2hu"}) + + result = + conn + |> get("/api/v1/search", %{"q" => "2hu", "limit" => 1}) + + assert results = json_response(result, 200) + assert [%{"id" => activity_id1}] = results["statuses"] + assert [_] = results["accounts"] + + results = + conn + |> get("/api/v1/search", %{"q" => "2hu", "limit" => 1, "offset" => 1}) + |> json_response(200) + + assert [%{"id" => activity_id2}] = results["statuses"] + assert [] = results["accounts"] + + assert activity_id1 != activity_id2 + end + + test "search returns results only for the given type", %{conn: conn} do + user = insert(:user) + _user_two = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) + + {:ok, _activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) + + assert %{"statuses" => [_activity], "accounts" => [], "hashtags" => []} = + conn + |> get("/api/v1/search", %{"q" => "2hu", "type" => "statuses"}) + |> json_response(200) + + assert %{"statuses" => [], "accounts" => [_user_two], "hashtags" => []} = + conn + |> get("/api/v1/search", %{"q" => "2hu", "type" => "accounts"}) + |> json_response(200) + end + + test "search uses account_id to filter statuses by the author", %{conn: conn} do + user = insert(:user, %{nickname: "shp@shitposter.club"}) + user_two = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) + + {:ok, activity1} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) + {:ok, activity2} = CommonAPI.post(user_two, %{"status" => "This is also about 2hu"}) + + results = + conn + |> get("/api/v1/search", %{"q" => "2hu", "account_id" => user.id}) + |> json_response(200) + + assert [%{"id" => activity_id1}] = results["statuses"] + assert activity_id1 == activity1.id + assert [_] = results["accounts"] + + results = + conn + |> get("/api/v1/search", %{"q" => "2hu", "account_id" => user_two.id}) + |> json_response(200) + + assert [%{"id" => activity_id2}] = results["statuses"] + assert activity_id2 == activity2.id + end + end +end diff --git a/test/web/mastodon_api/controllers/subscription_controller_test.exs b/test/web/mastodon_api/controllers/subscription_controller_test.exs new file mode 100644 index 000000000..7dfb02f63 --- /dev/null +++ b/test/web/mastodon_api/controllers/subscription_controller_test.exs @@ -0,0 +1,192 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do + use Pleroma.Web.ConnCase + + import Pleroma.Factory + alias Pleroma.Web.Push + alias Pleroma.Web.Push.Subscription + + @sub %{ + "endpoint" => "https://example.com/example/1234", + "keys" => %{ + "auth" => "8eDyX_uCN0XRhSbY5hs7Hg==", + "p256dh" => + "BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA=" + } + } + @server_key Keyword.get(Push.vapid_config(), :public_key) + + setup do + user = insert(:user) + token = insert(:oauth_token, user: user, scopes: ["push"]) + + conn = + build_conn() + |> assign(:user, user) + |> assign(:token, token) + + %{conn: conn, user: user, token: token} + end + + defmacro assert_error_when_disable_push(do: yield) do + quote do + vapid_details = Application.get_env(:web_push_encryption, :vapid_details, []) + Application.put_env(:web_push_encryption, :vapid_details, []) + assert "Something went wrong" == unquote(yield) + Application.put_env(:web_push_encryption, :vapid_details, vapid_details) + end + end + + describe "creates push subscription" do + test "returns error when push disabled ", %{conn: conn} do + assert_error_when_disable_push do + conn + |> post("/api/v1/push/subscription", %{}) + |> json_response(500) + end + end + + test "successful creation", %{conn: conn} do + result = + conn + |> post("/api/v1/push/subscription", %{ + "data" => %{"alerts" => %{"mention" => true, "test" => true}}, + "subscription" => @sub + }) + |> json_response(200) + + [subscription] = Pleroma.Repo.all(Subscription) + + assert %{ + "alerts" => %{"mention" => true}, + "endpoint" => subscription.endpoint, + "id" => to_string(subscription.id), + "server_key" => @server_key + } == result + end + end + + describe "gets a user subscription" do + test "returns error when push disabled ", %{conn: conn} do + assert_error_when_disable_push do + conn + |> get("/api/v1/push/subscription", %{}) + |> json_response(500) + end + end + + test "returns error when user hasn't subscription", %{conn: conn} do + res = + conn + |> get("/api/v1/push/subscription", %{}) + |> json_response(404) + + assert "Not found" == res + end + + test "returns a user subsciption", %{conn: conn, user: user, token: token} do + subscription = + insert(:push_subscription, + user: user, + token: token, + data: %{"alerts" => %{"mention" => true}} + ) + + res = + conn + |> get("/api/v1/push/subscription", %{}) + |> json_response(200) + + expect = %{ + "alerts" => %{"mention" => true}, + "endpoint" => "https://example.com/example/1234", + "id" => to_string(subscription.id), + "server_key" => @server_key + } + + assert expect == res + end + end + + describe "updates a user subsciption" do + setup %{conn: conn, user: user, token: token} do + subscription = + insert(:push_subscription, + user: user, + token: token, + data: %{"alerts" => %{"mention" => true}} + ) + + %{conn: conn, user: user, token: token, subscription: subscription} + end + + test "returns error when push disabled ", %{conn: conn} do + assert_error_when_disable_push do + conn + |> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}}) + |> json_response(500) + end + end + + test "returns updated subsciption", %{conn: conn, subscription: subscription} do + res = + conn + |> put("/api/v1/push/subscription", %{ + data: %{"alerts" => %{"mention" => false, "follow" => true}} + }) + |> json_response(200) + + expect = %{ + "alerts" => %{"follow" => true, "mention" => false}, + "endpoint" => "https://example.com/example/1234", + "id" => to_string(subscription.id), + "server_key" => @server_key + } + + assert expect == res + end + end + + describe "deletes the user subscription" do + test "returns error when push disabled ", %{conn: conn} do + assert_error_when_disable_push do + conn + |> delete("/api/v1/push/subscription", %{}) + |> json_response(500) + end + end + + test "returns error when user hasn't subscription", %{conn: conn} do + res = + conn + |> delete("/api/v1/push/subscription", %{}) + |> json_response(404) + + assert "Not found" == res + end + + test "returns empty result and delete user subsciption", %{ + conn: conn, + user: user, + token: token + } do + subscription = + insert(:push_subscription, + user: user, + token: token, + data: %{"alerts" => %{"mention" => true}} + ) + + res = + conn + |> delete("/api/v1/push/subscription", %{}) + |> json_response(200) + + assert %{} == res + refute Pleroma.Repo.get(Subscription, subscription.id) + end + end +end diff --git a/test/web/mastodon_api/conversation_view_test.exs b/test/web/mastodon_api/conversation_view_test.exs deleted file mode 100644 index a2a880705..000000000 --- a/test/web/mastodon_api/conversation_view_test.exs +++ /dev/null @@ -1,34 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do - use Pleroma.DataCase - - alias Pleroma.Conversation.Participation - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.MastodonAPI.ConversationView - - import Pleroma.Factory - - test "represents a Mastodon Conversation entity" do - user = insert(:user) - other_user = insert(:user) - - {:ok, activity} = - CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}", "visibility" => "direct"}) - - [participation] = Participation.for_user_with_last_activity_id(user) - - assert participation - - conversation = - ConversationView.render("participation.json", %{participation: participation, for: user}) - - assert conversation.id == participation.id |> to_string() - assert conversation.last_status.id == activity.id - - assert [account] = conversation.accounts - assert account.id == other_user.id - end -end diff --git a/test/web/mastodon_api/mastodon_api_controller/update_credentials_test.exs b/test/web/mastodon_api/mastodon_api_controller/update_credentials_test.exs deleted file mode 100644 index 87ee82050..000000000 --- a/test/web/mastodon_api/mastodon_api_controller/update_credentials_test.exs +++ /dev/null @@ -1,369 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do - alias Pleroma.Repo - alias Pleroma.User - - use Pleroma.Web.ConnCase - - import Pleroma.Factory - clear_config([:instance, :max_account_fields]) - - describe "updating credentials" do - test "sets user settings in a generic way", %{conn: conn} do - user = insert(:user) - - res_conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ - "pleroma_settings_store" => %{ - pleroma_fe: %{ - theme: "bla" - } - } - }) - - assert user = json_response(res_conn, 200) - assert user["pleroma"]["settings_store"] == %{"pleroma_fe" => %{"theme" => "bla"}} - - user = Repo.get(User, user["id"]) - - res_conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ - "pleroma_settings_store" => %{ - masto_fe: %{ - theme: "bla" - } - } - }) - - assert user = json_response(res_conn, 200) - - assert user["pleroma"]["settings_store"] == - %{ - "pleroma_fe" => %{"theme" => "bla"}, - "masto_fe" => %{"theme" => "bla"} - } - - user = Repo.get(User, user["id"]) - - res_conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ - "pleroma_settings_store" => %{ - masto_fe: %{ - theme: "blub" - } - } - }) - - assert user = json_response(res_conn, 200) - - assert user["pleroma"]["settings_store"] == - %{ - "pleroma_fe" => %{"theme" => "bla"}, - "masto_fe" => %{"theme" => "blub"} - } - end - - test "updates the user's bio", %{conn: conn} do - user = insert(:user) - user2 = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ - "note" => "I drink #cofe with @#{user2.nickname}" - }) - - assert user = json_response(conn, 200) - - assert user["note"] == - ~s(I drink with @) <> user2.nickname <> ~s() - end - - test "updates the user's locking status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{locked: "true"}) - - assert user = json_response(conn, 200) - assert user["locked"] == true - end - - test "updates the user's default scope", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{default_scope: "cofe"}) - - assert user = json_response(conn, 200) - assert user["source"]["privacy"] == "cofe" - end - - test "updates the user's hide_followers status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{hide_followers: "true"}) - - assert user = json_response(conn, 200) - assert user["pleroma"]["hide_followers"] == true - end - - test "updates the user's skip_thread_containment option", %{conn: conn} do - user = insert(:user) - - response = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{skip_thread_containment: "true"}) - |> json_response(200) - - assert response["pleroma"]["skip_thread_containment"] == true - assert refresh_record(user).info.skip_thread_containment - end - - test "updates the user's hide_follows status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{hide_follows: "true"}) - - assert user = json_response(conn, 200) - assert user["pleroma"]["hide_follows"] == true - end - - test "updates the user's hide_favorites status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{hide_favorites: "true"}) - - assert user = json_response(conn, 200) - assert user["pleroma"]["hide_favorites"] == true - end - - test "updates the user's show_role status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{show_role: "false"}) - - assert user = json_response(conn, 200) - assert user["source"]["pleroma"]["show_role"] == false - end - - test "updates the user's no_rich_text status", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{no_rich_text: "true"}) - - assert user = json_response(conn, 200) - assert user["source"]["pleroma"]["no_rich_text"] == true - end - - test "updates the user's name", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"display_name" => "markorepairs"}) - - assert user = json_response(conn, 200) - assert user["display_name"] == "markorepairs" - end - - test "updates the user's avatar", %{conn: conn} do - user = insert(:user) - - new_avatar = %Plug.Upload{ - content_type: "image/jpg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"avatar" => new_avatar}) - - assert user_response = json_response(conn, 200) - assert user_response["avatar"] != User.avatar_url(user) - end - - test "updates the user's banner", %{conn: conn} do - user = insert(:user) - - new_header = %Plug.Upload{ - content_type: "image/jpg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"header" => new_header}) - - assert user_response = json_response(conn, 200) - assert user_response["header"] != User.banner_url(user) - end - - test "updates the user's background", %{conn: conn} do - user = insert(:user) - - new_header = %Plug.Upload{ - content_type: "image/jpg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ - "pleroma_background_image" => new_header - }) - - assert user_response = json_response(conn, 200) - assert user_response["pleroma"]["background_image"] - end - - test "requires 'write' permission", %{conn: conn} do - token1 = insert(:oauth_token, scopes: ["read"]) - token2 = insert(:oauth_token, scopes: ["write", "follow"]) - - for token <- [token1, token2] do - conn = - conn - |> put_req_header("authorization", "Bearer #{token.token}") - |> patch("/api/v1/accounts/update_credentials", %{}) - - if token == token1 do - assert %{"error" => "Insufficient permissions: write."} == json_response(conn, 403) - else - assert json_response(conn, 200) - end - end - end - - test "updates profile emojos", %{conn: conn} do - user = insert(:user) - - note = "*sips :blank:*" - name = "I am :firefox:" - - conn = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{ - "note" => note, - "display_name" => name - }) - - assert json_response(conn, 200) - - conn = - conn - |> get("/api/v1/accounts/#{user.id}") - - assert user = json_response(conn, 200) - - assert user["note"] == note - assert user["display_name"] == name - assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user["emojis"] - end - - test "update fields", %{conn: conn} do - user = insert(:user) - - fields = [ - %{"name" => "foo", "value" => ""}, - %{"name" => "link", "value" => "cofe.io"} - ] - - account = - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"fields" => fields}) - |> json_response(200) - - assert account["fields"] == [ - %{"name" => "foo", "value" => "bar"}, - %{"name" => "link", "value" => "cofe.io"} - ] - - assert account["source"]["fields"] == [ - %{ - "name" => "foo", - "value" => "" - }, - %{"name" => "link", "value" => "cofe.io"} - ] - - name_limit = Pleroma.Config.get([:instance, :account_field_name_length]) - value_limit = Pleroma.Config.get([:instance, :account_field_value_length]) - - long_value = Enum.map(0..value_limit, fn _ -> "x" end) |> Enum.join() - - fields = [%{"name" => "foo", "value" => long_value}] - - assert %{"error" => "Invalid request"} == - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"fields" => fields}) - |> json_response(403) - - long_name = Enum.map(0..name_limit, fn _ -> "x" end) |> Enum.join() - - fields = [%{"name" => long_name, "value" => "bar"}] - - assert %{"error" => "Invalid request"} == - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"fields" => fields}) - |> json_response(403) - - Pleroma.Config.put([:instance, :max_account_fields], 1) - - fields = [ - %{"name" => "foo", "value" => "bar"}, - %{"name" => "link", "value" => "cofe.io"} - ] - - assert %{"error" => "Invalid request"} == - conn - |> assign(:user, user) - |> patch("/api/v1/accounts/update_credentials", %{"fields" => fields}) - |> json_response(403) - end - end -end diff --git a/test/web/mastodon_api/notification_view_test.exs b/test/web/mastodon_api/notification_view_test.exs deleted file mode 100644 index 977ea1e87..000000000 --- a/test/web/mastodon_api/notification_view_test.exs +++ /dev/null @@ -1,104 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do - use Pleroma.DataCase - - alias Pleroma.Activity - alias Pleroma.Notification - alias Pleroma.Repo - alias Pleroma.User - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.CommonAPI.Utils - alias Pleroma.Web.MastodonAPI.AccountView - alias Pleroma.Web.MastodonAPI.NotificationView - alias Pleroma.Web.MastodonAPI.StatusView - import Pleroma.Factory - - test "Mention notification" do - user = insert(:user) - mentioned_user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{mentioned_user.nickname}"}) - {:ok, [notification]} = Notification.create_notifications(activity) - user = User.get_cached_by_id(user.id) - - expected = %{ - id: to_string(notification.id), - pleroma: %{is_seen: false}, - type: "mention", - account: AccountView.render("account.json", %{user: user, for: mentioned_user}), - status: StatusView.render("status.json", %{activity: activity, for: mentioned_user}), - created_at: Utils.to_masto_date(notification.inserted_at) - } - - result = - NotificationView.render("index.json", %{notifications: [notification], for: mentioned_user}) - - assert [expected] == result - end - - test "Favourite notification" do - user = insert(:user) - another_user = insert(:user) - {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) - {:ok, favorite_activity, _object} = CommonAPI.favorite(create_activity.id, another_user) - {:ok, [notification]} = Notification.create_notifications(favorite_activity) - create_activity = Activity.get_by_id(create_activity.id) - - expected = %{ - id: to_string(notification.id), - pleroma: %{is_seen: false}, - type: "favourite", - account: AccountView.render("account.json", %{user: another_user, for: user}), - status: StatusView.render("status.json", %{activity: create_activity, for: user}), - created_at: Utils.to_masto_date(notification.inserted_at) - } - - result = NotificationView.render("index.json", %{notifications: [notification], for: user}) - - assert [expected] == result - end - - test "Reblog notification" do - user = insert(:user) - another_user = insert(:user) - {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) - {:ok, reblog_activity, _object} = CommonAPI.repeat(create_activity.id, another_user) - {:ok, [notification]} = Notification.create_notifications(reblog_activity) - reblog_activity = Activity.get_by_id(create_activity.id) - - expected = %{ - id: to_string(notification.id), - pleroma: %{is_seen: false}, - type: "reblog", - account: AccountView.render("account.json", %{user: another_user, for: user}), - status: StatusView.render("status.json", %{activity: reblog_activity, for: user}), - created_at: Utils.to_masto_date(notification.inserted_at) - } - - result = NotificationView.render("index.json", %{notifications: [notification], for: user}) - - assert [expected] == result - end - - test "Follow notification" do - follower = insert(:user) - followed = insert(:user) - {:ok, follower, followed, _activity} = CommonAPI.follow(follower, followed) - notification = Notification |> Repo.one() |> Repo.preload(:activity) - - expected = %{ - id: to_string(notification.id), - pleroma: %{is_seen: false}, - type: "follow", - account: AccountView.render("account.json", %{user: follower, for: followed}), - created_at: Utils.to_masto_date(notification.inserted_at) - } - - result = - NotificationView.render("index.json", %{notifications: [notification], for: followed}) - - assert [expected] == result - end -end diff --git a/test/web/mastodon_api/push_subscription_view_test.exs b/test/web/mastodon_api/push_subscription_view_test.exs deleted file mode 100644 index dc935fc82..000000000 --- a/test/web/mastodon_api/push_subscription_view_test.exs +++ /dev/null @@ -1,23 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do - use Pleroma.DataCase - import Pleroma.Factory - alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View - alias Pleroma.Web.Push - - test "Represent a subscription" do - subscription = insert(:push_subscription, data: %{"alerts" => %{"mention" => true}}) - - expected = %{ - alerts: %{"mention" => true}, - endpoint: subscription.endpoint, - id: to_string(subscription.id), - server_key: Keyword.get(Push.vapid_config(), :public_key) - } - - assert expected == View.render("push_subscription.json", %{subscription: subscription}) - end -end diff --git a/test/web/mastodon_api/scheduled_activity_view_test.exs b/test/web/mastodon_api/scheduled_activity_view_test.exs deleted file mode 100644 index ecbb855d4..000000000 --- a/test/web/mastodon_api/scheduled_activity_view_test.exs +++ /dev/null @@ -1,68 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do - use Pleroma.DataCase - alias Pleroma.ScheduledActivity - alias Pleroma.Web.ActivityPub.ActivityPub - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.CommonAPI.Utils - alias Pleroma.Web.MastodonAPI.ScheduledActivityView - alias Pleroma.Web.MastodonAPI.StatusView - import Pleroma.Factory - - test "A scheduled activity with a media attachment" do - user = insert(:user) - {:ok, activity} = CommonAPI.post(user, %{"status" => "hi"}) - - scheduled_at = - NaiveDateTime.utc_now() - |> NaiveDateTime.add(:timer.minutes(10), :millisecond) - |> NaiveDateTime.to_iso8601() - - file = %Plug.Upload{ - content_type: "image/jpg", - path: Path.absname("test/fixtures/image.jpg"), - filename: "an_image.jpg" - } - - {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) - - attrs = %{ - params: %{ - "media_ids" => [upload.id], - "status" => "hi", - "sensitive" => true, - "spoiler_text" => "spoiler", - "visibility" => "unlisted", - "in_reply_to_id" => to_string(activity.id) - }, - scheduled_at: scheduled_at - } - - {:ok, scheduled_activity} = ScheduledActivity.create(user, attrs) - result = ScheduledActivityView.render("show.json", %{scheduled_activity: scheduled_activity}) - - expected = %{ - id: to_string(scheduled_activity.id), - media_attachments: - %{"media_ids" => [upload.id]} - |> Utils.attachments_from_ids() - |> Enum.map(&StatusView.render("attachment.json", %{attachment: &1})), - params: %{ - in_reply_to_id: to_string(activity.id), - media_ids: [upload.id], - poll: nil, - scheduled_at: nil, - sensitive: true, - spoiler_text: "spoiler", - text: "hi", - visibility: "unlisted" - }, - scheduled_at: Utils.to_masto_date(scheduled_activity.scheduled_at) - } - - assert expected == result - end -end diff --git a/test/web/mastodon_api/search_controller_test.exs b/test/web/mastodon_api/search_controller_test.exs deleted file mode 100644 index 49c79ff0a..000000000 --- a/test/web/mastodon_api/search_controller_test.exs +++ /dev/null @@ -1,285 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.SearchControllerTest do - use Pleroma.Web.ConnCase - - alias Pleroma.Object - alias Pleroma.Web - alias Pleroma.Web.CommonAPI - import Pleroma.Factory - import ExUnit.CaptureLog - import Tesla.Mock - import Mock - - setup do - mock_global(fn env -> apply(HttpRequestMock, :request, [env]) end) - :ok - end - - describe ".search2" do - test "it returns empty result if user or status search return undefined error", %{conn: conn} do - with_mocks [ - {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]}, - {Pleroma.Activity, [], [search: fn _u, _q, _o -> raise "Oops" end]} - ] do - capture_log(fn -> - results = - conn - |> get("/api/v2/search", %{"q" => "2hu"}) - |> json_response(200) - - assert results["accounts"] == [] - assert results["statuses"] == [] - end) =~ - "[error] Elixir.Pleroma.Web.MastodonAPI.SearchController search error: %RuntimeError{message: \"Oops\"}" - end - end - - test "search", %{conn: conn} do - user = insert(:user) - user_two = insert(:user, %{nickname: "shp@shitposter.club"}) - user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - - {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu private"}) - - {:ok, _activity} = - CommonAPI.post(user, %{ - "status" => "This is about 2hu, but private", - "visibility" => "private" - }) - - {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"}) - - conn = get(conn, "/api/v2/search", %{"q" => "2hu #private"}) - - assert results = json_response(conn, 200) - - [account | _] = results["accounts"] - assert account["id"] == to_string(user_three.id) - - assert results["hashtags"] == [ - %{"name" => "private", "url" => "#{Web.base_url()}/tag/private"} - ] - - [status] = results["statuses"] - assert status["id"] == to_string(activity.id) - end - end - - describe ".account_search" do - test "account search", %{conn: conn} do - user = insert(:user) - user_two = insert(:user, %{nickname: "shp@shitposter.club"}) - user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - - results = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/search", %{"q" => "shp"}) - |> json_response(200) - - result_ids = for result <- results, do: result["acct"] - - assert user_two.nickname in result_ids - assert user_three.nickname in result_ids - - results = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/search", %{"q" => "2hu"}) - |> json_response(200) - - result_ids = for result <- results, do: result["acct"] - - assert user_three.nickname in result_ids - end - - test "returns account if query contains a space", %{conn: conn} do - user = insert(:user, %{nickname: "shp@shitposter.club"}) - - results = - conn - |> assign(:user, user) - |> get("/api/v1/accounts/search", %{"q" => "shp@shitposter.club xxx "}) - |> json_response(200) - - assert length(results) == 1 - end - end - - describe ".search" do - test "it returns empty result if user or status search return undefined error", %{conn: conn} do - with_mocks [ - {Pleroma.User, [], [search: fn _q, _o -> raise "Oops" end]}, - {Pleroma.Activity, [], [search: fn _u, _q, _o -> raise "Oops" end]} - ] do - capture_log(fn -> - results = - conn - |> get("/api/v1/search", %{"q" => "2hu"}) - |> json_response(200) - - assert results["accounts"] == [] - assert results["statuses"] == [] - end) =~ - "[error] Elixir.Pleroma.Web.MastodonAPI.SearchController search error: %RuntimeError{message: \"Oops\"}" - end - end - - test "search", %{conn: conn} do - user = insert(:user) - user_two = insert(:user, %{nickname: "shp@shitposter.club"}) - user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - - {:ok, activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) - - {:ok, _activity} = - CommonAPI.post(user, %{ - "status" => "This is about 2hu, but private", - "visibility" => "private" - }) - - {:ok, _} = CommonAPI.post(user_two, %{"status" => "This isn't"}) - - conn = - conn - |> get("/api/v1/search", %{"q" => "2hu"}) - - assert results = json_response(conn, 200) - - [account | _] = results["accounts"] - assert account["id"] == to_string(user_three.id) - - assert results["hashtags"] == [] - - [status] = results["statuses"] - assert status["id"] == to_string(activity.id) - end - - test "search fetches remote statuses", %{conn: conn} do - capture_log(fn -> - conn = - conn - |> get("/api/v1/search", %{"q" => "https://shitposter.club/notice/2827873"}) - - assert results = json_response(conn, 200) - - [status] = results["statuses"] - - assert status["uri"] == - "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment" - end) - end - - test "search doesn't show statuses that it shouldn't", %{conn: conn} do - {:ok, activity} = - CommonAPI.post(insert(:user), %{ - "status" => "This is about 2hu, but private", - "visibility" => "private" - }) - - capture_log(fn -> - conn = - conn - |> get("/api/v1/search", %{"q" => Object.normalize(activity).data["id"]}) - - assert results = json_response(conn, 200) - - [] = results["statuses"] - end) - end - - test "search fetches remote accounts", %{conn: conn} do - user = insert(:user) - - conn = - conn - |> assign(:user, user) - |> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "true"}) - - assert results = json_response(conn, 200) - [account] = results["accounts"] - assert account["acct"] == "shp@social.heldscal.la" - end - - test "search doesn't fetch remote accounts if resolve is false", %{conn: conn} do - conn = - conn - |> get("/api/v1/search", %{"q" => "shp@social.heldscal.la", "resolve" => "false"}) - - assert results = json_response(conn, 200) - assert [] == results["accounts"] - end - - test "search with limit and offset", %{conn: conn} do - user = insert(:user) - _user_two = insert(:user, %{nickname: "shp@shitposter.club"}) - _user_three = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - - {:ok, _activity1} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) - {:ok, _activity2} = CommonAPI.post(user, %{"status" => "This is also about 2hu"}) - - result = - conn - |> get("/api/v1/search", %{"q" => "2hu", "limit" => 1}) - - assert results = json_response(result, 200) - assert [%{"id" => activity_id1}] = results["statuses"] - assert [_] = results["accounts"] - - results = - conn - |> get("/api/v1/search", %{"q" => "2hu", "limit" => 1, "offset" => 1}) - |> json_response(200) - - assert [%{"id" => activity_id2}] = results["statuses"] - assert [] = results["accounts"] - - assert activity_id1 != activity_id2 - end - - test "search returns results only for the given type", %{conn: conn} do - user = insert(:user) - _user_two = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - - {:ok, _activity} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) - - assert %{"statuses" => [_activity], "accounts" => [], "hashtags" => []} = - conn - |> get("/api/v1/search", %{"q" => "2hu", "type" => "statuses"}) - |> json_response(200) - - assert %{"statuses" => [], "accounts" => [_user_two], "hashtags" => []} = - conn - |> get("/api/v1/search", %{"q" => "2hu", "type" => "accounts"}) - |> json_response(200) - end - - test "search uses account_id to filter statuses by the author", %{conn: conn} do - user = insert(:user, %{nickname: "shp@shitposter.club"}) - user_two = insert(:user, %{nickname: "shp@heldscal.la", name: "I love 2hu"}) - - {:ok, activity1} = CommonAPI.post(user, %{"status" => "This is about 2hu"}) - {:ok, activity2} = CommonAPI.post(user_two, %{"status" => "This is also about 2hu"}) - - results = - conn - |> get("/api/v1/search", %{"q" => "2hu", "account_id" => user.id}) - |> json_response(200) - - assert [%{"id" => activity_id1}] = results["statuses"] - assert activity_id1 == activity1.id - assert [_] = results["accounts"] - - results = - conn - |> get("/api/v1/search", %{"q" => "2hu", "account_id" => user_two.id}) - |> json_response(200) - - assert [%{"id" => activity_id2}] = results["statuses"] - assert activity_id2 == activity2.id - end - end -end diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs deleted file mode 100644 index 1b6beb6d2..000000000 --- a/test/web/mastodon_api/status_view_test.exs +++ /dev/null @@ -1,584 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2018 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.StatusViewTest do - use Pleroma.DataCase - - alias Pleroma.Activity - alias Pleroma.Bookmark - alias Pleroma.Object - alias Pleroma.Repo - alias Pleroma.User - alias Pleroma.Web.CommonAPI - alias Pleroma.Web.CommonAPI.Utils - alias Pleroma.Web.MastodonAPI.AccountView - alias Pleroma.Web.MastodonAPI.StatusView - alias Pleroma.Web.OStatus - import Pleroma.Factory - import Tesla.Mock - - setup do - mock(fn env -> apply(HttpRequestMock, :request, [env]) end) - :ok - end - - test "returns the direct conversation id when given the `with_conversation_id` option" do - user = insert(:user) - - {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) - - status = - StatusView.render("status.json", - activity: activity, - with_direct_conversation_id: true, - for: user - ) - - assert status[:pleroma][:direct_conversation_id] - end - - test "returns a temporary ap_id based user for activities missing db users" do - user = insert(:user) - - {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) - - Repo.delete(user) - Cachex.clear(:user_cache) - - %{account: ms_user} = StatusView.render("status.json", activity: activity) - - assert ms_user.acct == "erroruser@example.com" - end - - test "tries to get a user by nickname if fetching by ap_id doesn't work" do - user = insert(:user) - - {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) - - {:ok, user} = - user - |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"}) - |> Repo.update() - - Cachex.clear(:user_cache) - - result = StatusView.render("status.json", activity: activity) - - assert result[:account][:id] == to_string(user.id) - end - - test "a note with null content" do - note = insert(:note_activity) - note_object = Object.normalize(note) - - data = - note_object.data - |> Map.put("content", nil) - - Object.change(note_object, %{data: data}) - |> Object.update_and_set_cache() - - User.get_cached_by_ap_id(note.data["actor"]) - - status = StatusView.render("status.json", %{activity: note}) - - assert status.content == "" - end - - test "a note activity" do - note = insert(:note_activity) - object_data = Object.normalize(note).data - user = User.get_cached_by_ap_id(note.data["actor"]) - - convo_id = Utils.context_to_conversation_id(object_data["context"]) - - status = StatusView.render("status.json", %{activity: note}) - - created_at = - (object_data["published"] || "") - |> String.replace(~r/\.\d+Z/, ".000Z") - - expected = %{ - id: to_string(note.id), - uri: object_data["id"], - url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note), - account: AccountView.render("account.json", %{user: user}), - in_reply_to_id: nil, - in_reply_to_account_id: nil, - card: nil, - reblog: nil, - content: HtmlSanitizeEx.basic_html(object_data["content"]), - created_at: created_at, - reblogs_count: 0, - replies_count: 0, - favourites_count: 0, - reblogged: false, - bookmarked: false, - favourited: false, - muted: false, - pinned: false, - sensitive: false, - poll: nil, - spoiler_text: HtmlSanitizeEx.basic_html(object_data["summary"]), - visibility: "public", - media_attachments: [], - mentions: [], - tags: [ - %{ - name: "#{object_data["tag"]}", - url: "/tag/#{object_data["tag"]}" - } - ], - application: %{ - name: "Web", - website: nil - }, - language: nil, - emojis: [ - %{ - shortcode: "2hu", - url: "corndog.png", - static_url: "corndog.png", - visible_in_picker: false - } - ], - pleroma: %{ - local: true, - conversation_id: convo_id, - in_reply_to_account_acct: nil, - content: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["content"])}, - spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["summary"])}, - expires_at: nil, - direct_conversation_id: nil - } - } - - assert status == expected - end - - test "tells if the message is muted for some reason" do - user = insert(:user) - other_user = insert(:user) - - {:ok, user} = User.mute(user, other_user) - - {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"}) - status = StatusView.render("status.json", %{activity: activity}) - - assert status.muted == false - - status = StatusView.render("status.json", %{activity: activity, for: user}) - - assert status.muted == true - end - - test "tells if the status is bookmarked" do - user = insert(:user) - - {:ok, activity} = CommonAPI.post(user, %{"status" => "Cute girls doing cute things"}) - status = StatusView.render("status.json", %{activity: activity}) - - assert status.bookmarked == false - - status = StatusView.render("status.json", %{activity: activity, for: user}) - - assert status.bookmarked == false - - {:ok, _bookmark} = Bookmark.create(user.id, activity.id) - - activity = Activity.get_by_id_with_object(activity.id) - - status = StatusView.render("status.json", %{activity: activity, for: user}) - - assert status.bookmarked == true - end - - test "a reply" do - note = insert(:note_activity) - user = insert(:user) - - {:ok, activity} = - CommonAPI.post(user, %{"status" => "he", "in_reply_to_status_id" => note.id}) - - status = StatusView.render("status.json", %{activity: activity}) - - assert status.in_reply_to_id == to_string(note.id) - - [status] = StatusView.render("index.json", %{activities: [activity], as: :activity}) - - assert status.in_reply_to_id == to_string(note.id) - end - - test "contains mentions" do - incoming = File.read!("test/fixtures/incoming_reply_mastodon.xml") - # a user with this ap id might be in the cache. - recipient = "https://pleroma.soykaf.com/users/lain" - user = insert(:user, %{ap_id: recipient}) - - {:ok, [activity]} = OStatus.handle_incoming(incoming) - - status = StatusView.render("status.json", %{activity: activity}) - - assert status.mentions == - Enum.map([user], fn u -> AccountView.render("mention.json", %{user: u}) end) - end - - test "create mentions from the 'to' field" do - %User{ap_id: recipient_ap_id} = insert(:user) - cc = insert_pair(:user) |> Enum.map(& &1.ap_id) - - object = - insert(:note, %{ - data: %{ - "to" => [recipient_ap_id], - "cc" => cc - } - }) - - activity = - insert(:note_activity, %{ - note: object, - recipients: [recipient_ap_id | cc] - }) - - assert length(activity.recipients) == 3 - - %{mentions: [mention] = mentions} = StatusView.render("status.json", %{activity: activity}) - - assert length(mentions) == 1 - assert mention.url == recipient_ap_id - end - - test "create mentions from the 'tag' field" do - recipient = insert(:user) - cc = insert_pair(:user) |> Enum.map(& &1.ap_id) - - object = - insert(:note, %{ - data: %{ - "cc" => cc, - "tag" => [ - %{ - "href" => recipient.ap_id, - "name" => recipient.nickname, - "type" => "Mention" - }, - %{ - "href" => "https://example.com/search?tag=test", - "name" => "#test", - "type" => "Hashtag" - } - ] - } - }) - - activity = - insert(:note_activity, %{ - note: object, - recipients: [recipient.ap_id | cc] - }) - - assert length(activity.recipients) == 3 - - %{mentions: [mention] = mentions} = StatusView.render("status.json", %{activity: activity}) - - assert length(mentions) == 1 - assert mention.url == recipient.ap_id - end - - test "attachments" do - object = %{ - "type" => "Image", - "url" => [ - %{ - "mediaType" => "image/png", - "href" => "someurl" - } - ], - "uuid" => 6 - } - - expected = %{ - id: "1638338801", - type: "image", - url: "someurl", - remote_url: "someurl", - preview_url: "someurl", - text_url: "someurl", - description: nil, - pleroma: %{mime_type: "image/png"} - } - - assert expected == StatusView.render("attachment.json", %{attachment: object}) - - # If theres a "id", use that instead of the generated one - object = Map.put(object, "id", 2) - assert %{id: "2"} = StatusView.render("attachment.json", %{attachment: object}) - end - - test "put the url advertised in the Activity in to the url attribute" do - id = "https://wedistribute.org/wp-json/pterotype/v1/object/85810" - [activity] = Activity.search(nil, id) - - status = StatusView.render("status.json", %{activity: activity}) - - assert status.uri == id - assert status.url == "https://wedistribute.org/2019/07/mastodon-drops-ostatus/" - end - - test "a reblog" do - user = insert(:user) - activity = insert(:note_activity) - - {:ok, reblog, _} = CommonAPI.repeat(activity.id, user) - - represented = StatusView.render("status.json", %{for: user, activity: reblog}) - - assert represented[:id] == to_string(reblog.id) - assert represented[:reblog][:id] == to_string(activity.id) - assert represented[:emojis] == [] - end - - test "a peertube video" do - user = insert(:user) - - {:ok, object} = - Pleroma.Object.Fetcher.fetch_object_from_id( - "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3" - ) - - %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"]) - - represented = StatusView.render("status.json", %{for: user, activity: activity}) - - assert represented[:id] == to_string(activity.id) - assert length(represented[:media_attachments]) == 1 - end - - describe "build_tags/1" do - test "it returns a a dictionary tags" do - object_tags = [ - "fediverse", - "mastodon", - "nextcloud", - %{ - "href" => "https://kawen.space/users/lain", - "name" => "@lain@kawen.space", - "type" => "Mention" - } - ] - - assert StatusView.build_tags(object_tags) == [ - %{name: "fediverse", url: "/tag/fediverse"}, - %{name: "mastodon", url: "/tag/mastodon"}, - %{name: "nextcloud", url: "/tag/nextcloud"} - ] - end - end - - describe "rich media cards" do - test "a rich media card without a site name renders correctly" do - page_url = "http://example.com" - - card = %{ - url: page_url, - image: page_url <> "/example.jpg", - title: "Example website" - } - - %{provider_name: "example.com"} = - StatusView.render("card.json", %{page_url: page_url, rich_media: card}) - end - - test "a rich media card without a site name or image renders correctly" do - page_url = "http://example.com" - - card = %{ - url: page_url, - title: "Example website" - } - - %{provider_name: "example.com"} = - StatusView.render("card.json", %{page_url: page_url, rich_media: card}) - end - - test "a rich media card without an image renders correctly" do - page_url = "http://example.com" - - card = %{ - url: page_url, - site_name: "Example site name", - title: "Example website" - } - - %{provider_name: "Example site name"} = - StatusView.render("card.json", %{page_url: page_url, rich_media: card}) - end - - test "a rich media card with all relevant data renders correctly" do - page_url = "http://example.com" - - card = %{ - url: page_url, - site_name: "Example site name", - title: "Example website", - image: page_url <> "/example.jpg", - description: "Example description" - } - - %{provider_name: "Example site name"} = - 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: to_string(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 - - test "embeds a relationship in the account" do - user = insert(:user) - other_user = insert(:user) - - {:ok, activity} = - CommonAPI.post(user, %{ - "status" => "drink more water" - }) - - result = StatusView.render("status.json", %{activity: activity, for: other_user}) - - assert result[:account][:pleroma][:relationship] == - AccountView.render("relationship.json", %{user: other_user, target: user}) - end - - test "embeds a relationship in the account in reposts" do - user = insert(:user) - other_user = insert(:user) - - {:ok, activity} = - CommonAPI.post(user, %{ - "status" => "˙˙ɐʎns" - }) - - {:ok, activity, _object} = CommonAPI.repeat(activity.id, other_user) - - result = StatusView.render("status.json", %{activity: activity, for: user}) - - assert result[:account][:pleroma][:relationship] == - AccountView.render("relationship.json", %{user: user, target: other_user}) - - assert result[:reblog][:account][:pleroma][:relationship] == - AccountView.render("relationship.json", %{user: user, target: user}) - end - - test "visibility/list" do - user = insert(:user) - - {:ok, list} = Pleroma.List.create("foo", user) - - {:ok, activity} = - CommonAPI.post(user, %{"status" => "foobar", "visibility" => "list:#{list.id}"}) - - status = StatusView.render("status.json", activity: activity) - - assert status.visibility == "list" - end -end diff --git a/test/web/mastodon_api/subscription_controller_test.exs b/test/web/mastodon_api/subscription_controller_test.exs deleted file mode 100644 index 7dfb02f63..000000000 --- a/test/web/mastodon_api/subscription_controller_test.exs +++ /dev/null @@ -1,192 +0,0 @@ -# Pleroma: A lightweight social networking server -# Copyright © 2017-2019 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Pleroma.Web.MastodonAPI.SubscriptionControllerTest do - use Pleroma.Web.ConnCase - - import Pleroma.Factory - alias Pleroma.Web.Push - alias Pleroma.Web.Push.Subscription - - @sub %{ - "endpoint" => "https://example.com/example/1234", - "keys" => %{ - "auth" => "8eDyX_uCN0XRhSbY5hs7Hg==", - "p256dh" => - "BCIWgsnyXDv1VkhqL2P7YRBvdeuDnlwAPT2guNhdIoW3IP7GmHh1SMKPLxRf7x8vJy6ZFK3ol2ohgn_-0yP7QQA=" - } - } - @server_key Keyword.get(Push.vapid_config(), :public_key) - - setup do - user = insert(:user) - token = insert(:oauth_token, user: user, scopes: ["push"]) - - conn = - build_conn() - |> assign(:user, user) - |> assign(:token, token) - - %{conn: conn, user: user, token: token} - end - - defmacro assert_error_when_disable_push(do: yield) do - quote do - vapid_details = Application.get_env(:web_push_encryption, :vapid_details, []) - Application.put_env(:web_push_encryption, :vapid_details, []) - assert "Something went wrong" == unquote(yield) - Application.put_env(:web_push_encryption, :vapid_details, vapid_details) - end - end - - describe "creates push subscription" do - test "returns error when push disabled ", %{conn: conn} do - assert_error_when_disable_push do - conn - |> post("/api/v1/push/subscription", %{}) - |> json_response(500) - end - end - - test "successful creation", %{conn: conn} do - result = - conn - |> post("/api/v1/push/subscription", %{ - "data" => %{"alerts" => %{"mention" => true, "test" => true}}, - "subscription" => @sub - }) - |> json_response(200) - - [subscription] = Pleroma.Repo.all(Subscription) - - assert %{ - "alerts" => %{"mention" => true}, - "endpoint" => subscription.endpoint, - "id" => to_string(subscription.id), - "server_key" => @server_key - } == result - end - end - - describe "gets a user subscription" do - test "returns error when push disabled ", %{conn: conn} do - assert_error_when_disable_push do - conn - |> get("/api/v1/push/subscription", %{}) - |> json_response(500) - end - end - - test "returns error when user hasn't subscription", %{conn: conn} do - res = - conn - |> get("/api/v1/push/subscription", %{}) - |> json_response(404) - - assert "Not found" == res - end - - test "returns a user subsciption", %{conn: conn, user: user, token: token} do - subscription = - insert(:push_subscription, - user: user, - token: token, - data: %{"alerts" => %{"mention" => true}} - ) - - res = - conn - |> get("/api/v1/push/subscription", %{}) - |> json_response(200) - - expect = %{ - "alerts" => %{"mention" => true}, - "endpoint" => "https://example.com/example/1234", - "id" => to_string(subscription.id), - "server_key" => @server_key - } - - assert expect == res - end - end - - describe "updates a user subsciption" do - setup %{conn: conn, user: user, token: token} do - subscription = - insert(:push_subscription, - user: user, - token: token, - data: %{"alerts" => %{"mention" => true}} - ) - - %{conn: conn, user: user, token: token, subscription: subscription} - end - - test "returns error when push disabled ", %{conn: conn} do - assert_error_when_disable_push do - conn - |> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}}) - |> json_response(500) - end - end - - test "returns updated subsciption", %{conn: conn, subscription: subscription} do - res = - conn - |> put("/api/v1/push/subscription", %{ - data: %{"alerts" => %{"mention" => false, "follow" => true}} - }) - |> json_response(200) - - expect = %{ - "alerts" => %{"follow" => true, "mention" => false}, - "endpoint" => "https://example.com/example/1234", - "id" => to_string(subscription.id), - "server_key" => @server_key - } - - assert expect == res - end - end - - describe "deletes the user subscription" do - test "returns error when push disabled ", %{conn: conn} do - assert_error_when_disable_push do - conn - |> delete("/api/v1/push/subscription", %{}) - |> json_response(500) - end - end - - test "returns error when user hasn't subscription", %{conn: conn} do - res = - conn - |> delete("/api/v1/push/subscription", %{}) - |> json_response(404) - - assert "Not found" == res - end - - test "returns empty result and delete user subsciption", %{ - conn: conn, - user: user, - token: token - } do - subscription = - insert(:push_subscription, - user: user, - token: token, - data: %{"alerts" => %{"mention" => true}} - ) - - res = - conn - |> delete("/api/v1/push/subscription", %{}) - |> json_response(200) - - assert %{} == res - refute Pleroma.Repo.get(Subscription, subscription.id) - end - end -end diff --git a/test/web/mastodon_api/views/account_view_test.exs b/test/web/mastodon_api/views/account_view_test.exs new file mode 100644 index 000000000..1d8b28339 --- /dev/null +++ b/test/web/mastodon_api/views/account_view_test.exs @@ -0,0 +1,389 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.AccountViewTest do + use Pleroma.DataCase + import Pleroma.Factory + alias Pleroma.User + alias Pleroma.Web.CommonAPI + alias Pleroma.Web.MastodonAPI.AccountView + + test "Represent a user account" do + source_data = %{ + "tag" => [ + %{ + "type" => "Emoji", + "icon" => %{"url" => "/file.png"}, + "name" => ":karjalanpiirakka:" + } + ] + } + + background_image = %{ + "url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}] + } + + user = + insert(:user, %{ + info: %{ + note_count: 5, + follower_count: 3, + source_data: source_data, + background: background_image + }, + nickname: "shp@shitposter.club", + name: ":karjalanpiirakka: shp", + bio: "valid html", + inserted_at: ~N[2017-08-15 15:47:06.597036] + }) + + expected = %{ + id: to_string(user.id), + username: "shp", + acct: user.nickname, + display_name: user.name, + locked: false, + created_at: "2017-08-15T15:47:06.000Z", + followers_count: 3, + following_count: 0, + statuses_count: 5, + note: "valid html", + url: user.ap_id, + avatar: "http://localhost:4001/images/avi.png", + avatar_static: "http://localhost:4001/images/avi.png", + header: "http://localhost:4001/images/banner.png", + header_static: "http://localhost:4001/images/banner.png", + emojis: [ + %{ + "static_url" => "/file.png", + "url" => "/file.png", + "shortcode" => "karjalanpiirakka", + "visible_in_picker" => false + } + ], + fields: [], + bot: false, + source: %{ + note: "valid html", + sensitive: false, + pleroma: %{}, + fields: [] + }, + pleroma: %{ + background_image: "https://example.com/images/asuka_hospital.png", + confirmation_pending: false, + tags: [], + is_admin: false, + is_moderator: false, + hide_favorites: true, + hide_followers: false, + hide_follows: false, + relationship: %{}, + skip_thread_containment: false + } + } + + assert expected == AccountView.render("account.json", %{user: user}) + end + + test "Represent the user account for the account owner" do + user = insert(:user) + + notification_settings = %{ + "followers" => true, + "follows" => true, + "non_follows" => true, + "non_followers" => true + } + + privacy = user.info.default_scope + + assert %{ + pleroma: %{notification_settings: ^notification_settings}, + source: %{privacy: ^privacy} + } = AccountView.render("account.json", %{user: user, for: user}) + end + + test "Represent a Service(bot) account" do + user = + insert(:user, %{ + info: %{note_count: 5, follower_count: 3, source_data: %{"type" => "Service"}}, + nickname: "shp@shitposter.club", + inserted_at: ~N[2017-08-15 15:47:06.597036] + }) + + expected = %{ + id: to_string(user.id), + username: "shp", + acct: user.nickname, + display_name: user.name, + locked: false, + created_at: "2017-08-15T15:47:06.000Z", + followers_count: 3, + following_count: 0, + statuses_count: 5, + note: user.bio, + url: user.ap_id, + avatar: "http://localhost:4001/images/avi.png", + avatar_static: "http://localhost:4001/images/avi.png", + header: "http://localhost:4001/images/banner.png", + header_static: "http://localhost:4001/images/banner.png", + emojis: [], + fields: [], + bot: true, + source: %{ + note: user.bio, + sensitive: false, + pleroma: %{}, + fields: [] + }, + pleroma: %{ + background_image: nil, + confirmation_pending: false, + tags: [], + is_admin: false, + is_moderator: false, + hide_favorites: true, + hide_followers: false, + hide_follows: false, + relationship: %{}, + skip_thread_containment: false + } + } + + assert expected == AccountView.render("account.json", %{user: user}) + end + + test "Represent a deactivated user for an admin" do + admin = insert(:user, %{info: %{is_admin: true}}) + deactivated_user = insert(:user, %{info: %{deactivated: true}}) + represented = AccountView.render("account.json", %{user: deactivated_user, for: admin}) + assert represented[:pleroma][:deactivated] == true + end + + test "Represent a smaller mention" do + user = insert(:user) + + expected = %{ + id: to_string(user.id), + acct: user.nickname, + username: user.nickname, + url: user.ap_id + } + + assert expected == AccountView.render("mention.json", %{user: user}) + end + + describe "relationship" do + test "represent a relationship for the following and followed user" do + user = insert(:user) + other_user = insert(:user) + + {:ok, user} = User.follow(user, other_user) + {:ok, other_user} = User.follow(other_user, user) + {:ok, other_user} = User.subscribe(user, other_user) + {:ok, user} = User.mute(user, other_user, true) + {:ok, user} = CommonAPI.hide_reblogs(user, other_user) + + expected = %{ + id: to_string(other_user.id), + following: true, + followed_by: true, + blocking: false, + blocked_by: false, + muting: true, + muting_notifications: true, + subscribing: true, + requested: false, + domain_blocking: false, + showing_reblogs: false, + endorsed: false + } + + assert expected == + AccountView.render("relationship.json", %{user: user, target: other_user}) + end + + test "represent a relationship for the blocking and blocked user" do + user = insert(:user) + other_user = insert(:user) + + {:ok, user} = User.follow(user, other_user) + {:ok, other_user} = User.subscribe(user, other_user) + {:ok, user} = User.block(user, other_user) + {:ok, other_user} = User.block(other_user, user) + + expected = %{ + id: to_string(other_user.id), + following: false, + followed_by: false, + blocking: true, + blocked_by: true, + muting: false, + muting_notifications: false, + subscribing: false, + requested: false, + domain_blocking: false, + showing_reblogs: true, + endorsed: false + } + + assert expected == + AccountView.render("relationship.json", %{user: user, target: other_user}) + end + + test "represent a relationship for the user blocking a domain" do + user = insert(:user) + other_user = insert(:user, ap_id: "https://bad.site/users/other_user") + + {:ok, user} = User.block_domain(user, "bad.site") + + assert %{domain_blocking: true, blocking: false} = + AccountView.render("relationship.json", %{user: user, target: other_user}) + end + + test "represent a relationship for the user with a pending follow request" do + user = insert(:user) + other_user = insert(:user, %{info: %User.Info{locked: true}}) + + {:ok, user, other_user, _} = CommonAPI.follow(user, other_user) + user = User.get_cached_by_id(user.id) + other_user = User.get_cached_by_id(other_user.id) + + expected = %{ + id: to_string(other_user.id), + following: false, + followed_by: false, + blocking: false, + blocked_by: false, + muting: false, + muting_notifications: false, + subscribing: false, + requested: true, + domain_blocking: false, + showing_reblogs: true, + endorsed: false + } + + assert expected == + AccountView.render("relationship.json", %{user: user, target: other_user}) + end + end + + test "represent an embedded relationship" do + user = + insert(:user, %{ + info: %{note_count: 5, follower_count: 0, source_data: %{"type" => "Service"}}, + nickname: "shp@shitposter.club", + inserted_at: ~N[2017-08-15 15:47:06.597036] + }) + + other_user = insert(:user) + {:ok, other_user} = User.follow(other_user, user) + {:ok, other_user} = User.block(other_user, user) + {:ok, _} = User.follow(insert(:user), user) + + expected = %{ + id: to_string(user.id), + username: "shp", + acct: user.nickname, + display_name: user.name, + locked: false, + created_at: "2017-08-15T15:47:06.000Z", + followers_count: 1, + following_count: 0, + statuses_count: 5, + note: user.bio, + url: user.ap_id, + avatar: "http://localhost:4001/images/avi.png", + avatar_static: "http://localhost:4001/images/avi.png", + header: "http://localhost:4001/images/banner.png", + header_static: "http://localhost:4001/images/banner.png", + emojis: [], + fields: [], + bot: true, + source: %{ + note: user.bio, + sensitive: false, + pleroma: %{}, + fields: [] + }, + pleroma: %{ + background_image: nil, + confirmation_pending: false, + tags: [], + is_admin: false, + is_moderator: false, + hide_favorites: true, + hide_followers: false, + hide_follows: false, + relationship: %{ + id: to_string(user.id), + following: false, + followed_by: false, + blocking: true, + blocked_by: false, + subscribing: false, + muting: false, + muting_notifications: false, + requested: false, + domain_blocking: false, + showing_reblogs: true, + endorsed: false + }, + skip_thread_containment: false + } + } + + assert expected == AccountView.render("account.json", %{user: user, for: other_user}) + end + + test "returns the settings store if the requesting user is the represented user and it's requested specifically" do + user = insert(:user, %{info: %User.Info{pleroma_settings_store: %{fe: "test"}}}) + + result = + AccountView.render("account.json", %{user: user, for: user, with_pleroma_settings: true}) + + assert result.pleroma.settings_store == %{:fe => "test"} + + result = AccountView.render("account.json", %{user: user, with_pleroma_settings: true}) + assert result.pleroma[:settings_store] == nil + + result = AccountView.render("account.json", %{user: user, for: user}) + assert result.pleroma[:settings_store] == nil + end + + test "sanitizes display names" do + user = insert(:user, name: " username ") + result = AccountView.render("account.json", %{user: user}) + refute result.display_name == " username " + end + + describe "hiding follows/following" do + test "shows when follows/following are hidden and sets follower/following count to 0" do + user = insert(:user, info: %{hide_followers: true, hide_follows: true}) + other_user = insert(:user) + {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user) + {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) + + assert %{ + followers_count: 0, + following_count: 0, + pleroma: %{hide_follows: true, hide_followers: true} + } = AccountView.render("account.json", %{user: user}) + end + + test "shows actual follower/following count to the account owner" do + user = insert(:user, info: %{hide_followers: true, hide_follows: true}) + other_user = insert(:user) + {:ok, user, other_user, _activity} = CommonAPI.follow(user, other_user) + {:ok, _other_user, user, _activity} = CommonAPI.follow(other_user, user) + + assert %{ + followers_count: 1, + following_count: 1 + } = AccountView.render("account.json", %{user: user, for: user}) + end + end +end diff --git a/test/web/mastodon_api/views/conversation_view_test.exs b/test/web/mastodon_api/views/conversation_view_test.exs new file mode 100644 index 000000000..a2a880705 --- /dev/null +++ b/test/web/mastodon_api/views/conversation_view_test.exs @@ -0,0 +1,34 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.ConversationViewTest do + use Pleroma.DataCase + + alias Pleroma.Conversation.Participation + alias Pleroma.Web.CommonAPI + alias Pleroma.Web.MastodonAPI.ConversationView + + import Pleroma.Factory + + test "represents a Mastodon Conversation entity" do + user = insert(:user) + other_user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{"status" => "hey @#{other_user.nickname}", "visibility" => "direct"}) + + [participation] = Participation.for_user_with_last_activity_id(user) + + assert participation + + conversation = + ConversationView.render("participation.json", %{participation: participation, for: user}) + + assert conversation.id == participation.id |> to_string() + assert conversation.last_status.id == activity.id + + assert [account] = conversation.accounts + assert account.id == other_user.id + end +end diff --git a/test/web/mastodon_api/views/notification_view_test.exs b/test/web/mastodon_api/views/notification_view_test.exs new file mode 100644 index 000000000..977ea1e87 --- /dev/null +++ b/test/web/mastodon_api/views/notification_view_test.exs @@ -0,0 +1,104 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.NotificationViewTest do + use Pleroma.DataCase + + alias Pleroma.Activity + alias Pleroma.Notification + alias Pleroma.Repo + alias Pleroma.User + alias Pleroma.Web.CommonAPI + alias Pleroma.Web.CommonAPI.Utils + alias Pleroma.Web.MastodonAPI.AccountView + alias Pleroma.Web.MastodonAPI.NotificationView + alias Pleroma.Web.MastodonAPI.StatusView + import Pleroma.Factory + + test "Mention notification" do + user = insert(:user) + mentioned_user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "hey @#{mentioned_user.nickname}"}) + {:ok, [notification]} = Notification.create_notifications(activity) + user = User.get_cached_by_id(user.id) + + expected = %{ + id: to_string(notification.id), + pleroma: %{is_seen: false}, + type: "mention", + account: AccountView.render("account.json", %{user: user, for: mentioned_user}), + status: StatusView.render("status.json", %{activity: activity, for: mentioned_user}), + created_at: Utils.to_masto_date(notification.inserted_at) + } + + result = + NotificationView.render("index.json", %{notifications: [notification], for: mentioned_user}) + + assert [expected] == result + end + + test "Favourite notification" do + user = insert(:user) + another_user = insert(:user) + {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) + {:ok, favorite_activity, _object} = CommonAPI.favorite(create_activity.id, another_user) + {:ok, [notification]} = Notification.create_notifications(favorite_activity) + create_activity = Activity.get_by_id(create_activity.id) + + expected = %{ + id: to_string(notification.id), + pleroma: %{is_seen: false}, + type: "favourite", + account: AccountView.render("account.json", %{user: another_user, for: user}), + status: StatusView.render("status.json", %{activity: create_activity, for: user}), + created_at: Utils.to_masto_date(notification.inserted_at) + } + + result = NotificationView.render("index.json", %{notifications: [notification], for: user}) + + assert [expected] == result + end + + test "Reblog notification" do + user = insert(:user) + another_user = insert(:user) + {:ok, create_activity} = CommonAPI.post(user, %{"status" => "hey"}) + {:ok, reblog_activity, _object} = CommonAPI.repeat(create_activity.id, another_user) + {:ok, [notification]} = Notification.create_notifications(reblog_activity) + reblog_activity = Activity.get_by_id(create_activity.id) + + expected = %{ + id: to_string(notification.id), + pleroma: %{is_seen: false}, + type: "reblog", + account: AccountView.render("account.json", %{user: another_user, for: user}), + status: StatusView.render("status.json", %{activity: reblog_activity, for: user}), + created_at: Utils.to_masto_date(notification.inserted_at) + } + + result = NotificationView.render("index.json", %{notifications: [notification], for: user}) + + assert [expected] == result + end + + test "Follow notification" do + follower = insert(:user) + followed = insert(:user) + {:ok, follower, followed, _activity} = CommonAPI.follow(follower, followed) + notification = Notification |> Repo.one() |> Repo.preload(:activity) + + expected = %{ + id: to_string(notification.id), + pleroma: %{is_seen: false}, + type: "follow", + account: AccountView.render("account.json", %{user: follower, for: followed}), + created_at: Utils.to_masto_date(notification.inserted_at) + } + + result = + NotificationView.render("index.json", %{notifications: [notification], for: followed}) + + assert [expected] == result + end +end diff --git a/test/web/mastodon_api/views/push_subscription_view_test.exs b/test/web/mastodon_api/views/push_subscription_view_test.exs new file mode 100644 index 000000000..dc935fc82 --- /dev/null +++ b/test/web/mastodon_api/views/push_subscription_view_test.exs @@ -0,0 +1,23 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.PushSubscriptionViewTest do + use Pleroma.DataCase + import Pleroma.Factory + alias Pleroma.Web.MastodonAPI.PushSubscriptionView, as: View + alias Pleroma.Web.Push + + test "Represent a subscription" do + subscription = insert(:push_subscription, data: %{"alerts" => %{"mention" => true}}) + + expected = %{ + alerts: %{"mention" => true}, + endpoint: subscription.endpoint, + id: to_string(subscription.id), + server_key: Keyword.get(Push.vapid_config(), :public_key) + } + + assert expected == View.render("push_subscription.json", %{subscription: subscription}) + end +end diff --git a/test/web/mastodon_api/views/scheduled_activity_view_test.exs b/test/web/mastodon_api/views/scheduled_activity_view_test.exs new file mode 100644 index 000000000..ecbb855d4 --- /dev/null +++ b/test/web/mastodon_api/views/scheduled_activity_view_test.exs @@ -0,0 +1,68 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.ScheduledActivityViewTest do + use Pleroma.DataCase + alias Pleroma.ScheduledActivity + alias Pleroma.Web.ActivityPub.ActivityPub + alias Pleroma.Web.CommonAPI + alias Pleroma.Web.CommonAPI.Utils + alias Pleroma.Web.MastodonAPI.ScheduledActivityView + alias Pleroma.Web.MastodonAPI.StatusView + import Pleroma.Factory + + test "A scheduled activity with a media attachment" do + user = insert(:user) + {:ok, activity} = CommonAPI.post(user, %{"status" => "hi"}) + + scheduled_at = + NaiveDateTime.utc_now() + |> NaiveDateTime.add(:timer.minutes(10), :millisecond) + |> NaiveDateTime.to_iso8601() + + file = %Plug.Upload{ + content_type: "image/jpg", + path: Path.absname("test/fixtures/image.jpg"), + filename: "an_image.jpg" + } + + {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) + + attrs = %{ + params: %{ + "media_ids" => [upload.id], + "status" => "hi", + "sensitive" => true, + "spoiler_text" => "spoiler", + "visibility" => "unlisted", + "in_reply_to_id" => to_string(activity.id) + }, + scheduled_at: scheduled_at + } + + {:ok, scheduled_activity} = ScheduledActivity.create(user, attrs) + result = ScheduledActivityView.render("show.json", %{scheduled_activity: scheduled_activity}) + + expected = %{ + id: to_string(scheduled_activity.id), + media_attachments: + %{"media_ids" => [upload.id]} + |> Utils.attachments_from_ids() + |> Enum.map(&StatusView.render("attachment.json", %{attachment: &1})), + params: %{ + in_reply_to_id: to_string(activity.id), + media_ids: [upload.id], + poll: nil, + scheduled_at: nil, + sensitive: true, + spoiler_text: "spoiler", + text: "hi", + visibility: "unlisted" + }, + scheduled_at: Utils.to_masto_date(scheduled_activity.scheduled_at) + } + + assert expected == result + end +end diff --git a/test/web/mastodon_api/views/status_view_test.exs b/test/web/mastodon_api/views/status_view_test.exs new file mode 100644 index 000000000..1b6beb6d2 --- /dev/null +++ b/test/web/mastodon_api/views/status_view_test.exs @@ -0,0 +1,584 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2018 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.MastodonAPI.StatusViewTest do + use Pleroma.DataCase + + alias Pleroma.Activity + alias Pleroma.Bookmark + alias Pleroma.Object + alias Pleroma.Repo + alias Pleroma.User + alias Pleroma.Web.CommonAPI + alias Pleroma.Web.CommonAPI.Utils + alias Pleroma.Web.MastodonAPI.AccountView + alias Pleroma.Web.MastodonAPI.StatusView + alias Pleroma.Web.OStatus + import Pleroma.Factory + import Tesla.Mock + + setup do + mock(fn env -> apply(HttpRequestMock, :request, [env]) end) + :ok + end + + test "returns the direct conversation id when given the `with_conversation_id` option" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + status = + StatusView.render("status.json", + activity: activity, + with_direct_conversation_id: true, + for: user + ) + + assert status[:pleroma][:direct_conversation_id] + end + + test "returns a temporary ap_id based user for activities missing db users" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + Repo.delete(user) + Cachex.clear(:user_cache) + + %{account: ms_user} = StatusView.render("status.json", activity: activity) + + assert ms_user.acct == "erroruser@example.com" + end + + test "tries to get a user by nickname if fetching by ap_id doesn't work" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"}) + + {:ok, user} = + user + |> Ecto.Changeset.change(%{ap_id: "#{user.ap_id}/extension/#{user.nickname}"}) + |> Repo.update() + + Cachex.clear(:user_cache) + + result = StatusView.render("status.json", activity: activity) + + assert result[:account][:id] == to_string(user.id) + end + + test "a note with null content" do + note = insert(:note_activity) + note_object = Object.normalize(note) + + data = + note_object.data + |> Map.put("content", nil) + + Object.change(note_object, %{data: data}) + |> Object.update_and_set_cache() + + User.get_cached_by_ap_id(note.data["actor"]) + + status = StatusView.render("status.json", %{activity: note}) + + assert status.content == "" + end + + test "a note activity" do + note = insert(:note_activity) + object_data = Object.normalize(note).data + user = User.get_cached_by_ap_id(note.data["actor"]) + + convo_id = Utils.context_to_conversation_id(object_data["context"]) + + status = StatusView.render("status.json", %{activity: note}) + + created_at = + (object_data["published"] || "") + |> String.replace(~r/\.\d+Z/, ".000Z") + + expected = %{ + id: to_string(note.id), + uri: object_data["id"], + url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note), + account: AccountView.render("account.json", %{user: user}), + in_reply_to_id: nil, + in_reply_to_account_id: nil, + card: nil, + reblog: nil, + content: HtmlSanitizeEx.basic_html(object_data["content"]), + created_at: created_at, + reblogs_count: 0, + replies_count: 0, + favourites_count: 0, + reblogged: false, + bookmarked: false, + favourited: false, + muted: false, + pinned: false, + sensitive: false, + poll: nil, + spoiler_text: HtmlSanitizeEx.basic_html(object_data["summary"]), + visibility: "public", + media_attachments: [], + mentions: [], + tags: [ + %{ + name: "#{object_data["tag"]}", + url: "/tag/#{object_data["tag"]}" + } + ], + application: %{ + name: "Web", + website: nil + }, + language: nil, + emojis: [ + %{ + shortcode: "2hu", + url: "corndog.png", + static_url: "corndog.png", + visible_in_picker: false + } + ], + pleroma: %{ + local: true, + conversation_id: convo_id, + in_reply_to_account_acct: nil, + content: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["content"])}, + spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["summary"])}, + expires_at: nil, + direct_conversation_id: nil + } + } + + assert status == expected + end + + test "tells if the message is muted for some reason" do + user = insert(:user) + other_user = insert(:user) + + {:ok, user} = User.mute(user, other_user) + + {:ok, activity} = CommonAPI.post(other_user, %{"status" => "test"}) + status = StatusView.render("status.json", %{activity: activity}) + + assert status.muted == false + + status = StatusView.render("status.json", %{activity: activity, for: user}) + + assert status.muted == true + end + + test "tells if the status is bookmarked" do + user = insert(:user) + + {:ok, activity} = CommonAPI.post(user, %{"status" => "Cute girls doing cute things"}) + status = StatusView.render("status.json", %{activity: activity}) + + assert status.bookmarked == false + + status = StatusView.render("status.json", %{activity: activity, for: user}) + + assert status.bookmarked == false + + {:ok, _bookmark} = Bookmark.create(user.id, activity.id) + + activity = Activity.get_by_id_with_object(activity.id) + + status = StatusView.render("status.json", %{activity: activity, for: user}) + + assert status.bookmarked == true + end + + test "a reply" do + note = insert(:note_activity) + user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{"status" => "he", "in_reply_to_status_id" => note.id}) + + status = StatusView.render("status.json", %{activity: activity}) + + assert status.in_reply_to_id == to_string(note.id) + + [status] = StatusView.render("index.json", %{activities: [activity], as: :activity}) + + assert status.in_reply_to_id == to_string(note.id) + end + + test "contains mentions" do + incoming = File.read!("test/fixtures/incoming_reply_mastodon.xml") + # a user with this ap id might be in the cache. + recipient = "https://pleroma.soykaf.com/users/lain" + user = insert(:user, %{ap_id: recipient}) + + {:ok, [activity]} = OStatus.handle_incoming(incoming) + + status = StatusView.render("status.json", %{activity: activity}) + + assert status.mentions == + Enum.map([user], fn u -> AccountView.render("mention.json", %{user: u}) end) + end + + test "create mentions from the 'to' field" do + %User{ap_id: recipient_ap_id} = insert(:user) + cc = insert_pair(:user) |> Enum.map(& &1.ap_id) + + object = + insert(:note, %{ + data: %{ + "to" => [recipient_ap_id], + "cc" => cc + } + }) + + activity = + insert(:note_activity, %{ + note: object, + recipients: [recipient_ap_id | cc] + }) + + assert length(activity.recipients) == 3 + + %{mentions: [mention] = mentions} = StatusView.render("status.json", %{activity: activity}) + + assert length(mentions) == 1 + assert mention.url == recipient_ap_id + end + + test "create mentions from the 'tag' field" do + recipient = insert(:user) + cc = insert_pair(:user) |> Enum.map(& &1.ap_id) + + object = + insert(:note, %{ + data: %{ + "cc" => cc, + "tag" => [ + %{ + "href" => recipient.ap_id, + "name" => recipient.nickname, + "type" => "Mention" + }, + %{ + "href" => "https://example.com/search?tag=test", + "name" => "#test", + "type" => "Hashtag" + } + ] + } + }) + + activity = + insert(:note_activity, %{ + note: object, + recipients: [recipient.ap_id | cc] + }) + + assert length(activity.recipients) == 3 + + %{mentions: [mention] = mentions} = StatusView.render("status.json", %{activity: activity}) + + assert length(mentions) == 1 + assert mention.url == recipient.ap_id + end + + test "attachments" do + object = %{ + "type" => "Image", + "url" => [ + %{ + "mediaType" => "image/png", + "href" => "someurl" + } + ], + "uuid" => 6 + } + + expected = %{ + id: "1638338801", + type: "image", + url: "someurl", + remote_url: "someurl", + preview_url: "someurl", + text_url: "someurl", + description: nil, + pleroma: %{mime_type: "image/png"} + } + + assert expected == StatusView.render("attachment.json", %{attachment: object}) + + # If theres a "id", use that instead of the generated one + object = Map.put(object, "id", 2) + assert %{id: "2"} = StatusView.render("attachment.json", %{attachment: object}) + end + + test "put the url advertised in the Activity in to the url attribute" do + id = "https://wedistribute.org/wp-json/pterotype/v1/object/85810" + [activity] = Activity.search(nil, id) + + status = StatusView.render("status.json", %{activity: activity}) + + assert status.uri == id + assert status.url == "https://wedistribute.org/2019/07/mastodon-drops-ostatus/" + end + + test "a reblog" do + user = insert(:user) + activity = insert(:note_activity) + + {:ok, reblog, _} = CommonAPI.repeat(activity.id, user) + + represented = StatusView.render("status.json", %{for: user, activity: reblog}) + + assert represented[:id] == to_string(reblog.id) + assert represented[:reblog][:id] == to_string(activity.id) + assert represented[:emojis] == [] + end + + test "a peertube video" do + user = insert(:user) + + {:ok, object} = + Pleroma.Object.Fetcher.fetch_object_from_id( + "https://peertube.moe/videos/watch/df5f464b-be8d-46fb-ad81-2d4c2d1630e3" + ) + + %Activity{} = activity = Activity.get_create_by_object_ap_id(object.data["id"]) + + represented = StatusView.render("status.json", %{for: user, activity: activity}) + + assert represented[:id] == to_string(activity.id) + assert length(represented[:media_attachments]) == 1 + end + + describe "build_tags/1" do + test "it returns a a dictionary tags" do + object_tags = [ + "fediverse", + "mastodon", + "nextcloud", + %{ + "href" => "https://kawen.space/users/lain", + "name" => "@lain@kawen.space", + "type" => "Mention" + } + ] + + assert StatusView.build_tags(object_tags) == [ + %{name: "fediverse", url: "/tag/fediverse"}, + %{name: "mastodon", url: "/tag/mastodon"}, + %{name: "nextcloud", url: "/tag/nextcloud"} + ] + end + end + + describe "rich media cards" do + test "a rich media card without a site name renders correctly" do + page_url = "http://example.com" + + card = %{ + url: page_url, + image: page_url <> "/example.jpg", + title: "Example website" + } + + %{provider_name: "example.com"} = + StatusView.render("card.json", %{page_url: page_url, rich_media: card}) + end + + test "a rich media card without a site name or image renders correctly" do + page_url = "http://example.com" + + card = %{ + url: page_url, + title: "Example website" + } + + %{provider_name: "example.com"} = + StatusView.render("card.json", %{page_url: page_url, rich_media: card}) + end + + test "a rich media card without an image renders correctly" do + page_url = "http://example.com" + + card = %{ + url: page_url, + site_name: "Example site name", + title: "Example website" + } + + %{provider_name: "Example site name"} = + StatusView.render("card.json", %{page_url: page_url, rich_media: card}) + end + + test "a rich media card with all relevant data renders correctly" do + page_url = "http://example.com" + + card = %{ + url: page_url, + site_name: "Example site name", + title: "Example website", + image: page_url <> "/example.jpg", + description: "Example description" + } + + %{provider_name: "Example site name"} = + 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: to_string(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 + + test "embeds a relationship in the account" do + user = insert(:user) + other_user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{ + "status" => "drink more water" + }) + + result = StatusView.render("status.json", %{activity: activity, for: other_user}) + + assert result[:account][:pleroma][:relationship] == + AccountView.render("relationship.json", %{user: other_user, target: user}) + end + + test "embeds a relationship in the account in reposts" do + user = insert(:user) + other_user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{ + "status" => "˙˙ɐʎns" + }) + + {:ok, activity, _object} = CommonAPI.repeat(activity.id, other_user) + + result = StatusView.render("status.json", %{activity: activity, for: user}) + + assert result[:account][:pleroma][:relationship] == + AccountView.render("relationship.json", %{user: user, target: other_user}) + + assert result[:reblog][:account][:pleroma][:relationship] == + AccountView.render("relationship.json", %{user: user, target: user}) + end + + test "visibility/list" do + user = insert(:user) + + {:ok, list} = Pleroma.List.create("foo", user) + + {:ok, activity} = + CommonAPI.post(user, %{"status" => "foobar", "visibility" => "list:#{list.id}"}) + + status = StatusView.render("status.json", activity: activity) + + assert status.visibility == "list" + end +end -- cgit v1.2.3 From c338224c93c3e8111cecdd3ef652016a574b55f4 Mon Sep 17 00:00:00 2001 From: Maxim Filippov Date: Mon, 26 Aug 2019 17:24:22 +0300 Subject: Fix sporadic test --- test/web/admin_api/admin_api_controller_test.exs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'test') diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs index 1afdb6a50..4e2c27431 100644 --- a/test/web/admin_api/admin_api_controller_test.exs +++ b/test/web/admin_api/admin_api_controller_test.exs @@ -64,8 +64,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do log_entry = Repo.one(ModerationLog) - assert ModerationLog.get_log_entry_message(log_entry) == - "@#{admin.nickname} created users: @lain2, @lain" + assert ["lain", "lain2"] -- Enum.map(log_entry.data["subjects"], & &1["nickname"]) == [] end test "Cannot create user with exisiting email" do -- cgit v1.2.3 From 3da65292b389c1f1edeff03fd5097579721fb681 Mon Sep 17 00:00:00 2001 From: lain Date: Mon, 26 Aug 2019 14:34:52 -0500 Subject: Transmogrifier: Fix follow handling when the actor is an object. --- test/fixtures/osada-follow-activity.json | 56 ++++++++++++++++++++++ test/fixtures/tesla_mock/osada-user-indio.json | 1 + test/support/http_request_mock.ex | 5 ++ .../transmogrifier/follow_handling_test.exs | 19 ++++++++ 4 files changed, 81 insertions(+) create mode 100644 test/fixtures/osada-follow-activity.json create mode 100644 test/fixtures/tesla_mock/osada-user-indio.json (limited to 'test') diff --git a/test/fixtures/osada-follow-activity.json b/test/fixtures/osada-follow-activity.json new file mode 100644 index 000000000..b991eea36 --- /dev/null +++ b/test/fixtures/osada-follow-activity.json @@ -0,0 +1,56 @@ +{ + "@context":[ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + "https://apfed.club/apschema/v1.4" + ], + "id":"https://apfed.club/follow/9", + "type":"Follow", + "actor":{ + "type":"Person", + "id":"https://apfed.club/channel/indio", + "preferredUsername":"indio", + "name":"Indio", + "updated":"2019-08-20T23:52:34Z", + "icon":{ + "type":"Image", + "mediaType":"image/jpeg", + "updated":"2019-08-20T23:53:37Z", + "url":"https://apfed.club/photo/profile/l/2", + "height":300, + "width":300 + }, + "url":"https://apfed.club/channel/indio", + "inbox":"https://apfed.club/inbox/indio", + "outbox":"https://apfed.club/outbox/indio", + "followers":"https://apfed.club/followers/indio", + "following":"https://apfed.club/following/indio", + "endpoints":{ + "sharedInbox":"https://apfed.club/inbox" + }, + "publicKey":{ + "id":"https://apfed.club/channel/indio", + "owner":"https://apfed.club/channel/indio", + "publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA77TIR1VuSYFnmDRFGHHb\n4vaGdx9ranzRX4bfOKAqa++Ch5L4EqJpPy08RuM+NrYCYiYl4QQFDSSDXAEgb5g9\nC1TgWTfI7q/E0UBX2Vr0mU6X4i1ztv0tuQvegRjcSJ7l1AvoBs8Ip4MEJ3OPEQhB\ngJqAACB3Gnps4zi2I0yavkxUfGVKr6zKT3BxWh5hTpKC7Do+ChIrVZC2EwxND9K6 +\nsAnQHThcb5EQuvuzUQZKeS7IEOsd0JpZDmJjbfMGrAWE81pLIfEeeA2joCJiBBTO\nglDsW+juvZ+lWqJpMr2hMWpvfrFjJeUawNJCIzsLdVIZR+aKj5yy6yqoS8hkN9Ha\n1MljZpsXl+EmwcwAIqim1YeLwERCEAQ/JWbSt8pQTQbzZ6ibwQ4mchCxacrRbIVR +\nnL59fWMBassJcbY0VwrTugm2SBsYbDjESd55UZV03Rwr8qseGTyi+hH8O7w2SIaY\nzjN6AdZiPmsh00YflzlCk8MSLOHMol1vqIUzXxU8CdXn9+KsuQdZGrTz0YKN/db4\naVwUGJatz2Tsvf7R1tJBjJfeQWOWbbn3pycLVH86LjZ83qngp9ZVnAveUnUqz0yS +\nhe+buZ6UMsfGzbIYon2bKNlz6gYTH0YPcr+cLe+29drtt0GZiXha1agbpo4RB8zE +\naNL2fucF5YT0yNpbd/5WoV0CAwEAAQ==\n-----END PUBLIC KEY-----\n" + } + }, + "object":"https://pleroma.site/users/kaniini", + "to":[ + "https://pleroma.site/users/kaniini" + ], + "signature":{ + "@context":[ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1" + ], + "type":"RsaSignature2017", + "nonce":"52c035e0a9e81dce8b486159204e97c22637e91f75cdfad5378de91de68e9117", + "creator":"https://apfed.club/channel/indio/public_key_pem", + "created":"2019-08-22T03:38:02Z", + "signatureValue":"oVliRCIqNIh6yUp851dYrF0y21aHp3Rz6VkIpW1pFMWfXuzExyWSfcELpyLseeRmsw5bUu9zJkH44B4G2LiJQKA9UoEQDjrDMZBmbeUpiQqq3DVUzkrBOI8bHZ7xyJ/CjSZcNHHh0MHhSKxswyxWMGi4zIqzkAZG3vRRgoPVHdjPm00sR3B8jBLw1cjoffv+KKeM/zEUpe13gqX9qHAWHHqZepxgSWmq+EKOkRvHUPBXiEJZfXzc5uW+vZ09F3WBYmaRoy8Y0e1P29fnRLqSy7EEINdrHaGclRqoUZyiawpkgy3lWWlynesV/HiLBR7EXT79eKstxf4wfTDaPKBCfTCsOWuMWHr7Genu37ew2/t7eiBGqCwwW12ylhml/OLHgNK3LOhmRABhtfpaFZSxfDVnlXfaLpY1xekVOj2oC0FpBtnoxVKLpIcyLw6dkfSil5ANd+hl59W/bpPA8KT90ii1fSNCo3+FcwQVx0YsPznJNA60XfFuVsme7zNcOst6393e1WriZxBanFpfB63zVQc9u1fjyfktx/yiUNxIlre+sz9OCc0AACn94iRhBYh4bbzdleUOTnM7lnD4Dj2FP+xeDIP8CA8wXUeq5+9kopSp2kAmlUEyFUdg4no7naIeu1SZnopfUg56PsVCp9JHiUK1SYAyWbdC+FbUECu5CvI=" + } +} diff --git a/test/fixtures/tesla_mock/osada-user-indio.json b/test/fixtures/tesla_mock/osada-user-indio.json new file mode 100644 index 000000000..c1d52c92a --- /dev/null +++ b/test/fixtures/tesla_mock/osada-user-indio.json @@ -0,0 +1 @@ +{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"Person","id":"https://apfed.club/channel/indio","preferredUsername":"indio","name":"Indio","updated":"2019-08-20T23:52:34Z","icon":{"type":"Image","mediaType":"image/jpeg","updated":"2019-08-20T23:53:37Z","url":"https://apfed.club/photo/profile/l/2","height":300,"width":300},"url":"https://apfed.club/channel/indio","inbox":"https://apfed.club/inbox/indio","outbox":"https://apfed.club/outbox/indio","followers":"https://apfed.club/followers/indio","following":"https://apfed.club/following/indio","endpoints":{"sharedInbox":"https://apfed.club/inbox"},"publicKey":{"id":"https://apfed.club/channel/indio","owner":"https://apfed.club/channel/indio","publicKeyPem":"-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA77TIR1VuSYFnmDRFGHHb\n4vaGdx9ranzRX4bfOKAqa++Ch5L4EqJpPy08RuM+NrYCYiYl4QQFDSSDXAEgb5g9\nC1TgWTfI7q/E0UBX2Vr0mU6X4i1ztv0tuQvegRjcSJ7l1AvoBs8Ip4MEJ3OPEQhB\ngJqAACB3Gnps4zi2I0yavkxUfGVKr6zKT3BxWh5hTpKC7Do+ChIrVZC2EwxND9K6\nsAnQHThcb5EQuvuzUQZKeS7IEOsd0JpZDmJjbfMGrAWE81pLIfEeeA2joCJiBBTO\nglDsW+juvZ+lWqJpMr2hMWpvfrFjJeUawNJCIzsLdVIZR+aKj5yy6yqoS8hkN9Ha\n1MljZpsXl+EmwcwAIqim1YeLwERCEAQ/JWbSt8pQTQbzZ6ibwQ4mchCxacrRbIVR\nnL59fWMBassJcbY0VwrTugm2SBsYbDjESd55UZV03Rwr8qseGTyi+hH8O7w2SIaY\nzjN6AdZiPmsh00YflzlCk8MSLOHMol1vqIUzXxU8CdXn9+KsuQdZGrTz0YKN/db4\naVwUGJatz2Tsvf7R1tJBjJfeQWOWbbn3pycLVH86LjZ83qngp9ZVnAveUnUqz0yS\nhe+buZ6UMsfGzbIYon2bKNlz6gYTH0YPcr+cLe+29drtt0GZiXha1agbpo4RB8zE\naNL2fucF5YT0yNpbd/5WoV0CAwEAAQ==\n-----END PUBLIC KEY-----\n"},"signature":{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],"type":"RsaSignature2017","nonce":"c672a408d2e88b322b36a61bf0c25f586be9245d30293c55b8d653dcc867aaf7","creator":"https://apfed.club/channel/indio/public_key_pem","created":"2019-08-26T07:24:03Z","signatureValue":"MyAv5gnedu6L/DYFaE1TUYvp4LjI9ZUU0axwGYOhgD7qsjivMgwbOrjX/iH32xlcfF8nWOMh/ogu3+Qwr5sqLHkS2AimWmw1+Ubf2KccE58b8vI8zWfyu8QJnMuE92jtBPv8UTQUHw8ZebbExk3L99oXaeyVihKiMBmd63NpVTpGXZTg6m+H+KfWchVajPoyNKZtKMd3nH99x5j54Cqkz0BN5CSTwCSG0wP95G0VtZHtmhX+tsAPM3oAj0d+gtCZSCd8Nu8fvFAwCyTg1oKSfRqKb27EKHlskqK9X57x0jURH77CTAIQSejgGcKJ5GGLtvofubJkafadjagqrtqz6Mz6BZ642ssJ2KGkRAn79Q4F08goI6cfU5lLk2Tooe5A55XERnmE3SkYGyTvLpacZplxJdU0sa+deX9D7+alSGFJZSziaxpCxzrO6lEApe4b9kHXAzn9VaZt9trijkHq/kkq0i3NRcP7n8JG9q+Vv8jY9ddY6HcH89RNCBIA6MKLtAqc+vSc5G24qeZlw2MzlQWBp0KGuVG8DQR00AL6cXLBzF1WY8JZeEg6zqm+DMznbuNzgiS34BP+AehBSHlQ4MZebwDnK3ZPPqGSwioIWMxIFfZDaVDX9Pp1pXAARQMw0c/y4sDcf9FMzsr8jteEa7ZQcoqq5kXQTSCP56TEHnI="}} \ No newline at end of file diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index 55b141dd8..05eebbe9b 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -775,6 +775,11 @@ defmodule HttpRequestMock do {:ok, %Tesla.Env{status: 200, body: File.read!("test/fixtures/lambadalambda.json")}} end + def get("https://apfed.club/channel/indio", _, _, _) do + {:ok, + %Tesla.Env{status: 200, body: File.read!("test/fixtures/tesla_mock/osada-user-indio.json")}} + end + def get("https://social.heldscal.la/user/23211", _, _, Accept: "application/activity+json") do {:ok, Tesla.Mock.json(%{"id" => "https://social.heldscal.la/user/23211"}, status: 200)} end diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs index 857d65564..fe89f7cb0 100644 --- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs +++ b/test/web/activity_pub/transmogrifier/follow_handling_test.exs @@ -19,6 +19,25 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do end describe "handle_incoming" do + test "it works for osada follow request" do + user = insert(:user) + + data = + File.read!("test/fixtures/osada-follow-activity.json") + |> Poison.decode!() + |> Map.put("object", user.ap_id) + + {:ok, %Activity{data: data, local: false} = activity} = Transmogrifier.handle_incoming(data) + + assert data["actor"] == "https://apfed.club/channel/indio" + assert data["type"] == "Follow" + assert data["id"] == "https://apfed.club/follow/9" + + activity = Repo.get(Activity, activity.id) + assert activity.data["state"] == "accept" + assert User.following?(User.get_cached_by_ap_id(data["actor"]), user) + end + test "it works for incoming follow requests" do user = insert(:user) -- cgit v1.2.3 From 00abe099cd85b03b880908eef1e469e656d56365 Mon Sep 17 00:00:00 2001 From: Maksim Pechnikov Date: Tue, 27 Aug 2019 16:21:03 +0300 Subject: added tests for ActivityPub.like\unlike --- test/support/factory.ex | 16 +++-- test/web/activity_pub/activity_pub_test.exs | 44 ++++++++++++ test/web/activity_pub/utils_test.exs | 102 ++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+), 7 deletions(-) (limited to 'test') diff --git a/test/support/factory.ex b/test/support/factory.ex index 62d1de717..719115003 100644 --- a/test/support/factory.ex +++ b/test/support/factory.ex @@ -207,13 +207,15 @@ defmodule Pleroma.Factory do object = Object.normalize(note_activity) user = insert(:user) - data = %{ - "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(), - "actor" => user.ap_id, - "type" => "Like", - "object" => object.data["id"], - "published_at" => DateTime.utc_now() |> DateTime.to_iso8601() - } + data = + %{ + "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(), + "actor" => user.ap_id, + "type" => "Like", + "object" => object.data["id"], + "published_at" => DateTime.utc_now() |> DateTime.to_iso8601() + } + |> Map.merge(attrs[:data_attrs] || %{}) %Pleroma.Activity{ data: data diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs index 1515f4eb6..f72b44aed 100644 --- a/test/web/activity_pub/activity_pub_test.exs +++ b/test/web/activity_pub/activity_pub_test.exs @@ -21,6 +21,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do :ok end + clear_config([:instance, :federating]) + describe "streaming out participations" do test "it streams them out" do user = insert(:user) @@ -676,6 +678,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end describe "like an object" do + test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do + Pleroma.Config.put([:instance, :federating], true) + note_activity = insert(:note_activity) + assert object_activity = Object.normalize(note_activity) + + user = insert(:user) + + {:ok, like_activity, _object} = ActivityPub.like(user, object_activity) + assert called(Pleroma.Web.Federator.publish(like_activity, 5)) + end + + test "returns exist activity if object already liked" do + note_activity = insert(:note_activity) + assert object_activity = Object.normalize(note_activity) + + user = insert(:user) + + {:ok, like_activity, _object} = ActivityPub.like(user, object_activity) + + {:ok, like_activity_exist, _object} = ActivityPub.like(user, object_activity) + assert like_activity == like_activity_exist + end + test "adds a like activity to the db" do note_activity = insert(:note_activity) assert object = Object.normalize(note_activity) @@ -706,6 +731,25 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do end describe "unliking" do + test_with_mock "sends an activity to federation", Pleroma.Web.Federator, [:passthrough], [] do + Pleroma.Config.put([:instance, :federating], true) + + note_activity = insert(:note_activity) + object = Object.normalize(note_activity) + user = insert(:user) + + {:ok, object} = ActivityPub.unlike(user, object) + refute called(Pleroma.Web.Federator.publish()) + + {:ok, _like_activity, object} = ActivityPub.like(user, object) + assert object.data["like_count"] == 1 + + {:ok, unlike_activity, _, object} = ActivityPub.unlike(user, object) + assert object.data["like_count"] == 0 + + assert called(Pleroma.Web.Federator.publish(unlike_activity, 5)) + end + test "unliking a previously liked object" do note_activity = insert(:note_activity) object = Object.normalize(note_activity) diff --git a/test/web/activity_pub/utils_test.exs b/test/web/activity_pub/utils_test.exs index ca5f057a7..eb429b2c4 100644 --- a/test/web/activity_pub/utils_test.exs +++ b/test/web/activity_pub/utils_test.exs @@ -14,6 +14,8 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do import Pleroma.Factory + require Pleroma.Constants + describe "fetch the latest Follow" do test "fetches the latest Follow activity" do %Activity{data: %{"type" => "Follow"}} = activity = insert(:follow_activity) @@ -87,6 +89,32 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do end end + describe "make_unlike_data/3" do + test "returns data for unlike activity" do + user = insert(:user) + like_activity = insert(:like_activity, data_attrs: %{"context" => "test context"}) + + assert Utils.make_unlike_data(user, like_activity, nil) == %{ + "type" => "Undo", + "actor" => user.ap_id, + "object" => like_activity.data, + "to" => [user.follower_address, like_activity.data["actor"]], + "cc" => [Pleroma.Constants.as_public()], + "context" => like_activity.data["context"] + } + + assert Utils.make_unlike_data(user, like_activity, "9mJEZK0tky1w2xD2vY") == %{ + "type" => "Undo", + "actor" => user.ap_id, + "object" => like_activity.data, + "to" => [user.follower_address, like_activity.data["actor"]], + "cc" => [Pleroma.Constants.as_public()], + "context" => like_activity.data["context"], + "id" => "9mJEZK0tky1w2xD2vY" + } + end + end + describe "make_like_data" do setup do user = insert(:user) @@ -299,4 +327,78 @@ defmodule Pleroma.Web.ActivityPub.UtilsTest do assert Repo.get(Activity, follow_activity_two.id).data["state"] == "reject" end end + + describe "update_element_in_object/3" do + test "updates likes" do + user = insert(:user) + activity = insert(:note_activity) + object = Object.normalize(activity) + + assert {:ok, updated_object} = + Utils.update_element_in_object( + "like", + [user.ap_id], + object + ) + + assert updated_object.data["likes"] == [user.ap_id] + assert updated_object.data["like_count"] == 1 + end + end + + describe "add_like_to_object/2" do + test "add actor to likes" do + user = insert(:user) + user2 = insert(:user) + object = insert(:note) + + assert {:ok, updated_object} = + Utils.add_like_to_object( + %Activity{data: %{"actor" => user.ap_id}}, + object + ) + + assert updated_object.data["likes"] == [user.ap_id] + assert updated_object.data["like_count"] == 1 + + assert {:ok, updated_object2} = + Utils.add_like_to_object( + %Activity{data: %{"actor" => user2.ap_id}}, + updated_object + ) + + assert updated_object2.data["likes"] == [user2.ap_id, user.ap_id] + assert updated_object2.data["like_count"] == 2 + end + end + + describe "remove_like_from_object/2" do + test "removes ap_id from likes" do + user = insert(:user) + user2 = insert(:user) + object = insert(:note, data: %{"likes" => [user.ap_id, user2.ap_id], "like_count" => 2}) + + assert {:ok, updated_object} = + Utils.remove_like_from_object( + %Activity{data: %{"actor" => user.ap_id}}, + object + ) + + assert updated_object.data["likes"] == [user2.ap_id] + assert updated_object.data["like_count"] == 1 + end + end + + describe "get_existing_like/2" do + test "fetches existing like" do + note_activity = insert(:note_activity) + assert object = Object.normalize(note_activity) + + user = insert(:user) + refute Utils.get_existing_like(user.ap_id, object) + {:ok, like_activity, _object} = ActivityPub.like(user, object) + + assert ^like_activity = Utils.get_existing_like(user.ap_id, object) + end + end end -- cgit v1.2.3