From 702c703774b0f5c4d005d0b6fbd43117046c0c3f Mon Sep 17 00:00:00 2001 From: Alberto Sartori Date: Fri, 17 Nov 2023 18:35:29 +0100 Subject: [PATCH] Cast discriminator when no title present --- lib/open_api_spex/cast/discriminator.ex | 34 +++++++++++++---------- test/mix/tasks/openapi.spec.json_test.exs | 2 +- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/lib/open_api_spex/cast/discriminator.ex b/lib/open_api_spex/cast/discriminator.ex index cd9ef05e..18221f1b 100644 --- a/lib/open_api_spex/cast/discriminator.ex +++ b/lib/open_api_spex/cast/discriminator.ex @@ -37,7 +37,7 @@ defmodule OpenApiSpex.Cast.Discriminator do end end - defp cast_discriminator(%_{value: %{} = value, schema: schema} = ctx) do + defp cast_discriminator(%_{value: %{} = value, schema: schema, schemas: schemas} = ctx) do {discriminator_property, mappings} = discriminator_details(schema) case value["#{discriminator_property}"] || value[discriminator_property] do @@ -49,7 +49,7 @@ defmodule OpenApiSpex.Cast.Discriminator do # or return an error according to the Open API Spec. composite_ctx = %{ctx | schema: %{schema | discriminator: nil}} - cast_composition(composite_ctx, ctx, discriminator_value, mappings) + cast_composition(composite_ctx, ctx, discriminator_value, mappings, schemas) end end @@ -62,7 +62,8 @@ defmodule OpenApiSpex.Cast.Discriminator do %_{schema: %{allOf: [_ | _]}} = composite_ctx, ctx, discriminator_value, - mappings + mappings, + schemas ) do with {composite_schemas, cast_composition_result} <- {locate_composition_schemas(composite_ctx), Cast.cast(composite_ctx)}, @@ -71,7 +72,8 @@ defmodule OpenApiSpex.Cast.Discriminator do find_discriminator_schema( discriminator_value, mappings, - composite_schemas + composite_schemas, + schemas ) do Cast.cast(%{composite_ctx | schema: schema}) else @@ -80,9 +82,10 @@ defmodule OpenApiSpex.Cast.Discriminator do end end - defp cast_composition(composite_ctx, ctx, discriminator_value, mappings) do + defp cast_composition(composite_ctx, ctx, discriminator_value, mappings, schemas) do with composite_schemas <- locate_composition_schemas(composite_ctx), - %{} = schema <- find_discriminator_schema(discriminator_value, mappings, composite_schemas) do + %{} = schema <- + find_discriminator_schema(discriminator_value, mappings, composite_schemas, schemas) do Cast.cast(%{composite_ctx | schema: schema}) else nil -> error(:invalid_discriminator_value, ctx) @@ -90,27 +93,28 @@ defmodule OpenApiSpex.Cast.Discriminator do end end - defp find_discriminator_schema(discriminator, mappings = %{}, schemas) do + defp find_discriminator_schema(discriminator, mappings = %{}, composite_schemas, schemas) do case Map.fetch(mappings, discriminator) do {:ok, "#/components/schemas/" <> name} -> - find_discriminator_schema(name, nil, schemas) + find_discriminator_schema(name, nil, composite_schemas, schemas) || Map.get(schemas, name) {:ok, name} -> - find_discriminator_schema(name, nil, schemas) + find_discriminator_schema(name, nil, composite_schemas, schemas) :error -> - find_discriminator_schema(discriminator, nil, schemas) + find_discriminator_schema(discriminator, nil, composite_schemas, schemas) end end - defp find_discriminator_schema(discriminator, _mappings, schemas) + defp find_discriminator_schema(discriminator, nil, composite_schemas, _schemas) when is_atom(discriminator) and not is_nil(discriminator), - do: Enum.find(schemas, &Kernel.==(&1."x-struct", discriminator)) + do: Enum.find(composite_schemas, &Kernel.==(&1."x-struct", discriminator)) - defp find_discriminator_schema(discriminator, _mappings, schemas) when is_binary(discriminator), - do: Enum.find(schemas, &Kernel.==(&1.title, discriminator)) + defp find_discriminator_schema(discriminator, nil, composite_schemas, _schemas) + when is_binary(discriminator), + do: Enum.find(composite_schemas, &Kernel.==(&1.title, discriminator)) - defp find_discriminator_schema(_discriminator, _mappings, _schemas), do: nil + defp find_discriminator_schema(_discriminator, _mappings, _composite_schemas, _schemas), do: nil defp discriminator_details(%{discriminator: %{propertyName: property_name, mapping: mappings}}), do: {String.to_existing_atom(property_name), mappings} diff --git a/test/mix/tasks/openapi.spec.json_test.exs b/test/mix/tasks/openapi.spec.json_test.exs index ef27b464..8b941c90 100644 --- a/test/mix/tasks/openapi.spec.json_test.exs +++ b/test/mix/tasks/openapi.spec.json_test.exs @@ -23,7 +23,7 @@ defmodule Mix.Tasks.Openapi.Spec.JsonTest do Mix.Tasks.Openapi.Spec.Json.run(~w( --quiet=true --spec OpenApiSpexTest.Tasks.SpecModule - "tmp/openapi.json" + tmp/openapi.json )) refute_received {:mix_shell, :info, ["* creating tmp"]}