# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors 
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.OStatus.ActivityRepresenterTest do
  use Pleroma.DataCase
  alias Pleroma.Web.OStatus.ActivityRepresenter
  alias Pleroma.{User, Activity, Object}
  alias Pleroma.Web.ActivityPub.ActivityPub
  alias Pleroma.Web.OStatus
  import Pleroma.Factory
  import Tesla.Mock
  setup do
    mock(fn env -> apply(HttpRequestMock, :request, [env]) end)
    :ok
  end
  test "an external note activity" do
    incoming = File.read!("test/fixtures/mastodon-note-cw.xml")
    {:ok, [activity]} = OStatus.handle_incoming(incoming)
    user = User.get_cached_by_ap_id(activity.data["actor"])
    tuple = ActivityRepresenter.to_simple_form(activity, user)
    res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary()
    assert String.contains?(
             res,
             ~s{}
           )
  end
  test "a note activity" do
    note_activity = insert(:note_activity)
    user = User.get_cached_by_ap_id(note_activity.data["actor"])
    expected = """
    http://activitystrea.ms/schema/1.0/note
    http://activitystrea.ms/schema/1.0/post
    #{note_activity.data["object"]["id"]}
    
New note by #{user.nickname}
    #{note_activity.data["object"]["content"]}
    #{note_activity.data["object"]["published"]}
    #{note_activity.data["object"]["published"]}
    #{note_activity.data["context"]}
    
    #{note_activity.data["object"]["summary"]}
    
    
    
    
    
    """
    tuple = ActivityRepresenter.to_simple_form(note_activity, user)
    res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary()
    assert clean(res) == clean(expected)
  end
  test "a reply note" do
    note = insert(:note_activity)
    answer = insert(:note_activity)
    object = answer.data["object"]
    object = Map.put(object, "inReplyTo", note.data["object"]["id"])
    data = %{answer.data | "object" => object}
    answer = %{answer | data: data}
    note_object = Object.get_by_ap_id(note.data["object"]["id"])
    Repo.update!(
      Object.change(note_object, %{data: Map.put(note_object.data, "external_url", "someurl")})
    )
    user = User.get_cached_by_ap_id(answer.data["actor"])
    expected = """
    http://activitystrea.ms/schema/1.0/note
    http://activitystrea.ms/schema/1.0/post
    #{answer.data["object"]["id"]}
    New note by #{user.nickname}
    #{answer.data["object"]["content"]}
    #{answer.data["object"]["published"]}
    #{answer.data["object"]["published"]}
    #{answer.data["context"]}
    
    2hu
    
    
    
    
    
    
    """
    tuple = ActivityRepresenter.to_simple_form(answer, user)
    res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary()
    assert clean(res) == clean(expected)
  end
  test "an announce activity" do
    note = insert(:note_activity)
    user = insert(:user)
    object = Object.get_cached_by_ap_id(note.data["object"]["id"])
    {:ok, announce, _object} = ActivityPub.announce(user, object)
    announce = Repo.get(Activity, announce.id)
    note_user = User.get_cached_by_ap_id(note.data["actor"])
    note = Repo.get(Activity, note.id)
    note_xml =
      ActivityRepresenter.to_simple_form(note, note_user, true)
      |> :xmerl.export_simple_content(:xmerl_xml)
      |> to_string
    expected = """
    http://activitystrea.ms/schema/1.0/activity
    http://activitystrea.ms/schema/1.0/share
    #{announce.data["id"]}
    #{user.nickname} repeated a notice
    RT #{note.data["object"]["content"]}
    #{announce.data["published"]}
    #{announce.data["published"]}
    #{announce.data["context"]}
    
    
    
      #{note_xml}
    
    
    
    """
    announce_xml =
      ActivityRepresenter.to_simple_form(announce, user)
      |> :xmerl.export_simple_content(:xmerl_xml)
      |> to_string
    assert clean(expected) == clean(announce_xml)
  end
  test "a like activity" do
    note = insert(:note)
    user = insert(:user)
    {:ok, like, _note} = ActivityPub.like(user, note)
    tuple = ActivityRepresenter.to_simple_form(like, user)
    refute is_nil(tuple)
    res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary()
    expected = """
    http://activitystrea.ms/schema/1.0/favorite
    #{like.data["id"]}
    New favorite by #{user.nickname}
    #{user.nickname} favorited something
    #{like.data["published"]}
    #{like.data["published"]}
    
      http://activitystrea.ms/schema/1.0/note
      #{note.data["id"]}
    
    #{like.data["context"]}
    
    
    
    
    
    """
    assert clean(res) == clean(expected)
  end
  test "a follow activity" do
    follower = insert(:user)
    followed = insert(:user)
    {:ok, activity} =
      ActivityPub.insert(%{
        "type" => "Follow",
        "actor" => follower.ap_id,
        "object" => followed.ap_id,
        "to" => [followed.ap_id]
      })
    tuple = ActivityRepresenter.to_simple_form(activity, follower)
    refute is_nil(tuple)
    res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary()
    expected = """
    http://activitystrea.ms/schema/1.0/activity
    http://activitystrea.ms/schema/1.0/follow
    #{activity.data["id"]}
    #{follower.nickname} started following #{activity.data["object"]}
     #{follower.nickname} started following #{activity.data["object"]}
    #{activity.data["published"]}
    #{activity.data["published"]}
    
      http://activitystrea.ms/schema/1.0/person
      #{activity.data["object"]}
      #{activity.data["object"]}
    
    
    
    """
    assert clean(res) == clean(expected)
  end
  test "an unfollow activity" do
    follower = insert(:user)
    followed = insert(:user)
    {:ok, _activity} = ActivityPub.follow(follower, followed)
    {:ok, activity} = ActivityPub.unfollow(follower, followed)
    tuple = ActivityRepresenter.to_simple_form(activity, follower)
    refute is_nil(tuple)
    res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary()
    expected = """
    http://activitystrea.ms/schema/1.0/activity
    http://activitystrea.ms/schema/1.0/unfollow
    #{activity.data["id"]}
    #{follower.nickname} stopped following #{followed.ap_id}
     #{follower.nickname} stopped following #{followed.ap_id}
    #{activity.data["published"]}
    #{activity.data["published"]}
    
      http://activitystrea.ms/schema/1.0/person
      #{followed.ap_id}
      #{followed.ap_id}
    
    
    
    """
    assert clean(res) == clean(expected)
  end
  test "a delete" do
    user = insert(:user)
    activity = %Activity{
      data: %{
        "id" => "ap_id",
        "type" => "Delete",
        "actor" => user.ap_id,
        "object" => "some_id",
        "published" => "2017-06-18T12:00:18+00:00"
      }
    }
    tuple = ActivityRepresenter.to_simple_form(activity, nil)
    refute is_nil(tuple)
    res = :xmerl.export_simple_content(tuple, :xmerl_xml) |> IO.iodata_to_binary()
    expected = """
    http://activitystrea.ms/schema/1.0/activity
    http://activitystrea.ms/schema/1.0/delete
    #{activity.data["object"]}
    An object was deleted
    An object was deleted
    #{activity.data["published"]}
    #{activity.data["published"]}
    """
    assert clean(res) == clean(expected)
  end
  test "an unknown activity" do
    tuple = ActivityRepresenter.to_simple_form(%Activity{}, nil)
    assert is_nil(tuple)
  end
  defp clean(string) do
    String.replace(string, ~r/\s/, "")
  end
end