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
					
				
					 10 changed files with 182 additions and 56 deletions
				
			
		| 
						 | 
				
			
			@ -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 Ecto to 3.0.7
 | 
			
		||||
- 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
 | 
			
		||||
- Followers counter not being updated when a follower is blocked
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										53
									
								
								lib/pleroma/bookmark.ex
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								lib/pleroma/bookmark.ex
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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 Pleroma.Activity
 | 
			
		||||
  alias Pleroma.Bookmark
 | 
			
		||||
  alias Pleroma.Formatter
 | 
			
		||||
  alias Pleroma.Notification
 | 
			
		||||
  alias Pleroma.Object
 | 
			
		||||
| 
						 | 
				
			
			@ -53,8 +54,8 @@ defmodule Pleroma.User do
 | 
			
		|||
    field(:search_rank, :float, virtual: true)
 | 
			
		||||
    field(:search_type, :integer, virtual: true)
 | 
			
		||||
    field(:tags, {:array, :string}, default: [])
 | 
			
		||||
    field(:bookmarks, {:array, :string}, default: [])
 | 
			
		||||
    field(:last_refreshed_at, :naive_datetime_usec)
 | 
			
		||||
    has_many(:bookmarks, Bookmark)
 | 
			
		||||
    has_many(:notifications, Notification)
 | 
			
		||||
    has_many(:registrations, Registration)
 | 
			
		||||
    embeds_one(:info, Pleroma.User.Info)
 | 
			
		||||
| 
						 | 
				
			
			@ -1379,22 +1380,6 @@ defp update_tags(%User{} = user, new_tags) do
 | 
			
		|||
    updated_user
 | 
			
		||||
  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
 | 
			
		||||
    [tags]
 | 
			
		||||
    |> List.flatten()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
 | 
			
		|||
  use Pleroma.Web, :controller
 | 
			
		||||
  alias Ecto.Changeset
 | 
			
		||||
  alias Pleroma.Activity
 | 
			
		||||
  alias Pleroma.Bookmark
 | 
			
		||||
  alias Pleroma.Config
 | 
			
		||||
  alias Pleroma.Filter
 | 
			
		||||
  alias Pleroma.Notification
 | 
			
		||||
| 
						 | 
				
			
			@ -283,6 +284,8 @@ def home_timeline(%{assigns: %{user: user}} = conn, params) do
 | 
			
		|||
      |> ActivityPub.contain_timeline(user)
 | 
			
		||||
      |> Enum.reverse()
 | 
			
		||||
 | 
			
		||||
    user = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(:home_timeline, activities)
 | 
			
		||||
    |> put_view(StatusView)
 | 
			
		||||
| 
						 | 
				
			
			@ -301,6 +304,8 @@ def public_timeline(%{assigns: %{user: user}} = conn, params) do
 | 
			
		|||
      |> ActivityPub.fetch_public_activities()
 | 
			
		||||
      |> Enum.reverse()
 | 
			
		||||
 | 
			
		||||
    user = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(:public_timeline, activities, false, %{"local" => local_only})
 | 
			
		||||
    |> put_view(StatusView)
 | 
			
		||||
| 
						 | 
				
			
			@ -308,7 +313,8 @@ def public_timeline(%{assigns: %{user: user}} = conn, params) do
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  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)
 | 
			
		||||
 | 
			
		||||
      conn
 | 
			
		||||
| 
						 | 
				
			
			@ -335,6 +341,8 @@ def dm_timeline(%{assigns: %{user: user}} = conn, params) do
 | 
			
		|||
      |> ActivityPub.fetch_activities_query(params)
 | 
			
		||||
      |> Pagination.fetch_paginated(params)
 | 
			
		||||
 | 
			
		||||
    user = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(:dm_timeline, activities)
 | 
			
		||||
    |> 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
 | 
			
		||||
    with %Activity{} = activity <- Activity.get_by_id_with_object(id),
 | 
			
		||||
         true <- Visibility.visible_for_user?(activity, user) do
 | 
			
		||||
      user = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
      conn
 | 
			
		||||
      |> put_view(StatusView)
 | 
			
		||||
      |> 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
 | 
			
		||||
    with {:ok, announce, _activity} <- CommonAPI.repeat(ap_id_or_id, user),
 | 
			
		||||
         %Activity{} = announce <- Activity.normalize(announce.data) do
 | 
			
		||||
      user = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
      conn
 | 
			
		||||
      |> put_view(StatusView)
 | 
			
		||||
      |> 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
 | 
			
		||||
    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
 | 
			
		||||
      user = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
      conn
 | 
			
		||||
      |> put_view(StatusView)
 | 
			
		||||
      |> 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
 | 
			
		||||
    with %Activity{} = activity <- Activity.get_by_id_with_object(id),
 | 
			
		||||
         %Object{} = object <- Object.normalize(activity),
 | 
			
		||||
         %User{} = user <- User.get_cached_by_nickname(user.nickname),
 | 
			
		||||
         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
 | 
			
		||||
      |> put_view(StatusView)
 | 
			
		||||
      |> 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
 | 
			
		||||
    with %Activity{} = activity <- Activity.get_by_id_with_object(id),
 | 
			
		||||
         %Object{} = object <- Object.normalize(activity),
 | 
			
		||||
         %User{} = user <- User.get_cached_by_nickname(user.nickname),
 | 
			
		||||
         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
 | 
			
		||||
      |> put_view(StatusView)
 | 
			
		||||
      |> 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)
 | 
			
		||||
      |> Enum.reverse()
 | 
			
		||||
 | 
			
		||||
    user = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(:favourites, activities)
 | 
			
		||||
    |> put_view(StatusView)
 | 
			
		||||
| 
						 | 
				
			
			@ -1128,15 +1146,20 @@ def user_favourites(%{assigns: %{user: for_user}} = conn, %{"id" => id} = params
 | 
			
		|||
    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 = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
    bookmarks =
 | 
			
		||||
      Bookmark.for_user_query(user.id)
 | 
			
		||||
      |> Pagination.fetch_paginated(params)
 | 
			
		||||
 | 
			
		||||
    activities =
 | 
			
		||||
      user.bookmarks
 | 
			
		||||
      |> Enum.map(fn id -> Activity.get_create_by_object_ap_id(id) end)
 | 
			
		||||
      |> Enum.reverse()
 | 
			
		||||
      bookmarks
 | 
			
		||||
      |> Enum.map(fn b -> b.activity end)
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> add_link_headers(:bookmarks, bookmarks)
 | 
			
		||||
    |> put_view(StatusView)
 | 
			
		||||
    |> render("index.json", %{activities: activities, for: user, as: :activity})
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -1242,6 +1265,8 @@ def list_timeline(%{assigns: %{user: user}} = conn, %{"list_id" => id} = params)
 | 
			
		|||
        |> ActivityPub.fetch_activities_bounded(following, params)
 | 
			
		||||
        |> Enum.reverse()
 | 
			
		||||
 | 
			
		||||
      user = Repo.preload(user, bookmarks: :activity)
 | 
			
		||||
 | 
			
		||||
      conn
 | 
			
		||||
      |> put_view(StatusView)
 | 
			
		||||
      |> render("index.json", %{activities: activities, for: user, as: :activity})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -85,7 +85,12 @@ def render(
 | 
			
		|||
 | 
			
		||||
    activity_object = Object.normalize(activity)
 | 
			
		||||
    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 =
 | 
			
		||||
      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"] || [])
 | 
			
		||||
 | 
			
		||||
    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"] || []
 | 
			
		||||
    attachments = render_many(attachment_data, StatusView, "attachment.json", as: :attachment)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								priv/repo/migrations/20190413082658_create_bookmarks.exs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								priv/repo/migrations/20190413082658_create_bookmarks.exs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
							
								
								
									
										37
									
								
								test/bookmark_test.exs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								test/bookmark_test.exs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
  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
 | 
			
		||||
    user = insert(:user)
 | 
			
		||||
    follower = insert(:user)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1022,7 +1022,7 @@ test "reblogged status for another user", %{conn: conn} do
 | 
			
		|||
      user2 = insert(:user)
 | 
			
		||||
      user3 = insert(:user)
 | 
			
		||||
      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, _, _object} = CommonAPI.repeat(activity.id, user2)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue