diff options
| -rw-r--r-- | lib/pleroma/notification.ex | 31 | ||||
| -rw-r--r-- | lib/pleroma/web/mastodon_api/mastodon_api_controller.ex | 65 | ||||
| -rw-r--r-- | lib/pleroma/web/router.ex | 3 | ||||
| -rw-r--r-- | test/notification_test.exs | 61 | ||||
| -rw-r--r-- | test/web/mastodon_api/mastodon_api_controller_test.exs | 71 | 
5 files changed, 213 insertions, 18 deletions
| diff --git a/lib/pleroma/notification.ex b/lib/pleroma/notification.ex index 00a382f31..039cc7312 100644 --- a/lib/pleroma/notification.ex +++ b/lib/pleroma/notification.ex @@ -36,6 +36,37 @@ defmodule Pleroma.Notification do      Repo.all(query)    end +  def get(%{id: user_id} = _user, id) do +    query = from n in Notification, +      where: n.id == ^id, +      preload: [:activity] + +    notification = Repo.one(query) +    case notification do +      %{user_id: ^user_id} -> +        {:ok, notification} +      _ -> +        {:error, "Cannot get notification"} +    end +  end + +  def clear(user) do +    query = from n in Notification, +      where: n.user_id == ^user.id + +    Repo.delete_all(query) +  end + +  def dismiss(%{id: user_id} = _user, id) do +    notification = Repo.get(Notification, id) +    case notification do +      %{user_id: ^user_id} -> +        Repo.delete(notification) +      _ -> +        {:error, "Cannot dismiss notification"} +    end +  end +    def create_notifications(%Activity{id: id, data: %{"to" => to, "type" => type}} = activity) when type in ["Create", "Like", "Announce", "Follow"] do      users = User.get_notified_from_activity(activity) diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index fb06d55c1..9f50dc596 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -244,23 +244,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do    def notifications(%{assigns: %{user: user}} = conn, params) do      notifications = Notification.for_user(user, params) -    result = Enum.map(notifications, fn (%{id: id, activity: activity, inserted_at: created_at}) -> -      actor = User.get_cached_by_ap_id(activity.data["actor"]) -      created_at = NaiveDateTime.to_iso8601(created_at) -      |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false) -      case activity.data["type"] do -        "Create" -> -          %{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})} -        "Like" -> -          liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) -          %{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})} -        "Announce" -> -          announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) -          %{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})} -        "Follow" -> -          %{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})} -        _ -> nil -      end +    result = Enum.map(notifications, fn x -> +      render_notification(user, x)      end)      |> Enum.filter(&(&1)) @@ -269,6 +254,33 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      |> json(result)    end +  def get_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do +    with {:ok, notification} <- Notification.get(user, id) do +      json(conn, render_notification(user, notification)) +    else +      {:error, reason} -> +        conn +        |> put_resp_content_type("application/json") +        |> send_resp(403, Poison.encode!(%{"error" => reason})) +    end +  end + +  def clear_notifications(%{assigns: %{user: user}} = conn, _params) do +    Notification.clear(user) +    json(conn, %{}) +  end + +  def dismiss_notification(%{assigns: %{user: user}} = conn, %{"id" => id} = _params) do +    with {:ok, _notif} <- Notification.dismiss(user, id) do +      json(conn, %{}) +    else +      {:error, reason} -> +        conn +        |> put_resp_content_type("application/json") +        |> send_resp(403, Poison.encode!(%{"error" => reason})) +    end +  end +    def relationships(%{assigns: %{user: user}} = conn, %{"id" => id}) do      id = List.wrap(id)      q = from u in User, @@ -467,4 +479,23 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do      Logger.debug("Unimplemented, returning an empty array")      json(conn, [])    end + +  defp render_notification(user, %{id: id, activity: activity, inserted_at: created_at} = _params) do +    actor = User.get_cached_by_ap_id(activity.data["actor"]) +    created_at = NaiveDateTime.to_iso8601(created_at) +    |> String.replace(~r/(\.\d+)?$/, ".000Z", global: false) +    case activity.data["type"] do +      "Create" -> +        %{id: id, type: "mention", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: activity, for: user})} +      "Like" -> +        liked_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) +        %{id: id, type: "favourite", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: liked_activity, for: user})} +      "Announce" -> +        announced_activity = Activity.get_create_activity_by_object_ap_id(activity.data["object"]) +        %{id: id, type: "reblog", created_at: created_at, account: AccountView.render("account.json", %{user: actor}), status: StatusView.render("status.json", %{activity: announced_activity, for: user})} +      "Follow" -> +        %{id: id, type: "follow", created_at: created_at, account: AccountView.render("account.json", %{user: actor})} +      _ -> nil +    end +  end  end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 4c74736e2..637c300c8 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -83,7 +83,10 @@ defmodule Pleroma.Web.Router do      post "/statuses/:id/favourite", MastodonAPIController, :fav_status      post "/statuses/:id/unfavourite", MastodonAPIController, :unfav_status +    post "/notifications/clear", MastodonAPIController, :clear_notifications +    post "/notifications/dismiss", MastodonAPIController, :dismiss_notification      get "/notifications", MastodonAPIController, :notifications +    get "/notifications/:id", MastodonAPIController, :get_notification      post "/media", MastodonAPIController, :upload    end diff --git a/test/notification_test.exs b/test/notification_test.exs index 77fdb532f..eee1c9fa3 100644 --- a/test/notification_test.exs +++ b/test/notification_test.exs @@ -31,4 +31,65 @@ defmodule Pleroma.NotificationTest do        assert nil == Notification.create_notification(activity, user)      end    end + +  describe "get notification" do +    test "it gets a notification that belongs to the user" do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"}) +      {:ok, [notification]} = Notification.create_notifications(activity) +      {:ok, notification} = Notification.get(other_user, notification.id) + +      assert notification.user_id == other_user.id +    end + +    test "it returns error if the notification doesn't belong to the user" do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"}) +      {:ok, [notification]} = Notification.create_notifications(activity) +      {:error, notification} = Notification.get(user, notification.id) +    end +  end + +  describe "dismiss notification" do +    test "it dismisses a notification that belongs to the user" do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"}) +      {:ok, [notification]} = Notification.create_notifications(activity) +      {:ok, notification} = Notification.dismiss(other_user, notification.id) + +      assert notification.user_id == other_user.id +    end + +    test "it returns error if the notification doesn't belong to the user" do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname}"}) +      {:ok, [notification]} = Notification.create_notifications(activity) +      {:error, notification} = Notification.dismiss(user, notification.id) +    end +  end + +  describe "clear notification" do +    test "it clears all notifications belonging to the user" do +      user = insert(:user) +      other_user = insert(:user) +      third_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey @#{other_user.nickname} and @#{third_user.nickname} !"}) +      {:ok, _notifs} = Notification.create_notifications(activity) +      {:ok, activity} = TwitterAPI.create_status(user, %{"status" => "hey again @#{other_user.nickname} and @#{third_user.nickname} !"}) +      {:ok, _notifs} = Notification.create_notifications(activity) +      Notification.clear(other_user) + +      assert Notification.for_user(other_user) == [] +      assert Notification.for_user(third_user) != [] +    end +  end  end diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index cf60b4a51..f506d56a1 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -2,7 +2,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do    use Pleroma.Web.ConnCase    alias Pleroma.Web.TwitterAPI.TwitterAPI -  alias Pleroma.{Repo, User, Activity} +  alias Pleroma.{Repo, User, Activity, Notification}    alias Pleroma.Web.{OStatus, CommonAPI}    import Pleroma.Factory @@ -122,6 +122,75 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do      end    end +  describe "notifications" do +    test "list of notifications", %{conn: conn} do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"}) +      {:ok, [notification]} = Notification.create_notifications(activity) + +      conn = conn +      |> assign(:user, user) +      |> get("/api/v1/notifications") + +      expected_response = "hi <a href=\"#{user.ap_id}\">@#{user.nickname}</a>" +      assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200) +      assert response == expected_response +    end + +    test "getting a single notification", %{conn: conn} do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"}) +      {:ok, [notification]} = Notification.create_notifications(activity) + +      conn = conn +      |> assign(:user, user) +      |> get("/api/v1/notifications/#{notification.id}") + +      expected_response = "hi <a href=\"#{user.ap_id}\">@#{user.nickname}</a>" +      assert %{"status" => %{"content" => response}} = json_response(conn, 200) +      assert response == expected_response +    end + +    test "dismissing a single notification", %{conn: conn} do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"}) +      {:ok, [notification]} = Notification.create_notifications(activity) + +      conn = conn +      |> assign(:user, user) +      |> post("/api/v1/notifications/dismiss", %{"id" => notification.id}) + +      assert %{} = json_response(conn, 200) +    end + +    test "clearing all notifications", %{conn: conn} do +      user = insert(:user) +      other_user = insert(:user) + +      {:ok, activity} = TwitterAPI.create_status(other_user, %{"status" => "hi @#{user.nickname}"}) +      {:ok, [notification]} = Notification.create_notifications(activity) + +      conn = conn +      |> assign(:user, user) +      |> post("/api/v1/notifications/clear") + +      assert %{} = json_response(conn, 200) + +      conn = build_conn() +      |> assign(:user, user) +      |> get("/api/v1/notifications") + +      assert all = json_response(conn, 200) +      assert all == [] +    end +  end +    describe "reblogging" do      test "reblogs and returns the reblogged status", %{conn: conn} do        activity = insert(:note_activity) | 
