Merge branch 'feature/807-bookmark-endpoint-extension' into 'develop'
Feature/807 bookmark endpoint extension Closes #807 See merge request pleroma/pleroma!1059
This commit is contained in:
commit
4de5fef1f8
|
@ -58,6 +58,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Deps: Updated Cowboy to 2.6
|
- Deps: Updated Cowboy to 2.6
|
||||||
- Deps: Updated Ecto to 3.0.7
|
- Deps: Updated Ecto to 3.0.7
|
||||||
- Don't ship finmoji by default, they can be installed as an emoji pack
|
- Don't ship finmoji by default, they can be installed as an emoji pack
|
||||||
|
- Mastodon API: Added support max_id & since_id for bookmark timeline endpoints.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Followers counter not being updated when a follower is blocked
|
- Followers counter not being updated when a follower is blocked
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
defmodule Pleroma.Bookmark do
|
||||||
|
use Ecto.Schema
|
||||||
|
|
||||||
|
import Ecto.Changeset
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Bookmark
|
||||||
|
alias Pleroma.FlakeId
|
||||||
|
alias Pleroma.Repo
|
||||||
|
alias Pleroma.User
|
||||||
|
|
||||||
|
@type t :: %__MODULE__{}
|
||||||
|
|
||||||
|
schema "bookmarks" do
|
||||||
|
belongs_to(:user, User, type: FlakeId)
|
||||||
|
belongs_to(:activity, Activity, type: FlakeId)
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec create(FlakeId.t(), FlakeId.t()) :: {:ok, Bookmark.t()} | {:error, Changeset.t()}
|
||||||
|
def create(user_id, activity_id) do
|
||||||
|
attrs = %{
|
||||||
|
user_id: user_id,
|
||||||
|
activity_id: activity_id
|
||||||
|
}
|
||||||
|
|
||||||
|
%Bookmark{}
|
||||||
|
|> cast(attrs, [:user_id, :activity_id])
|
||||||
|
|> validate_required([:user_id, :activity_id])
|
||||||
|
|> unique_constraint(:activity_id, name: :bookmarks_user_id_activity_id_index)
|
||||||
|
|> Repo.insert()
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec for_user_query(FlakeId.t()) :: Ecto.Query.t()
|
||||||
|
def for_user_query(user_id) do
|
||||||
|
Bookmark
|
||||||
|
|> where(user_id: ^user_id)
|
||||||
|
|> join(:inner, [b], activity in assoc(b, :activity))
|
||||||
|
|> preload([b, a], activity: a)
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec destroy(FlakeId.t(), FlakeId.t()) :: {:ok, Bookmark.t()} | {:error, Changeset.t()}
|
||||||
|
def destroy(user_id, activity_id) do
|
||||||
|
from(b in Bookmark,
|
||||||
|
where: b.user_id == ^user_id,
|
||||||
|
where: b.activity_id == ^activity_id
|
||||||
|
)
|
||||||
|
|> Repo.one()
|
||||||
|
|> Repo.delete()
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,6 +10,7 @@ defmodule Pleroma.User do
|
||||||
|
|
||||||
alias Comeonin.Pbkdf2
|
alias Comeonin.Pbkdf2
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Bookmark
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.Notification
|
alias Pleroma.Notification
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
|
@ -53,8 +54,8 @@ defmodule Pleroma.User do
|
||||||
field(:search_rank, :float, virtual: true)
|
field(:search_rank, :float, virtual: true)
|
||||||
field(:search_type, :integer, virtual: true)
|
field(:search_type, :integer, virtual: true)
|
||||||
field(:tags, {:array, :string}, default: [])
|
field(:tags, {:array, :string}, default: [])
|
||||||
field(:bookmarks, {:array, :string}, default: [])
|
|
||||||
field(:last_refreshed_at, :naive_datetime_usec)
|
field(:last_refreshed_at, :naive_datetime_usec)
|
||||||
|
has_many(:bookmarks, Bookmark)
|
||||||
has_many(:notifications, Notification)
|
has_many(:notifications, Notification)
|
||||||
has_many(:registrations, Registration)
|
has_many(:registrations, Registration)
|
||||||
embeds_one(:info, Pleroma.User.Info)
|
embeds_one(:info, Pleroma.User.Info)
|
||||||
|
@ -1379,22 +1380,6 @@ defp update_tags(%User{} = user, new_tags) do
|
||||||
updated_user
|
updated_user
|
||||||
end
|
end
|
||||||
|
|
||||||
def bookmark(%User{} = user, status_id) do
|
|
||||||
bookmarks = Enum.uniq(user.bookmarks ++ [status_id])
|
|
||||||
update_bookmarks(user, bookmarks)
|
|
||||||
end
|
|
||||||
|
|
||||||
def unbookmark(%User{} = user, status_id) do
|
|
||||||
bookmarks = Enum.uniq(user.bookmarks -- [status_id])
|
|
||||||
update_bookmarks(user, bookmarks)
|
|
||||||
end
|
|
||||||
|
|
||||||
def update_bookmarks(%User{} = user, bookmarks) do
|
|
||||||
user
|
|
||||||
|> change(%{bookmarks: bookmarks})
|
|
||||||
|> update_and_set_cache
|
|
||||||
end
|
|
||||||
|
|
||||||
defp normalize_tags(tags) do
|
defp normalize_tags(tags) do
|
||||||
[tags]
|
[tags]
|
||||||
|> List.flatten()
|
|> List.flatten()
|
||||||
|
|
|
@ -6,6 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Bookmark
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
alias Pleroma.Filter
|
alias Pleroma.Filter
|
||||||
alias Pleroma.Notification
|
alias Pleroma.Notification
|
||||||
|
@ -283,6 +284,8 @@ def home_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|> ActivityPub.contain_timeline(user)
|
|> ActivityPub.contain_timeline(user)
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> add_link_headers(:home_timeline, activities)
|
|> add_link_headers(:home_timeline, activities)
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|
@ -301,6 +304,8 @@ def public_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|> ActivityPub.fetch_public_activities()
|
|> ActivityPub.fetch_public_activities()
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> add_link_headers(:public_timeline, activities, false, %{"local" => local_only})
|
|> add_link_headers(:public_timeline, activities, false, %{"local" => local_only})
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|
@ -308,7 +313,8 @@ def public_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
def user_statuses(%{assigns: %{user: reading_user}} = conn, params) do
|
||||||
with %User{} = user <- User.get_cached_by_id(params["id"]) do
|
with %User{} = user <- User.get_cached_by_id(params["id"]),
|
||||||
|
reading_user <- Repo.preload(reading_user, :bookmarks) do
|
||||||
activities = ActivityPub.fetch_user_activities(user, reading_user, params)
|
activities = ActivityPub.fetch_user_activities(user, reading_user, params)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
@ -335,6 +341,8 @@ def dm_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
|> ActivityPub.fetch_activities_query(params)
|
|> ActivityPub.fetch_activities_query(params)
|
||||||
|> Pagination.fetch_paginated(params)
|
|> Pagination.fetch_paginated(params)
|
||||||
|
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> add_link_headers(:dm_timeline, activities)
|
|> add_link_headers(:dm_timeline, activities)
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|
@ -344,6 +352,8 @@ def dm_timeline(%{assigns: %{user: user}} = conn, params) do
|
||||||
def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
def get_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
|
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
|
||||||
true <- Visibility.visible_for_user?(activity, user) do
|
true <- Visibility.visible_for_user?(activity, user) do
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> try_render("status.json", %{activity: activity, for: user})
|
|> try_render("status.json", %{activity: activity, for: user})
|
||||||
|
@ -493,6 +503,8 @@ def delete_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
|
def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
|
||||||
with {:ok, announce, _activity} <- CommonAPI.repeat(ap_id_or_id, user),
|
with {:ok, announce, _activity} <- CommonAPI.repeat(ap_id_or_id, user),
|
||||||
%Activity{} = announce <- Activity.normalize(announce.data) do
|
%Activity{} = announce <- Activity.normalize(announce.data) do
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> try_render("status.json", %{activity: announce, for: user, as: :activity})
|
|> try_render("status.json", %{activity: announce, for: user, as: :activity})
|
||||||
|
@ -502,6 +514,8 @@ def reblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
|
||||||
def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
|
def unreblog_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
|
||||||
with {:ok, _unannounce, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user),
|
with {:ok, _unannounce, %{data: %{"id" => id}}} <- CommonAPI.unrepeat(ap_id_or_id, user),
|
||||||
%Activity{} = activity <- Activity.get_create_by_object_ap_id_with_object(id) do
|
%Activity{} = activity <- Activity.get_create_by_object_ap_id_with_object(id) do
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
||||||
|
@ -549,10 +563,11 @@ def unpin_status(%{assigns: %{user: user}} = conn, %{"id" => ap_id_or_id}) do
|
||||||
|
|
||||||
def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
|
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
|
||||||
%Object{} = object <- Object.normalize(activity),
|
|
||||||
%User{} = user <- User.get_cached_by_nickname(user.nickname),
|
%User{} = user <- User.get_cached_by_nickname(user.nickname),
|
||||||
true <- Visibility.visible_for_user?(activity, user),
|
true <- Visibility.visible_for_user?(activity, user),
|
||||||
{:ok, user} <- User.bookmark(user, object.data["id"]) do
|
{:ok, _bookmark} <- Bookmark.create(user.id, activity.id) do
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
||||||
|
@ -561,10 +576,11 @@ def bookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
|
|
||||||
def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
def unbookmark_status(%{assigns: %{user: user}} = conn, %{"id" => id}) do
|
||||||
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
|
with %Activity{} = activity <- Activity.get_by_id_with_object(id),
|
||||||
%Object{} = object <- Object.normalize(activity),
|
|
||||||
%User{} = user <- User.get_cached_by_nickname(user.nickname),
|
%User{} = user <- User.get_cached_by_nickname(user.nickname),
|
||||||
true <- Visibility.visible_for_user?(activity, user),
|
true <- Visibility.visible_for_user?(activity, user),
|
||||||
{:ok, user} <- User.unbookmark(user, object.data["id"]) do
|
{:ok, _bookmark} <- Bookmark.destroy(user.id, activity.id) do
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
|> try_render("status.json", %{activity: activity, for: user, as: :activity})
|
||||||
|
@ -1085,6 +1101,8 @@ def favourites(%{assigns: %{user: user}} = conn, params) do
|
||||||
ActivityPub.fetch_activities([], params)
|
ActivityPub.fetch_activities([], params)
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> add_link_headers(:favourites, activities)
|
|> add_link_headers(:favourites, activities)
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|
@ -1128,15 +1146,20 @@ def user_favourites(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def bookmarks(%{assigns: %{user: user}} = conn, _) do
|
def bookmarks(%{assigns: %{user: user}} = conn, params) do
|
||||||
user = User.get_cached_by_id(user.id)
|
user = User.get_cached_by_id(user.id)
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
|
bookmarks =
|
||||||
|
Bookmark.for_user_query(user.id)
|
||||||
|
|> Pagination.fetch_paginated(params)
|
||||||
|
|
||||||
activities =
|
activities =
|
||||||
user.bookmarks
|
bookmarks
|
||||||
|> Enum.map(fn id -> Activity.get_create_by_object_ap_id(id) end)
|
|> Enum.map(fn b -> b.activity end)
|
||||||
|> Enum.reverse()
|
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
|> add_link_headers(:bookmarks, bookmarks)
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> render("index.json", %{activities: activities, for: user, as: :activity})
|
|> render("index.json", %{activities: activities, for: user, as: :activity})
|
||||||
end
|
end
|
||||||
|
@ -1242,6 +1265,8 @@ def list_timeline(%{assigns: %{user: user}} = conn, %{"list_id" => id} = params)
|
||||||
|> ActivityPub.fetch_activities_bounded(following, params)
|
|> ActivityPub.fetch_activities_bounded(following, params)
|
||||||
|> Enum.reverse()
|
|> Enum.reverse()
|
||||||
|
|
||||||
|
user = Repo.preload(user, bookmarks: :activity)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_view(StatusView)
|
|> put_view(StatusView)
|
||||||
|> render("index.json", %{activities: activities, for: user, as: :activity})
|
|> render("index.json", %{activities: activities, for: user, as: :activity})
|
||||||
|
|
|
@ -85,7 +85,12 @@ def render(
|
||||||
|
|
||||||
activity_object = Object.normalize(activity)
|
activity_object = Object.normalize(activity)
|
||||||
favorited = opts[:for] && opts[:for].ap_id in (activity_object.data["likes"] || [])
|
favorited = opts[:for] && opts[:for].ap_id in (activity_object.data["likes"] || [])
|
||||||
bookmarked = opts[:for] && activity_object.data["id"] in opts[:for].bookmarks
|
|
||||||
|
bookmarked =
|
||||||
|
opts[:for] && Ecto.assoc_loaded?(opts[:for].bookmarks) &&
|
||||||
|
Enum.any?(opts[:for].bookmarks, fn b ->
|
||||||
|
b.activity_id == activity.id or b.activity.data["object"]["id"] == object
|
||||||
|
end)
|
||||||
|
|
||||||
mentions =
|
mentions =
|
||||||
activity.recipients
|
activity.recipients
|
||||||
|
@ -148,7 +153,11 @@ def render("status.json", %{activity: %{data: %{"object" => _object}} = activity
|
||||||
|
|
||||||
favorited = opts[:for] && opts[:for].ap_id in (object.data["likes"] || [])
|
favorited = opts[:for] && opts[:for].ap_id in (object.data["likes"] || [])
|
||||||
|
|
||||||
bookmarked = opts[:for] && object.data["id"] in opts[:for].bookmarks
|
bookmarked =
|
||||||
|
opts[:for] && Ecto.assoc_loaded?(opts[:for].bookmarks) &&
|
||||||
|
Enum.any?(opts[:for].bookmarks, fn b ->
|
||||||
|
b.activity_id == activity.id
|
||||||
|
end)
|
||||||
|
|
||||||
attachment_data = object.data["attachment"] || []
|
attachment_data = object.data["attachment"] || []
|
||||||
attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment)
|
attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment)
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.CreateBookmarks do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
create table(:bookmarks) do
|
||||||
|
add(:user_id, references(:users, type: :uuid, on_delete: :delete_all))
|
||||||
|
add(:activity_id, references(:activities, type: :uuid, on_delete: :delete_all))
|
||||||
|
|
||||||
|
timestamps()
|
||||||
|
end
|
||||||
|
|
||||||
|
create(unique_index(:bookmarks, [:user_id, :activity_id]))
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,29 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.MigrateOldBookmarks do
|
||||||
|
use Ecto.Migration
|
||||||
|
import Ecto.Query
|
||||||
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Bookmark
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
|
|
||||||
|
def change do
|
||||||
|
query =
|
||||||
|
from(u in User,
|
||||||
|
where: u.local == true,
|
||||||
|
where: fragment("array_length(bookmarks, 1)") > 0,
|
||||||
|
select: %{id: u.id, bookmarks: fragment("bookmarks")}
|
||||||
|
)
|
||||||
|
|
||||||
|
Repo.stream(query)
|
||||||
|
|> Enum.each(fn %{id: user_id, bookmarks: bookmarks} ->
|
||||||
|
Enum.each(bookmarks, fn ap_id ->
|
||||||
|
activity = Activity.get_create_by_object_ap_id(ap_id)
|
||||||
|
{:ok, _} = Bookmark.create(user_id, activity.id)
|
||||||
|
end)
|
||||||
|
end)
|
||||||
|
|
||||||
|
alter table(:users) do
|
||||||
|
remove(:bookmarks)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,37 @@
|
||||||
|
defmodule Pleroma.BookmarkTest do
|
||||||
|
use Pleroma.DataCase
|
||||||
|
import Pleroma.Factory
|
||||||
|
alias Pleroma.Bookmark
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
|
|
||||||
|
describe "create/2" do
|
||||||
|
test "with valid params" do
|
||||||
|
user = insert(:user)
|
||||||
|
{:ok, activity} = CommonAPI.post(user, %{"status" => "Some cool information"})
|
||||||
|
{:ok, bookmark} = Bookmark.create(user.id, activity.id)
|
||||||
|
assert bookmark.user_id == user.id
|
||||||
|
assert bookmark.activity_id == activity.id
|
||||||
|
end
|
||||||
|
|
||||||
|
test "with invalid params" do
|
||||||
|
{:error, changeset} = Bookmark.create(nil, "")
|
||||||
|
refute changeset.valid?
|
||||||
|
|
||||||
|
assert changeset.errors == [
|
||||||
|
user_id: {"can't be blank", [validation: :required]},
|
||||||
|
activity_id: {"can't be blank", [validation: :required]}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "destroy/2" do
|
||||||
|
test "with valid params" do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, activity} = CommonAPI.post(user, %{"status" => "Some cool information"})
|
||||||
|
{:ok, _bookmark} = Bookmark.create(user.id, activity.id)
|
||||||
|
|
||||||
|
{:ok, _deleted_bookmark} = Bookmark.destroy(user.id, activity.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1125,33 +1125,6 @@ test "Adds rel=me on linkbacked urls" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "bookmarks" do
|
|
||||||
user = insert(:user)
|
|
||||||
|
|
||||||
{:ok, activity1} =
|
|
||||||
CommonAPI.post(user, %{
|
|
||||||
"status" => "heweoo!"
|
|
||||||
})
|
|
||||||
|
|
||||||
id1 = Object.normalize(activity1).data["id"]
|
|
||||||
|
|
||||||
{:ok, activity2} =
|
|
||||||
CommonAPI.post(user, %{
|
|
||||||
"status" => "heweoo!"
|
|
||||||
})
|
|
||||||
|
|
||||||
id2 = Object.normalize(activity2).data["id"]
|
|
||||||
|
|
||||||
assert {:ok, user_state1} = User.bookmark(user, id1)
|
|
||||||
assert user_state1.bookmarks == [id1]
|
|
||||||
|
|
||||||
assert {:ok, user_state2} = User.unbookmark(user, id1)
|
|
||||||
assert user_state2.bookmarks == []
|
|
||||||
|
|
||||||
assert {:ok, user_state3} = User.bookmark(user, id2)
|
|
||||||
assert user_state3.bookmarks == [id2]
|
|
||||||
end
|
|
||||||
|
|
||||||
test "follower count is updated when a follower is blocked" do
|
test "follower count is updated when a follower is blocked" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
follower = insert(:user)
|
follower = insert(:user)
|
||||||
|
|
|
@ -1022,7 +1022,7 @@ test "reblogged status for another user", %{conn: conn} do
|
||||||
user2 = insert(:user)
|
user2 = insert(:user)
|
||||||
user3 = insert(:user)
|
user3 = insert(:user)
|
||||||
CommonAPI.favorite(activity.id, user2)
|
CommonAPI.favorite(activity.id, user2)
|
||||||
{:ok, user2} = User.bookmark(user2, activity.data["object"]["id"])
|
{:ok, _bookmark} = Pleroma.Bookmark.create(user2.id, activity.id)
|
||||||
{:ok, reblog_activity1, _object} = CommonAPI.repeat(activity.id, user1)
|
{:ok, reblog_activity1, _object} = CommonAPI.repeat(activity.id, user1)
|
||||||
{:ok, _, _object} = CommonAPI.repeat(activity.id, user2)
|
{:ok, _, _object} = CommonAPI.repeat(activity.id, user2)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue