Skip to content

Commit

Permalink
Merge pull request #53 from Frameio/develop
Browse files Browse the repository at this point in the history
Release 5/20 (v0.6.1)
  • Loading branch information
bceskavich authored May 21, 2019
2 parents 5db2824 + ddc3b55 commit 924b66f
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 31 deletions.
14 changes: 9 additions & 5 deletions lib/rolodex/content_utils.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,17 @@ defmodule Rolodex.ContentUtils do
Module.register_attribute(__MODULE__, :content_types, accumulate: true)
Module.register_attribute(__MODULE__, :current_content_type, accumulate: false)
Module.register_attribute(__MODULE__, :body_description, accumulate: false)
Module.register_attribute(__MODULE__, :headers, accumulate: false)
Module.register_attribute(__MODULE__, :headers, accumulate: true)

@body_description nil
@headers nil

unquote(block)

Module.delete_attribute(__MODULE__, :current_content_type)

def unquote(type)(:name), do: unquote(name)
def unquote(type)(:desc), do: @body_description
def unquote(type)(:headers), do: @headers
def unquote(type)(:headers), do: @headers |> Enum.reverse()
def unquote(type)(:content_types), do: @content_types |> Enum.reverse()
end
end
Expand Down Expand Up @@ -149,8 +148,13 @@ defmodule Rolodex.ContentUtils do
|> set_content_refs(data)
end

defp set_headers_ref(refs, %{headers: %{type: :ref, ref: ref}}), do: MapSet.put(refs, ref)
defp set_headers_ref(refs, _), do: refs
defp set_headers_ref(refs, %{headers: []}), do: refs

defp set_headers_ref(refs, %{headers: headers}),
do: Enum.reduce(headers, refs, &collect_headers_refs/2)

defp collect_headers_refs(%{type: :ref, ref: ref}, refs), do: MapSet.put(refs, ref)
defp collect_headers_refs(_, refs), do: refs

defp set_content_refs(refs, %{content: content}) do
Enum.reduce(content, refs, fn {_, %{schema: schema}}, acc ->
Expand Down
13 changes: 8 additions & 5 deletions lib/rolodex/processors/swagger.ex
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,24 @@ defmodule Rolodex.Processors.Swagger do
defp process_content_body_examples(examples),
do: Map.new(examples, fn {name, example} -> {name, %{value: example}} end)

defp process_content_body_headers(content, %{headers: nil}), do: content
defp process_content_body_headers(content, %{headers: []}), do: content

defp process_content_body_headers(content, %{headers: headers}),
do: Map.put(content, :headers, Enum.reduce(headers, %{}, &serialize_headers_group/2))

# OpenAPI 3 does not support using `$ref` syntax for reusable header components,
# so we need to serialize them out in full each time.
defp process_content_body_headers(content, %{headers: %{type: :ref, ref: ref}}) do
defp serialize_headers_group(%{type: :ref, ref: ref}, serialized) do
headers =
ref
|> Headers.to_map()
|> process_header_fields()

Map.put(content, :headers, headers)
Map.merge(serialized, headers)
end

defp process_content_body_headers(content, %{headers: headers}),
do: Map.put(content, :headers, process_header_fields(headers))
defp serialize_headers_group(headers, serialized),
do: Map.merge(serialized, process_header_fields(headers))

defp process_header_fields(fields) do
Map.new(fields, fn {header, value} -> {header, process_header_field(value)} end)
Expand Down
2 changes: 1 addition & 1 deletion lib/rolodex/request_body.ex
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ defmodule Rolodex.RequestBody do
iex> Rolodex.RequestBody.to_map(MyRequestBody)
%{
desc: "A demo request body",
headers: nil,
headers: [],
content: %{
"application/json" => %{
examples: %{
Expand Down
11 changes: 7 additions & 4 deletions lib/rolodex/response.ex
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ defmodule Rolodex.Response do

@doc """
Sets headers to be included in the response. You can use a shared headers ref
defined via `Rolodex.Headers`, or just pass in a bare map or keyword list.
defined via `Rolodex.Headers`, or just pass in a bare map or keyword list. If
the macro is called multiple times, all headers passed in will be merged together
in the docs result.
## Examples
Expand All @@ -81,6 +83,7 @@ defmodule Rolodex.Response do
response "MyResponse" do
headers MyResponseHeaders
headers MyAdditionalResponseHeaders
end
end
Expand Down Expand Up @@ -237,9 +240,9 @@ defmodule Rolodex.Response do
iex> Rolodex.Response.to_map(MyResponse)
%{
desc: "A demo response",
headers: %{
"X-Rate-Limited" => %{type: :boolean}
},
headers: [
%{"X-Rate-Limited" => %{type: :boolean}}
],
content: %{
"application/json" => %{
examples: %{
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Rolodex.MixProject do
app: :rolodex,
name: "Rolodex",
description: "Automated docs generation",
version: "0.6.0",
version: "0.6.1",
elixir: "~> 1.7",
elixirc_paths: elixirc_paths(Mix.env()),
start_permanent: Mix.env() == :prod,
Expand Down
2 changes: 1 addition & 1 deletion test/rolodex/request_body_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ defmodule Rolodex.RequestBodyTest do
test "It serializes the request body as expected" do
assert RequestBody.to_map(PaginatedUsersRequestBody) == %{
desc: "A paginated list of user entities",
headers: nil,
headers: [],
content: %{
"application/json" => %{
schema: %{
Expand Down
51 changes: 38 additions & 13 deletions test/rolodex/response_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule Rolodex.ResponseTest do
UserResponse,
UsersResponse,
PaginatedUsersResponse,
RateLimitHeaders,
ParentsResponse,
MultiResponse,
User,
Expand Down Expand Up @@ -36,17 +37,34 @@ defmodule Rolodex.ResponseTest do

describe "#set_headers/1 macro" do
test "It handles a shared headers module" do
assert UsersResponse.__response__(:headers) == %{
type: :ref,
ref: PaginationHeaders
}
assert UsersResponse.__response__(:headers) == [
%{
type: :ref,
ref: PaginationHeaders
}
]
end

test "It handles a bare map or kwl" do
assert ParentsResponse.__response__(:headers) == %{
"total" => %{type: :integer},
"per-page" => %{type: :integer, required: true}
}
assert ParentsResponse.__response__(:headers) == [
%{
"total" => %{type: :integer},
"per-page" => %{type: :integer, required: true}
}
]
end

test "It handles multiple headers" do
assert MultiResponse.__response__(:headers) == [
%{
type: :ref,
ref: PaginationHeaders
},
%{
type: :ref,
ref: RateLimitHeaders
}
]
end
end

Expand Down Expand Up @@ -112,10 +130,12 @@ defmodule Rolodex.ResponseTest do
test "It serializes the response as expected" do
assert Response.to_map(PaginatedUsersResponse) == %{
desc: "A paginated list of user entities",
headers: %{
type: :ref,
ref: PaginationHeaders
},
headers: [
%{
type: :ref,
ref: PaginationHeaders
}
],
content: %{
"application/json" => %{
schema: %{
Expand All @@ -140,7 +160,12 @@ defmodule Rolodex.ResponseTest do

describe "#get_refs/1" do
test "It gets refs within a response module" do
assert Response.get_refs(MultiResponse) == [Comment, PaginationHeaders, User]
assert Response.get_refs(MultiResponse) == [
Comment,
PaginationHeaders,
RateLimitHeaders,
User
]
end
end
end
35 changes: 35 additions & 0 deletions test/rolodex_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,40 @@ defmodule RolodexTest do
},
"description" => "An error response"
},
"MultiResponse" => %{
"description" => nil,
"headers" => %{
"total" => %{
"description" => "Total entries to be retrieved",
"schema" => %{"type" => "integer"}
},
"per-page" => %{
"description" => "Total entries per page of results",
"schema" => %{"type" => "integer"}
},
"limited" => %{
"description" => "Have you been rate limited",
"schema" => %{"type" => "boolean"}
}
},
"content" => %{
"application/json" => %{
"examples" => %{},
"schema" => %{
"$ref" => "#/components/schemas/User"
}
},
"application/lolsob" => %{
"examples" => %{},
"schema" => %{
"type" => "array",
"items" => %{
"$ref" => "#/components/schemas/Comment"
}
}
}
}
},
"PaginatedUsersResponse" => %{
"content" => %{
"application/json" => %{
Expand Down Expand Up @@ -406,6 +440,7 @@ defmodule RolodexTest do
"parameters" => [],
"responses" => %{
"200" => %{"$ref" => "#/components/responses/UserResponse"},
"201" => %{"$ref" => "#/components/responses/MultiResponse"},
"404" => %{"$ref" => "#/components/responses/ErrorResponse"}
},
"security" => [%{"JWTAuth" => []}],
Expand Down
2 changes: 2 additions & 0 deletions test/support/mocks/controllers.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule Rolodex.Mocks.TestController do
alias Rolodex.Mocks.{
UserRequestBody,
UserResponse,
MultiResponse,
PaginatedUsersResponse,
PaginationHeaders,
ErrorResponse
Expand Down Expand Up @@ -45,6 +46,7 @@ defmodule Rolodex.Mocks.TestController do
auth: :JWTAuth,
responses: %{
200 => UserResponse,
201 => MultiResponse,
404 => ErrorResponse
}
],
Expand Down
9 changes: 8 additions & 1 deletion test/support/mocks/responses.ex
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,17 @@ end

defmodule Rolodex.Mocks.MultiResponse do
use Rolodex.Response
alias Rolodex.Mocks.{Comment, PaginationHeaders, User}

alias Rolodex.Mocks.{
Comment,
PaginationHeaders,
RateLimitHeaders,
User
}

response "MultiResponse" do
headers(PaginationHeaders)
headers(RateLimitHeaders)

content "application/json" do
schema(User)
Expand Down

0 comments on commit 924b66f

Please sign in to comment.