Skip to content

Commit

Permalink
decode/1 function correctly populates the :extensions field of structs (
Browse files Browse the repository at this point in the history
  • Loading branch information
albertored authored and lucacorti committed Feb 13, 2022
1 parent 392d012 commit d1b9fa1
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
17 changes: 17 additions & 0 deletions lib/open_api_spex/open_api/decode.ex
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
|> prop_to_struct(:components, Components)
|> prop_to_struct(:tags, Tag)
|> prop_to_struct(:externalDocs, ExternalDocumentation)
|> add_extensions(map)
end

defp struct_from_map(struct, map) when is_atom(struct) do
Expand Down Expand Up @@ -142,6 +143,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
Tag
|> struct_from_map(map)
|> prop_to_struct(:externalDocs, ExternalDocumentation)
|> add_extensions(map)
end

defp to_struct(list, Tag) when is_list(list) do
Expand Down Expand Up @@ -177,6 +179,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
SecurityScheme
|> struct_from_map(map)
|> prop_to_struct(:flows, OAuthFlows)
|> add_extensions(map)
end

defp to_struct(map, SecuritySchemes), do: embedded_ref_or_struct(map, SecurityScheme)
Expand Down Expand Up @@ -280,6 +283,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
|> prop_to_struct(:requestBody, RequestBody)
|> prop_to_struct(:callbacks, Callbacks)
|> prop_to_struct(:servers, Server)
|> add_extensions(map)
end

defp to_struct(%{"$ref" => _} = map, RequestBody), do: struct_from_map(Reference, map)
Expand All @@ -301,6 +305,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
|> prop_to_struct(:examples, Examples)
|> prop_to_struct(:content, Content)
|> prop_to_struct(:schema, Schema)
|> add_extensions(map)
end

defp to_struct(map_or_list, Parameters), do: embedded_ref_or_struct(map_or_list, Parameter)
Expand Down Expand Up @@ -332,6 +337,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
|> prop_to_struct(:headers, Headers)
|> prop_to_struct(:content, Content)
|> prop_to_struct(:links, Links)
|> add_extensions(map)
end

defp to_struct(map, Responses), do: embedded_ref_or_struct(map, Response)
Expand Down Expand Up @@ -386,6 +392,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
|> prop_to_struct(:trace, Operation)
|> prop_to_struct(:parameters, Parameters)
|> prop_to_struct(:servers, Servers)
|> add_extensions(map)
end

defp to_struct(map, PathItems) do
Expand All @@ -400,6 +407,7 @@ defmodule OpenApiSpex.OpenApi.Decode do
|> struct_from_map(map)
|> prop_to_struct(:contact, Contact)
|> prop_to_struct(:license, License)
|> add_extensions(map)
end

defp to_struct(list, mod) when is_list(list) and is_atom(mod),
Expand Down Expand Up @@ -429,4 +437,13 @@ defmodule OpenApiSpex.OpenApi.Decode do
end

defp manage_additional_properties(map), do: map

defp add_extensions(struct, map) do
extensions =
map
|> Enum.filter(fn {key, _val} -> String.starts_with?(key, "x-") end)
|> Map.new()

Map.put(struct, :extensions, if(map_size(extensions) == 0, do: nil, else: extensions))
end
end
23 changes: 18 additions & 5 deletions test/open_api/decode_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,17 @@ defmodule OpenApiSpex.OpenApi.DecodeTest do
version: _version,
description: _description,
contact: contact,
license: license
license: license,
extensions: info_extensions
} = info

assert %OpenApiSpex.Contact{} = contact

assert %OpenApiSpex.License{} = license

assert nil == extensions
assert info_extensions == %{"x-extension" => "foo"}

assert %{"x-extension" => %{"value" => "haha"}} == extensions

assert %OpenApiSpex.ExternalDocumentation{
description: _,
Expand Down Expand Up @@ -154,7 +157,8 @@ defmodule OpenApiSpex.OpenApi.DecodeTest do
schema: %OpenApiSpex.Schema{
example: "gzip",
type: :string
}
},
extensions: %{"x-extension" => "foo"}
} == components_parameters_parameter

assert %{
Expand Down Expand Up @@ -228,14 +232,18 @@ defmodule OpenApiSpex.OpenApi.DecodeTest do
} == link

assert %{
"api_key" => _api_key_security_scheme,
"api_key" => api_key_security_scheme,
"petstore_auth" => petstore_auth_security_scheme
} = securitySchemes

assert %OpenApiSpex.SecurityScheme{
flows: oauth_flows
} = petstore_auth_security_scheme

assert %OpenApiSpex.SecurityScheme{
extensions: %{"x-extension" => "foo"}
} = api_key_security_scheme

assert %OpenApiSpex.OAuthFlows{
implicit: oauth_flow
} = oauth_flows
Expand Down Expand Up @@ -278,6 +286,7 @@ defmodule OpenApiSpex.OpenApi.DecodeTest do
assert [tag] = tags

assert %OpenApiSpex.Tag{
extensions: %{"x-extension" => "foo"},
description: "Pets operations",
externalDocs: %OpenApiSpex.ExternalDocumentation{
description: "Find more info here",
Expand All @@ -296,13 +305,15 @@ defmodule OpenApiSpex.OpenApi.DecodeTest do
"/example" => %OpenApiSpex.PathItem{
summary: "/example summary",
description: "/example description",
extensions: %{"x-extension" => "foo"},
servers: [%OpenApiSpex.Server{}],
parameters: [
%OpenApiSpex.Reference{
"$ref": "#/components/parameters/ContentTypeHeader"
}
],
post: %OpenApiSpex.Operation{
extensions: %{"x-extension" => "foo"},
parameters: [
%OpenApiSpex.Reference{},
%OpenApiSpex.Reference{},
Expand Down Expand Up @@ -346,7 +357,9 @@ defmodule OpenApiSpex.OpenApi.DecodeTest do
] == operationSecurity

assert %{
"200" => %OpenApiSpex.Response{}
"200" => %OpenApiSpex.Response{
extensions: %{"x-extension" => "foo"}
}
} = operationResponses

assert %{
Expand Down
14 changes: 11 additions & 3 deletions test/support/encoded_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"name": "test"
},
"title": "Duffel Technology Ltd.",
"version": "1.0.0"
"version": "1.0.0",
"x-extension": "foo"
},
"x-extension": {
"value": "haha"
Expand Down Expand Up @@ -43,7 +44,8 @@
"schema": {
"example": "gzip",
"type": "string"
}
},
"x-extension": "foo"
}
},
"headers": {
Expand Down Expand Up @@ -83,6 +85,7 @@
},
"securitySchemes": {
"api_key": {
"x-extension": "foo",
"type": "apiKey",
"name": "api_key",
"in": "header"
Expand Down Expand Up @@ -319,9 +322,11 @@
},
"paths": {
"/example": {
"x-extension": "foo",
"summary": "/example summary",
"description": "/example description",
"post": {
"x-extension": "foo",
"operationId": "example-post-test",
"callbacks": {
"operationCallback": {
Expand Down Expand Up @@ -445,6 +450,7 @@
},
"responses": {
"200": {
"x-extension": "foo",
"content": {
"application/json": {
"example": {
Expand Down Expand Up @@ -483,6 +489,7 @@
},
"responses": {
"200": {
"x-extension": "foo",
"content": {
"application/json": {
"example": {
Expand Down Expand Up @@ -543,7 +550,8 @@
"externalDocs": {
"description": "Find more info here",
"url": "https://example.com"
}
},
"x-extension": "foo"
}
],
"externalDocs": {
Expand Down

0 comments on commit d1b9fa1

Please sign in to comment.