forked from YokaiRick/akkoma
Add OpenAPI spec for ScheduledActivityController
This commit is contained in:
parent
6ba25d1197
commit
332e016bcd
6 changed files with 144 additions and 21 deletions
|
@ -0,0 +1,96 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ApiSpec.ScheduledActivityOperation do
|
||||
alias OpenApiSpex.Operation
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError
|
||||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
|
||||
alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus
|
||||
|
||||
import Pleroma.Web.ApiSpec.Helpers
|
||||
|
||||
def open_api_operation(action) do
|
||||
operation = String.to_existing_atom("#{action}_operation")
|
||||
apply(__MODULE__, operation, [])
|
||||
end
|
||||
|
||||
def index_operation do
|
||||
%Operation{
|
||||
tags: ["Scheduled Statuses"],
|
||||
summary: "View scheduled statuses",
|
||||
security: [%{"oAuth" => ["read:statuses"]}],
|
||||
parameters: pagination_params(),
|
||||
operationId: "ScheduledActivity.index",
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Array of ScheduledStatus", "application/json", %Schema{
|
||||
type: :array,
|
||||
items: ScheduledStatus
|
||||
})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def show_operation do
|
||||
%Operation{
|
||||
tags: ["Scheduled Statuses"],
|
||||
summary: "View a single scheduled status",
|
||||
security: [%{"oAuth" => ["read:statuses"]}],
|
||||
parameters: [id_param()],
|
||||
operationId: "ScheduledActivity.show",
|
||||
responses: %{
|
||||
200 => Operation.response("Scheduled Status", "application/json", ScheduledStatus),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_operation do
|
||||
%Operation{
|
||||
tags: ["Scheduled Statuses"],
|
||||
summary: "Schedule a status",
|
||||
operationId: "ScheduledActivity.update",
|
||||
security: [%{"oAuth" => ["write:statuses"]}],
|
||||
parameters: [id_param()],
|
||||
requestBody:
|
||||
request_body("Parameters", %Schema{
|
||||
type: :object,
|
||||
properties: %{
|
||||
scheduled_at: %Schema{
|
||||
type: :string,
|
||||
format: :"date-time",
|
||||
description:
|
||||
"ISO 8601 Datetime at which the status will be published. Must be at least 5 minutes into the future."
|
||||
}
|
||||
}
|
||||
}),
|
||||
responses: %{
|
||||
200 => Operation.response("Scheduled Status", "application/json", ScheduledStatus),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def delete_operation do
|
||||
%Operation{
|
||||
tags: ["Scheduled Statuses"],
|
||||
summary: "Cancel a scheduled status",
|
||||
security: [%{"oAuth" => ["write:statuses"]}],
|
||||
parameters: [id_param()],
|
||||
operationId: "ScheduledActivity.delete",
|
||||
responses: %{
|
||||
200 => Operation.response("Empty object", "application/json", %Schema{type: :object}),
|
||||
404 => Operation.response("Error", "application/json", ApiError)
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
defp id_param do
|
||||
Operation.parameter(:id, :path, FlakeID, "Poll ID",
|
||||
example: "123",
|
||||
required: true
|
||||
)
|
||||
end
|
||||
end
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
|
||||
alias OpenApiSpex.Schema
|
||||
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Attachment
|
||||
alias Pleroma.Web.ApiSpec.Schemas.Poll
|
||||
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
|
||||
|
||||
require OpenApiSpex
|
||||
|
||||
|
@ -17,7 +18,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
|
|||
properties: %{
|
||||
id: %Schema{type: :string},
|
||||
scheduled_at: %Schema{type: :string, format: :"date-time"},
|
||||
media_attachments: %Schema{type: :array, format: :"date-time"},
|
||||
media_attachments: %Schema{type: :array, items: Attachment},
|
||||
params: %Schema{
|
||||
type: :object,
|
||||
required: [:text, :visibility],
|
||||
|
@ -47,7 +48,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
|
|||
idempotency: nil,
|
||||
in_reply_to_id: nil
|
||||
},
|
||||
media_attachments: []
|
||||
media_attachments: [Attachment.schema().example]
|
||||
}
|
||||
})
|
||||
end
|
||||
|
|
|
@ -11,17 +11,21 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityController do
|
|||
alias Pleroma.ScheduledActivity
|
||||
alias Pleroma.Web.MastodonAPI.MastodonAPI
|
||||
|
||||
plug(:assign_scheduled_activity when action != :index)
|
||||
|
||||
@oauth_read_actions [:show, :index]
|
||||
|
||||
plug(Pleroma.Web.ApiSpec.CastAndValidate)
|
||||
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in @oauth_read_actions)
|
||||
plug(OAuthScopesPlug, %{scopes: ["write:statuses"]} when action not in @oauth_read_actions)
|
||||
plug(:assign_scheduled_activity when action != :index)
|
||||
|
||||
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||
|
||||
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ScheduledActivityOperation
|
||||
|
||||
@doc "GET /api/v1/scheduled_statuses"
|
||||
def index(%{assigns: %{user: user}} = conn, params) do
|
||||
params = Map.new(params, fn {key, value} -> {to_string(key), value} end)
|
||||
|
||||
with scheduled_activities <- MastodonAPI.get_scheduled_activities(user, params) do
|
||||
conn
|
||||
|> add_link_headers(scheduled_activities)
|
||||
|
@ -35,7 +39,7 @@ def show(%{assigns: %{scheduled_activity: scheduled_activity}} = conn, _params)
|
|||
end
|
||||
|
||||
@doc "PUT /api/v1/scheduled_statuses/:id"
|
||||
def update(%{assigns: %{scheduled_activity: scheduled_activity}} = conn, params) do
|
||||
def update(%{assigns: %{scheduled_activity: scheduled_activity}, body_params: params} = conn, _) do
|
||||
with {:ok, scheduled_activity} <- ScheduledActivity.update(scheduled_activity, params) do
|
||||
render(conn, "show.json", scheduled_activity: scheduled_activity)
|
||||
end
|
||||
|
@ -48,7 +52,7 @@ def delete(%{assigns: %{scheduled_activity: scheduled_activity}} = conn, _params
|
|||
end
|
||||
end
|
||||
|
||||
defp assign_scheduled_activity(%{assigns: %{user: user}, params: %{"id" => id}} = conn, _) do
|
||||
defp assign_scheduled_activity(%{assigns: %{user: user}, params: %{id: id}} = conn, _) do
|
||||
case ScheduledActivity.get(user, id) do
|
||||
%ScheduledActivity{} = activity -> assign(conn, :scheduled_activity, activity)
|
||||
nil -> Pleroma.Web.MastodonAPI.FallbackController.call(conn, {:error, :not_found}) |> halt()
|
||||
|
|
|
@ -40,12 +40,18 @@ defmacro __using__(_opts) do
|
|||
clear_config: 2
|
||||
]
|
||||
|
||||
def to_datetime(naive_datetime) do
|
||||
def to_datetime(%NaiveDateTime{} = naive_datetime) do
|
||||
naive_datetime
|
||||
|> DateTime.from_naive!("Etc/UTC")
|
||||
|> DateTime.truncate(:second)
|
||||
end
|
||||
|
||||
def to_datetime(datetime) when is_binary(datetime) do
|
||||
datetime
|
||||
|> NaiveDateTime.from_iso8601!()
|
||||
|> to_datetime()
|
||||
end
|
||||
|
||||
def collect_ids(collection) do
|
||||
collection
|
||||
|> Enum.map(& &1.id)
|
||||
|
|
|
@ -24,19 +24,19 @@ test "shows scheduled activities" do
|
|||
# min_id
|
||||
conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&min_id=#{scheduled_activity_id1}")
|
||||
|
||||
result = json_response(conn_res, 200)
|
||||
result = json_response_and_validate_schema(conn_res, 200)
|
||||
assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result
|
||||
|
||||
# since_id
|
||||
conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&since_id=#{scheduled_activity_id1}")
|
||||
|
||||
result = json_response(conn_res, 200)
|
||||
result = json_response_and_validate_schema(conn_res, 200)
|
||||
assert [%{"id" => ^scheduled_activity_id4}, %{"id" => ^scheduled_activity_id3}] = result
|
||||
|
||||
# max_id
|
||||
conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&max_id=#{scheduled_activity_id4}")
|
||||
|
||||
result = json_response(conn_res, 200)
|
||||
result = json_response_and_validate_schema(conn_res, 200)
|
||||
assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result
|
||||
end
|
||||
|
||||
|
@ -46,12 +46,12 @@ test "shows a scheduled activity" do
|
|||
|
||||
res_conn = get(conn, "/api/v1/scheduled_statuses/#{scheduled_activity.id}")
|
||||
|
||||
assert %{"id" => scheduled_activity_id} = json_response(res_conn, 200)
|
||||
assert %{"id" => scheduled_activity_id} = json_response_and_validate_schema(res_conn, 200)
|
||||
assert scheduled_activity_id == scheduled_activity.id |> to_string()
|
||||
|
||||
res_conn = get(conn, "/api/v1/scheduled_statuses/404")
|
||||
|
||||
assert %{"error" => "Record not found"} = json_response(res_conn, 404)
|
||||
assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404)
|
||||
end
|
||||
|
||||
test "updates a scheduled activity" do
|
||||
|
@ -74,22 +74,32 @@ test "updates a scheduled activity" do
|
|||
assert job.args == %{"activity_id" => scheduled_activity.id}
|
||||
assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(scheduled_at)
|
||||
|
||||
new_scheduled_at = Timex.shift(NaiveDateTime.utc_now(), minutes: 120)
|
||||
new_scheduled_at =
|
||||
NaiveDateTime.utc_now()
|
||||
|> Timex.shift(minutes: 120)
|
||||
|> Timex.format!("%Y-%m-%dT%H:%M:%S.%fZ", :strftime)
|
||||
|
||||
res_conn =
|
||||
put(conn, "/api/v1/scheduled_statuses/#{scheduled_activity.id}", %{
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/scheduled_statuses/#{scheduled_activity.id}", %{
|
||||
scheduled_at: new_scheduled_at
|
||||
})
|
||||
|
||||
assert %{"scheduled_at" => expected_scheduled_at} = json_response(res_conn, 200)
|
||||
assert %{"scheduled_at" => expected_scheduled_at} =
|
||||
json_response_and_validate_schema(res_conn, 200)
|
||||
|
||||
assert expected_scheduled_at == Pleroma.Web.CommonAPI.Utils.to_masto_date(new_scheduled_at)
|
||||
job = refresh_record(job)
|
||||
|
||||
assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(new_scheduled_at)
|
||||
|
||||
res_conn = put(conn, "/api/v1/scheduled_statuses/404", %{scheduled_at: new_scheduled_at})
|
||||
res_conn =
|
||||
conn
|
||||
|> put_req_header("content-type", "application/json")
|
||||
|> put("/api/v1/scheduled_statuses/404", %{scheduled_at: new_scheduled_at})
|
||||
|
||||
assert %{"error" => "Record not found"} = json_response(res_conn, 404)
|
||||
assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404)
|
||||
end
|
||||
|
||||
test "deletes a scheduled activity" do
|
||||
|
@ -115,7 +125,7 @@ test "deletes a scheduled activity" do
|
|||
|> assign(:user, user)
|
||||
|> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
|
||||
|
||||
assert %{} = json_response(res_conn, 200)
|
||||
assert %{} = json_response_and_validate_schema(res_conn, 200)
|
||||
refute Repo.get(ScheduledActivity, scheduled_activity.id)
|
||||
refute Repo.get(Oban.Job, job.id)
|
||||
|
||||
|
@ -124,6 +134,6 @@ test "deletes a scheduled activity" do
|
|||
|> assign(:user, user)
|
||||
|> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
|
||||
|
||||
assert %{"error" => "Record not found"} = json_response(res_conn, 404)
|
||||
assert %{"error" => "Record not found"} = json_response_and_validate_schema(res_conn, 404)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -402,11 +402,17 @@ test "attachments" do
|
|||
pleroma: %{mime_type: "image/png"}
|
||||
}
|
||||
|
||||
api_spec = Pleroma.Web.ApiSpec.spec()
|
||||
|
||||
assert expected == StatusView.render("attachment.json", %{attachment: object})
|
||||
OpenApiSpex.TestAssertions.assert_schema(expected, "Attachment", api_spec)
|
||||
|
||||
# If theres a "id", use that instead of the generated one
|
||||
object = Map.put(object, "id", 2)
|
||||
assert %{id: "2"} = StatusView.render("attachment.json", %{attachment: object})
|
||||
result = StatusView.render("attachment.json", %{attachment: object})
|
||||
|
||||
assert %{id: "2"} = result
|
||||
OpenApiSpex.TestAssertions.assert_schema(result, "Attachment", api_spec)
|
||||
end
|
||||
|
||||
test "put the url advertised in the Activity in to the url attribute" do
|
||||
|
|
Loading…
Reference in a new issue