Skip to content

Commit

Permalink
Support response code ranges
Browse files Browse the repository at this point in the history
  • Loading branch information
zorbash committed Apr 30, 2024
1 parent 12dc58f commit 8898859
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 5 deletions.
5 changes: 5 additions & 0 deletions lib/open_api_spex/operation_builder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ defmodule OpenApiSpex.OperationBuilder do
def build_responses(_), do: []

defp status_to_code(:default), do: :default

defp status_to_code(status)
when status in [:"1XX", "1XX", :"2XX", "2XX", :"3XX", "3XX", :"4XX", "4XX", :"5XX", "5XX"],
do: status

defp status_to_code(status), do: Status.code(status)

def build_request_body(%{body: {description, media_type, schema}}) do
Expand Down
14 changes: 11 additions & 3 deletions lib/open_api_spex/test/test_assertions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,18 @@ defmodule OpenApiSpex.TestAssertions do
defp validate_operation_response(conn, %Operation{operationId: operation_id} = operation, spec) do
content_type = Utils.content_type_from_header(conn, :response)

responses = Map.get(operation, :responses, %{})
code_range = String.first(to_string(conn.status)) <> "XX"

response =
Map.get(responses, conn.status) ||
Map.get(responses, "#{conn.status}") ||
Map.get(responses, :"#{conn.status}") ||
Map.get(responses, code_range) ||
Map.get(responses, :"#{code_range}", %{})

resolved_schema =
operation
|> Map.get(:responses, %{})
|> Map.get(conn.status, %{})
response
|> Map.get(:content, %{})
|> Map.get(content_type, %{})
|> Map.get(:schema)
Expand Down
4 changes: 3 additions & 1 deletion test/support/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ defmodule OpenApiSpexTest.Router do
get "/noapi", OpenApiSpexTest.NoApiController, :noapi
get "/noapi_with_struct", OpenApiSpexTest.NoApiControllerWithStructSpecs, :noapi

resources "/users_no_replace", OpenApiSpexTest.UserNoRepalceController, only: [:create, :index]
get "/response_code_ranges", OpenApiSpexTest.ResponseCodeRangesController, :index

resources "/users_no_replace", OpenApiSpexTest.UserNoReplaceController, only: [:create, :index]

# Used by ParamsTest
resources "/custom_error_users", OpenApiSpexTest.CustomErrorUserController, only: [:index]
Expand Down
58 changes: 58 additions & 0 deletions test/support/string_response_codes_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
defmodule OpenApiSpexTest.ResponseCodeRangesController do
use Phoenix.Controller
use OpenApiSpex.ControllerSpecs

alias OpenApiSpex.Operation

defmodule GenericResponse do
alias OpenApiSpex.Schema
require OpenApiSpex

OpenApiSpex.schema(%{
type: :object,
properties: %{
type: %Schema{
type: :string,
enum: ["generic"]
}
}
})
end

defmodule CreatedResponse do
alias OpenApiSpex.Schema
require OpenApiSpex

OpenApiSpex.schema(%{
type: :object,
properties: %{
type: %Schema{
type: :string,
enum: ["created"]
}
}
})
end

operation :index,
operation_id: "response_code_ranges",
summary: "String response codes index",
responses: [
created:
Operation.response(
"Created response",
"application/json",
CreatedResponse
),
"2XX":
Operation.response(
"Generic response",
"application/json",
GenericResponse
)
]

def index(conn, _) do
json(conn, %{type: "generic"})
end
end
2 changes: 1 addition & 1 deletion test/support/user_no_replace_controller.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule OpenApiSpexTest.UserNoRepalceController do
defmodule OpenApiSpexTest.UserNoReplaceController do
@moduledoc tags: ["users_no_replace"]

use Phoenix.Controller
Expand Down
12 changes: 12 additions & 0 deletions test/test_assertions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,18 @@ defmodule OpenApiSpex.TestAssertionsTest do
TestAssertions.assert_operation_response(conn)
end

test "success with a response code range" do
conn =
:get
|> Plug.Test.conn("/api/response_code_ranges")
|> Plug.Conn.put_req_header("content-type", "application/json")

conn = OpenApiSpexTest.Router.call(conn, [])

assert conn.status == 200
TestAssertions.assert_operation_response(conn, "response_code_ranges")
end

test "missing operation id" do
conn =
:get
Expand Down

0 comments on commit 8898859

Please sign in to comment.