Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

** (UndefinedFunctionError) function nil.operationId/0 is undefined #447

Merged
merged 9 commits into from
Jul 30, 2022
44 changes: 30 additions & 14 deletions lib/open_api_spex/plug/cast_and_validate.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
defmodule OpenApiSpex.Plug.CastAndValidate do
@moduledoc """
Module plug that will cast and validate the `Conn.params` and `Conn.body_params` according to the schemas defined for the operation.
Module plug that will cast and validate the `Conn.params` and `Conn.body_params` according to the schemas defined for the operation.
zorbash marked this conversation as resolved.
Show resolved Hide resolved

The operation_id can be given at compile time as an argument to `init`:

Expand Down Expand Up @@ -90,25 +90,41 @@ defmodule OpenApiSpex.Plug.CastAndValidate do

# This caching is to improve performance of extracting Operation specs
# at runtime when they're using the @doc-based syntax.
operation =
operation_lookup =
case operation_lookup[{controller, action}] do
nil ->
operation_id = controller.open_api_operation(action).operationId

PutApiSpec.get_and_cache_controller_action(
conn,
operation_id,
{controller, action}
)
operation = controller.open_api_operation(action)

if operation do
operation =
PutApiSpec.get_and_cache_controller_action(
conn,
operation.operationId,
{controller, action}
)

{:found_it, operation}
else
# this is the case when operation: false was used
{:skip_it, nil}
end

operation ->
operation
{:found_it, operation}
end

if operation.operationId do
call(conn, Map.put(opts, :operation_id, operation.operationId))
else
raise "operationId was not found in action API spec"
case operation_lookup do
{:skip_it, _} ->
conn

{:found_it, nil} ->
raise "operationId was not found in action API spec"

{:found_it, operation} ->
call(conn, opts |> Map.put(:operation_id, operation.operationId))

_ ->
zorbash marked this conversation as resolved.
Show resolved Hide resolved
raise "Unexpected case detected"
end
end

Expand Down
39 changes: 25 additions & 14 deletions test/plug/cast_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,19 @@ defmodule OpenApiSpex.Plug.CastTest do

alias OpenApiSpexTest.ApiSpec

describe "valid operation (not annotated)" do
test "should work" do
conn =
:get
|> Plug.Test.conn("/api/noapi")
|> OpenApiSpexTest.Router.call([])

assert conn.status == 200
end
end

describe "query params - basics" do
test "Valid Param" do
test "valid Param" do
conn =
:get
|> Plug.Test.conn("/api/users?validParam=true")
Expand All @@ -16,7 +27,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

@tag :capture_log
test "Invalid value" do
test "invalid value" do
conn =
:get
|> Plug.Test.conn("/api/users?validParam=123")
Expand All @@ -26,7 +37,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

@tag :capture_log
test "Invalid Param" do
test "invalid param" do
conn =
:get
|> Plug.Test.conn("/api/users?validParam=123")
Expand Down Expand Up @@ -83,7 +94,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

describe "query params - param with custom error handling" do
test "Valid Param" do
test "valid param" do
conn =
:get
|> Plug.Test.conn("/api/custom_error_users?validParam=true")
Expand All @@ -93,7 +104,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

@tag :capture_log
test "Invalid value" do
test "invalid value" do
conn =
:get
|> Plug.Test.conn("/api/custom_error_users?validParam=123")
Expand All @@ -103,7 +114,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

@tag :capture_log
test "Invalid Param" do
test "invalid param" do
conn =
:get
|> Plug.Test.conn("/api/custom_error_users?validParam=123")
Expand All @@ -115,7 +126,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

describe "body params" do
test "Valid Request" do
test "valid request" do
request_body = %{
"user" => %{
"id" => 123,
Expand Down Expand Up @@ -154,7 +165,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

@tag :capture_log
test "Invalid Request" do
test "invalid request" do
request_body = %{
"user" => %{
"id" => 123,
Expand Down Expand Up @@ -185,7 +196,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

describe "oneOf body params" do
test "Valid Request" do
test "valid request" do
request_body = %{
"pet" => %{
"pet_type" => "Dog",
Expand Down Expand Up @@ -215,7 +226,7 @@ defmodule OpenApiSpex.Plug.CastTest do
end

@tag :capture_log
test "Invalid Request" do
test "invalid request" do
request_body = %{
"pet" => %{
"pet_type" => "Human",
Expand All @@ -241,7 +252,7 @@ defmodule OpenApiSpex.Plug.CastTest do
}
end

test "Header params" do
test "header params" do
conn =
:post
|> Plug.Test.conn("/api/pets/1/adopt")
Expand All @@ -257,7 +268,7 @@ defmodule OpenApiSpex.Plug.CastTest do
}
end

test "Optional param" do
test "optional param" do
conn =
:post
|> Plug.Test.conn("/api/pets/1/adopt?status=adopted")
Expand All @@ -273,7 +284,7 @@ defmodule OpenApiSpex.Plug.CastTest do
}
end

test "Cookie params" do
test "cookie params" do
conn =
:post
|> Plug.Test.conn("/api/pets/1/adopt")
Expand All @@ -290,7 +301,7 @@ defmodule OpenApiSpex.Plug.CastTest do
}
end

test "Discriminator with mapping" do
test "discriminator with mapping" do
body =
Jason.encode!(%{
appointment_type: "grooming",
Expand Down
15 changes: 15 additions & 0 deletions test/support/noapi_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule OpenApiSpexTest.NoApiController do
@moduledoc false

use Phoenix.Controller
use OpenApiSpex.ControllerSpecs

plug OpenApiSpex.Plug.CastAndValidate, json_render_error_v2: true
zorbash marked this conversation as resolved.
Show resolved Hide resolved

operation :noapi, false

def noapi(conn, _opts) do
conn
|> put_status(200)
end
end
1 change: 1 addition & 0 deletions test/support/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule OpenApiSpexTest.Router do
scope "/api" do
pipe_through :api
resources "/users", OpenApiSpexTest.UserController, only: [:create, :index, :show]
get "/noapi", OpenApiSpexTest.NoApiController, :noapi

# Used by ParamsTest
resources "/custom_error_users", OpenApiSpexTest.CustomErrorUserController, only: [:index]
Expand Down