From: kaniini Date: Wed, 9 Oct 2019 16:33:05 +0000 (+0000) Subject: Merge branch 'unicode-search' into 'develop' X-Git-Url: http://git.squeep.com/?a=commitdiff_plain;h=9fd5176c35d21846fb8368ea7bc0285f9cd74ad4;hp=c1bae0137666505c16482fd22cb3a14bed7a4499;p=akkoma Merge branch 'unicode-search' into 'develop' Search: Add tests for unicode searches. See merge request pleroma/pleroma!1824 --- diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b24db7f4..bd06ec866 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - OAuth: support for hierarchical permissions / [Mastodon 2.4.3 OAuth permissions](https://docs.joinmastodon.org/api/permissions/) - Authentication: Added rate limit for password-authorized actions / login existence checks - Metadata Link: Atom syndication Feed +- Mix task to re-count statuses for all users (`mix pleroma.count_statuses`) ### Changed - **Breaking:** Elixir >=1.8 is now required (was >= 1.7) @@ -27,6 +28,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Admin API: Return link alongside with token on password reset - MRF (Simple Policy): Also use `:accept`/`:reject` on the actors rather than only their activities - OStatus: Extract RSS functionality +- Mastodon API: Add `pleroma.direct_conversation_id` to the status endpoint (`GET /api/v1/statuses/:id`) ### Fixed - Mastodon API: Fix private and direct statuses not being filtered out from the public timeline for an authenticated user (`GET /api/v1/timelines/public`) diff --git a/lib/mix/tasks/pleroma/count_statuses.ex b/lib/mix/tasks/pleroma/count_statuses.ex new file mode 100644 index 000000000..e1e8195dd --- /dev/null +++ b/lib/mix/tasks/pleroma/count_statuses.ex @@ -0,0 +1,22 @@ +defmodule Mix.Tasks.Pleroma.CountStatuses do + @shortdoc "Re-counts statuses for all users" + + use Mix.Task + alias Pleroma.User + import Ecto.Query + + def run([]) do + Mix.Pleroma.start_pleroma() + + stream = + User + |> where(local: true) + |> Pleroma.Repo.stream() + + Pleroma.Repo.transaction(fn -> + Enum.each(stream, &User.update_note_count/1) + end) + + Mix.Pleroma.shell_info("Done") + end +end diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index 0c16e9b0f..e5d016f63 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -167,7 +167,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do def show(%{assigns: %{user: user}} = conn, %{"id" => id}) do with %Activity{} = activity <- Activity.get_by_id_with_object(id), true <- Visibility.visible_for_user?(activity, user) do - try_render(conn, "show.json", activity: activity, for: user) + try_render(conn, "show.json", + activity: activity, + for: user, + with_direct_conversation_id: true + ) end end diff --git a/test/fixtures/tesla_mock/mstdn.jp_host_meta b/test/fixtures/tesla_mock/mstdn.jp_host_meta new file mode 100644 index 000000000..e76ddd47f --- /dev/null +++ b/test/fixtures/tesla_mock/mstdn.jp_host_meta @@ -0,0 +1,4 @@ + + + + diff --git a/test/fixtures/tesla_mock/pekorino@pawoo.net_host_meta.json b/test/fixtures/tesla_mock/pekorino@pawoo.net_host_meta.json new file mode 100644 index 000000000..3757c0dad --- /dev/null +++ b/test/fixtures/tesla_mock/pekorino@pawoo.net_host_meta.json @@ -0,0 +1,12 @@ +{ + "subject":"acct:pekorino@pawoo.net", + "aliases":["https://pawoo.net/@pekorino","https://pawoo.net/users/pekorino"], + "links":[ + {"rel":"http://webfinger.net/rel/profile-page","type":"text/html","href":"https://pawoo.net/@pekorino"}, + {"rel":"http://schemas.google.com/g/2010#updates-from","type":"application/atom+xml","href":"https://pawoo.net/users/pekorino.atom"}, + {"rel":"self","type":"application/activity+json","href":"https://pawoo.net/users/pekorino"}, + {"rel":"salmon","href":"https://pawoo.net/api/salmon/128378"}, + {"rel":"magic-public-key","href":"data:application/magic-public-key,RSA.1x8XXmBqzyb-QRkfUKxKPd7Ac2KbaFhdKy2FkJY64G-ifga-BppzEb62Q5TdkRdVKdHjh5qI7A1Hk3KfnNQcNWqqak-jxII_txC2grbWpp7v-boceD2pnzdVK5l-RR-9wEwxcoCUeRWS1Ak6DStqE5tFQOAK4IIGQB-thSQGlU75KZ-2080fPA3Xc_ycH3_eB4YqawSxXrh6IeScMevN0YHSF84GAcvhXmwLKZRugiF6nYrknbPEe_niIOmN8hhEXLN9_4kDcH83hkVZd5VXssRrxqDhtokx9emvTHkA7sY1AjYeehTPZErlV74GN-kFYLeI6DluXoSI2sX1QcS08w==.AQAB"}, + {"rel":"http://ostatus.org/schema/1.0/subscribe","template":"https://pawoo.net/authorize_follow?acct={uri}"} + ] +} diff --git a/test/fixtures/tesla_mock/sdf.org_host_meta b/test/fixtures/tesla_mock/sdf.org_host_meta new file mode 100644 index 000000000..0ffc4f096 --- /dev/null +++ b/test/fixtures/tesla_mock/sdf.org_host_meta @@ -0,0 +1,4 @@ + + + + diff --git a/test/fixtures/tesla_mock/snowdusk@sdf.org_host_meta.json b/test/fixtures/tesla_mock/snowdusk@sdf.org_host_meta.json new file mode 100644 index 000000000..273fc3804 --- /dev/null +++ b/test/fixtures/tesla_mock/snowdusk@sdf.org_host_meta.json @@ -0,0 +1,12 @@ +{ + "subject":"acct:snowdusk@mastodon.sdf.org", + "aliases":["https://mastodon.sdf.org/@snowdusk","https://mastodon.sdf.org/users/snowdusk"], + "links":[ + {"rel":"http://webfinger.net/rel/profile-page","type":"text/html","href":"https://mastodon.sdf.org/@snowdusk"}, + {"rel":"http://schemas.google.com/g/2010#updates-from","type":"application/atom+xml","href":"https://mastodon.sdf.org/users/snowdusk.atom"}, + {"rel":"self","type":"application/activity+json","href":"https://mastodon.sdf.org/users/snowdusk"}, + {"rel":"salmon","href":"https://mastodon.sdf.org/api/salmon/2"}, + {"rel":"magic-public-key","href":"data:application/magic-public-key,RSA.k4_Hr0WQUHumAD4uwWIz7OybovIKgIuanbXhX5pl7oGyb2TuifBf3nAqEhD6eLSo6-_6160L4BvPPV_l_6rlZEi6_nbeJUgVkayZgcZN3oou3IErSt8L0IbUdWT5s4fWM2zpkndLCkVbeeNQ3DOBccvJw7iA_QNTao8wr3ILvQaKEDnf-H5QBd9Tj3seyo4-7E0e6wCKOH_uBm8pSRgpdMdl2CehiFzaABBkmCeUKH-buU7iNQGi0fsV5VIHn6zffrv6p0EVNkjTDi1vTmmfrp9W0mcKZJ9DtvdehOKSgh3J7Mem-ILbPy6FSL2Oi6Ekj_Wh4M8Ie-YKuxI3N_0Baw==.AQAB"}, + {"rel":"http://ostatus.org/schema/1.0/subscribe","template":"https://mastodon.sdf.org/authorize_interaction?uri={uri}"} + ] +} diff --git a/test/fixtures/tesla_mock/soykaf.com_host_meta b/test/fixtures/tesla_mock/soykaf.com_host_meta new file mode 100644 index 000000000..99d552d32 --- /dev/null +++ b/test/fixtures/tesla_mock/soykaf.com_host_meta @@ -0,0 +1,4 @@ + + + + diff --git a/test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta b/test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta new file mode 100644 index 000000000..481cfec8d --- /dev/null +++ b/test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta @@ -0,0 +1,31 @@ +{ + "links":[ + { + "rel":"lrdd", + "type":"application\/jrd+json", + "template":"https:\/\/social.stopwatchingus-heidelberg.de\/.well-known\/webfinger?resource={uri}" + }, + { + "rel":"lrdd", + "type":"application\/json", + "template":"https:\/\/social.stopwatchingus-heidelberg.de\/.well-known\/webfinger?resource={uri}" + }, + { + "rel":"lrdd", + "type":"application\/xrd+xml", + "template":"https:\/\/social.stopwatchingus-heidelberg.de\/.well-known\/webfinger?resource={uri}" + }, + { + "rel":"http:\/\/apinamespace.org\/oauth\/access_token", + "href":"https:\/\/social.stopwatchingus-heidelberg.de\/api\/oauth\/access_token" + }, + { + "rel":"http:\/\/apinamespace.org\/oauth\/request_token", + "href":"https:\/\/social.stopwatchingus-heidelberg.de\/api\/oauth\/request_token" + }, + { + "rel":"http:\/\/apinamespace.org\/oauth\/authorize", + "href":"https:\/\/social.stopwatchingus-heidelberg.de\/api\/oauth\/authorize" + } + ] +} diff --git a/test/fixtures/tesla_mock/xn--q9jyb4c_host_meta b/test/fixtures/tesla_mock/xn--q9jyb4c_host_meta new file mode 100644 index 000000000..45d260e55 --- /dev/null +++ b/test/fixtures/tesla_mock/xn--q9jyb4c_host_meta @@ -0,0 +1,4 @@ + + + + diff --git a/test/support/http_request_mock.ex b/test/support/http_request_mock.ex index b825a9307..4feb57f3a 100644 --- a/test/support/http_request_mock.ex +++ b/test/support/http_request_mock.ex @@ -344,6 +344,181 @@ defmodule HttpRequestMock do {:error, :nxdomain} end + def get("http://osada.macgirvin.com/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 404, + body: "" + }} + end + + def get("https://osada.macgirvin.com/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 404, + body: "" + }} + end + + def get("http://mastodon.sdf.org/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/sdf.org_host_meta") + }} + end + + def get("https://mastodon.sdf.org/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/sdf.org_host_meta") + }} + end + + def get( + "https://mastodon.sdf.org/.well-known/webfinger?resource=https://mastodon.sdf.org/users/snowdusk", + _, + _, + _ + ) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/snowdusk@sdf.org_host_meta.json") + }} + end + + def get("http://mstdn.jp/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/mstdn.jp_host_meta") + }} + end + + def get("https://mstdn.jp/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/mstdn.jp_host_meta") + }} + end + + def get("https://mstdn.jp/.well-known/webfinger?resource=kpherox@mstdn.jp", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/kpherox@mstdn.jp.xml") + }} + end + + def get("http://mamot.fr/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/mamot.fr_host_meta") + }} + end + + def get("https://mamot.fr/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/mamot.fr_host_meta") + }} + end + + def get( + "https://mamot.fr/.well-known/webfinger?resource=https://mamot.fr/users/Skruyb", + _, + _, + _ + ) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/skruyb@mamot.fr.atom") + }} + end + + def get("http://pawoo.net/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta") + }} + end + + def get("https://pawoo.net/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta") + }} + end + + def get( + "https://pawoo.net/.well-known/webfinger?resource=https://pawoo.net/users/pekorino", + _, + _, + _ + ) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/pekorino@pawoo.net_host_meta.json") + }} + end + + def get("http://zetsubou.xn--q9jyb4c/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/xn--q9jyb4c_host_meta") + }} + end + + def get("https://zetsubou.xn--q9jyb4c/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/xn--q9jyb4c_host_meta") + }} + end + + def get("http://pleroma.soykaf.com/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/soykaf.com_host_meta") + }} + end + + def get("https://pleroma.soykaf.com/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/soykaf.com_host_meta") + }} + end + + def get("http://social.stopwatchingus-heidelberg.de/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta") + }} + end + + def get("https://social.stopwatchingus-heidelberg.de/.well-known/host-meta", _, _, _) do + {:ok, + %Tesla.Env{ + status: 200, + body: File.read!("test/fixtures/tesla_mock/stopwatchingus-heidelberg.de_host_meta") + }} + end + def get( "http://mastodon.example.org/@admin/99541947525187367", _, diff --git a/test/tasks/count_statuses_test.exs b/test/tasks/count_statuses_test.exs new file mode 100644 index 000000000..6035da3c3 --- /dev/null +++ b/test/tasks/count_statuses_test.exs @@ -0,0 +1,39 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2019 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Mix.Tasks.Pleroma.CountStatusesTest do + use Pleroma.DataCase + + alias Pleroma.User + alias Pleroma.Web.CommonAPI + + import ExUnit.CaptureIO, only: [capture_io: 1] + import Pleroma.Factory + + test "counts statuses" do + user = insert(:user) + {:ok, _} = CommonAPI.post(user, %{"status" => "test"}) + {:ok, _} = CommonAPI.post(user, %{"status" => "test2"}) + + user2 = insert(:user) + {:ok, _} = CommonAPI.post(user2, %{"status" => "test3"}) + + user = refresh_record(user) + user2 = refresh_record(user2) + + assert %{info: %{note_count: 2}} = user + assert %{info: %{note_count: 1}} = user2 + + {:ok, user} = User.update_info(user, &User.Info.set_note_count(&1, 0)) + {:ok, user2} = User.update_info(user2, &User.Info.set_note_count(&1, 0)) + + assert %{info: %{note_count: 0}} = user + assert %{info: %{note_count: 0}} = user2 + + assert capture_io(fn -> Mix.Tasks.Pleroma.CountStatuses.run([]) end) == "Done\n" + + assert %{info: %{note_count: 2}} = refresh_record(user) + assert %{info: %{note_count: 1}} = refresh_record(user2) + end +end diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs index a4bbfe055..2de2725e0 100644 --- a/test/web/mastodon_api/controllers/status_controller_test.exs +++ b/test/web/mastodon_api/controllers/status_controller_test.exs @@ -8,6 +8,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do alias Pleroma.Activity alias Pleroma.ActivityExpiration alias Pleroma.Config + alias Pleroma.Conversation.Participation alias Pleroma.Object alias Pleroma.Repo alias Pleroma.ScheduledActivity @@ -465,6 +466,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do assert id == to_string(activity.id) end + test "get a direct status", %{conn: conn} do + user = insert(:user) + other_user = insert(:user) + + {:ok, activity} = + CommonAPI.post(user, %{"status" => "@#{other_user.nickname}", "visibility" => "direct"}) + + conn = + conn + |> assign(:user, user) + |> get("/api/v1/statuses/#{activity.id}") + + [participation] = Participation.for_user(user) + + res = json_response(conn, 200) + assert res["pleroma"]["direct_conversation_id"] == participation.id + end + test "get statuses by IDs", %{conn: conn} do %{id: id1} = insert(:note_activity) %{id: id2} = insert(:note_activity)