Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support passing a %Reference{} as a response when doing controller specs #532

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions examples/phoenix_app/lib/phoenix_app_web/api_spec.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ defmodule PhoenixAppWeb.ApiSpec do
}
}
}
},
schemas: %{
responses: %{
unprocessable_entity: %Response{
description: "Unprocessable Entity",
content: %{"application/json" => %MediaType{schema: %Schema{type: :object}}}
}
}
}
},
security: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule PhoenixAppWeb.UserController do
use PhoenixAppWeb, :controller
use OpenApiSpex.ControllerSpecs

alias OpenApiSpex.Schema
alias OpenApiSpex.{Schema, Reference}
alias PhoenixApp.{Accounts, Accounts.User}
alias PhoenixAppWeb.Schemas

Expand All @@ -23,6 +23,7 @@ defmodule PhoenixAppWeb.UserController do
description: "List all users",
responses: [
ok: {"User List Response", "application/json", Schemas.UsersResponse}
unprocessable_entity: %Reference{"$ref": "#/components/responses/unprocessable_entity"},
]

def index(conn, _params) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule PhoenixAppWeb.UserControllerWithStructSpecs do
"""
use PhoenixAppWeb, :controller
import OpenApiSpex.Operation, only: [parameter: 5, request_body: 4, response: 3]
alias OpenApiSpex.Operation
alias OpenApiSpex.{Operation, Reference}
alias PhoenixApp.{Accounts, Accounts.User}
alias PhoenixAppWeb.Schemas

Expand Down Expand Up @@ -36,6 +36,7 @@ defmodule PhoenixAppWeb.UserControllerWithStructSpecs do
operationId: "UserController.index",
responses: %{
200 => response("User List Response", "application/json", Schemas.UsersResponse)
422 => %Reference{"$ref": "#/components/responses/unprocessable_entity"},
}
}
end
Expand Down
2 changes: 1 addition & 1 deletion lib/open_api_spex/operation_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ defmodule OpenApiSpex.OperationBuilder do
{status, {description, mime, schema, opts}} ->
{status_to_code(status), Operation.response(description, mime, schema, opts)}

{status, %Response{} = response} ->
{status, %struct{} = response} when struct in [Reference, Response] ->
{status_to_code(status), response}

{status, description} when is_binary(description) ->
Expand Down
4 changes: 4 additions & 0 deletions test/controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ defmodule OpenApiSpex.ControllerTest do
assert %{responses: %{404 => _}} = @controller.open_api_operation(:update)
end

test "has response as reference for HTTP 422" do
assert %{responses: %{422 => %Reference{}}} = @controller.open_api_operation(:update)
end

test "has default response" do
assert %{responses: %{:default => _}} = @controller.open_api_operation(:update)
end
Expand Down
11 changes: 9 additions & 2 deletions test/support/api_spec.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
defmodule OpenApiSpexTest.ApiSpec do
alias OpenApiSpex.{
Components,
Components,
Contact,
Info,
Expand All @@ -9,7 +8,9 @@ defmodule OpenApiSpexTest.ApiSpec do
Parameter,
Paths,
Schema,
Server
Server,
Response,
MediaType
}

alias OpenApiSpexTest.{Router, Schemas}
Expand Down Expand Up @@ -73,6 +74,12 @@ defmodule OpenApiSpexTest.ApiSpec do
required: true,
example: 12
}
},
responses: %{
unprocessable_entity: %Response{
description: "Unprocessable Entity",
content: %{"application/json" => %MediaType{schema: %Schema{type: :object}}}
}
}
},
paths: Paths.from_router(Router)
Expand Down
3 changes: 2 additions & 1 deletion test/support/user_controller_annotated.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule OpenApiSpexTest.UserControllerAnnotated do
@moduledoc tags: ["User"]

use OpenApiSpex.Controller
alias OpenApiSpex.Header
alias OpenApiSpex.{Header, Reference}
alias OpenApiSpexTest.Schemas.{GenericError, NotFound, Unauthorized, User}

@doc """
Expand All @@ -27,6 +27,7 @@ defmodule OpenApiSpexTest.UserControllerAnnotated do
},
unauthorized: Unauthorized.response(),
not_found: NotFound.response(),
unprocessable_entity: %Reference{"$ref": "#/components/responses/unprocessable_entity"},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the referenced response defined? In the tests we should show how such references are mean to be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like this? 0ccecab

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also update examples/phoenix_app showing how this can be used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work? a3824e4

default: GenericError.response()
]
@doc security: [%{"authorization" => []}]
Expand Down