forked from AkkomaGang/akkoma
Merge branch 'issue/1276-2' into 'develop'
[#1276] added an endpoint for getting unread notification count See merge request pleroma/pleroma!2392
This commit is contained in:
commit
0cf43391f2
13 changed files with 237 additions and 26 deletions
|
@ -156,6 +156,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Mastodon API: `pleroma.thread_muted` to the Status entity
|
- Mastodon API: `pleroma.thread_muted` to the Status entity
|
||||||
- Mastodon API: Mark the direct conversation as read for the author when they send a new direct message
|
- Mastodon API: Mark the direct conversation as read for the author when they send a new direct message
|
||||||
- Mastodon API, streaming: Add `pleroma.direct_conversation_id` to the `conversation` stream event payload.
|
- Mastodon API, streaming: Add `pleroma.direct_conversation_id` to the `conversation` stream event payload.
|
||||||
|
- Mastodon API: Add `pleroma.unread_count` to the Marker entity
|
||||||
- Admin API: Render whole status in grouped reports
|
- Admin API: Render whole status in grouped reports
|
||||||
- Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise).
|
- Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise).
|
||||||
- Mastodon API: Favoriting / Repeating a post multiple times will now return the identical response every time. Before, executing that action twice would return an error ("already favorited") on the second try.
|
- Mastodon API: Favoriting / Repeating a post multiple times will now return the identical response every time. Before, executing that action twice would return an error ("already favorited") on the second try.
|
||||||
|
|
|
@ -61,6 +61,7 @@ Has these additional fields under the `pleroma` object:
|
||||||
- `deactivated`: boolean, true when the user is deactivated
|
- `deactivated`: boolean, true when the user is deactivated
|
||||||
- `allow_following_move`: boolean, true when the user allows automatically follow moved following accounts
|
- `allow_following_move`: boolean, true when the user allows automatically follow moved following accounts
|
||||||
- `unread_conversation_count`: The count of unread conversations. Only returned to the account owner.
|
- `unread_conversation_count`: The count of unread conversations. Only returned to the account owner.
|
||||||
|
- `unread_notifications_count`: The count of unread notifications. Only returned to the account owner.
|
||||||
|
|
||||||
### Source
|
### Source
|
||||||
|
|
||||||
|
@ -218,3 +219,9 @@ Has theses additional parameters (which are the same as in Pleroma-API):
|
||||||
- `pleroma.metadata.features`: A list of supported features
|
- `pleroma.metadata.features`: A list of supported features
|
||||||
- `pleroma.metadata.federation`: The federation restrictions of this instance
|
- `pleroma.metadata.federation`: The federation restrictions of this instance
|
||||||
- `vapid_public_key`: The public key needed for push messages
|
- `vapid_public_key`: The public key needed for push messages
|
||||||
|
|
||||||
|
## Markers
|
||||||
|
|
||||||
|
Has these additional fields under the `pleroma` object:
|
||||||
|
|
||||||
|
- `unread_count`: contains number unread notifications
|
||||||
|
|
|
@ -9,24 +9,34 @@ defmodule Pleroma.Marker do
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias Ecto.Multi
|
alias Ecto.Multi
|
||||||
|
alias Pleroma.Notification
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
|
alias __MODULE__
|
||||||
|
|
||||||
@timelines ["notifications"]
|
@timelines ["notifications"]
|
||||||
|
@type t :: %__MODULE__{}
|
||||||
|
|
||||||
schema "markers" do
|
schema "markers" do
|
||||||
field(:last_read_id, :string, default: "")
|
field(:last_read_id, :string, default: "")
|
||||||
field(:timeline, :string, default: "")
|
field(:timeline, :string, default: "")
|
||||||
field(:lock_version, :integer, default: 0)
|
field(:lock_version, :integer, default: 0)
|
||||||
|
field(:unread_count, :integer, default: 0, virtual: true)
|
||||||
|
|
||||||
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
|
belongs_to(:user, User, type: FlakeId.Ecto.CompatType)
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc "Gets markers by user and timeline."
|
||||||
|
@spec get_markers(User.t(), list(String)) :: list(t())
|
||||||
def get_markers(user, timelines \\ []) do
|
def get_markers(user, timelines \\ []) do
|
||||||
Repo.all(get_query(user, timelines))
|
user
|
||||||
|
|> get_query(timelines)
|
||||||
|
|> unread_count_query()
|
||||||
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec upsert(User.t(), map()) :: {:ok | :error, any()}
|
||||||
def upsert(%User{} = user, attrs) do
|
def upsert(%User{} = user, attrs) do
|
||||||
attrs
|
attrs
|
||||||
|> Map.take(@timelines)
|
|> Map.take(@timelines)
|
||||||
|
@ -45,6 +55,27 @@ def upsert(%User{} = user, attrs) do
|
||||||
|> Repo.transaction()
|
|> Repo.transaction()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec multi_set_last_read_id(Multi.t(), User.t(), String.t()) :: Multi.t()
|
||||||
|
def multi_set_last_read_id(multi, %User{} = user, "notifications") do
|
||||||
|
multi
|
||||||
|
|> Multi.run(:counters, fn _repo, _changes ->
|
||||||
|
{:ok, %{last_read_id: Repo.one(Notification.last_read_query(user))}}
|
||||||
|
end)
|
||||||
|
|> Multi.insert(
|
||||||
|
:marker,
|
||||||
|
fn %{counters: attrs} ->
|
||||||
|
%Marker{timeline: "notifications", user_id: user.id}
|
||||||
|
|> struct(attrs)
|
||||||
|
|> Ecto.Changeset.change()
|
||||||
|
end,
|
||||||
|
returning: true,
|
||||||
|
on_conflict: {:replace, [:last_read_id]},
|
||||||
|
conflict_target: [:user_id, :timeline]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def multi_set_last_read_id(multi, _, _), do: multi
|
||||||
|
|
||||||
defp get_marker(user, timeline) do
|
defp get_marker(user, timeline) do
|
||||||
case Repo.find_resource(get_query(user, timeline)) do
|
case Repo.find_resource(get_query(user, timeline)) do
|
||||||
{:ok, marker} -> %__MODULE__{marker | user: user}
|
{:ok, marker} -> %__MODULE__{marker | user: user}
|
||||||
|
@ -71,4 +102,16 @@ defp get_query(user, timelines) do
|
||||||
|> by_user_id(user.id)
|
|> by_user_id(user.id)
|
||||||
|> by_timeline(timelines)
|
|> by_timeline(timelines)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp unread_count_query(query) do
|
||||||
|
from(
|
||||||
|
q in query,
|
||||||
|
left_join: n in "notifications",
|
||||||
|
on: n.user_id == q.user_id and n.seen == false,
|
||||||
|
group_by: [:id],
|
||||||
|
select_merge: %{
|
||||||
|
unread_count: fragment("count(?)", n.id)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,10 @@
|
||||||
defmodule Pleroma.Notification do
|
defmodule Pleroma.Notification do
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
|
|
||||||
|
alias Ecto.Multi
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.FollowingRelationship
|
alias Pleroma.FollowingRelationship
|
||||||
|
alias Pleroma.Marker
|
||||||
alias Pleroma.Notification
|
alias Pleroma.Notification
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Pagination
|
alias Pleroma.Pagination
|
||||||
|
@ -34,11 +36,30 @@ defmodule Pleroma.Notification do
|
||||||
timestamps()
|
timestamps()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec unread_notifications_count(User.t()) :: integer()
|
||||||
|
def unread_notifications_count(%User{id: user_id}) do
|
||||||
|
from(q in __MODULE__,
|
||||||
|
where: q.user_id == ^user_id and q.seen == false
|
||||||
|
)
|
||||||
|
|> Repo.aggregate(:count, :id)
|
||||||
|
end
|
||||||
|
|
||||||
def changeset(%Notification{} = notification, attrs) do
|
def changeset(%Notification{} = notification, attrs) do
|
||||||
notification
|
notification
|
||||||
|> cast(attrs, [:seen])
|
|> cast(attrs, [:seen])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec last_read_query(User.t()) :: Ecto.Queryable.t()
|
||||||
|
def last_read_query(user) do
|
||||||
|
from(q in Pleroma.Notification,
|
||||||
|
where: q.user_id == ^user.id,
|
||||||
|
where: q.seen == true,
|
||||||
|
select: type(q.id, :string),
|
||||||
|
limit: 1,
|
||||||
|
order_by: [desc: :id]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
defp for_user_query_ap_id_opts(user, opts) do
|
defp for_user_query_ap_id_opts(user, opts) do
|
||||||
ap_id_relationships =
|
ap_id_relationships =
|
||||||
[:block] ++
|
[:block] ++
|
||||||
|
@ -185,25 +206,23 @@ def for_user_since(user, date) do
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_read_up_to(%{id: user_id} = _user, id) do
|
def set_read_up_to(%{id: user_id} = user, id) do
|
||||||
query =
|
query =
|
||||||
from(
|
from(
|
||||||
n in Notification,
|
n in Notification,
|
||||||
where: n.user_id == ^user_id,
|
where: n.user_id == ^user_id,
|
||||||
where: n.id <= ^id,
|
where: n.id <= ^id,
|
||||||
where: n.seen == false,
|
where: n.seen == false,
|
||||||
update: [
|
|
||||||
set: [
|
|
||||||
seen: true,
|
|
||||||
updated_at: ^NaiveDateTime.utc_now()
|
|
||||||
]
|
|
||||||
],
|
|
||||||
# Ideally we would preload object and activities here
|
# Ideally we would preload object and activities here
|
||||||
# but Ecto does not support preloads in update_all
|
# but Ecto does not support preloads in update_all
|
||||||
select: n.id
|
select: n.id
|
||||||
)
|
)
|
||||||
|
|
||||||
{_, notification_ids} = Repo.update_all(query, [])
|
{:ok, %{ids: {_, notification_ids}}} =
|
||||||
|
Multi.new()
|
||||||
|
|> Multi.update_all(:ids, query, set: [seen: true, updated_at: NaiveDateTime.utc_now()])
|
||||||
|
|> Marker.multi_set_last_read_id(user, "notifications")
|
||||||
|
|> Repo.transaction()
|
||||||
|
|
||||||
Notification
|
Notification
|
||||||
|> where([n], n.id in ^notification_ids)
|
|> where([n], n.id in ^notification_ids)
|
||||||
|
@ -220,11 +239,18 @@ def set_read_up_to(%{id: user_id} = _user, id) do
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec read_one(User.t(), String.t()) ::
|
||||||
|
{:ok, Notification.t()} | {:error, Ecto.Changeset.t()} | nil
|
||||||
def read_one(%User{} = user, notification_id) do
|
def read_one(%User{} = user, notification_id) do
|
||||||
with {:ok, %Notification{} = notification} <- get(user, notification_id) do
|
with {:ok, %Notification{} = notification} <- get(user, notification_id) do
|
||||||
notification
|
Multi.new()
|
||||||
|> changeset(%{seen: true})
|
|> Multi.update(:update, changeset(notification, %{seen: true}))
|
||||||
|> Repo.update()
|
|> Marker.multi_set_last_read_id(user, "notifications")
|
||||||
|
|> Repo.transaction()
|
||||||
|
|> case do
|
||||||
|
{:ok, %{update: notification}} -> {:ok, notification}
|
||||||
|
{:error, :update, changeset, _} -> {:error, changeset}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -316,8 +342,11 @@ defp do_create_notifications(%Activity{} = activity) do
|
||||||
# TODO move to sql, too.
|
# TODO move to sql, too.
|
||||||
def create_notification(%Activity{} = activity, %User{} = user, do_send \\ true) do
|
def create_notification(%Activity{} = activity, %User{} = user, do_send \\ true) do
|
||||||
unless skip?(activity, user) do
|
unless skip?(activity, user) do
|
||||||
notification = %Notification{user_id: user.id, activity: activity}
|
{:ok, %{notification: notification}} =
|
||||||
{:ok, notification} = Repo.insert(notification)
|
Multi.new()
|
||||||
|
|> Multi.insert(:notification, %Notification{user_id: user.id, activity: activity})
|
||||||
|
|> Marker.multi_set_last_read_id(user, "notifications")
|
||||||
|
|> Repo.transaction()
|
||||||
|
|
||||||
if do_send do
|
if do_send do
|
||||||
Streamer.stream(["user", "user:notification"], notification)
|
Streamer.stream(["user", "user:notification"], notification)
|
||||||
|
|
|
@ -36,9 +36,11 @@ def render("index.json", %{users: users} = opts) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("show.json", %{user: user} = opts) do
|
def render("show.json", %{user: user} = opts) do
|
||||||
if User.visible_for?(user, opts[:for]),
|
if User.visible_for?(user, opts[:for]) do
|
||||||
do: do_render("show.json", opts),
|
do_render("show.json", opts)
|
||||||
else: %{}
|
else
|
||||||
|
%{}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def render("mention.json", %{user: user}) do
|
def render("mention.json", %{user: user}) do
|
||||||
|
@ -221,7 +223,7 @@ defp do_render("show.json", %{user: user} = opts) do
|
||||||
fields: user.fields,
|
fields: user.fields,
|
||||||
bot: bot,
|
bot: bot,
|
||||||
source: %{
|
source: %{
|
||||||
note: (user.bio || "") |> String.replace(~r(<br */?>), "\n") |> Pleroma.HTML.strip_tags(),
|
note: prepare_user_bio(user),
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
fields: user.raw_fields,
|
fields: user.raw_fields,
|
||||||
pleroma: %{
|
pleroma: %{
|
||||||
|
@ -253,8 +255,17 @@ defp do_render("show.json", %{user: user} = opts) do
|
||||||
|> maybe_put_follow_requests_count(user, opts[:for])
|
|> maybe_put_follow_requests_count(user, opts[:for])
|
||||||
|> maybe_put_allow_following_move(user, opts[:for])
|
|> maybe_put_allow_following_move(user, opts[:for])
|
||||||
|> maybe_put_unread_conversation_count(user, opts[:for])
|
|> maybe_put_unread_conversation_count(user, opts[:for])
|
||||||
|
|> maybe_put_unread_notification_count(user, opts[:for])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp prepare_user_bio(%User{bio: ""}), do: ""
|
||||||
|
|
||||||
|
defp prepare_user_bio(%User{bio: bio}) when is_binary(bio) do
|
||||||
|
bio |> String.replace(~r(<br */?>), "\n") |> Pleroma.HTML.strip_tags()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp prepare_user_bio(_), do: ""
|
||||||
|
|
||||||
defp username_from_nickname(string) when is_binary(string) do
|
defp username_from_nickname(string) when is_binary(string) do
|
||||||
hd(String.split(string, "@"))
|
hd(String.split(string, "@"))
|
||||||
end
|
end
|
||||||
|
@ -350,6 +361,16 @@ defp maybe_put_unread_conversation_count(data, %User{id: user_id} = user, %User{
|
||||||
|
|
||||||
defp maybe_put_unread_conversation_count(data, _, _), do: data
|
defp maybe_put_unread_conversation_count(data, _, _), do: data
|
||||||
|
|
||||||
|
defp maybe_put_unread_notification_count(data, %User{id: user_id}, %User{id: user_id} = user) do
|
||||||
|
Kernel.put_in(
|
||||||
|
data,
|
||||||
|
[:pleroma, :unread_notifications_count],
|
||||||
|
Pleroma.Notification.unread_notifications_count(user)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_put_unread_notification_count(data, _, _), do: data
|
||||||
|
|
||||||
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
|
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
|
||||||
defp image_url(_), do: nil
|
defp image_url(_), do: nil
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,7 +11,10 @@ def render("markers.json", %{markers: markers}) do
|
||||||
%{
|
%{
|
||||||
last_read_id: m.last_read_id,
|
last_read_id: m.last_read_id,
|
||||||
version: m.lock_version,
|
version: m.lock_version,
|
||||||
updated_at: NaiveDateTime.to_iso8601(m.updated_at)
|
updated_at: NaiveDateTime.to_iso8601(m.updated_at),
|
||||||
|
pleroma: %{
|
||||||
|
unread_count: m.unread_count
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
40
priv/repo/migrations/20200415181818_update_markers.exs
Normal file
40
priv/repo/migrations/20200415181818_update_markers.exs
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.UpdateMarkers do
|
||||||
|
use Ecto.Migration
|
||||||
|
import Ecto.Query
|
||||||
|
alias Pleroma.Repo
|
||||||
|
|
||||||
|
def up do
|
||||||
|
update_markers()
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
defp update_markers do
|
||||||
|
now = NaiveDateTime.utc_now()
|
||||||
|
|
||||||
|
markers_attrs =
|
||||||
|
from(q in "notifications",
|
||||||
|
select: %{
|
||||||
|
timeline: "notifications",
|
||||||
|
user_id: q.user_id,
|
||||||
|
last_read_id:
|
||||||
|
type(fragment("MAX( CASE WHEN seen = true THEN id ELSE null END )"), :string)
|
||||||
|
},
|
||||||
|
group_by: [q.user_id]
|
||||||
|
)
|
||||||
|
|> Repo.all()
|
||||||
|
|> Enum.map(fn %{last_read_id: last_read_id} = attrs ->
|
||||||
|
attrs
|
||||||
|
|> Map.put(:last_read_id, last_read_id || "")
|
||||||
|
|> Map.put_new(:inserted_at, now)
|
||||||
|
|> Map.put_new(:updated_at, now)
|
||||||
|
end)
|
||||||
|
|
||||||
|
Repo.insert_all("markers", markers_attrs,
|
||||||
|
on_conflict: {:replace, [:last_read_id]},
|
||||||
|
conflict_target: [:user_id, :timeline]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,12 +8,39 @@ defmodule Pleroma.MarkerTest do
|
||||||
|
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
describe "multi_set_unread_count/3" do
|
||||||
|
test "returns multi" do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
assert %Ecto.Multi{
|
||||||
|
operations: [marker: {:run, _}, counters: {:run, _}]
|
||||||
|
} =
|
||||||
|
Marker.multi_set_last_read_id(
|
||||||
|
Ecto.Multi.new(),
|
||||||
|
user,
|
||||||
|
"notifications"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "return empty multi" do
|
||||||
|
user = insert(:user)
|
||||||
|
multi = Ecto.Multi.new()
|
||||||
|
assert Marker.multi_set_last_read_id(multi, user, "home") == multi
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "get_markers/2" do
|
describe "get_markers/2" do
|
||||||
test "returns user markers" do
|
test "returns user markers" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
marker = insert(:marker, user: user)
|
marker = insert(:marker, user: user)
|
||||||
|
insert(:notification, user: user)
|
||||||
|
insert(:notification, user: user)
|
||||||
insert(:marker, timeline: "home", user: user)
|
insert(:marker, timeline: "home", user: user)
|
||||||
assert Marker.get_markers(user, ["notifications"]) == [refresh_record(marker)]
|
|
||||||
|
assert Marker.get_markers(
|
||||||
|
user,
|
||||||
|
["notifications"]
|
||||||
|
) == [%Marker{refresh_record(marker) | unread_count: 2}]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,9 @@ test "notifies someone when they are directly addressed" do
|
||||||
assert notified_ids == [other_user.id, third_user.id]
|
assert notified_ids == [other_user.id, third_user.id]
|
||||||
assert notification.activity_id == activity.id
|
assert notification.activity_id == activity.id
|
||||||
assert other_notification.activity_id == activity.id
|
assert other_notification.activity_id == activity.id
|
||||||
|
|
||||||
|
assert [%Pleroma.Marker{unread_count: 2}] =
|
||||||
|
Pleroma.Marker.get_markers(other_user, ["notifications"])
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it creates a notification for subscribed users" do
|
test "it creates a notification for subscribed users" do
|
||||||
|
@ -466,6 +469,16 @@ test "it sets all notifications as read up to a specified notification ID" do
|
||||||
assert n1.seen == true
|
assert n1.seen == true
|
||||||
assert n2.seen == true
|
assert n2.seen == true
|
||||||
assert n3.seen == false
|
assert n3.seen == false
|
||||||
|
|
||||||
|
assert %Pleroma.Marker{} =
|
||||||
|
m =
|
||||||
|
Pleroma.Repo.get_by(
|
||||||
|
Pleroma.Marker,
|
||||||
|
user_id: other_user.id,
|
||||||
|
timeline: "notifications"
|
||||||
|
)
|
||||||
|
|
||||||
|
assert m.last_read_id == to_string(n2.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1196,12 +1196,15 @@ test "returns lists to which the account belongs" do
|
||||||
describe "verify_credentials" do
|
describe "verify_credentials" do
|
||||||
test "verify_credentials" do
|
test "verify_credentials" do
|
||||||
%{user: user, conn: conn} = oauth_access(["read:accounts"])
|
%{user: user, conn: conn} = oauth_access(["read:accounts"])
|
||||||
|
[notification | _] = insert_list(7, :notification, user: user)
|
||||||
|
Pleroma.Notification.set_read_up_to(user, notification.id)
|
||||||
conn = get(conn, "/api/v1/accounts/verify_credentials")
|
conn = get(conn, "/api/v1/accounts/verify_credentials")
|
||||||
|
|
||||||
response = json_response_and_validate_schema(conn, 200)
|
response = json_response_and_validate_schema(conn, 200)
|
||||||
|
|
||||||
assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
|
assert %{"id" => id, "source" => %{"privacy" => "public"}} = response
|
||||||
assert response["pleroma"]["chat_token"]
|
assert response["pleroma"]["chat_token"]
|
||||||
|
assert response["pleroma"]["unread_notifications_count"] == 6
|
||||||
assert id == to_string(user.id)
|
assert id == to_string(user.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ defmodule Pleroma.Web.MastodonAPI.MarkerControllerTest do
|
||||||
test "gets markers with correct scopes", %{conn: conn} do
|
test "gets markers with correct scopes", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
|
token = insert(:oauth_token, user: user, scopes: ["read:statuses"])
|
||||||
|
insert_list(7, :notification, user: user)
|
||||||
|
|
||||||
{:ok, %{"notifications" => marker}} =
|
{:ok, %{"notifications" => marker}} =
|
||||||
Pleroma.Marker.upsert(
|
Pleroma.Marker.upsert(
|
||||||
|
@ -29,7 +30,8 @@ test "gets markers with correct scopes", %{conn: conn} do
|
||||||
"notifications" => %{
|
"notifications" => %{
|
||||||
"last_read_id" => "69420",
|
"last_read_id" => "69420",
|
||||||
"updated_at" => NaiveDateTime.to_iso8601(marker.updated_at),
|
"updated_at" => NaiveDateTime.to_iso8601(marker.updated_at),
|
||||||
"version" => 0
|
"version" => 0,
|
||||||
|
"pleroma" => %{"unread_count" => 7}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -71,7 +73,8 @@ test "creates a marker with correct scopes", %{conn: conn} do
|
||||||
"notifications" => %{
|
"notifications" => %{
|
||||||
"last_read_id" => "69420",
|
"last_read_id" => "69420",
|
||||||
"updated_at" => _,
|
"updated_at" => _,
|
||||||
"version" => 0
|
"version" => 0,
|
||||||
|
"pleroma" => %{"unread_count" => 0}
|
||||||
}
|
}
|
||||||
} = response
|
} = response
|
||||||
end
|
end
|
||||||
|
@ -101,7 +104,8 @@ test "updates exist marker", %{conn: conn} do
|
||||||
"notifications" => %{
|
"notifications" => %{
|
||||||
"last_read_id" => "69888",
|
"last_read_id" => "69888",
|
||||||
"updated_at" => NaiveDateTime.to_iso8601(marker.updated_at),
|
"updated_at" => NaiveDateTime.to_iso8601(marker.updated_at),
|
||||||
"version" => 0
|
"version" => 0,
|
||||||
|
"pleroma" => %{"unread_count" => 0}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
|
@ -466,6 +466,24 @@ test "shows unread_conversation_count only to the account owner" do
|
||||||
:unread_conversation_count
|
:unread_conversation_count
|
||||||
] == 1
|
] == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "shows unread_count only to the account owner" do
|
||||||
|
user = insert(:user)
|
||||||
|
insert_list(7, :notification, user: user)
|
||||||
|
other_user = insert(:user)
|
||||||
|
|
||||||
|
user = User.get_cached_by_ap_id(user.ap_id)
|
||||||
|
|
||||||
|
assert AccountView.render(
|
||||||
|
"show.json",
|
||||||
|
%{user: user, for: other_user}
|
||||||
|
)[:pleroma][:unread_notifications_count] == nil
|
||||||
|
|
||||||
|
assert AccountView.render(
|
||||||
|
"show.json",
|
||||||
|
%{user: user, for: user}
|
||||||
|
)[:pleroma][:unread_notifications_count] == 7
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "follow requests counter" do
|
describe "follow requests counter" do
|
||||||
|
|
|
@ -8,19 +8,21 @@ defmodule Pleroma.Web.MastodonAPI.MarkerViewTest do
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
test "returns markers" do
|
test "returns markers" do
|
||||||
marker1 = insert(:marker, timeline: "notifications", last_read_id: "17")
|
marker1 = insert(:marker, timeline: "notifications", last_read_id: "17", unread_count: 5)
|
||||||
marker2 = insert(:marker, timeline: "home", last_read_id: "42")
|
marker2 = insert(:marker, timeline: "home", last_read_id: "42")
|
||||||
|
|
||||||
assert MarkerView.render("markers.json", %{markers: [marker1, marker2]}) == %{
|
assert MarkerView.render("markers.json", %{markers: [marker1, marker2]}) == %{
|
||||||
"home" => %{
|
"home" => %{
|
||||||
last_read_id: "42",
|
last_read_id: "42",
|
||||||
updated_at: NaiveDateTime.to_iso8601(marker2.updated_at),
|
updated_at: NaiveDateTime.to_iso8601(marker2.updated_at),
|
||||||
version: 0
|
version: 0,
|
||||||
|
pleroma: %{unread_count: 0}
|
||||||
},
|
},
|
||||||
"notifications" => %{
|
"notifications" => %{
|
||||||
last_read_id: "17",
|
last_read_id: "17",
|
||||||
updated_at: NaiveDateTime.to_iso8601(marker1.updated_at),
|
updated_at: NaiveDateTime.to_iso8601(marker1.updated_at),
|
||||||
version: 0
|
version: 0,
|
||||||
|
pleroma: %{unread_count: 5}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue