Chats: Add API specs.

This commit is contained in:
lain 2020-04-21 17:51:06 +02:00
parent a185b5455f
commit 97ad0c4597
7 changed files with 346 additions and 33 deletions

View file

@ -4,7 +4,12 @@
defmodule Pleroma.Web.ApiSpec.ChatOperation do defmodule Pleroma.Web.ApiSpec.ChatOperation do
alias OpenApiSpex.Operation alias OpenApiSpex.Operation
alias OpenApiSpex.Schema alias Pleroma.Web.ApiSpec.Helpers
alias Pleroma.Web.ApiSpec.Schemas.ChatMessageCreateRequest
alias Pleroma.Web.ApiSpec.Schemas.ChatMessageResponse
alias Pleroma.Web.ApiSpec.Schemas.ChatMessagesResponse
alias Pleroma.Web.ApiSpec.Schemas.ChatResponse
alias Pleroma.Web.ApiSpec.Schemas.ChatsResponse
@spec open_api_operation(atom) :: Operation.t() @spec open_api_operation(atom) :: Operation.t()
def open_api_operation(action) do def open_api_operation(action) do
@ -16,16 +21,25 @@ def create_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["chat"],
summary: "Create a chat", summary: "Create a chat",
parameters: [
Operation.parameter(
:ap_id,
:path,
:string,
"The ActivityPub id of the recipient of this chat.",
required: true,
example: "https://lain.com/users/lain"
)
],
responses: %{ responses: %{
200 => 200 =>
Operation.response("Chat", "application/json", %Schema{ Operation.response("The created or existing chat", "application/json", ChatResponse)
type: :object, },
description: "A created chat is returned", security: [
properties: %{ %{
id: %Schema{type: :integer} "oAuth" => ["write"]
}
})
} }
]
} }
end end
@ -33,17 +47,19 @@ def index_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["chat"],
summary: "Get a list of chats that you participated in", summary: "Get a list of chats that you participated in",
parameters: [
Operation.parameter(:limit, :query, :integer, "How many results to return", example: 20),
Operation.parameter(:min_id, :query, :string, "Return only chats after this id"),
Operation.parameter(:max_id, :query, :string, "Return only chats before this id")
],
responses: %{ responses: %{
200 => 200 => Operation.response("The chats of the user", "application/json", ChatsResponse)
Operation.response("Chats", "application/json", %Schema{ },
type: :array, security: [
description: "A list of chats", %{
items: %Schema{ "oAuth" => ["read"]
type: :object,
description: "A chat"
}
})
} }
]
} }
end end
@ -51,17 +67,21 @@ def messages_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["chat"],
summary: "Get the most recent messages of the chat", summary: "Get the most recent messages of the chat",
parameters: [
Operation.parameter(:id, :path, :string, "The ID of the Chat"),
Operation.parameter(:limit, :query, :integer, "How many results to return", example: 20),
Operation.parameter(:min_id, :query, :string, "Return only messages after this id"),
Operation.parameter(:max_id, :query, :string, "Return only messages before this id")
],
responses: %{ responses: %{
200 => 200 =>
Operation.response("Messages", "application/json", %Schema{ Operation.response("The messages in the chat", "application/json", ChatMessagesResponse)
type: :array, },
description: "A list of chat messages", security: [
items: %Schema{ %{
type: :object, "oAuth" => ["read"]
description: "A chat message"
}
})
} }
]
} }
end end
@ -69,13 +89,23 @@ def post_chat_message_operation do
%Operation{ %Operation{
tags: ["chat"], tags: ["chat"],
summary: "Post a message to the chat", summary: "Post a message to the chat",
parameters: [
Operation.parameter(:id, :path, :string, "The ID of the Chat")
],
requestBody: Helpers.request_body("Parameters", ChatMessageCreateRequest, required: true),
responses: %{ responses: %{
200 => 200 =>
Operation.response("Message", "application/json", %Schema{ Operation.response(
type: :object, "The newly created ChatMessage",
description: "A chat message" "application/json",
}) ChatMessageResponse
)
},
security: [
%{
"oAuth" => ["write"]
} }
]
} }
end end
end end

View file

@ -0,0 +1,20 @@
# 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.Schemas.ChatMessageCreateRequest do
alias OpenApiSpex.Schema
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ChatMessageCreateRequest",
description: "POST body for creating an chat message",
type: :object,
properties: %{
content: %Schema{type: :string, description: "The content of your message"}
},
example: %{
"content" => "Hey wanna buy feet pics?"
}
})
end

View file

@ -0,0 +1,38 @@
# 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.Schemas.ChatMessageResponse do
alias OpenApiSpex.Schema
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ChatMessageResponse",
description: "Response schema for a ChatMessage",
type: :object,
properties: %{
id: %Schema{type: :string},
actor: %Schema{type: :string, description: "The ActivityPub id of the actor"},
chat_id: %Schema{type: :string},
content: %Schema{type: :string},
created_at: %Schema{type: :string, format: :datetime},
emojis: %Schema{type: :array}
},
example: %{
"actor" => "https://dontbulling.me/users/lain",
"chat_id" => "1",
"content" => "hey you again",
"created_at" => "2020-04-21T15:06:45.000Z",
"emojis" => [
%{
"static_url" => "https://dontbulling.me/emoji/Firefox.gif",
"visible_in_picker" => false,
"shortcode" => "firefox",
"url" => "https://dontbulling.me/emoji/Firefox.gif"
}
],
"id" => "14"
}
})
end

View file

@ -0,0 +1,41 @@
# 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.Schemas.ChatMessagesResponse do
alias Pleroma.Web.ApiSpec.Schemas.ChatMessageResponse
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ChatMessagesResponse",
description: "Response schema for multiple ChatMessages",
type: :array,
items: ChatMessageResponse,
example: [
%{
"emojis" => [
%{
"static_url" => "https://dontbulling.me/emoji/Firefox.gif",
"visible_in_picker" => false,
"shortcode" => "firefox",
"url" => "https://dontbulling.me/emoji/Firefox.gif"
}
],
"created_at" => "2020-04-21T15:11:46.000Z",
"content" => "Check this out :firefox:",
"id" => "13",
"chat_id" => "1",
"actor" => "https://dontbulling.me/users/lain"
},
%{
"actor" => "https://dontbulling.me/users/lain",
"content" => "Whats' up?",
"id" => "12",
"chat_id" => "1",
"emojis" => [],
"created_at" => "2020-04-21T15:06:45.000Z"
}
]
})
end

View file

@ -0,0 +1,73 @@
# 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.Schemas.ChatResponse do
alias OpenApiSpex.Schema
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ChatResponse",
description: "Response schema for a Chat",
type: :object,
properties: %{
id: %Schema{type: :string},
recipient: %Schema{type: :string},
# TODO: Make this reference the account structure.
recipient_account: %Schema{type: :object},
unread: %Schema{type: :integer}
},
example: %{
"recipient" => "https://dontbulling.me/users/lain",
"recipient_account" => %{
"pleroma" => %{
"is_admin" => false,
"confirmation_pending" => false,
"hide_followers_count" => false,
"is_moderator" => false,
"hide_favorites" => true,
"ap_id" => "https://dontbulling.me/users/lain",
"hide_follows_count" => false,
"hide_follows" => false,
"background_image" => nil,
"skip_thread_containment" => false,
"hide_followers" => false,
"relationship" => %{},
"tags" => []
},
"avatar" =>
"https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg",
"following_count" => 0,
"header_static" => "https://originalpatchou.li/images/banner.png",
"source" => %{
"sensitive" => false,
"note" => "lain",
"pleroma" => %{
"discoverable" => false,
"actor_type" => "Person"
},
"fields" => []
},
"statuses_count" => 1,
"locked" => false,
"created_at" => "2020-04-16T13:40:15.000Z",
"display_name" => "lain",
"fields" => [],
"acct" => "lain@dontbulling.me",
"id" => "9u6Qw6TAZANpqokMkK",
"emojis" => [],
"avatar_static" =>
"https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg",
"username" => "lain",
"followers_count" => 0,
"header" => "https://originalpatchou.li/images/banner.png",
"bot" => false,
"note" => "lain",
"url" => "https://dontbulling.me/users/lain"
},
"id" => "1",
"unread" => 2
}
})
end

View file

@ -0,0 +1,69 @@
# 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.Schemas.ChatsResponse do
alias Pleroma.Web.ApiSpec.Schemas.ChatResponse
require OpenApiSpex
OpenApiSpex.schema(%{
title: "ChatsResponse",
description: "Response schema for multiple Chats",
type: :array,
items: ChatResponse,
example: [
%{
"recipient" => "https://dontbulling.me/users/lain",
"recipient_account" => %{
"pleroma" => %{
"is_admin" => false,
"confirmation_pending" => false,
"hide_followers_count" => false,
"is_moderator" => false,
"hide_favorites" => true,
"ap_id" => "https://dontbulling.me/users/lain",
"hide_follows_count" => false,
"hide_follows" => false,
"background_image" => nil,
"skip_thread_containment" => false,
"hide_followers" => false,
"relationship" => %{},
"tags" => []
},
"avatar" =>
"https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg",
"following_count" => 0,
"header_static" => "https://originalpatchou.li/images/banner.png",
"source" => %{
"sensitive" => false,
"note" => "lain",
"pleroma" => %{
"discoverable" => false,
"actor_type" => "Person"
},
"fields" => []
},
"statuses_count" => 1,
"locked" => false,
"created_at" => "2020-04-16T13:40:15.000Z",
"display_name" => "lain",
"fields" => [],
"acct" => "lain@dontbulling.me",
"id" => "9u6Qw6TAZANpqokMkK",
"emojis" => [],
"avatar_static" =>
"https://dontbulling.me/media/065a4dd3c6740dab13ff9c71ec7d240bb9f8be9205c9e7467fb2202117da1e32.jpg",
"username" => "lain",
"followers_count" => 0,
"header" => "https://originalpatchou.li/images/banner.png",
"bot" => false,
"note" => "lain",
"url" => "https://dontbulling.me/users/lain"
},
"id" => "1",
"unread" => 2
}
]
})
end

View file

@ -5,8 +5,14 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do
use Pleroma.Web.ConnCase, async: true use Pleroma.Web.ConnCase, async: true
alias Pleroma.Chat alias Pleroma.Chat
alias Pleroma.Web.ApiSpec
alias Pleroma.Web.ApiSpec.Schemas.ChatResponse
alias Pleroma.Web.ApiSpec.Schemas.ChatsResponse
alias Pleroma.Web.ApiSpec.Schemas.ChatMessageResponse
alias Pleroma.Web.ApiSpec.Schemas.ChatMessagesResponse
alias Pleroma.Web.CommonAPI alias Pleroma.Web.CommonAPI
import OpenApiSpex.TestAssertions
import Pleroma.Factory import Pleroma.Factory
describe "POST /api/v1/pleroma/chats/:id/messages" do describe "POST /api/v1/pleroma/chats/:id/messages" do
@ -24,6 +30,7 @@ test "it posts a message to the chat", %{conn: conn, user: user} do
assert result["content"] == "Hallo!!" assert result["content"] == "Hallo!!"
assert result["chat_id"] == chat.id |> to_string() assert result["chat_id"] == chat.id |> to_string()
assert_schema(result, "ChatMessageResponse", ApiSpec.spec())
end end
end end
@ -45,6 +52,7 @@ test "it paginates", %{conn: conn, user: user} do
|> json_response(200) |> json_response(200)
assert length(result) == 20 assert length(result) == 20
assert_schema(result, "ChatMessagesResponse", ApiSpec.spec())
result = result =
conn conn
@ -52,6 +60,7 @@ test "it paginates", %{conn: conn, user: user} do
|> json_response(200) |> json_response(200)
assert length(result) == 10 assert length(result) == 10
assert_schema(result, "ChatMessagesResponse", ApiSpec.spec())
end end
test "it returns the messages for a given chat", %{conn: conn, user: user} do test "it returns the messages for a given chat", %{conn: conn, user: user} do
@ -76,6 +85,7 @@ test "it returns the messages for a given chat", %{conn: conn, user: user} do
end) end)
assert length(result) == 3 assert length(result) == 3
assert_schema(result, "ChatMessagesResponse", ApiSpec.spec())
# Trying to get the chat of a different user # Trying to get the chat of a different user
result = result =
@ -99,6 +109,7 @@ test "it creates or returns a chat", %{conn: conn} do
|> json_response(200) |> json_response(200)
assert result["id"] assert result["id"]
assert_schema(result, "ChatResponse", ApiSpec.spec())
end end
end end
@ -117,6 +128,7 @@ test "it paginates", %{conn: conn, user: user} do
|> json_response(200) |> json_response(200)
assert length(result) == 20 assert length(result) == 20
assert_schema(result, "ChatsResponse", ApiSpec.spec())
result = result =
conn conn
@ -124,6 +136,8 @@ test "it paginates", %{conn: conn, user: user} do
|> json_response(200) |> json_response(200)
assert length(result) == 10 assert length(result) == 10
assert_schema(result, "ChatsResponse", ApiSpec.spec())
end end
test "it return a list of chats the current user is participating in, in descending order of updates", test "it return a list of chats the current user is participating in, in descending order of updates",
@ -154,6 +168,34 @@ test "it return a list of chats the current user is participating in, in descend
chat_3.id |> to_string(), chat_3.id |> to_string(),
chat_1.id |> to_string() chat_1.id |> to_string()
] ]
assert_schema(result, "ChatsResponse", ApiSpec.spec())
end
end
describe "schemas" do
test "Chat example matches schema" do
api_spec = ApiSpec.spec()
schema = ChatResponse.schema()
assert_schema(schema.example, "ChatResponse", api_spec)
end
test "Chats example matches schema" do
api_spec = ApiSpec.spec()
schema = ChatsResponse.schema()
assert_schema(schema.example, "ChatsResponse", api_spec)
end
test "ChatMessage example matches schema" do
api_spec = ApiSpec.spec()
schema = ChatMessageResponse.schema()
assert_schema(schema.example, "ChatMessageResponse", api_spec)
end
test "ChatsMessage example matches schema" do
api_spec = ApiSpec.spec()
schema = ChatMessagesResponse.schema()
assert_schema(schema.example, "ChatMessagesResponse", api_spec)
end end
end end
end end