Skip to content

Commit

Permalink
Resolve schema modules in discriminator mapping (#511) - Fixes (#387)
Browse files Browse the repository at this point in the history
Schema modules may now be used in discriminator mapping
  • Loading branch information
mbuhot authored Nov 14, 2022
1 parent 8fffa58 commit f54a044
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 4 deletions.
27 changes: 26 additions & 1 deletion lib/open_api_spex/schema_resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ defmodule OpenApiSpex.SchemaResolver do
@moduledoc """
Internal module used to resolve `OpenApiSpex.Schema` structs from atoms.
"""
alias OpenApiSpex.Discriminator

alias OpenApiSpex.{
Components,
MediaType,
Expand Down Expand Up @@ -228,6 +230,9 @@ defmodule OpenApiSpex.SchemaResolver do
{properties, schemas} =
resolve_schema_modules_from_schema_properties(schema.properties, schemas)

{discriminator, schemas} =
resolve_schema_modules_from_discriminator(schema.discriminator, schemas)

schema = %{
schema
| allOf: all_of,
Expand All @@ -236,7 +241,8 @@ defmodule OpenApiSpex.SchemaResolver do
not: not_schema,
items: items,
additionalProperties: additional,
properties: properties
properties: properties,
discriminator: discriminator
}

{schema, schemas}
Expand All @@ -257,4 +263,23 @@ defmodule OpenApiSpex.SchemaResolver do
defp resolve_schema_modules_from_schema_properties(properties, _schemas) do
raise "Expected :properties to be a map. Got: #{inspect(properties)}"
end

defp resolve_schema_modules_from_discriminator(
discriminator = %Discriminator{mapping: mapping = %{}},
schemas
) do
{mapping, schemas} =
Enum.map_reduce(mapping, schemas, fn
{key, module}, schemas when is_atom(module) ->
{%Reference{"$ref": path}, schemas} = resolve_schema_modules_from_schema(module, schemas)
{{key, path}, schemas}

{key, path}, schemas ->
{{key, path}, schemas}
end)

{%{discriminator | mapping: Map.new(mapping)}, schemas}
end

defp resolve_schema_modules_from_discriminator(disciminator, schemas), do: {disciminator, schemas}
end
30 changes: 29 additions & 1 deletion test/schema_resolver_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,25 @@ defmodule OpenApiSpex.SchemaResolverTest do
}
}
}
},
"/api/appointsments" => %PathItem{
post: %Operation{
description: "Create a new pet appointment",
operationId: "PetAppointmentController.create",
requestBody: %RequestBody{
required: true,
content: %{
"application/json" => %MediaType{
schema: OpenApiSpexTest.Schemas.PetAppointmentRequest
}
}
},
responses: %{
201 => %Response{
description: "Appointment created"
}
}
}
}
}
}
Expand All @@ -149,14 +168,23 @@ defmodule OpenApiSpex.SchemaResolverTest do
assert %Reference{"$ref": "#/components/schemas/UserRequest"} =
resolved.paths["/api/users"].post.requestBody.content["application/json"].schema

assert "#/components/schemas/TrainingAppointment" =
resolved.components.schemas["PetAppointmentRequest"].discriminator.mapping["training"]

assert "#/components/schemas/GroomingAppointment" =
resolved.components.schemas["PetAppointmentRequest"].discriminator.mapping["grooming"]

assert %{
"UserRequest" => %Schema{},
"UserResponse" => %Schema{},
"User" => %Schema{},
"UserSubscribeRequest" => %Schema{},
"PaymentDetails" => %Schema{},
"CreditCardPaymentDetails" => %Schema{},
"DirectDebitPaymentDetails" => %Schema{}
"DirectDebitPaymentDetails" => %Schema{},
"PetAppointmentRequest" => %Schema{},
"TrainingAppointment" => %Schema{},
"GroomingAppointment" => %Schema{}
} = resolved.components.schemas

get_friends = resolved.paths["/api/users/{id}/friends"].get
Expand Down
4 changes: 2 additions & 2 deletions test/support/schemas.ex
Original file line number Diff line number Diff line change
Expand Up @@ -645,8 +645,8 @@ defmodule OpenApiSpexTest.Schemas do
discriminator: %OpenApiSpex.Discriminator{
propertyName: "appointment_type",
mapping: %{
"training" => "TrainingAppointment",
"grooming" => "GroomingAppointment"
"training" => TrainingAppointment,
"grooming" => GroomingAppointment
}
}
})
Expand Down

0 comments on commit f54a044

Please sign in to comment.