diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/pleroma/announcement_read_relationship_test.exs | 40 | ||||
| -rw-r--r-- | test/pleroma/announcement_test.exs | 98 | ||||
| -rw-r--r-- | test/pleroma/web/admin_api/controllers/announcement_controller_test.exs | 281 | ||||
| -rw-r--r-- | test/pleroma/web/mastodon_api/controllers/announcement_controller_test.exs | 169 | ||||
| -rw-r--r-- | test/support/factory.ex | 12 | 
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 | 
