From 78a5edd0bd227b3c6f4edd29275ba9b285c2ef7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Pavl=C3=ADk?= Date: Fri, 1 Nov 2024 14:51:04 +0100 Subject: [PATCH] Treat parameters without explicit `style` field as with `style: :form` Form style should be the default, according to https://swagger.io/docs/specification/v3_0/serialization/ Therefore, if the form field was not explicitly set, we should treat as if it was set to form. --- lib/open_api_spex/cast_parameters.ex | 4 +- test/cast_parameters_test.exs | 89 ++++++++++++++-------------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/lib/open_api_spex/cast_parameters.ex b/lib/open_api_spex/cast_parameters.ex index 1155cb79..89c34ca8 100644 --- a/lib/open_api_spex/cast_parameters.ex +++ b/lib/open_api_spex/cast_parameters.ex @@ -160,7 +160,9 @@ defmodule OpenApiSpex.CastParameters do end) end - defp pre_parse_parameter(parameter, %{explode: false, style: :form} = _context, _parsers) do + defp pre_parse_parameter(parameter, %{explode: false, style: form} = _context, _parsers) + # allow nil as `style: :form` should be the default behaviour according to OpenAPI + when form in [:form, nil] do # e.g. sizes=S,L,M # This does not take care of cases where the value may contain a comma itself {:ok, String.split(parameter, ",")} diff --git a/test/cast_parameters_test.exs b/test/cast_parameters_test.exs index b881a914..4a9cb6f1 100644 --- a/test/cast_parameters_test.exs +++ b/test/cast_parameters_test.exs @@ -55,57 +55,60 @@ defmodule OpenApiSpex.CastParametersTest do assert %{params: %{"Content-Type": "application/json"}} = conn end - test "cast style: form, explode: false query parameters" do - size_schema = %Schema{ - type: :string, - enum: [ - "XS", - "S", - "M", - "L", - "XL" - ] - } + for style <- [:form, nil] do + @tag style: style + test "cast style: #{inspect(style)}, explode: false query parameters", %{style: style} do + size_schema = %Schema{ + type: :string, + enum: [ + "XS", + "S", + "M", + "L", + "XL" + ] + } - schema = %Schema{ - title: "SizeParams", - type: :array, - uniqueItems: true, - minItems: 2, - items: size_schema - } + schema = %Schema{ + title: "SizeParams", + type: :array, + uniqueItems: true, + minItems: 2, + items: size_schema + } - parameter = %Parameter{ - in: :query, - name: :sizes, - required: true, - style: :form, - explode: false, - schema: schema - } + parameter = %Parameter{ + in: :query, + name: :sizes, + required: true, + style: style, + explode: false, + schema: schema + } - operation = %Operation{ - parameters: [parameter], - responses: %{ - 200 => %Schema{type: :object} + operation = %Operation{ + parameters: [parameter], + responses: %{ + 200 => %Schema{type: :object} + } } - } - spec = - spec_with_components(%Components{ - schemas: %{"SizeParams" => schema} - }) + spec = + spec_with_components(%Components{ + schemas: %{"SizeParams" => schema} + }) - sizes_param = "S,M,L" + sizes_param = "S,M,L" - conn = - :get - |> Plug.Test.conn("/api/t-shirts?sizes=#{sizes_param}") - |> Plug.Conn.put_req_header("content-type", "application/json") - |> Plug.Conn.fetch_query_params() + conn = + :get + |> Plug.Test.conn("/api/t-shirts?sizes=#{sizes_param}") + |> Plug.Conn.put_req_header("content-type", "application/json") + |> Plug.Conn.fetch_query_params() - assert {:ok, conn} = CastParameters.cast(conn, operation, spec) - assert %{params: %{sizes: ["S", "M", "L"]}} = conn + assert {:ok, conn} = CastParameters.cast(conn, operation, spec) + assert %{params: %{sizes: ["S", "M", "L"]}} = conn + end end test "cast json query params with default parser" do