Merge branch '878-activity-object-decoupling-in-tests' into 'develop'
[#878] Refactored assumptions on embedded object presence in tests Closes #878 See merge request pleroma/pleroma!1390
This commit is contained in:
		
						commit
						81f1017b84
					
				
					 17 changed files with 168 additions and 137 deletions
				
			
		| 
						 | 
				
			
			@ -44,7 +44,15 @@ def get_by_ap_id(ap_id) do
 | 
			
		|||
    Repo.one(from(object in Object, where: fragment("(?)->>'id' = ?", object.data, ^ap_id)))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  defp warn_on_no_object_preloaded(ap_id) do
 | 
			
		||||
    "Object.normalize() called without preloaded object (#{ap_id}). Consider preloading the object"
 | 
			
		||||
    |> Logger.debug()
 | 
			
		||||
 | 
			
		||||
    Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}")
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def normalize(_, fetch_remote \\ true, options \\ [])
 | 
			
		||||
 | 
			
		||||
  # If we pass an Activity to Object.normalize(), we can try to use the preloaded object.
 | 
			
		||||
  # Use this whenever possible, especially when walking graphs in an O(N) loop!
 | 
			
		||||
  def normalize(%Object{} = object, _, _), do: object
 | 
			
		||||
| 
						 | 
				
			
			@ -55,25 +63,15 @@ def normalize(%Activity{data: %{"object" => %{"fake" => true} = data}}, _, _) do
 | 
			
		|||
    %Object{id: "pleroma:fake_object_id", data: data}
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # Catch and log Object.normalize() calls where the Activity's child object is not
 | 
			
		||||
  # preloaded.
 | 
			
		||||
  # No preloaded object
 | 
			
		||||
  def normalize(%Activity{data: %{"object" => %{"id" => ap_id}}}, fetch_remote, _) do
 | 
			
		||||
    Logger.debug(
 | 
			
		||||
      "Object.normalize() called without preloaded object (#{ap_id}).  Consider preloading the object!"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}")
 | 
			
		||||
 | 
			
		||||
    warn_on_no_object_preloaded(ap_id)
 | 
			
		||||
    normalize(ap_id, fetch_remote)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  # No preloaded object
 | 
			
		||||
  def normalize(%Activity{data: %{"object" => ap_id}}, fetch_remote, _) do
 | 
			
		||||
    Logger.debug(
 | 
			
		||||
      "Object.normalize() called without preloaded object (#{ap_id}).  Consider preloading the object!"
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}")
 | 
			
		||||
 | 
			
		||||
    warn_on_no_object_preloaded(ap_id)
 | 
			
		||||
    normalize(ap_id, fetch_remote)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ defmodule Pleroma.ActivityTest do
 | 
			
		|||
  use Pleroma.DataCase
 | 
			
		||||
  alias Pleroma.Activity
 | 
			
		||||
  alias Pleroma.Bookmark
 | 
			
		||||
  alias Pleroma.Object
 | 
			
		||||
  alias Pleroma.ThreadMute
 | 
			
		||||
  import Pleroma.Factory
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -18,15 +19,18 @@ test "returns an activity by it's AP id" do
 | 
			
		|||
 | 
			
		||||
  test "returns activities by it's objects AP ids" do
 | 
			
		||||
    activity = insert(:note_activity)
 | 
			
		||||
    [found_activity] = Activity.get_all_create_by_object_ap_id(activity.data["object"]["id"])
 | 
			
		||||
    object_data = Object.normalize(activity).data
 | 
			
		||||
 | 
			
		||||
    [found_activity] = Activity.get_all_create_by_object_ap_id(object_data["id"])
 | 
			
		||||
 | 
			
		||||
    assert activity == found_activity
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "returns the activity that created an object" do
 | 
			
		||||
    activity = insert(:note_activity)
 | 
			
		||||
    object_data = Object.normalize(activity).data
 | 
			
		||||
 | 
			
		||||
    found_activity = Activity.get_create_by_object_ap_id(activity.data["object"]["id"])
 | 
			
		||||
    found_activity = Activity.get_create_by_object_ap_id(object_data["id"])
 | 
			
		||||
 | 
			
		||||
    assert activity == found_activity
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,6 +59,7 @@ test "replying" do
 | 
			
		|||
    another_user = insert(:user)
 | 
			
		||||
 | 
			
		||||
    {:ok, activity} = CommonAPI.post(another_user, %{"status" => "this is a test post"})
 | 
			
		||||
    activity_object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    output =
 | 
			
		||||
      capture_io(fn ->
 | 
			
		||||
| 
						 | 
				
			
			@ -76,8 +77,9 @@ test "replying" do
 | 
			
		|||
      )
 | 
			
		||||
 | 
			
		||||
    assert reply.actor == user.ap_id
 | 
			
		||||
    object = Object.normalize(reply)
 | 
			
		||||
    assert object.data["content"] == "this is a reply"
 | 
			
		||||
    assert object.data["inReplyTo"] == activity.data["object"]
 | 
			
		||||
 | 
			
		||||
    reply_object_data = Object.normalize(reply).data
 | 
			
		||||
    assert reply_object_data["content"] == "this is a reply"
 | 
			
		||||
    assert reply_object_data["inReplyTo"] == activity_object.data["id"]
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,7 @@
 | 
			
		|||
 | 
			
		||||
defmodule Pleroma.Factory do
 | 
			
		||||
  use ExMachina.Ecto, repo: Pleroma.Repo
 | 
			
		||||
  alias Pleroma.Object
 | 
			
		||||
  alias Pleroma.User
 | 
			
		||||
 | 
			
		||||
  def participation_factory do
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +123,7 @@ def note_activity_factory(attrs \\ %{}) do
 | 
			
		|||
      "type" => "Create",
 | 
			
		||||
      "actor" => note.data["actor"],
 | 
			
		||||
      "to" => note.data["to"],
 | 
			
		||||
      "object" => note.data,
 | 
			
		||||
      "object" => note.data["id"],
 | 
			
		||||
      "published" => DateTime.utc_now() |> DateTime.to_iso8601(),
 | 
			
		||||
      "context" => note.data["context"]
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -176,13 +177,14 @@ def announce_activity_factory(attrs \\ %{}) do
 | 
			
		|||
 | 
			
		||||
  def like_activity_factory do
 | 
			
		||||
    note_activity = insert(:note_activity)
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
    user = insert(:user)
 | 
			
		||||
 | 
			
		||||
    data = %{
 | 
			
		||||
      "id" => Pleroma.Web.ActivityPub.Utils.generate_activity_id(),
 | 
			
		||||
      "actor" => user.ap_id,
 | 
			
		||||
      "type" => "Like",
 | 
			
		||||
      "object" => note_activity.data["object"]["id"],
 | 
			
		||||
      "object" => object.data["id"],
 | 
			
		||||
      "published_at" => DateTime.utc_now() |> DateTime.to_iso8601()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -170,7 +170,8 @@ test "it returns 404 for tombstone objects", %{conn: conn} do
 | 
			
		|||
  describe "/object/:uuid/likes" do
 | 
			
		||||
    test "it returns the like activities in a collection", %{conn: conn} do
 | 
			
		||||
      like = insert(:like_activity)
 | 
			
		||||
      uuid = String.split(like.data["object"], "/") |> List.last()
 | 
			
		||||
      like_object_ap_id = Object.normalize(like).data["id"]
 | 
			
		||||
      uuid = String.split(like_object_ap_id, "/") |> List.last()
 | 
			
		||||
 | 
			
		||||
      result =
 | 
			
		||||
        conn
 | 
			
		||||
| 
						 | 
				
			
			@ -309,6 +310,7 @@ test "it rejects reads from other users", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
    test "it returns a note activity in a collection", %{conn: conn} do
 | 
			
		||||
      note_activity = insert(:direct_note_activity)
 | 
			
		||||
      note_object = Object.normalize(note_activity)
 | 
			
		||||
      user = User.get_cached_by_ap_id(hd(note_activity.data["to"]))
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
| 
						 | 
				
			
			@ -317,7 +319,7 @@ test "it returns a note activity in a collection", %{conn: conn} do
 | 
			
		|||
        |> put_req_header("accept", "application/activity+json")
 | 
			
		||||
        |> get("/users/#{user.nickname}/inbox")
 | 
			
		||||
 | 
			
		||||
      assert response(conn, 200) =~ note_activity.data["object"]["content"]
 | 
			
		||||
      assert response(conn, 200) =~ note_object.data["content"]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "it clears `unreachable` federation status of the sender", %{conn: conn, data: data} do
 | 
			
		||||
| 
						 | 
				
			
			@ -395,6 +397,7 @@ test "it will not bomb when there is no activity", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
    test "it returns a note activity in a collection", %{conn: conn} do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      note_object = Object.normalize(note_activity)
 | 
			
		||||
      user = User.get_cached_by_ap_id(note_activity.data["actor"])
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
| 
						 | 
				
			
			@ -402,7 +405,7 @@ test "it returns a note activity in a collection", %{conn: conn} do
 | 
			
		|||
        |> put_req_header("accept", "application/activity+json")
 | 
			
		||||
        |> get("/users/#{user.nickname}/outbox")
 | 
			
		||||
 | 
			
		||||
      assert response(conn, 200) =~ note_activity.data["object"]["content"]
 | 
			
		||||
      assert response(conn, 200) =~ note_object.data["content"]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "it returns an announce activity in a collection", %{conn: conn} do
 | 
			
		||||
| 
						 | 
				
			
			@ -464,12 +467,13 @@ test "it rejects an incoming activity with bogus type", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
    test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      note_object = Object.normalize(note_activity)
 | 
			
		||||
      user = User.get_cached_by_ap_id(note_activity.data["actor"])
 | 
			
		||||
 | 
			
		||||
      data = %{
 | 
			
		||||
        type: "Delete",
 | 
			
		||||
        object: %{
 | 
			
		||||
          id: note_activity.data["object"]["id"]
 | 
			
		||||
          id: note_object.data["id"]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -482,19 +486,19 @@ test "it erects a tombstone when receiving a delete activity", %{conn: conn} do
 | 
			
		|||
      result = json_response(conn, 201)
 | 
			
		||||
      assert Activity.get_by_ap_id(result["id"])
 | 
			
		||||
 | 
			
		||||
      object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
      assert object
 | 
			
		||||
      assert object = Object.get_by_ap_id(note_object.data["id"])
 | 
			
		||||
      assert object.data["type"] == "Tombstone"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    test "it rejects delete activity of object from other actor", %{conn: conn} do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      note_object = Object.normalize(note_activity)
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
 | 
			
		||||
      data = %{
 | 
			
		||||
        type: "Delete",
 | 
			
		||||
        object: %{
 | 
			
		||||
          id: note_activity.data["object"]["id"]
 | 
			
		||||
          id: note_object.data["id"]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -509,12 +513,13 @@ test "it rejects delete activity of object from other actor", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
    test "it increases like count when receiving a like action", %{conn: conn} do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      note_object = Object.normalize(note_activity)
 | 
			
		||||
      user = User.get_cached_by_ap_id(note_activity.data["actor"])
 | 
			
		||||
 | 
			
		||||
      data = %{
 | 
			
		||||
        type: "Like",
 | 
			
		||||
        object: %{
 | 
			
		||||
          id: note_activity.data["object"]["id"]
 | 
			
		||||
          id: note_object.data["id"]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -527,8 +532,7 @@ test "it increases like count when receiving a like action", %{conn: conn} do
 | 
			
		|||
      result = json_response(conn, 201)
 | 
			
		||||
      assert Activity.get_by_ap_id(result["id"])
 | 
			
		||||
 | 
			
		||||
      object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
      assert object
 | 
			
		||||
      assert object = Object.get_by_ap_id(note_object.data["id"])
 | 
			
		||||
      assert object.data["like_count"] == 1
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -254,10 +254,8 @@ test "adds an id to a given object if it lacks one and is a note and inserts it
 | 
			
		|||
      }
 | 
			
		||||
 | 
			
		||||
      {:ok, %Activity{} = activity} = ActivityPub.insert(data)
 | 
			
		||||
      object = Object.normalize(activity.data["object"])
 | 
			
		||||
 | 
			
		||||
      assert object = Object.normalize(activity)
 | 
			
		||||
      assert is_binary(object.data["id"])
 | 
			
		||||
      assert %Object{} = Object.get_by_ap_id(activity.data["object"])
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -659,7 +657,8 @@ test "returns reblogs for users for whom reblogs have not been muted" do
 | 
			
		|||
  describe "like an object" do
 | 
			
		||||
    test "adds a like activity to the db" do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
      assert object = Object.normalize(note_activity)
 | 
			
		||||
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
      user_two = insert(:user)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -678,19 +677,23 @@ test "adds a like activity to the db" do
 | 
			
		|||
 | 
			
		||||
      assert like_activity == same_like_activity
 | 
			
		||||
      assert object.data["likes"] == [user.ap_id]
 | 
			
		||||
      assert object.data["like_count"] == 1
 | 
			
		||||
 | 
			
		||||
      [note_activity] = Activity.get_all_create_by_object_ap_id(object.data["id"])
 | 
			
		||||
      assert note_activity.data["object"]["like_count"] == 1
 | 
			
		||||
 | 
			
		||||
      {:ok, _like_activity, object} = ActivityPub.like(user_two, object)
 | 
			
		||||
      assert object.data["like_count"] == 2
 | 
			
		||||
 | 
			
		||||
      [note_activity] = Activity.get_all_create_by_object_ap_id(object.data["id"])
 | 
			
		||||
      assert note_activity.data["object"]["like_count"] == 2
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "unliking" do
 | 
			
		||||
    test "unliking a previously liked object" do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
      object = Object.normalize(note_activity)
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
 | 
			
		||||
      # Unliking something that hasn't been liked does nothing
 | 
			
		||||
| 
						 | 
				
			
			@ -710,7 +713,7 @@ test "unliking a previously liked object" do
 | 
			
		|||
  describe "announcing an object" do
 | 
			
		||||
    test "adds an announce activity to the db" do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
      object = Object.normalize(note_activity)
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
 | 
			
		||||
      {:ok, announce_activity, object} = ActivityPub.announce(user, object)
 | 
			
		||||
| 
						 | 
				
			
			@ -731,7 +734,7 @@ test "adds an announce activity to the db" do
 | 
			
		|||
  describe "unannouncing an object" do
 | 
			
		||||
    test "unannouncing a previously announced object" do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
      object = Object.normalize(note_activity)
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
 | 
			
		||||
      # Unannouncing an object that is not announced does nothing
 | 
			
		||||
| 
						 | 
				
			
			@ -810,10 +813,11 @@ test "creates an undo activity for the last follow" do
 | 
			
		|||
      assert activity.data["type"] == "Undo"
 | 
			
		||||
      assert activity.data["actor"] == follower.ap_id
 | 
			
		||||
 | 
			
		||||
      assert is_map(activity.data["object"])
 | 
			
		||||
      assert activity.data["object"]["type"] == "Follow"
 | 
			
		||||
      assert activity.data["object"]["object"] == followed.ap_id
 | 
			
		||||
      assert activity.data["object"]["id"] == follow_activity.data["id"]
 | 
			
		||||
      embedded_object = activity.data["object"]
 | 
			
		||||
      assert is_map(embedded_object)
 | 
			
		||||
      assert embedded_object["type"] == "Follow"
 | 
			
		||||
      assert embedded_object["object"] == followed.ap_id
 | 
			
		||||
      assert embedded_object["id"] == follow_activity.data["id"]
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -839,22 +843,23 @@ test "creates an undo activity for the last block" do
 | 
			
		|||
      assert activity.data["type"] == "Undo"
 | 
			
		||||
      assert activity.data["actor"] == blocker.ap_id
 | 
			
		||||
 | 
			
		||||
      assert is_map(activity.data["object"])
 | 
			
		||||
      assert activity.data["object"]["type"] == "Block"
 | 
			
		||||
      assert activity.data["object"]["object"] == blocked.ap_id
 | 
			
		||||
      assert activity.data["object"]["id"] == block_activity.data["id"]
 | 
			
		||||
      embedded_object = activity.data["object"]
 | 
			
		||||
      assert is_map(embedded_object)
 | 
			
		||||
      assert embedded_object["type"] == "Block"
 | 
			
		||||
      assert embedded_object["object"] == blocked.ap_id
 | 
			
		||||
      assert embedded_object["id"] == block_activity.data["id"]
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  describe "deletion" do
 | 
			
		||||
    test "it creates a delete activity and deletes the original object" do
 | 
			
		||||
      note = insert(:note_activity)
 | 
			
		||||
      object = Object.get_by_ap_id(note.data["object"]["id"])
 | 
			
		||||
      object = Object.normalize(note)
 | 
			
		||||
      {:ok, delete} = ActivityPub.delete(object)
 | 
			
		||||
 | 
			
		||||
      assert delete.data["type"] == "Delete"
 | 
			
		||||
      assert delete.data["actor"] == note.data["actor"]
 | 
			
		||||
      assert delete.data["object"] == note.data["object"]["id"]
 | 
			
		||||
      assert delete.data["object"] == object.data["id"]
 | 
			
		||||
 | 
			
		||||
      assert Activity.get_by_id(delete.id) != nil
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -900,13 +905,14 @@ test "decrements user note count only for public activities" do
 | 
			
		|||
    test "it creates a delete activity and checks that it is also sent to users mentioned by the deleted object" do
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
      note = insert(:note_activity)
 | 
			
		||||
      object = Object.normalize(note)
 | 
			
		||||
 | 
			
		||||
      {:ok, object} =
 | 
			
		||||
        Object.get_by_ap_id(note.data["object"]["id"])
 | 
			
		||||
        object
 | 
			
		||||
        |> Object.change(%{
 | 
			
		||||
          data: %{
 | 
			
		||||
            "actor" => note.data["object"]["actor"],
 | 
			
		||||
            "id" => note.data["object"]["id"],
 | 
			
		||||
            "actor" => object.data["actor"],
 | 
			
		||||
            "id" => object.data["id"],
 | 
			
		||||
            "to" => [user.ap_id],
 | 
			
		||||
            "type" => "Note"
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -1018,8 +1024,9 @@ test "it creates an update activity with the new user data" do
 | 
			
		|||
 | 
			
		||||
      assert update.data["actor"] == user.ap_id
 | 
			
		||||
      assert update.data["to"] == [user.follower_address]
 | 
			
		||||
      assert update.data["object"]["id"] == user_data["id"]
 | 
			
		||||
      assert update.data["object"]["type"] == user_data["type"]
 | 
			
		||||
      assert embedded_object = update.data["object"]
 | 
			
		||||
      assert embedded_object["id"] == user_data["id"]
 | 
			
		||||
      assert embedded_object["type"] == user_data["type"]
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ test "it ignores an incoming notice if we already have it" do
 | 
			
		|||
      data =
 | 
			
		||||
        File.read!("test/fixtures/mastodon-post-activity.json")
 | 
			
		||||
        |> Poison.decode!()
 | 
			
		||||
        |> Map.put("object", activity.data["object"])
 | 
			
		||||
        |> Map.put("object", Object.normalize(activity).data)
 | 
			
		||||
 | 
			
		||||
      {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -49,8 +49,7 @@ test "it fetches replied-to activities if we don't have them" do
 | 
			
		|||
 | 
			
		||||
      data = Map.put(data, "object", object)
 | 
			
		||||
      {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
 | 
			
		||||
 | 
			
		||||
      returned_object = Object.normalize(returned_activity.data["object"], false)
 | 
			
		||||
      returned_object = Object.normalize(returned_activity, false)
 | 
			
		||||
 | 
			
		||||
      assert activity =
 | 
			
		||||
               Activity.get_create_by_object_ap_id(
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +74,7 @@ test "it does not fetch replied-to activities beyond max_replies_depth" do
 | 
			
		|||
        allowed_incoming_reply_depth?: fn _ -> false end do
 | 
			
		||||
        {:ok, returned_activity} = Transmogrifier.handle_incoming(data)
 | 
			
		||||
 | 
			
		||||
        returned_object = Object.normalize(returned_activity.data["object"], false)
 | 
			
		||||
        returned_object = Object.normalize(returned_activity, false)
 | 
			
		||||
 | 
			
		||||
        refute Activity.get_create_by_object_ap_id(
 | 
			
		||||
                 "tag:shitposter.club,2017-05-05:noticeId=2827873:objectType=comment"
 | 
			
		||||
| 
						 | 
				
			
			@ -124,25 +123,27 @@ test "it works for incoming notices" do
 | 
			
		|||
 | 
			
		||||
      assert data["actor"] == "http://mastodon.example.org/users/admin"
 | 
			
		||||
 | 
			
		||||
      object = Object.normalize(data["object"]).data
 | 
			
		||||
      assert object["id"] == "http://mastodon.example.org/users/admin/statuses/99512778738411822"
 | 
			
		||||
      object_data = Object.normalize(data["object"]).data
 | 
			
		||||
 | 
			
		||||
      assert object["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
 | 
			
		||||
      assert object_data["id"] ==
 | 
			
		||||
               "http://mastodon.example.org/users/admin/statuses/99512778738411822"
 | 
			
		||||
 | 
			
		||||
      assert object["cc"] == [
 | 
			
		||||
      assert object_data["to"] == ["https://www.w3.org/ns/activitystreams#Public"]
 | 
			
		||||
 | 
			
		||||
      assert object_data["cc"] == [
 | 
			
		||||
               "http://mastodon.example.org/users/admin/followers",
 | 
			
		||||
               "http://localtesting.pleroma.lol/users/lain"
 | 
			
		||||
             ]
 | 
			
		||||
 | 
			
		||||
      assert object["actor"] == "http://mastodon.example.org/users/admin"
 | 
			
		||||
      assert object["attributedTo"] == "http://mastodon.example.org/users/admin"
 | 
			
		||||
      assert object_data["actor"] == "http://mastodon.example.org/users/admin"
 | 
			
		||||
      assert object_data["attributedTo"] == "http://mastodon.example.org/users/admin"
 | 
			
		||||
 | 
			
		||||
      assert object["context"] ==
 | 
			
		||||
      assert object_data["context"] ==
 | 
			
		||||
               "tag:mastodon.example.org,2018-02-12:objectId=20:objectType=Conversation"
 | 
			
		||||
 | 
			
		||||
      assert object["sensitive"] == true
 | 
			
		||||
      assert object_data["sensitive"] == true
 | 
			
		||||
 | 
			
		||||
      user = User.get_cached_by_ap_id(object["actor"])
 | 
			
		||||
      user = User.get_cached_by_ap_id(object_data["actor"])
 | 
			
		||||
 | 
			
		||||
      assert user.info.note_count == 1
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -573,10 +574,11 @@ test "it works for incoming unannounces with an existing notice" do
 | 
			
		|||
      {:ok, %Activity{data: data, local: false}} = Transmogrifier.handle_incoming(data)
 | 
			
		||||
 | 
			
		||||
      assert data["type"] == "Undo"
 | 
			
		||||
      assert data["object"]["type"] == "Announce"
 | 
			
		||||
      assert data["object"]["object"] == activity.data["object"]
 | 
			
		||||
      assert object_data = data["object"]
 | 
			
		||||
      assert object_data["type"] == "Announce"
 | 
			
		||||
      assert object_data["object"] == activity.data["object"]
 | 
			
		||||
 | 
			
		||||
      assert data["object"]["id"] ==
 | 
			
		||||
      assert object_data["id"] ==
 | 
			
		||||
               "http://mastodon.example.org/users/admin/statuses/99542391527669785/activity"
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -886,7 +888,7 @@ test "it accepts Flag activities" do
 | 
			
		|||
      other_user = insert(:user)
 | 
			
		||||
 | 
			
		||||
      {:ok, activity} = CommonAPI.post(user, %{"status" => "test post"})
 | 
			
		||||
      object = Object.normalize(activity.data["object"])
 | 
			
		||||
      object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
      message = %{
 | 
			
		||||
        "@context" => "https://www.w3.org/ns/activitystreams",
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectViewTest do
 | 
			
		|||
  use Pleroma.DataCase
 | 
			
		||||
  import Pleroma.Factory
 | 
			
		||||
 | 
			
		||||
  alias Pleroma.Object
 | 
			
		||||
  alias Pleroma.Web.ActivityPub.ObjectView
 | 
			
		||||
  alias Pleroma.Web.CommonAPI
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -19,19 +20,21 @@ test "renders a note object" do
 | 
			
		|||
 | 
			
		||||
  test "renders a note activity" do
 | 
			
		||||
    note = insert(:note_activity)
 | 
			
		||||
    object = Object.normalize(note)
 | 
			
		||||
 | 
			
		||||
    result = ObjectView.render("object.json", %{object: note})
 | 
			
		||||
 | 
			
		||||
    assert result["id"] == note.data["id"]
 | 
			
		||||
    assert result["to"] == note.data["to"]
 | 
			
		||||
    assert result["object"]["type"] == "Note"
 | 
			
		||||
    assert result["object"]["content"] == note.data["object"]["content"]
 | 
			
		||||
    assert result["object"]["content"] == object.data["content"]
 | 
			
		||||
    assert result["type"] == "Create"
 | 
			
		||||
    assert result["@context"]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "renders a like activity" do
 | 
			
		||||
    note = insert(:note_activity)
 | 
			
		||||
    object = Object.normalize(note)
 | 
			
		||||
    user = insert(:user)
 | 
			
		||||
 | 
			
		||||
    {:ok, like_activity, _} = CommonAPI.favorite(note.id, user)
 | 
			
		||||
| 
						 | 
				
			
			@ -39,12 +42,13 @@ test "renders a like activity" do
 | 
			
		|||
    result = ObjectView.render("object.json", %{object: like_activity})
 | 
			
		||||
 | 
			
		||||
    assert result["id"] == like_activity.data["id"]
 | 
			
		||||
    assert result["object"] == note.data["object"]["id"]
 | 
			
		||||
    assert result["object"] == object.data["id"]
 | 
			
		||||
    assert result["type"] == "Like"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "renders an announce activity" do
 | 
			
		||||
    note = insert(:note_activity)
 | 
			
		||||
    object = Object.normalize(note)
 | 
			
		||||
    user = insert(:user)
 | 
			
		||||
 | 
			
		||||
    {:ok, announce_activity, _} = CommonAPI.repeat(note.id, user)
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +56,7 @@ test "renders an announce activity" do
 | 
			
		|||
    result = ObjectView.render("object.json", %{object: announce_activity})
 | 
			
		||||
 | 
			
		||||
    assert result["id"] == announce_activity.data["id"]
 | 
			
		||||
    assert result["object"] == note.data["object"]["id"]
 | 
			
		||||
    assert result["object"] == object.data["id"]
 | 
			
		||||
    assert result["type"] == "Announce"
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,7 @@ test "it de-duplicates tags" do
 | 
			
		|||
    user = insert(:user)
 | 
			
		||||
    {:ok, activity} = CommonAPI.post(user, %{"status" => "#2hu #2HU"})
 | 
			
		||||
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    assert object.data["tag"] == ["2hu"]
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -87,7 +87,7 @@ test "it filters out obviously bad tags when accepting a post as HTML" do
 | 
			
		|||
          "content_type" => "text/html"
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
      object = Object.normalize(activity.data["object"])
 | 
			
		||||
      object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
      assert object.data["content"] == "<p><b>2hu</b></p>alert('xss')"
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +103,7 @@ test "it filters out obviously bad tags when accepting a post as Markdown" do
 | 
			
		|||
          "content_type" => "text/markdown"
 | 
			
		||||
        })
 | 
			
		||||
 | 
			
		||||
      object = Object.normalize(activity.data["object"])
 | 
			
		||||
      object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
      assert object.data["content"] == "<p><b>2hu</b></p>alert('xss')"
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,7 +55,7 @@ test "tries to get a user by nickname if fetching by ap_id doesn't work" do
 | 
			
		|||
 | 
			
		||||
  test "a note with null content" do
 | 
			
		||||
    note = insert(:note_activity)
 | 
			
		||||
    note_object = Object.normalize(note.data["object"])
 | 
			
		||||
    note_object = Object.normalize(note)
 | 
			
		||||
 | 
			
		||||
    data =
 | 
			
		||||
      note_object.data
 | 
			
		||||
| 
						 | 
				
			
			@ -73,26 +73,27 @@ test "a note with null content" do
 | 
			
		|||
 | 
			
		||||
  test "a note activity" do
 | 
			
		||||
    note = insert(:note_activity)
 | 
			
		||||
    object_data = Object.normalize(note).data
 | 
			
		||||
    user = User.get_cached_by_ap_id(note.data["actor"])
 | 
			
		||||
 | 
			
		||||
    convo_id = Utils.context_to_conversation_id(note.data["object"]["context"])
 | 
			
		||||
    convo_id = Utils.context_to_conversation_id(object_data["context"])
 | 
			
		||||
 | 
			
		||||
    status = StatusView.render("status.json", %{activity: note})
 | 
			
		||||
 | 
			
		||||
    created_at =
 | 
			
		||||
      (note.data["object"]["published"] || "")
 | 
			
		||||
      (object_data["published"] || "")
 | 
			
		||||
      |> String.replace(~r/\.\d+Z/, ".000Z")
 | 
			
		||||
 | 
			
		||||
    expected = %{
 | 
			
		||||
      id: to_string(note.id),
 | 
			
		||||
      uri: note.data["object"]["id"],
 | 
			
		||||
      uri: object_data["id"],
 | 
			
		||||
      url: Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, note),
 | 
			
		||||
      account: AccountView.render("account.json", %{user: user}),
 | 
			
		||||
      in_reply_to_id: nil,
 | 
			
		||||
      in_reply_to_account_id: nil,
 | 
			
		||||
      card: nil,
 | 
			
		||||
      reblog: nil,
 | 
			
		||||
      content: HtmlSanitizeEx.basic_html(note.data["object"]["content"]),
 | 
			
		||||
      content: HtmlSanitizeEx.basic_html(object_data["content"]),
 | 
			
		||||
      created_at: created_at,
 | 
			
		||||
      reblogs_count: 0,
 | 
			
		||||
      replies_count: 0,
 | 
			
		||||
| 
						 | 
				
			
			@ -104,14 +105,14 @@ test "a note activity" do
 | 
			
		|||
      pinned: false,
 | 
			
		||||
      sensitive: false,
 | 
			
		||||
      poll: nil,
 | 
			
		||||
      spoiler_text: HtmlSanitizeEx.basic_html(note.data["object"]["summary"]),
 | 
			
		||||
      spoiler_text: HtmlSanitizeEx.basic_html(object_data["summary"]),
 | 
			
		||||
      visibility: "public",
 | 
			
		||||
      media_attachments: [],
 | 
			
		||||
      mentions: [],
 | 
			
		||||
      tags: [
 | 
			
		||||
        %{
 | 
			
		||||
          name: "#{note.data["object"]["tag"]}",
 | 
			
		||||
          url: "/tag/#{note.data["object"]["tag"]}"
 | 
			
		||||
          name: "#{object_data["tag"]}",
 | 
			
		||||
          url: "/tag/#{object_data["tag"]}"
 | 
			
		||||
        }
 | 
			
		||||
      ],
 | 
			
		||||
      application: %{
 | 
			
		||||
| 
						 | 
				
			
			@ -131,8 +132,8 @@ test "a note activity" do
 | 
			
		|||
        local: true,
 | 
			
		||||
        conversation_id: convo_id,
 | 
			
		||||
        in_reply_to_account_acct: nil,
 | 
			
		||||
        content: %{"text/plain" => HtmlSanitizeEx.strip_tags(note.data["object"]["content"])},
 | 
			
		||||
        spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(note.data["object"]["summary"])}
 | 
			
		||||
        content: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["content"])},
 | 
			
		||||
        spoiler_text: %{"text/plain" => HtmlSanitizeEx.strip_tags(object_data["summary"])}
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,22 +38,23 @@ test "an external note activity" do
 | 
			
		|||
 | 
			
		||||
  test "a note activity" do
 | 
			
		||||
    note_activity = insert(:note_activity)
 | 
			
		||||
    object_data = Object.normalize(note_activity).data
 | 
			
		||||
 | 
			
		||||
    user = User.get_cached_by_ap_id(note_activity.data["actor"])
 | 
			
		||||
 | 
			
		||||
    expected = """
 | 
			
		||||
    <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
 | 
			
		||||
    <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
 | 
			
		||||
    <id>#{note_activity.data["object"]["id"]}</id>
 | 
			
		||||
    <id>#{object_data["id"]}</id>
 | 
			
		||||
    <title>New note by #{user.nickname}</title>
 | 
			
		||||
    <content type="html">#{note_activity.data["object"]["content"]}</content>
 | 
			
		||||
    <published>#{note_activity.data["object"]["published"]}</published>
 | 
			
		||||
    <updated>#{note_activity.data["object"]["published"]}</updated>
 | 
			
		||||
    <content type="html">#{object_data["content"]}</content>
 | 
			
		||||
    <published>#{object_data["published"]}</published>
 | 
			
		||||
    <updated>#{object_data["published"]}</updated>
 | 
			
		||||
    <ostatus:conversation ref="#{note_activity.data["context"]}">#{note_activity.data["context"]}</ostatus:conversation>
 | 
			
		||||
    <link ref="#{note_activity.data["context"]}" rel="ostatus:conversation" />
 | 
			
		||||
    <summary>#{note_activity.data["object"]["summary"]}</summary>
 | 
			
		||||
    <link type="application/atom+xml" href="#{note_activity.data["object"]["id"]}" rel="self" />
 | 
			
		||||
    <link type="text/html" href="#{note_activity.data["object"]["id"]}" rel="alternate" />
 | 
			
		||||
    <summary>#{object_data["summary"]}</summary>
 | 
			
		||||
    <link type="application/atom+xml" href="#{object_data["id"]}" rel="self" />
 | 
			
		||||
    <link type="text/html" href="#{object_data["id"]}" rel="alternate" />
 | 
			
		||||
    <category term="2hu"/>
 | 
			
		||||
    <link rel="mentioned" ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" href="http://activityschema.org/collection/public"/>
 | 
			
		||||
    <link name="2hu" rel="emoji" href="corndog.png" />
 | 
			
		||||
| 
						 | 
				
			
			@ -106,7 +107,7 @@ test "a reply note" do
 | 
			
		|||
  test "an announce activity" do
 | 
			
		||||
    note = insert(:note_activity)
 | 
			
		||||
    user = insert(:user)
 | 
			
		||||
    object = Object.get_cached_by_ap_id(note.data["object"]["id"])
 | 
			
		||||
    object = Object.normalize(note)
 | 
			
		||||
 | 
			
		||||
    {:ok, announce, _object} = ActivityPub.announce(user, object)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -125,7 +126,7 @@ test "an announce activity" do
 | 
			
		|||
    <activity:verb>http://activitystrea.ms/schema/1.0/share</activity:verb>
 | 
			
		||||
    <id>#{announce.data["id"]}</id>
 | 
			
		||||
    <title>#{user.nickname} repeated a notice</title>
 | 
			
		||||
    <content type="html">RT #{note.data["object"]["content"]}</content>
 | 
			
		||||
    <content type="html">RT #{object.data["content"]}</content>
 | 
			
		||||
    <published>#{announce.data["published"]}</published>
 | 
			
		||||
    <updated>#{announce.data["published"]}</updated>
 | 
			
		||||
    <ostatus:conversation ref="#{announce.data["context"]}">#{announce.data["context"]}</ostatus:conversation>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,8 +17,9 @@ defmodule Pleroma.Web.OStatus.DeleteHandlingTest do
 | 
			
		|||
    test "it removes the mentioned activity" do
 | 
			
		||||
      note = insert(:note_activity)
 | 
			
		||||
      second_note = insert(:note_activity)
 | 
			
		||||
      object = Object.normalize(note)
 | 
			
		||||
      second_object = Object.normalize(second_note)
 | 
			
		||||
      user = insert(:user)
 | 
			
		||||
      object = Object.get_by_ap_id(note.data["object"]["id"])
 | 
			
		||||
 | 
			
		||||
      {:ok, like, _object} = Pleroma.Web.ActivityPub.ActivityPub.like(user, object)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -26,16 +27,16 @@ test "it removes the mentioned activity" do
 | 
			
		|||
        File.read!("test/fixtures/delete.xml")
 | 
			
		||||
        |> String.replace(
 | 
			
		||||
          "tag:mastodon.sdf.org,2017-06-10:objectId=310513:objectType=Status",
 | 
			
		||||
          note.data["object"]["id"]
 | 
			
		||||
          object.data["id"]
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
      {:ok, [delete]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
 | 
			
		||||
      refute Activity.get_by_id(note.id)
 | 
			
		||||
      refute Activity.get_by_id(like.id)
 | 
			
		||||
      assert Object.get_by_ap_id(note.data["object"]["id"]).data["type"] == "Tombstone"
 | 
			
		||||
      assert Object.get_by_ap_id(object.data["id"]).data["type"] == "Tombstone"
 | 
			
		||||
      assert Activity.get_by_id(second_note.id)
 | 
			
		||||
      assert Object.get_by_ap_id(second_note.data["object"]["id"])
 | 
			
		||||
      assert Object.get_by_ap_id(second_object.data["id"])
 | 
			
		||||
 | 
			
		||||
      assert delete.data["type"] == "Delete"
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,6 +72,7 @@ test "decodes a salmon with a changed magic key", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
  test "gets a feed", %{conn: conn} do
 | 
			
		||||
    note_activity = insert(:note_activity)
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
    user = User.get_cached_by_ap_id(note_activity.data["actor"])
 | 
			
		||||
 | 
			
		||||
    conn =
 | 
			
		||||
| 
						 | 
				
			
			@ -79,7 +80,7 @@ test "gets a feed", %{conn: conn} do
 | 
			
		|||
      |> put_req_header("content-type", "application/atom+xml")
 | 
			
		||||
      |> get("/users/#{user.nickname}/feed.atom")
 | 
			
		||||
 | 
			
		||||
    assert response(conn, 200) =~ note_activity.data["object"]["content"]
 | 
			
		||||
    assert response(conn, 200) =~ object.data["content"]
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "returns 404 for a missing feed", %{conn: conn} do
 | 
			
		||||
| 
						 | 
				
			
			@ -93,8 +94,9 @@ test "returns 404 for a missing feed", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
  test "gets an object", %{conn: conn} do
 | 
			
		||||
    note_activity = insert(:note_activity)
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
    user = User.get_cached_by_ap_id(note_activity.data["actor"])
 | 
			
		||||
    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["object"]["id"]))
 | 
			
		||||
    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
 | 
			
		||||
    url = "/objects/#{uuid}"
 | 
			
		||||
 | 
			
		||||
    conn =
 | 
			
		||||
| 
						 | 
				
			
			@ -113,7 +115,8 @@ test "gets an object", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
  test "404s on private objects", %{conn: conn} do
 | 
			
		||||
    note_activity = insert(:direct_note_activity)
 | 
			
		||||
    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["object"]["id"]))
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> get("/objects/#{uuid}")
 | 
			
		||||
| 
						 | 
				
			
			@ -138,8 +141,8 @@ test "gets an activity in xml format", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
  test "404s on deleted objects", %{conn: conn} do
 | 
			
		||||
    note_activity = insert(:note_activity)
 | 
			
		||||
    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, note_activity.data["object"]["id"]))
 | 
			
		||||
    object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
    [_, uuid] = hd(Regex.scan(~r/.+\/([\w-]+)$/, object.data["id"]))
 | 
			
		||||
 | 
			
		||||
    conn
 | 
			
		||||
    |> put_req_header("accept", "application/xml")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,7 @@ test "don't insert create notes twice" do
 | 
			
		|||
  test "handle incoming note - GS, Salmon" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/incoming_note_activity.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    user = User.get_cached_by_ap_id(activity.data["actor"])
 | 
			
		||||
    assert user.info.note_count == 1
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +53,7 @@ test "handle incoming note - GS, Salmon" do
 | 
			
		|||
  test "handle incoming notes - GS, subscription" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/ostatus_incoming_post.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Create"
 | 
			
		||||
    assert object.data["type"] == "Note"
 | 
			
		||||
| 
						 | 
				
			
			@ -67,7 +67,7 @@ test "handle incoming notes - GS, subscription" do
 | 
			
		|||
  test "handle incoming notes with attachments - GS, subscription" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/incoming_websub_gnusocial_attachments.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Create"
 | 
			
		||||
    assert object.data["type"] == "Note"
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +80,7 @@ test "handle incoming notes with attachments - GS, subscription" do
 | 
			
		|||
  test "handle incoming notes with tags" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/ostatus_incoming_post_tag.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    assert object.data["tag"] == ["nsfw"]
 | 
			
		||||
    assert "https://www.w3.org/ns/activitystreams#Public" in activity.data["to"]
 | 
			
		||||
| 
						 | 
				
			
			@ -97,7 +97,7 @@ test "handle incoming notes - Mastodon, salmon, reply" do
 | 
			
		|||
 | 
			
		||||
    incoming = File.read!("test/fixtures/incoming_reply_mastodon.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Create"
 | 
			
		||||
    assert object.data["type"] == "Note"
 | 
			
		||||
| 
						 | 
				
			
			@ -109,7 +109,7 @@ test "handle incoming notes - Mastodon, salmon, reply" do
 | 
			
		|||
  test "handle incoming notes - Mastodon, with CW" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/mastodon-note-cw.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Create"
 | 
			
		||||
    assert object.data["type"] == "Note"
 | 
			
		||||
| 
						 | 
				
			
			@ -121,7 +121,7 @@ test "handle incoming notes - Mastodon, with CW" do
 | 
			
		|||
  test "handle incoming unlisted messages, put public into cc" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/mastodon-note-unlisted.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    refute "https://www.w3.org/ns/activitystreams#Public" in activity.data["to"]
 | 
			
		||||
    assert "https://www.w3.org/ns/activitystreams#Public" in activity.data["cc"]
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ test "handle incoming unlisted messages, put public into cc" do
 | 
			
		|||
  test "handle incoming retweets - Mastodon, with CW" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/cw_retweet.xml")
 | 
			
		||||
    {:ok, [[_activity, retweeted_activity]]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    retweeted_object = Object.normalize(retweeted_activity.data["object"])
 | 
			
		||||
    retweeted_object = Object.normalize(retweeted_activity)
 | 
			
		||||
 | 
			
		||||
    assert retweeted_object.data["summary"] == "Hey."
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -140,7 +140,7 @@ test "handle incoming retweets - Mastodon, with CW" do
 | 
			
		|||
  test "handle incoming notes - GS, subscription, reply" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/ostatus_incoming_reply.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Create"
 | 
			
		||||
    assert object.data["type"] == "Note"
 | 
			
		||||
| 
						 | 
				
			
			@ -166,7 +166,7 @@ test "handle incoming retweets - GS, subscription" do
 | 
			
		|||
    refute activity.local
 | 
			
		||||
 | 
			
		||||
    retweeted_activity = Activity.get_by_id(retweeted_activity.id)
 | 
			
		||||
    retweeted_object = Object.normalize(retweeted_activity.data["object"])
 | 
			
		||||
    retweeted_object = Object.normalize(retweeted_activity)
 | 
			
		||||
    assert retweeted_activity.data["type"] == "Create"
 | 
			
		||||
    assert retweeted_activity.data["actor"] == "https://pleroma.soykaf.com/users/lain"
 | 
			
		||||
    refute retweeted_activity.local
 | 
			
		||||
| 
						 | 
				
			
			@ -178,18 +178,19 @@ test "handle incoming retweets - GS, subscription" do
 | 
			
		|||
  test "handle incoming retweets - GS, subscription - local message" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/share-gs-local.xml")
 | 
			
		||||
    note_activity = insert(:note_activity)
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
    user = User.get_cached_by_ap_id(note_activity.data["actor"])
 | 
			
		||||
 | 
			
		||||
    incoming =
 | 
			
		||||
      incoming
 | 
			
		||||
      |> String.replace("LOCAL_ID", note_activity.data["object"]["id"])
 | 
			
		||||
      |> String.replace("LOCAL_ID", object.data["id"])
 | 
			
		||||
      |> String.replace("LOCAL_USER", user.ap_id)
 | 
			
		||||
 | 
			
		||||
    {:ok, [[activity, retweeted_activity]]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Announce"
 | 
			
		||||
    assert activity.data["actor"] == "https://social.heldscal.la/user/23211"
 | 
			
		||||
    assert activity.data["object"] == retweeted_activity.data["object"]["id"]
 | 
			
		||||
    assert activity.data["object"] == object.data["id"]
 | 
			
		||||
    assert user.ap_id in activity.data["to"]
 | 
			
		||||
    refute activity.local
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +205,7 @@ test "handle incoming retweets - GS, subscription - local message" do
 | 
			
		|||
  test "handle incoming retweets - Mastodon, salmon" do
 | 
			
		||||
    incoming = File.read!("test/fixtures/share.xml")
 | 
			
		||||
    {:ok, [[activity, retweeted_activity]]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    retweeted_object = Object.normalize(retweeted_activity.data["object"])
 | 
			
		||||
    retweeted_object = Object.normalize(retweeted_activity)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Announce"
 | 
			
		||||
    assert activity.data["actor"] == "https://mastodon.social/users/lambadalambda"
 | 
			
		||||
| 
						 | 
				
			
			@ -253,16 +254,17 @@ test "handle conversation references" do
 | 
			
		|||
 | 
			
		||||
  test "handle incoming favorites with locally available object - GS, websub" do
 | 
			
		||||
    note_activity = insert(:note_activity)
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
 | 
			
		||||
    incoming =
 | 
			
		||||
      File.read!("test/fixtures/favorite_with_local_note.xml")
 | 
			
		||||
      |> String.replace("localid", note_activity.data["object"]["id"])
 | 
			
		||||
      |> String.replace("localid", object.data["id"])
 | 
			
		||||
 | 
			
		||||
    {:ok, [[activity, favorited_activity]]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Like"
 | 
			
		||||
    assert activity.data["actor"] == "https://social.heldscal.la/user/23211"
 | 
			
		||||
    assert activity.data["object"] == favorited_activity.data["object"]["id"]
 | 
			
		||||
    assert activity.data["object"] == object.data["id"]
 | 
			
		||||
    refute activity.local
 | 
			
		||||
    assert note_activity.id == favorited_activity.id
 | 
			
		||||
    assert favorited_activity.local
 | 
			
		||||
| 
						 | 
				
			
			@ -274,7 +276,7 @@ test "handle incoming favorites with locally available object - GS, websub" do
 | 
			
		|||
                 [] do
 | 
			
		||||
    incoming = File.read!("test/fixtures/incoming_note_activity_answer.xml")
 | 
			
		||||
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
    object = Object.normalize(activity.data["object"], false)
 | 
			
		||||
    object = Object.normalize(activity, false)
 | 
			
		||||
 | 
			
		||||
    assert activity.data["type"] == "Create"
 | 
			
		||||
    assert object.data["type"] == "Note"
 | 
			
		||||
| 
						 | 
				
			
			@ -300,7 +302,7 @@ test "handle incoming favorites with locally available object - GS, websub" do
 | 
			
		|||
    with_mock Pleroma.Web.Federator,
 | 
			
		||||
      allowed_incoming_reply_depth?: fn _ -> false end do
 | 
			
		||||
      {:ok, [activity]} = OStatus.handle_incoming(incoming)
 | 
			
		||||
      object = Object.normalize(activity.data["object"], false)
 | 
			
		||||
      object = Object.normalize(activity, false)
 | 
			
		||||
 | 
			
		||||
      refute called(OStatus.fetch_activity_from_url(object.data["inReplyTo"], :_))
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			@ -337,13 +339,14 @@ test "handle incoming unfollows with existing follow" do
 | 
			
		|||
             "undo:tag:social.heldscal.la,2017-05-07:subscription:23211:person:44803:2017-05-07T09:54:48+00:00"
 | 
			
		||||
 | 
			
		||||
    assert activity.data["actor"] == "https://social.heldscal.la/user/23211"
 | 
			
		||||
    assert is_map(activity.data["object"])
 | 
			
		||||
    assert activity.data["object"]["type"] == "Follow"
 | 
			
		||||
    assert activity.data["object"]["object"] == "https://pawoo.net/users/pekorino"
 | 
			
		||||
    embedded_object = activity.data["object"]
 | 
			
		||||
    assert is_map(embedded_object)
 | 
			
		||||
    assert embedded_object["type"] == "Follow"
 | 
			
		||||
    assert embedded_object["object"] == "https://pawoo.net/users/pekorino"
 | 
			
		||||
    refute activity.local
 | 
			
		||||
 | 
			
		||||
    follower = User.get_cached_by_ap_id(activity.data["actor"])
 | 
			
		||||
    followed = User.get_cached_by_ap_id(activity.data["object"]["object"])
 | 
			
		||||
    followed = User.get_cached_by_ap_id(embedded_object["object"])
 | 
			
		||||
 | 
			
		||||
    refute User.following?(follower, followed)
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -560,8 +563,7 @@ test "Note objects are representable" do
 | 
			
		|||
 | 
			
		||||
    test "Article objects are not representable" do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
 | 
			
		||||
      note_object = Object.normalize(note_activity.data["object"])
 | 
			
		||||
      note_object = Object.normalize(note_activity)
 | 
			
		||||
 | 
			
		||||
      note_data =
 | 
			
		||||
        note_object.data
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -929,7 +929,7 @@ test "without valid credentials", %{conn: conn} do
 | 
			
		|||
 | 
			
		||||
    test "with credentials", %{conn: conn, user: current_user} do
 | 
			
		||||
      note_activity = insert(:note_activity)
 | 
			
		||||
      object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
      object = Object.normalize(note_activity)
 | 
			
		||||
      ActivityPub.like(current_user, object)
 | 
			
		||||
 | 
			
		||||
      conn =
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ test "create a status" do
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    {:ok, activity = %Activity{}} = TwitterAPI.create_status(user, input)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    expected_text =
 | 
			
		||||
      "Hello again, <span class='h-card'><a data-user='#{mentioned_user.id}' class='u-url mention' href='shp'>@<span>shp</span></a></span>.<script></script><br>This is on another :firefox: line. <a class='hashtag' data-tag='2hu' href='http://localhost:4001/tag/2hu' rel='tag'>#2hu</a> <a class='hashtag' data-tag='epic' href='http://localhost:4001/tag/epic' rel='tag'>#epic</a> <a class='hashtag' data-tag='phantasmagoric' href='http://localhost:4001/tag/phantasmagoric' rel='tag'>#phantasmagoric</a><br><a href=\"http://example.org/image.jpg\" class='attachment'>image.jpg</a>"
 | 
			
		||||
| 
						 | 
				
			
			@ -91,7 +91,7 @@ test "create a status that is a reply" do
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    {:ok, activity = %Activity{}} = TwitterAPI.create_status(user, input)
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    input = %{
 | 
			
		||||
      "status" => "Here's your (you).",
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ test "create a status that is a reply" do
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    {:ok, reply = %Activity{}} = TwitterAPI.create_status(user, input)
 | 
			
		||||
    reply_object = Object.normalize(reply.data["object"])
 | 
			
		||||
    reply_object = Object.normalize(reply)
 | 
			
		||||
 | 
			
		||||
    assert get_in(reply.data, ["context"]) == get_in(activity.data, ["context"])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -216,7 +216,7 @@ test "it favorites a status, returns the updated activity" do
 | 
			
		|||
    updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
 | 
			
		||||
    assert ActivityView.render("activity.json", %{activity: updated_activity})["fave_num"] == 1
 | 
			
		||||
 | 
			
		||||
    object = Object.normalize(note_activity.data["object"])
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
 | 
			
		||||
    assert object.data["like_count"] == 1
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +224,7 @@ test "it favorites a status, returns the updated activity" do
 | 
			
		|||
 | 
			
		||||
    {:ok, _status} = TwitterAPI.fav(other_user, note_activity.id)
 | 
			
		||||
 | 
			
		||||
    object = Object.normalize(note_activity.data["object"])
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
 | 
			
		||||
    assert object.data["like_count"] == 2
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -235,7 +235,7 @@ test "it favorites a status, returns the updated activity" do
 | 
			
		|||
  test "it unfavorites a status, returns the updated activity" do
 | 
			
		||||
    user = insert(:user)
 | 
			
		||||
    note_activity = insert(:note_activity)
 | 
			
		||||
    object = Object.get_by_ap_id(note_activity.data["object"]["id"])
 | 
			
		||||
    object = Object.normalize(note_activity)
 | 
			
		||||
 | 
			
		||||
    {:ok, _like_activity, _object} = ActivityPub.like(user, object)
 | 
			
		||||
    updated_activity = Activity.get_by_ap_id(note_activity.data["id"])
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -126,7 +126,7 @@ test "a create activity with a note" do
 | 
			
		|||
    other_user = insert(:user, %{nickname: "shp"})
 | 
			
		||||
 | 
			
		||||
    {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!", "visibility" => "direct"})
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    result = ActivityView.render("activity.json", activity: activity)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -177,7 +177,7 @@ test "a list of activities" do
 | 
			
		|||
    user = insert(:user)
 | 
			
		||||
    other_user = insert(:user, %{nickname: "shp"})
 | 
			
		||||
    {:ok, activity} = CommonAPI.post(user, %{"status" => "Hey @shp!"})
 | 
			
		||||
    object = Object.normalize(activity.data["object"])
 | 
			
		||||
    object = Object.normalize(activity)
 | 
			
		||||
 | 
			
		||||
    convo_id = Utils.context_to_conversation_id(object.data["context"])
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -351,7 +351,7 @@ test "a delete activity" do
 | 
			
		|||
      "is_post_verb" => false,
 | 
			
		||||
      "statusnet_html" => "deleted notice {{tag",
 | 
			
		||||
      "text" => "deleted notice {{tag",
 | 
			
		||||
      "uri" => delete.data["object"],
 | 
			
		||||
      "uri" => Object.normalize(delete).data["id"],
 | 
			
		||||
      "user" => UserView.render("show.json", user: user)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue