summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTusooa Zhu <tusooa@kazv.moe>2022-03-08 20:55:41 -0500
committerTusooa Zhu <tusooa@kazv.moe>2022-03-08 20:55:41 -0500
commit11a1996bf5f283099fd9ecbb5c64e051ec46a5df (patch)
treef197e0f2def0049f6546dd48915b29afc36761f2
parent881179ec725c3b71868fdcba983fdedd295e5125 (diff)
downloadpleroma-11a1996bf5f283099fd9ecbb5c64e051ec46a5df.tar.gz
pleroma-11a1996bf5f283099fd9ecbb5c64e051ec46a5df.zip
Implement update announcement admin api
-rw-r--r--lib/pleroma/announcement.ex22
-rw-r--r--lib/pleroma/web/admin_api/controllers/announcement_controller.ex29
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex49
-rw-r--r--lib/pleroma/web/router.ex1
-rw-r--r--test/pleroma/web/admin_api/controllers/announcement_controller_test.exs80
-rw-r--r--test/support/factory.ex6
6 files changed, 165 insertions, 22 deletions
diff --git a/lib/pleroma/announcement.ex b/lib/pleroma/announcement.ex
index 85500751e..8c15d5bdf 100644
--- a/lib/pleroma/announcement.ex
+++ b/lib/pleroma/announcement.ex
@@ -24,18 +24,20 @@ defmodule Pleroma.Announcement do
def change(struct, params \\ %{}) do
struct
- |> cast(validate_params(params), [:data, :starts_at, :ends_at])
+ |> cast(validate_params(struct, params), [:data, :starts_at, :ends_at])
|> validate_required([:data])
end
- defp validate_params(params) do
- base_struct = %{
- "content" => "",
- "all_day" => false
- }
+ defp validate_params(struct, params) do
+ base_data =
+ %{
+ "content" => "",
+ "all_day" => false
+ }
+ |> Map.merge((struct && struct.data) || %{})
merged_data =
- Map.merge(base_struct, params.data)
+ Map.merge(base_data, params.data)
|> Map.take(["content", "all_day"])
params
@@ -48,6 +50,12 @@ defmodule Pleroma.Announcement do
Repo.insert(changeset)
end
+ def update(announcement, params) do
+ changeset = change(announcement, params)
+
+ Repo.update(changeset)
+ end
+
def list_all do
__MODULE__
|> Repo.all()
diff --git a/lib/pleroma/web/admin_api/controllers/announcement_controller.ex b/lib/pleroma/web/admin_api/controllers/announcement_controller.ex
index ad94e2642..6195e582a 100644
--- a/lib/pleroma/web/admin_api/controllers/announcement_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/announcement_controller.ex
@@ -10,7 +10,7 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementController do
alias Pleroma.Web.Plugs.OAuthScopesPlug
plug(Pleroma.Web.ApiSpec.CastAndValidate)
- plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action in [:create, :delete])
+ plug(OAuthScopesPlug, %{scopes: ["admin:write"]} when action in [:create, :delete, :change])
plug(OAuthScopesPlug, %{scopes: ["admin:read"]} when action in [:index, :show])
action_fallback(Pleroma.Web.AdminAPI.FallbackController)
@@ -33,18 +33,33 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementController do
end
def create(%{body_params: params} = conn, _params) do
+ with {:ok, announcement} <- Announcement.add(change_params(params)) do
+ render(conn, "show.json", announcement: announcement)
+ else
+ _ ->
+ {:error, 400}
+ end
+ end
+
+ def change_params(orig_params) do
data =
%{}
- |> Pleroma.Maps.put_if_present("content", params, &Map.fetch(&1, :content))
- |> Pleroma.Maps.put_if_present("all_day", params, &Map.fetch(&1, :all_day))
+ |> Pleroma.Maps.put_if_present("content", orig_params, &Map.fetch(&1, :content))
+ |> Pleroma.Maps.put_if_present("all_day", orig_params, &Map.fetch(&1, :all_day))
- add_params =
- params
- |> Map.merge(%{data: data})
+ orig_params
+ |> Map.merge(%{data: data})
+ end
- with {:ok, announcement} <- Announcement.add(add_params) do
+ def change(%{body_params: params} = conn, %{id: id} = _params) do
+ with announcement <- Announcement.get_by_id(id),
+ {:exists, true} <- {:exists, not is_nil(announcement)},
+ {:ok, announcement} <- Announcement.update(announcement, change_params(params)) do
render(conn, "show.json", announcement: announcement)
else
+ {:exists, false} ->
+ {:error, :not_found}
+
_ ->
{:error, 400}
end
diff --git a/lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex b/lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex
index 8179a0e7b..cdf04d357 100644
--- a/lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/announcement_operation.ex
@@ -89,17 +89,54 @@ defmodule Pleroma.Web.ApiSpec.Admin.AnnouncementOperation do
}
end
+ def change_operation do
+ %Operation{
+ tags: ["Announcement managment"],
+ summary: "Change one announcement",
+ operationId: "AdminAPI.AnnouncementController.change",
+ security: [%{"oAuth" => ["admin:write"]}],
+ parameters: [
+ Operation.parameter(
+ :id,
+ :path,
+ :string,
+ "announcement id"
+ )
+ | admin_api_params()
+ ],
+ requestBody: request_body("Parameters", change_request(), required: true),
+ responses: %{
+ 200 => Operation.response("Response", "application/json", Announcement),
+ 400 => Operation.response("Bad Request", "application/json", ApiError),
+ 403 => Operation.response("Forbidden", "application/json", ApiError),
+ 404 => Operation.response("Not Found", "application/json", ApiError)
+ }
+ }
+ end
+
+ defp create_or_change_props do
+ %{
+ content: %Schema{type: :string},
+ starts_at: %Schema{type: :string, format: "date-time", nullable: true},
+ ends_at: %Schema{type: :string, format: "date-time", nullable: true},
+ all_day: %Schema{type: :boolean}
+ }
+ end
+
def create_request do
%Schema{
title: "AnnouncementCreateRequest",
type: :object,
required: [:content],
- properties: %{
- content: %Schema{type: :string},
- starts_at: %Schema{type: :string, format: "date-time"},
- ends_at: %Schema{type: :string, format: "date-time"},
- all_day: %Schema{type: :boolean}
- }
+ properties: create_or_change_props()
+ }
+ end
+
+ def change_request do
+ %Schema{
+ title: "AnnouncementChangeRequest",
+ type: :object,
+ properties: create_or_change_props()
}
end
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index 51a9dec6b..af56494a2 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -233,6 +233,7 @@ defmodule Pleroma.Web.Router do
get("/announcements", AnnouncementController, :index)
post("/announcements", AnnouncementController, :create)
get("/announcements/:id", AnnouncementController, :show)
+ patch("/announcements/:id", AnnouncementController, :change)
delete("/announcements/:id", AnnouncementController, :delete)
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
index 5c9d50120..c6b2163d0 100644
--- a/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs
+++ b/test/pleroma/web/admin_api/controllers/announcement_controller_test.exs
@@ -69,11 +69,89 @@ defmodule Pleroma.Web.AdminAPI.AnnouncementControllerTest do
_response =
conn
- |> get("/api/v1/pleroma/admin/announcements/#{id}xxx")
+ |> 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 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
diff --git a/test/support/factory.ex b/test/support/factory.ex
index 64b0049ac..d28a56345 100644
--- a/test/support/factory.ex
+++ b/test/support/factory.ex
@@ -628,7 +628,11 @@ defmodule Pleroma.Factory do
}
end
- def announcement_factory(params \\ %{}, data \\ %{}) do
+ 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)
}