From a85bef6b8231fefee2b1b708d7ae2cdd9a823d27 Mon Sep 17 00:00:00 2001 From: Amir Hasanbasic Date: Wed, 3 Jan 2024 16:45:45 +0100 Subject: [PATCH] Remove matching params before constructing exploded params --- examples/plug_app/.tool-versions | 2 + .../plug_app/lib/plug_app/user_handler.ex | 5 +-- examples/plug_app/mix.exs | 3 +- lib/open_api_spex/cast_parameters.ex | 42 +++++++++---------- test/cast_parameters_test.exs | 5 --- 5 files changed, 24 insertions(+), 33 deletions(-) create mode 100644 examples/plug_app/.tool-versions diff --git a/examples/plug_app/.tool-versions b/examples/plug_app/.tool-versions new file mode 100644 index 00000000..7fe274f8 --- /dev/null +++ b/examples/plug_app/.tool-versions @@ -0,0 +1,2 @@ +elixir 1.11.4-otp-22 +erlang 22.3.4.26 diff --git a/examples/plug_app/lib/plug_app/user_handler.ex b/examples/plug_app/lib/plug_app/user_handler.ex index 292b87f9..50061033 100644 --- a/examples/plug_app/lib/plug_app/user_handler.ex +++ b/examples/plug_app/lib/plug_app/user_handler.ex @@ -103,10 +103,7 @@ defmodule PlugApp.UserHandler do end end - # def show(conn = %Plug.Conn{assigns: %{user: user}}, _opts) do - def show(conn, _opts) do - IO.inspect(conn.params) - + def show(conn = %Plug.Conn{assigns: %{user: user}}, _opts) do user = Accounts.get_user!(conn.params.id) conn diff --git a/examples/plug_app/mix.exs b/examples/plug_app/mix.exs index 9d5858e9..0d6d4216 100644 --- a/examples/plug_app/mix.exs +++ b/examples/plug_app/mix.exs @@ -29,8 +29,7 @@ defmodule PlugApp.Mixfile do {:plug, "~> 1.0"}, {:ecto, "~> 2.2"}, {:sqlite_ecto2, "~> 2.4"}, - {:jason, "~> 1.0"}, - {:cors_plug, "~> 3.0"} + {:jason, "~> 1.0"} # {:dep_from_hexpm, "~> 0.3.0"}, # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}, ] diff --git a/lib/open_api_spex/cast_parameters.ex b/lib/open_api_spex/cast_parameters.ex index d8338042..1b4285b1 100644 --- a/lib/open_api_spex/cast_parameters.ex +++ b/lib/open_api_spex/cast_parameters.ex @@ -69,7 +69,6 @@ defmodule OpenApiSpex.CastParameters do properties: parameters |> Map.new(fn p -> {p.name, Parameter.schema(p)} end), required: parameters |> Enum.filter(& &1.required) |> Enum.map(& &1.name) } - # |> maybe_combine_oneOfs(parameters, components) |> maybe_add_additional_properties(components), parameters_contexts(parameters) } @@ -141,7 +140,23 @@ defmodule OpenApiSpex.CastParameters do # fields in parameters and combine the parameters in a single struct # so that the casting can do further work defp maybe_combine_params(%{} = parameters, %{} = schema, %{} = parameters_contexts) do - Enum.reduce(parameters_contexts, parameters, fn + # first filter out from parameters fields that match non exploding properties. + # we do this because we want to keep the original parameters struct intact + # and not remove fields that are not part of the exploding property + + non_exploding_matches = Enum.reduce(parameters, Map.new(), fn {key, value}, acc -> + case Map.get(parameters_contexts, key, %{}) do + %{explode: false} -> + Map.put(acc, key, value) + + _ -> + acc + end + end) + + possible_exploding_matches = Enum.reject(parameters, &Enum.member?(non_exploding_matches, &1)) |> Map.new() + + combined_params = Enum.reduce(parameters_contexts, possible_exploding_matches, fn {key, %{explode: true}}, parameters -> # we have exploding property, we need to search for it's possible fields # and add them under the key into the parameters struct. @@ -153,18 +168,15 @@ defmodule OpenApiSpex.CastParameters do Schema.possible_properties(schema_of_exploding_property) {struct_params, found_keys} = - Enum.reduce(fields, {Map.new(), []}, fn {field_key, _}, {struct_params, found_keys} -> + Enum.reduce(fields, {Map.new(), []}, fn {field_key, _default}, {struct_params, found_keys} -> param_field_key = field_key |> Atom.to_string() val = Map.get(parameters, param_field_key) - {new_params, new_found_keys} = unless is_nil(val) do {Map.put(struct_params, param_field_key, val), [param_field_key | found_keys]} else {struct_params, found_keys} end - - {new_params, new_found_keys} end) parameters @@ -174,6 +186,8 @@ defmodule OpenApiSpex.CastParameters do _, parameters -> parameters end) + + Map.merge(non_exploding_matches, combined_params) end defp pre_parse_parameters(%{} = parameters, %{} = parameters_context, parsers) do @@ -250,20 +264,4 @@ defmodule OpenApiSpex.CastParameters do _ -> schema end end - - defp maybe_combine_oneOfs(schema, parameters, components) do - # check if any params have explode, - # if so add the properties of it's schema to the top level - # and remove the key for that - %{} - end - - defp create_one_of_schemas(parameters) do - if Enum.any?(parameters, fn p -> - p.explode == true and is_list(Parameter.schema(p).oneOf) - end) do - # in this case we need to create multiple schemas. Each of the schemas - # has to have properties defined in other parameters + add required properties - end - end end diff --git a/test/cast_parameters_test.exs b/test/cast_parameters_test.exs index a887f8b1..fb250e05 100644 --- a/test/cast_parameters_test.exs +++ b/test/cast_parameters_test.exs @@ -1,8 +1,6 @@ defmodule OpenApiSpex.CastParametersTest do use ExUnit.Case - require IEx - alias OpenApiSpex.{ CastParameters, Components, @@ -205,9 +203,6 @@ defmodule OpenApiSpex.CastParametersTest do |> Plug.Conn.put_req_header("content-type", "application/json") |> Plug.Conn.fetch_query_params() - # require IEx - # IEx.pry() - assert {:ok, _} = CastParameters.cast(conn, operation, spec) end end