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
|
defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
|
||||||
alias OpenApiSpex.Schema
|
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.Poll
|
||||||
|
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
|
||||||
|
|
||||||
require OpenApiSpex
|
require OpenApiSpex
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
|
||||||
properties: %{
|
properties: %{
|
||||||
id: %Schema{type: :string},
|
id: %Schema{type: :string},
|
||||||
scheduled_at: %Schema{type: :string, format: :"date-time"},
|
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{
|
params: %Schema{
|
||||||
type: :object,
|
type: :object,
|
||||||
required: [:text, :visibility],
|
required: [:text, :visibility],
|
||||||
|
@ -47,7 +48,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do
|
||||||
idempotency: nil,
|
idempotency: nil,
|
||||||
in_reply_to_id: nil
|
in_reply_to_id: nil
|
||||||
},
|
},
|
||||||
media_attachments: []
|
media_attachments: [Attachment.schema().example]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,17 +11,21 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityController do
|
||||||
alias Pleroma.ScheduledActivity
|
alias Pleroma.ScheduledActivity
|
||||||
alias Pleroma.Web.MastodonAPI.MastodonAPI
|
alias Pleroma.Web.MastodonAPI.MastodonAPI
|
||||||
|
|
||||||
plug(:assign_scheduled_activity when action != :index)
|
|
||||||
|
|
||||||
@oauth_read_actions [:show, :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: ["read:statuses"]} when action in @oauth_read_actions)
|
||||||
plug(OAuthScopesPlug, %{scopes: ["write:statuses"]} when action not 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)
|
action_fallback(Pleroma.Web.MastodonAPI.FallbackController)
|
||||||
|
|
||||||
|
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ScheduledActivityOperation
|
||||||
|
|
||||||
@doc "GET /api/v1/scheduled_statuses"
|
@doc "GET /api/v1/scheduled_statuses"
|
||||||
def index(%{assigns: %{user: user}} = conn, params) do
|
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
|
with scheduled_activities <- MastodonAPI.get_scheduled_activities(user, params) do
|
||||||
conn
|
conn
|
||||||
|> add_link_headers(scheduled_activities)
|
|> add_link_headers(scheduled_activities)
|
||||||
|
@ -35,7 +39,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityController do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "PUT /api/v1/scheduled_statuses/:id"
|
@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
|
with {:ok, scheduled_activity} <- ScheduledActivity.update(scheduled_activity, params) do
|
||||||
render(conn, "show.json", scheduled_activity: scheduled_activity)
|
render(conn, "show.json", scheduled_activity: scheduled_activity)
|
||||||
end
|
end
|
||||||
|
@ -48,7 +52,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityController do
|
||||||
end
|
end
|
||||||
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
|
case ScheduledActivity.get(user, id) do
|
||||||
%ScheduledActivity{} = activity -> assign(conn, :scheduled_activity, activity)
|
%ScheduledActivity{} = activity -> assign(conn, :scheduled_activity, activity)
|
||||||
nil -> Pleroma.Web.MastodonAPI.FallbackController.call(conn, {:error, :not_found}) |> halt()
|
nil -> Pleroma.Web.MastodonAPI.FallbackController.call(conn, {:error, :not_found}) |> halt()
|
||||||
|
|
|
@ -40,12 +40,18 @@ defmodule Pleroma.Tests.Helpers do
|
||||||
clear_config: 2
|
clear_config: 2
|
||||||
]
|
]
|
||||||
|
|
||||||
def to_datetime(naive_datetime) do
|
def to_datetime(%NaiveDateTime{} = naive_datetime) do
|
||||||
naive_datetime
|
naive_datetime
|
||||||
|> DateTime.from_naive!("Etc/UTC")
|
|> DateTime.from_naive!("Etc/UTC")
|
||||||
|> DateTime.truncate(:second)
|
|> DateTime.truncate(:second)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def to_datetime(datetime) when is_binary(datetime) do
|
||||||
|
datetime
|
||||||
|
|> NaiveDateTime.from_iso8601!()
|
||||||
|
|> to_datetime()
|
||||||
|
end
|
||||||
|
|
||||||
def collect_ids(collection) do
|
def collect_ids(collection) do
|
||||||
collection
|
collection
|
||||||
|> Enum.map(& &1.id)
|
|> Enum.map(& &1.id)
|
||||||
|
|
|
@ -24,19 +24,19 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
||||||
# min_id
|
# min_id
|
||||||
conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&min_id=#{scheduled_activity_id1}")
|
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
|
assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result
|
||||||
|
|
||||||
# since_id
|
# since_id
|
||||||
conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&since_id=#{scheduled_activity_id1}")
|
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
|
assert [%{"id" => ^scheduled_activity_id4}, %{"id" => ^scheduled_activity_id3}] = result
|
||||||
|
|
||||||
# max_id
|
# max_id
|
||||||
conn_res = get(conn, "/api/v1/scheduled_statuses?limit=2&max_id=#{scheduled_activity_id4}")
|
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
|
assert [%{"id" => ^scheduled_activity_id3}, %{"id" => ^scheduled_activity_id2}] = result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -46,12 +46,12 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
||||||
|
|
||||||
res_conn = get(conn, "/api/v1/scheduled_statuses/#{scheduled_activity.id}")
|
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()
|
assert scheduled_activity_id == scheduled_activity.id |> to_string()
|
||||||
|
|
||||||
res_conn = get(conn, "/api/v1/scheduled_statuses/404")
|
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
|
end
|
||||||
|
|
||||||
test "updates a scheduled activity" do
|
test "updates a scheduled activity" do
|
||||||
|
@ -74,22 +74,32 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
||||||
assert job.args == %{"activity_id" => scheduled_activity.id}
|
assert job.args == %{"activity_id" => scheduled_activity.id}
|
||||||
assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(scheduled_at)
|
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 =
|
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
|
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)
|
assert expected_scheduled_at == Pleroma.Web.CommonAPI.Utils.to_masto_date(new_scheduled_at)
|
||||||
job = refresh_record(job)
|
job = refresh_record(job)
|
||||||
|
|
||||||
assert DateTime.truncate(job.scheduled_at, :second) == to_datetime(new_scheduled_at)
|
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
|
end
|
||||||
|
|
||||||
test "deletes a scheduled activity" do
|
test "deletes a scheduled activity" do
|
||||||
|
@ -115,7 +125,7 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
|
|> 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(ScheduledActivity, scheduled_activity.id)
|
||||||
refute Repo.get(Oban.Job, job.id)
|
refute Repo.get(Oban.Job, job.id)
|
||||||
|
|
||||||
|
@ -124,6 +134,6 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityControllerTest do
|
||||||
|> assign(:user, user)
|
|> assign(:user, user)
|
||||||
|> delete("/api/v1/scheduled_statuses/#{scheduled_activity.id}")
|
|> 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
|
||||||
end
|
end
|
||||||
|
|
|
@ -402,11 +402,17 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
|
||||||
pleroma: %{mime_type: "image/png"}
|
pleroma: %{mime_type: "image/png"}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
api_spec = Pleroma.Web.ApiSpec.spec()
|
||||||
|
|
||||||
assert expected == StatusView.render("attachment.json", %{attachment: object})
|
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
|
# If theres a "id", use that instead of the generated one
|
||||||
object = Map.put(object, "id", 2)
|
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
|
end
|
||||||
|
|
||||||
test "put the url advertised in the Activity in to the url attribute" do
|
test "put the url advertised in the Activity in to the url attribute" do
|
||||||
|
|
Loading…
Reference in a new issue