diff --git a/lib/absinthe/phase/schema/validation/input_output_types_correctly_placed.ex b/lib/absinthe/phase/schema/validation/input_output_types_correctly_placed.ex index 442b7c55f5..7ea2b06a23 100644 --- a/lib/absinthe/phase/schema/validation/input_output_types_correctly_placed.ex +++ b/lib/absinthe/phase/schema/validation/input_output_types_correctly_placed.ex @@ -9,7 +9,7 @@ defmodule Absinthe.Phase.Schema.Validation.InputOutputTypesCorrectlyPlaced do defp handle_schemas(%Blueprint.Schema.SchemaDefinition{} = schema) do types = Map.new(schema.type_definitions, &{&1.identifier, &1}) - schema = Blueprint.prewalk(schema, &validate_type(&1, types)) + schema = Blueprint.prewalk(schema, &validate_type(&1, types, schema)) {:halt, schema} end @@ -17,8 +17,12 @@ defmodule Absinthe.Phase.Schema.Validation.InputOutputTypesCorrectlyPlaced do obj end - defp validate_type(%Blueprint.Schema.InputValueDefinition{} = arg, types) do - arg_type = Map.get(types, Blueprint.TypeReference.unwrap(arg.type)) + defp validate_type(%Blueprint.Schema.InputValueDefinition{} = arg, types, schema) do + type = + Blueprint.TypeReference.unwrap(arg.type) + |> Blueprint.TypeReference.to_type(schema) + + arg_type = Map.get(types, type) if arg_type && wrong_type?(Blueprint.Schema.InputValueDefinition, arg_type) do detail = %{ @@ -33,11 +37,15 @@ defmodule Absinthe.Phase.Schema.Validation.InputOutputTypesCorrectlyPlaced do end end - defp validate_type(%struct{fields: fields} = type, types) do + defp validate_type(%struct{fields: fields} = type, types, schema) do fields = Enum.map(fields, fn %{type: _} = field -> - field_type = Map.get(types, Blueprint.TypeReference.unwrap(field.type)) + type = + Blueprint.TypeReference.unwrap(field.type) + |> Blueprint.TypeReference.to_type(schema) + + field_type = Map.get(types, type) if field_type && wrong_type?(struct, field_type) do detail = %{ @@ -59,7 +67,7 @@ defmodule Absinthe.Phase.Schema.Validation.InputOutputTypesCorrectlyPlaced do %{type | fields: fields} end - defp validate_type(type, _types) do + defp validate_type(type, _types, _schema) do type end diff --git a/test/absinthe/schema/rule/input_output_types_correctly_placed_test.exs b/test/absinthe/schema/rule/input_output_types_correctly_placed_test.exs index fe861c6c45..18e7dd6999 100644 --- a/test/absinthe/schema/rule/input_output_types_correctly_placed_test.exs +++ b/test/absinthe/schema/rule/input_output_types_correctly_placed_test.exs @@ -1,7 +1,7 @@ defmodule Absinthe.Schema.Rule.InputOutputTypesCorrectlyPlacedTest do use Absinthe.Case, async: true - describe "rule" do + describe "macro schema" do test "is enforced with output types on arguments" do assert_schema_error("invalid_output_types", [ %{ @@ -56,4 +56,74 @@ defmodule Absinthe.Schema.Rule.InputOutputTypesCorrectlyPlacedTest do ]) end end + + describe "sdl schema" do + test "is enforced with output types on arguments" do + assert_schema_error("invalid_output_types_sdl", [ + %{ + extra: %{ + field: :blah, + parent: Absinthe.Blueprint.Schema.ObjectTypeDefinition, + struct: Absinthe.Blueprint.Schema.InputObjectTypeDefinition, + type: :input + }, + locations: [ + %{ + file: "test/support/fixtures/dynamic/invalid_output_types_sdl.exs", + line: 4 + } + ], + phase: Absinthe.Phase.Schema.Validation.InputOutputTypesCorrectlyPlaced + }, + %{ + extra: %{ + argument: :invalid_arg, + struct: Absinthe.Blueprint.Schema.ObjectTypeDefinition, + type: :user + }, + locations: [ + %{ + file: "test/support/fixtures/dynamic/invalid_output_types_sdl.exs", + line: 4 + } + ], + phase: Absinthe.Phase.Schema.Validation.InputOutputTypesCorrectlyPlaced + } + ]) + end + + test "is enforced with input types on arguments" do + assert_schema_error("invalid_input_types_sdl", [ + %{ + extra: %{ + argument: :blah, + struct: Absinthe.Blueprint.Schema.ObjectTypeDefinition, + type: :user + }, + locations: [ + %{ + file: "test/support/fixtures/dynamic/invalid_input_types_sdl.exs", + line: 4 + } + ], + phase: Absinthe.Phase.Schema.Validation.InputOutputTypesCorrectlyPlaced + }, + %{ + extra: %{ + field: :blah, + parent: Absinthe.Blueprint.Schema.InputObjectTypeDefinition, + struct: Absinthe.Blueprint.Schema.ObjectTypeDefinition, + type: :user + }, + locations: [ + %{ + file: "test/support/fixtures/dynamic/invalid_input_types_sdl.exs", + line: 4 + } + ], + phase: Absinthe.Phase.Schema.Validation.InputOutputTypesCorrectlyPlaced + } + ]) + end + end end diff --git a/test/support/fixtures/dynamic/invalid_input_types_sdl.exs b/test/support/fixtures/dynamic/invalid_input_types_sdl.exs new file mode 100644 index 0000000000..0f87f2dc77 --- /dev/null +++ b/test/support/fixtures/dynamic/invalid_input_types_sdl.exs @@ -0,0 +1,15 @@ +defmodule Absinthe.Fixtures.InvalidOutputTypesSdlSchema do + use Absinthe.Schema + + import_sdl """ + type User + + input Foo { + blah: User + } + + type Query { + foo(arg: Foo): User + } + """ +end diff --git a/test/support/fixtures/dynamic/invalid_output_types_sdl.exs b/test/support/fixtures/dynamic/invalid_output_types_sdl.exs new file mode 100644 index 0000000000..c313726e4b --- /dev/null +++ b/test/support/fixtures/dynamic/invalid_output_types_sdl.exs @@ -0,0 +1,17 @@ +defmodule Absinthe.Fixtures.InvalidInputTypesSdlSchema do + use Absinthe.Schema + + import_sdl """ + type User + + input Input + + type BadObject { + blah: Input + } + + type Query { + foo(invalidArg: User): User + } + """ +end