Merge branch 'fix/webpush-and-emojireact' into 'develop'

Push notifications: add pleroma:emoji_reaction, improve tests

Closes #2185

See merge request pleroma/pleroma!3141
This commit is contained in:
lain 2020-11-18 18:33:48 +00:00
commit aae669d05e
7 changed files with 158 additions and 35 deletions

View File

@ -42,6 +42,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
</details> </details>
## Unreleased (Patch) ## Unreleased (Patch)
### Changed
- Fix ability to update Pleroma Chat push notifications with PUT /api/v1/push/subscription and alert type pleroma:chat_mention
### Fixed ### Fixed
- Config generation: rename `Pleroma.Upload.Filter.ExifTool` to `Pleroma.Upload.Filter.Exiftool`. - Config generation: rename `Pleroma.Upload.Filter.ExifTool` to `Pleroma.Upload.Filter.Exiftool`.

View File

@ -233,7 +233,7 @@ Post here request with `grant_type=refresh_token` to obtain new access token. Re
`POST /api/v1/accounts` `POST /api/v1/accounts`
Has theses additional parameters (which are the same as in Pleroma-API): Has these additional parameters (which are the same as in Pleroma-API):
- `fullname`: optional - `fullname`: optional
- `bio`: optional - `bio`: optional
@ -261,6 +261,16 @@ Has theses additional parameters (which are the same as in Pleroma-API):
- `pleroma.metadata.post_formats`: A list of the allowed post format types - `pleroma.metadata.post_formats`: A list of the allowed post format types
- `vapid_public_key`: The public key needed for push messages - `vapid_public_key`: The public key needed for push messages
## Push Subscription
`POST /api/v1/push/subscription`
`PUT /api/v1/push/subscription`
Permits these additional alert types:
- pleroma:chat_mention
- pleroma:emoji_reaction
## Markers ## Markers
Has these additional fields under the `pleroma` object: Has these additional fields under the `pleroma` object:

View File

@ -146,6 +146,11 @@ defp create_request do
allOf: [BooleanLike], allOf: [BooleanLike],
nullable: true, nullable: true,
description: "Receive chat notifications?" description: "Receive chat notifications?"
},
"pleroma:emoji_reaction": %Schema{
allOf: [BooleanLike],
nullable: true,
description: "Receive emoji reaction notifications?"
} }
} }
} }
@ -210,6 +215,16 @@ defp update_request do
allOf: [BooleanLike], allOf: [BooleanLike],
nullable: true, nullable: true,
description: "Receive poll notifications?" description: "Receive poll notifications?"
},
"pleroma:chat_mention": %Schema{
allOf: [BooleanLike],
nullable: true,
description: "Receive chat notifications?"
},
"pleroma:emoji_reaction": %Schema{
allOf: [BooleanLike],
nullable: true,
description: "Receive emoji reaction notifications?"
} }
} }
} }

View File

@ -16,7 +16,7 @@ defmodule Pleroma.Web.Push.Impl do
require Logger require Logger
import Ecto.Query import Ecto.Query
@types ["Create", "Follow", "Announce", "Like", "Move"] @types ["Create", "Follow", "Announce", "Like", "Move", "EmojiReact"]
@doc "Performs sending notifications for user subscriptions" @doc "Performs sending notifications for user subscriptions"
@spec perform(Notification.t()) :: list(any) | :error | {:error, :unknown_type} @spec perform(Notification.t()) :: list(any) | :error | {:error, :unknown_type}
@ -149,6 +149,15 @@ def format_body(
"@#{actor.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}" "@#{actor.nickname} repeated: #{Utils.scrub_html_and_truncate(content, 80)}"
end end
def format_body(
%{activity: %{data: %{"type" => "EmojiReact", "content" => content}}},
actor,
_object,
_mastodon_type
) do
"@#{actor.nickname} reacted with #{content}"
end
def format_body( def format_body(
%{activity: %{data: %{"type" => type}}} = notification, %{activity: %{data: %{"type" => type}}} = notification,
actor, actor,
@ -179,6 +188,7 @@ def format_title(%{type: type}, mastodon_type) do
"reblog" -> "New Repeat" "reblog" -> "New Repeat"
"favourite" -> "New Favorite" "favourite" -> "New Favorite"
"pleroma:chat_mention" -> "New Chat Message" "pleroma:chat_mention" -> "New Chat Message"
"pleroma:emoji_reaction" -> "New Reaction"
type -> "New #{String.capitalize(type || "event")}" type -> "New #{String.capitalize(type || "event")}"
end end
end end

View File

@ -25,7 +25,8 @@ defmodule Pleroma.Web.Push.Subscription do
timestamps() timestamps()
end end
@supported_alert_types ~w[follow favourite mention reblog pleroma:chat_mention]a # credo:disable-for-next-line Credo.Check.Readability.MaxLineLength
@supported_alert_types ~w[follow favourite mention reblog pleroma:chat_mention pleroma:emoji_reaction]a
defp alerts(%{data: %{alerts: alerts}}) do defp alerts(%{data: %{alerts: alerts}}) do
alerts = Map.take(alerts, @supported_alert_types) alerts = Map.take(alerts, @supported_alert_types)

View File

@ -45,21 +45,77 @@ defmacro assert_error_when_disable_push(do: yield) do
end end
end end
describe "creates push subscription" do describe "when disabled" do
test "returns error when push disabled ", %{conn: conn} do test "POST returns error", %{conn: conn} do
assert_error_when_disable_push do assert_error_when_disable_push do
conn conn
|> post("/api/v1/push/subscription", %{subscription: @sub}) |> post("/api/v1/push/subscription", %{
"data" => %{"alerts" => %{"mention" => true}},
"subscription" => @sub
})
|> json_response_and_validate_schema(403) |> json_response_and_validate_schema(403)
end end
end end
test "GET returns error", %{conn: conn} do
assert_error_when_disable_push do
conn
|> get("/api/v1/push/subscription", %{})
|> json_response_and_validate_schema(403)
end
end
test "PUT returns error", %{conn: conn} do
assert_error_when_disable_push do
conn
|> put("/api/v1/push/subscription", %{data: %{"alerts" => %{"mention" => false}}})
|> json_response_and_validate_schema(403)
end
end
test "DELETE returns error", %{conn: conn} do
assert_error_when_disable_push do
conn
|> delete("/api/v1/push/subscription", %{})
|> json_response_and_validate_schema(403)
end
end
end
describe "creates push subscription" do
test "ignores unsupported types", %{conn: conn} do
result =
conn
|> post("/api/v1/push/subscription", %{
"data" => %{
"alerts" => %{
"fake_unsupported_type" => true
}
},
"subscription" => @sub
})
|> json_response_and_validate_schema(200)
refute %{
"alerts" => %{
"fake_unsupported_type" => true
}
} == result
end
test "successful creation", %{conn: conn} do test "successful creation", %{conn: conn} do
result = result =
conn conn
|> post("/api/v1/push/subscription", %{ |> post("/api/v1/push/subscription", %{
"data" => %{ "data" => %{
"alerts" => %{"mention" => true, "test" => true, "pleroma:chat_mention" => true} "alerts" => %{
"mention" => true,
"favourite" => true,
"follow" => true,
"reblog" => true,
"pleroma:chat_mention" => true,
"pleroma:emoji_reaction" => true
}
}, },
"subscription" => @sub "subscription" => @sub
}) })
@ -68,7 +124,14 @@ test "successful creation", %{conn: conn} do
[subscription] = Pleroma.Repo.all(Subscription) [subscription] = Pleroma.Repo.all(Subscription)
assert %{ assert %{
"alerts" => %{"mention" => true, "pleroma:chat_mention" => true}, "alerts" => %{
"mention" => true,
"favourite" => true,
"follow" => true,
"reblog" => true,
"pleroma:chat_mention" => true,
"pleroma:emoji_reaction" => true
},
"endpoint" => subscription.endpoint, "endpoint" => subscription.endpoint,
"id" => to_string(subscription.id), "id" => to_string(subscription.id),
"server_key" => @server_key "server_key" => @server_key
@ -77,14 +140,6 @@ test "successful creation", %{conn: conn} do
end end
describe "gets a user subscription" do 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_and_validate_schema(403)
end
end
test "returns error when user hasn't subscription", %{conn: conn} do test "returns error when user hasn't subscription", %{conn: conn} do
res = res =
conn conn
@ -124,30 +179,47 @@ test "returns a user subsciption", %{conn: conn, user: user, token: token} do
insert(:push_subscription, insert(:push_subscription,
user: user, user: user,
token: token, token: token,
data: %{"alerts" => %{"mention" => true}} data: %{
"alerts" => %{
"mention" => true,
"favourite" => true,
"follow" => true,
"reblog" => true,
"pleroma:chat_mention" => true,
"pleroma:emoji_reaction" => true
}
}
) )
%{conn: conn, user: user, token: token, subscription: subscription} %{conn: conn, user: user, token: token, subscription: subscription}
end 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_and_validate_schema(403)
end
end
test "returns updated subsciption", %{conn: conn, subscription: subscription} do test "returns updated subsciption", %{conn: conn, subscription: subscription} do
res = res =
conn conn
|> put("/api/v1/push/subscription", %{ |> put("/api/v1/push/subscription", %{
data: %{"alerts" => %{"mention" => false, "follow" => true}} data: %{
"alerts" => %{
"mention" => false,
"favourite" => false,
"follow" => false,
"reblog" => false,
"pleroma:chat_mention" => false,
"pleroma:emoji_reaction" => false
}
}
}) })
|> json_response_and_validate_schema(200) |> json_response_and_validate_schema(200)
expect = %{ expect = %{
"alerts" => %{"follow" => true, "mention" => false}, "alerts" => %{
"mention" => false,
"favourite" => false,
"follow" => false,
"reblog" => false,
"pleroma:chat_mention" => false,
"pleroma:emoji_reaction" => false
},
"endpoint" => "https://example.com/example/1234", "endpoint" => "https://example.com/example/1234",
"id" => to_string(subscription.id), "id" => to_string(subscription.id),
"server_key" => @server_key "server_key" => @server_key
@ -158,14 +230,6 @@ test "returns updated subsciption", %{conn: conn, subscription: subscription} do
end end
describe "deletes the user subscription" do 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_and_validate_schema(403)
end
end
test "returns error when user hasn't subscription", %{conn: conn} do test "returns error when user hasn't subscription", %{conn: conn} do
res = res =
conn conn

View File

@ -184,6 +184,24 @@ test "renders title and body for like activity" do
"New Favorite" "New Favorite"
end end
test "renders title and body for pleroma:emoji_reaction activity" do
user = insert(:user, nickname: "Bob")
{:ok, activity} =
CommonAPI.post(user, %{
status: "This post is a really good post!"
})
{:ok, activity} = CommonAPI.react_with_emoji(activity.id, user, "👍")
object = Object.normalize(activity)
assert Impl.format_body(%{activity: activity, type: "pleroma:emoji_reaction"}, user, object) ==
"@Bob reacted with 👍"
assert Impl.format_title(%{activity: activity, type: "pleroma:emoji_reaction"}) ==
"New Reaction"
end
test "renders title for create activity with direct visibility" do test "renders title for create activity with direct visibility" do
user = insert(:user, nickname: "Bob") user = insert(:user, nickname: "Bob")