From 77642feba69b3ac195cd72f695d4d1b129a237eb Mon Sep 17 00:00:00 2001 From: marcos ferreira Date: Wed, 5 Apr 2023 16:49:45 -0300 Subject: [PATCH 1/4] Support passing a %Reference{} as a response when doing controller specs --- lib/open_api_spex/operation_builder.ex | 2 +- test/controller_test.exs | 4 ++++ test/support/user_controller_annotated.ex | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/lib/open_api_spex/operation_builder.ex b/lib/open_api_spex/operation_builder.ex index ab81897b..6802c286 100644 --- a/lib/open_api_spex/operation_builder.ex +++ b/lib/open_api_spex/operation_builder.ex @@ -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) -> diff --git a/test/controller_test.exs b/test/controller_test.exs index 987e23b9..60d85422 100644 --- a/test/controller_test.exs +++ b/test/controller_test.exs @@ -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 diff --git a/test/support/user_controller_annotated.ex b/test/support/user_controller_annotated.ex index fa17e15c..811c6ed2 100644 --- a/test/support/user_controller_annotated.ex +++ b/test/support/user_controller_annotated.ex @@ -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 """ @@ -27,6 +27,7 @@ defmodule OpenApiSpexTest.UserControllerAnnotated do }, unauthorized: Unauthorized.response(), not_found: NotFound.response(), + unprocessable_entity: %Reference{"$ref": "#/components/responses/unprocessable_entity"}, default: GenericError.response() ] @doc security: [%{"authorization" => []}] From 43f11c8cafb0e6d3a11bb69f7edbfe3e44bc550b Mon Sep 17 00:00:00 2001 From: marcos ferreira Date: Fri, 7 Apr 2023 11:09:06 -0300 Subject: [PATCH 2/4] Remove unused alias in example test api spec --- test/support/api_spec.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/test/support/api_spec.ex b/test/support/api_spec.ex index a622f0f3..2d28ae86 100644 --- a/test/support/api_spec.ex +++ b/test/support/api_spec.ex @@ -1,6 +1,5 @@ defmodule OpenApiSpexTest.ApiSpec do alias OpenApiSpex.{ - Components, Components, Contact, Info, From 0ccecab534ea1ed425a3bc390b73d761b35a89c7 Mon Sep 17 00:00:00 2001 From: marcos ferreira Date: Fri, 7 Apr 2023 11:12:51 -0300 Subject: [PATCH 3/4] fixup! Support passing a %Reference{} as a response when doing controller specs --- test/support/api_spec.ex | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/support/api_spec.ex b/test/support/api_spec.ex index 2d28ae86..5c2629af 100644 --- a/test/support/api_spec.ex +++ b/test/support/api_spec.ex @@ -8,7 +8,9 @@ defmodule OpenApiSpexTest.ApiSpec do Parameter, Paths, Schema, - Server + Server, + Response, + MediaType } alias OpenApiSpexTest.{Router, Schemas} @@ -72,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) From a3824e4286c417657ca94f795c117dd15530201e Mon Sep 17 00:00:00 2001 From: marcos ferreira Date: Fri, 7 Apr 2023 11:31:33 -0300 Subject: [PATCH 4/4] Add examples using references for responses --- examples/phoenix_app/lib/phoenix_app_web/api_spec.ex | 8 ++++++++ .../lib/phoenix_app_web/controllers/user_controller.ex | 3 ++- .../controllers/user_controller_with_struct_specs.ex | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/examples/phoenix_app/lib/phoenix_app_web/api_spec.ex b/examples/phoenix_app/lib/phoenix_app_web/api_spec.ex index e9c8b7ea..0ca50fcc 100644 --- a/examples/phoenix_app/lib/phoenix_app_web/api_spec.ex +++ b/examples/phoenix_app/lib/phoenix_app_web/api_spec.ex @@ -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: [ diff --git a/examples/phoenix_app/lib/phoenix_app_web/controllers/user_controller.ex b/examples/phoenix_app/lib/phoenix_app_web/controllers/user_controller.ex index e75660c1..f437e7dd 100644 --- a/examples/phoenix_app/lib/phoenix_app_web/controllers/user_controller.ex +++ b/examples/phoenix_app/lib/phoenix_app_web/controllers/user_controller.ex @@ -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 @@ -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 diff --git a/examples/phoenix_app/lib/phoenix_app_web/controllers/user_controller_with_struct_specs.ex b/examples/phoenix_app/lib/phoenix_app_web/controllers/user_controller_with_struct_specs.ex index ddfd5158..97031496 100644 --- a/examples/phoenix_app/lib/phoenix_app_web/controllers/user_controller_with_struct_specs.ex +++ b/examples/phoenix_app/lib/phoenix_app_web/controllers/user_controller_with_struct_specs.ex @@ -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 @@ -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