summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/pleroma/announcement_read_relationship_test.exs40
-rw-r--r--test/pleroma/announcement_test.exs98
-rw-r--r--test/pleroma/web/admin_api/controllers/announcement_controller_test.exs281
-rw-r--r--test/pleroma/web/mastodon_api/controllers/announcement_controller_test.exs169
-rw-r--r--test/support/factory.ex12
5 files changed, 600 insertions, 0 deletions
diff --git a/test/pleroma/announcement_read_relationship_test.exs b/test/pleroma/announcement_read_relationship_test.exs
new file mode 100644
index 000000000..5fd4ffbef
--- /dev/null
+++ b/test/pleroma/announcement_read_relationship_test.exs
@@ -0,0 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.AnnouncementReadRelationshipTest do
+ alias Pleroma.AnnouncementReadRelationship
+
+ use Pleroma.DataCase, async: true
+
+ import Pleroma.Factory
+
+ setup do
+ {:ok, user: insert(:user), announcement: insert(:announcement)}
+ end
+
+ describe "mark_read/2" do
+ test "should insert relationship", %{user: user, announcement: announcement} do
+ {:ok, _} = AnnouncementReadRelationship.mark_read(user, announcement)
+
+ assert AnnouncementReadRelationship.exists?(user, announcement)
+ end
+ end
+
+ describe "mark_unread/2" do
+ test "should delete relationship", %{user: user, announcement: announcement} do
+ {:ok, _} = AnnouncementReadRelationship.mark_read(user, announcement)
+
+ assert :ok = AnnouncementReadRelationship.mark_unread(user, announcement)
+ refute AnnouncementReadRelationship.exists?(user, announcement)
+ end
+
+ test "should not fail if relationship does not exist", %{
+ user: user,
+ announcement: announcement
+ } do
+ assert :ok = AnnouncementReadRelationship.mark_unread(user, announcement)
+ refute AnnouncementReadRelationship.exists?(user, announcement)
+ end
+ end
+end
diff --git a/test/pleroma/announcement_test.exs b/test/pleroma/announcement_test.exs
new file mode 100644
index 000000000..a007c3718
--- /dev/null
+++ b/test/pleroma/announcement_test.exs
@@ -0,0 +1,98 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.AnnouncementTest do
+ alias Pleroma.Announcement
+
+ use Pleroma.DataCase, async: true
+
+ import Pleroma.Factory
+
+ describe "list_all_visible_when/1" do
+ setup do: {:ok, time: NaiveDateTime.utc_now()}
+
+ test "with no start or end time", %{time: time} do
+ _announcement = insert(:announcement)
+
+ assert [_] = Announcement.list_all_visible_when(time)
+ end
+
+ test "with start time before current", %{time: time} do
+ before_now = NaiveDateTime.add(time, -10, :second)
+
+ _announcement = insert(:announcement, %{starts_at: before_now})
+
+ assert [_] = Announcement.list_all_visible_when(time)
+ end
+
+ test "with start time after current", %{time: time} do
+ after_now = NaiveDateTime.add(time, 10, :second)
+
+ _announcement = insert(:announcement, %{starts_at: after_now})
+
+ assert [] = Announcement.list_all_visible_when(time)
+ end
+
+ test "with end time after current", %{time: time} do
+ after_now = NaiveDateTime.add(time, 10, :second)
+
+ _announcement = insert(:announcement, %{ends_at: after_now})
+
+ assert [_] = Announcement.list_all_visible_when(time)
+ end
+
+ test "with end time before current", %{time: time} do
+ before_now = NaiveDateTime.add(time, -10, :second)
+
+ _announcement = insert(:announcement, %{ends_at: before_now})
+
+ assert [] = Announcement.list_all_visible_when(time)
+ end
+
+ test "with both start and end time", %{time: time} do
+ before_now = NaiveDateTime.add(time, -10, :second)
+ after_now = NaiveDateTime.add(time, 10, :second)
+
+ _announcement = insert(:announcement, %{starts_at: before_now, ends_at: after_now})
+
+ assert [_] = Announcement.list_all_visible_when(time)
+ end
+
+ test "with both start and end time, current not in the range", %{time: time} do
+ before_now = NaiveDateTime.add(time, -10, :second)
+ after_now = NaiveDateTime.add(time, 10, :second)
+
+ _announcement = insert(:announcement, %{starts_at: after_now, ends_at: before_now})
+
+ assert [] = Announcement.list_all_visible_when(time)
+ end
+ end
+
+ describe "announcements formatting" do
+ test "it formats links" do
+ raw = "something on https://pleroma.social ."
+ announcement = insert(:announcement, %{data: %{"content" => raw}})
+
+ assert announcement.rendered["content"] =~ ~r(<a.+?https://pleroma.social)
+ assert announcement.data["content"] == raw
+ end
+
+ test "it formats mentions" do
+ user = insert(:user)
+ raw = "something on @#{user.nickname} ."
+ announcement = insert(:announcement, %{data: %{"content" => raw}})
+
+ assert announcement.rendered["content"] =~ ~r(<a.+?#{user.nickname})
+ assert announcement.data["content"] == raw
+ end
+
+ test "it formats tags" do
+ raw = "something on #mew ."
+ announcement = insert(:announcement, %{data: %{"content" => raw}})
+
+ assert announcement.rendered["content"] =~ ~r(<a.+?#mew)
+ assert announcement.data["content"] == raw
+ end
+ end
+end
diff --git a/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs b/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs
new file mode 100644
index 000000000..5b8148c05
--- /dev/null
+++ b/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs
@@ -0,0 +1,281 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
+ use Pleroma.Web.ConnCase
+
+ import Pleroma.Factory
+
+ setup do
+ admin = insert(:user, is_admin: true)
+ token = insert(:oauth_admin_token, user: admin)
+
+ conn =
+ build_conn()
+ |> assign(:user, admin)
+ |> assign(:token, token)
+
+ {:ok, %{admin: admin, token: token, conn: conn}}
+ end
+
+ describe "GET /api/v1/pleroma/admin/announcements" do
+ test "it lists all announcements", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ response =
+ conn
+ |> get("/api/v1/pleroma/admin/announcements")
+ |> json_response_and_validate_schema(:ok)
+
+ assert [%{"id" => ^id}] = response
+ end
+
+ test "it paginates announcements", %{conn: conn} do
+ _announcements = Enum.map(0..20, fn _ -> insert(:announcement) end)
+
+ response =
+ conn
+ |> get("/api/v1/pleroma/admin/announcements")
+ |> json_response_and_validate_schema(:ok)
+
+ assert length(response) == 20
+ end
+
+ test "it paginates announcements with custom params", %{conn: conn} do
+ announcements = Enum.map(0..20, fn _ -> insert(:announcement) end)
+
+ response =
+ conn
+ |> get("/api/v1/pleroma/admin/announcements", limit: 5, offset: 7)
+ |> json_response_and_validate_schema(:ok)
+
+ assert length(response) == 5
+ assert Enum.at(response, 0)["id"] == Enum.at(announcements, 7).id
+ end
+
+ test "it returns empty list with out-of-bounds offset", %{conn: conn} do
+ _announcements = Enum.map(0..20, fn _ -> insert(:announcement) end)
+
+ response =
+ conn
+ |> get("/api/v1/pleroma/admin/announcements", offset: 21)
+ |> json_response_and_validate_schema(:ok)
+
+ assert [] = response
+ end
+
+ test "it rejects invalid pagination params", %{conn: conn} do
+ conn
+ |> get("/api/v1/pleroma/admin/announcements", limit: 0)
+ |> json_response_and_validate_schema(400)
+
+ conn
+ |> get("/api/v1/pleroma/admin/announcements", limit: -1)
+ |> json_response_and_validate_schema(400)
+
+ conn
+ |> get("/api/v1/pleroma/admin/announcements", offset: -1)
+ |> json_response_and_validate_schema(400)
+ end
+ end
+
+ describe "GET /api/v1/pleroma/admin/announcements/:id" do
+ test "it displays one announcement", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ response =
+ conn
+ |> get("/api/v1/pleroma/admin/announcements/#{id}")
+ |> json_response_and_validate_schema(:ok)
+
+ assert %{"id" => ^id} = response
+ end
+
+ test "it returns not found for non-existent id", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ _response =
+ conn
+ |> get("/api/v1/pleroma/admin/announcements/#{id}xxx")
+ |> json_response_and_validate_schema(:not_found)
+ end
+ end
+
+ describe "DELETE /api/v1/pleroma/admin/announcements/:id" do
+ test "it deletes specified announcement", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ _response =
+ conn
+ |> delete("/api/v1/pleroma/admin/announcements/#{id}")
+ |> json_response_and_validate_schema(:ok)
+ end
+
+ test "it returns not found for non-existent id", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ _response =
+ conn
+ |> delete("/api/v1/pleroma/admin/announcements/#{id}xxx")
+ |> json_response_and_validate_schema(:not_found)
+
+ assert %{id: ^id} = Pleroma.Announcement.get_by_id(id)
+ end
+ end
+
+ describe "PATCH /api/v1/pleroma/admin/announcements/:id" do
+ test "it returns not found for non-existent id", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ _response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch("/api/v1/pleroma/admin/announcements/#{id}xxx", %{})
+ |> json_response_and_validate_schema(:not_found)
+
+ assert %{id: ^id} = Pleroma.Announcement.get_by_id(id)
+ end
+
+ test "it updates a field", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
+ starts_at = NaiveDateTime.add(now, -10, :second)
+
+ _response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
+ starts_at: NaiveDateTime.to_iso8601(starts_at)
+ })
+ |> json_response_and_validate_schema(:ok)
+
+ new = Pleroma.Announcement.get_by_id(id)
+
+ assert NaiveDateTime.compare(new.starts_at, starts_at) == :eq
+ end
+
+ test "it updates with time with utc timezone", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ now = DateTime.now("Etc/UTC") |> elem(1) |> DateTime.truncate(:second)
+ starts_at = DateTime.add(now, -10, :second)
+
+ _response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
+ starts_at: DateTime.to_iso8601(starts_at)
+ })
+ |> json_response_and_validate_schema(:ok)
+
+ new = Pleroma.Announcement.get_by_id(id)
+
+ assert DateTime.compare(new.starts_at, starts_at) == :eq
+ end
+
+ test "it updates a data field", %{conn: conn} do
+ %{id: id} = announcement = insert(:announcement, data: %{"all_day" => true})
+
+ assert announcement.data["all_day"] == true
+
+ new_content = "new content"
+
+ response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
+ content: new_content
+ })
+ |> json_response_and_validate_schema(:ok)
+
+ assert response["content"] == new_content
+ assert response["all_day"] == true
+
+ new = Pleroma.Announcement.get_by_id(id)
+
+ assert new.data["content"] == new_content
+ assert new.data["all_day"] == true
+ end
+
+ test "it nullifies a nullable field", %{conn: conn} do
+ now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
+ starts_at = NaiveDateTime.add(now, -10, :second)
+
+ %{id: id} = insert(:announcement, starts_at: starts_at)
+
+ response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> patch("/api/v1/pleroma/admin/announcements/#{id}", %{
+ starts_at: nil
+ })
+ |> json_response_and_validate_schema(:ok)
+
+ assert response["starts_at"] == nil
+
+ new = Pleroma.Announcement.get_by_id(id)
+
+ assert new.starts_at == nil
+ end
+ end
+
+ describe "POST /api/v1/pleroma/admin/announcements" do
+ test "it creates an announcement", %{conn: conn} do
+ content = "test post announcement api"
+
+ now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
+ starts_at = NaiveDateTime.add(now, -10, :second)
+ ends_at = NaiveDateTime.add(now, 10, :second)
+
+ response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/pleroma/admin/announcements", %{
+ "content" => content,
+ "starts_at" => NaiveDateTime.to_iso8601(starts_at),
+ "ends_at" => NaiveDateTime.to_iso8601(ends_at),
+ "all_day" => true
+ })
+ |> json_response_and_validate_schema(:ok)
+
+ assert %{"content" => ^content, "all_day" => true} = response
+
+ announcement = Pleroma.Announcement.get_by_id(response["id"])
+
+ assert not is_nil(announcement)
+
+ assert NaiveDateTime.compare(announcement.starts_at, starts_at) == :eq
+ assert NaiveDateTime.compare(announcement.ends_at, ends_at) == :eq
+ end
+
+ test "creating with time with utc timezones", %{conn: conn} do
+ content = "test post announcement api"
+
+ now = DateTime.now("Etc/UTC") |> elem(1) |> DateTime.truncate(:second)
+ starts_at = DateTime.add(now, -10, :second)
+ ends_at = DateTime.add(now, 10, :second)
+
+ response =
+ conn
+ |> put_req_header("content-type", "application/json")
+ |> post("/api/v1/pleroma/admin/announcements", %{
+ "content" => content,
+ "starts_at" => DateTime.to_iso8601(starts_at),
+ "ends_at" => DateTime.to_iso8601(ends_at),
+ "all_day" => true
+ })
+ |> json_response_and_validate_schema(:ok)
+
+ assert %{"content" => ^content, "all_day" => true} = response
+
+ announcement = Pleroma.Announcement.get_by_id(response["id"])
+
+ assert not is_nil(announcement)
+
+ assert DateTime.compare(announcement.starts_at, starts_at) == :eq
+ assert DateTime.compare(announcement.ends_at, ends_at) == :eq
+ end
+ end
+end
diff --git a/test/pleroma/web/mastodon_api/controllers/announcement_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/announcement_controller_test.exs
new file mode 100644
index 000000000..60c9978c2
--- /dev/null
+++ b/test/pleroma/web/mastodon_api/controllers/announcement_controller_test.exs
@@ -0,0 +1,169 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.AnnouncementControllerTest do
+ use Pleroma.Web.ConnCase
+
+ import Pleroma.Factory
+
+ alias Pleroma.Announcement
+ alias Pleroma.AnnouncementReadRelationship
+
+ describe "GET /api/v1/announcements" do
+ setup do
+ %{conn: conn} = oauth_access([])
+ {:ok, conn: conn}
+ end
+
+ test "it does not allow guests", %{conn: conn} do
+ _response =
+ conn
+ |> assign(:token, nil)
+ |> get("/api/v1/announcements")
+ |> json_response_and_validate_schema(:forbidden)
+ end
+
+ test "it allows users with scopes" do
+ %{conn: conn} = oauth_access(["read:accounts"])
+
+ _response =
+ conn
+ |> get("/api/v1/announcements")
+ |> json_response_and_validate_schema(:ok)
+ end
+
+ test "it lists all announcements", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ response =
+ conn
+ |> get("/api/v1/announcements")
+ |> json_response_and_validate_schema(:ok)
+
+ assert [%{"id" => ^id}] = response
+ end
+
+ test "it returns time with utc timezone", %{conn: conn} do
+ start_time =
+ NaiveDateTime.utc_now()
+ |> NaiveDateTime.add(-999_999, :second)
+ |> NaiveDateTime.truncate(:second)
+
+ end_time =
+ NaiveDateTime.utc_now()
+ |> NaiveDateTime.add(999_999, :second)
+ |> NaiveDateTime.truncate(:second)
+
+ %{id: id} = insert(:announcement, %{starts_at: start_time, ends_at: end_time})
+
+ response =
+ conn
+ |> get("/api/v1/announcements")
+ |> json_response_and_validate_schema(:ok)
+
+ assert [%{"id" => ^id}] = [announcement] = response
+
+ assert String.ends_with?(announcement["starts_at"], "Z")
+ assert String.ends_with?(announcement["ends_at"], "Z")
+ end
+
+ test "it does not list announcements starting after current time", %{conn: conn} do
+ time = NaiveDateTime.utc_now() |> NaiveDateTime.add(999_999, :second)
+ insert(:announcement, starts_at: time)
+
+ response =
+ conn
+ |> get("/api/v1/announcements")
+ |> json_response_and_validate_schema(:ok)
+
+ assert [] = response
+ end
+
+ test "it does not list announcements ending before current time", %{conn: conn} do
+ time = NaiveDateTime.utc_now() |> NaiveDateTime.add(-999_999, :second)
+ insert(:announcement, ends_at: time)
+
+ response =
+ conn
+ |> get("/api/v1/announcements")
+ |> json_response_and_validate_schema(:ok)
+
+ assert [] = response
+ end
+
+ test "when authenticated, also expose read property", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ response =
+ conn
+ |> get("/api/v1/announcements")
+ |> json_response_and_validate_schema(:ok)
+
+ assert [%{"id" => ^id, "read" => false}] = response
+ end
+
+ test "when authenticated and announcement is read by user" do
+ %{id: id} = announcement = insert(:announcement)
+ user = insert(:user)
+
+ AnnouncementReadRelationship.mark_read(user, announcement)
+
+ %{conn: conn} = oauth_access(["read:accounts"], user: user)
+
+ response =
+ conn
+ |> get("/api/v1/announcements")
+ |> json_response_and_validate_schema(:ok)
+
+ assert [%{"id" => ^id, "read" => true}] = response
+ end
+ end
+
+ describe "POST /api/v1/announcements/:id/dismiss" do
+ setup do: oauth_access(["write:accounts"])
+
+ test "it requires auth", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ _response =
+ conn
+ |> assign(:token, nil)
+ |> post("/api/v1/announcements/#{id}/dismiss")
+ |> json_response_and_validate_schema(:forbidden)
+ end
+
+ test "it requires write:accounts oauth scope" do
+ %{id: id} = insert(:announcement)
+
+ %{conn: conn} = oauth_access(["read:accounts"])
+
+ _response =
+ conn
+ |> post("/api/v1/announcements/#{id}/dismiss")
+ |> json_response_and_validate_schema(:forbidden)
+ end
+
+ test "it gives 404 for non-existent announcements", %{conn: conn} do
+ %{id: id} = insert(:announcement)
+
+ _response =
+ conn
+ |> post("/api/v1/announcements/#{id}xxx/dismiss")
+ |> json_response_and_validate_schema(:not_found)
+ end
+
+ test "it marks announcement as read", %{user: user, conn: conn} do
+ %{id: id} = announcement = insert(:announcement)
+
+ refute Announcement.read_by?(announcement, user)
+
+ _response =
+ conn
+ |> post("/api/v1/announcements/#{id}/dismiss")
+ |> json_response_and_validate_schema(:ok)
+
+ assert Announcement.read_by?(announcement, user)
+ end
+ end
+end
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 09456debf..efbf3df2e 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -627,4 +627,16 @@ defmodule Pleroma.Factory do
context: ["home"]
}
end
+
+ def announcement_factory(params \\ %{}) do
+ data = Map.get(params, :data, %{})
+
+ {_, params} = Map.pop(params, :data)
+
+ %Pleroma.Announcement{
+ data: Map.merge(%{"content" => "test announcement", "all_day" => false}, data)
+ }
+ |> Map.merge(params)
+ |> Pleroma.Announcement.add_rendered_properties()
+ end
end