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

Fix wrapped unknown types #1138

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

## Unreleased

- Bug Fix: [Validate field names are unique to an object/interface/input object](https://github.com/absinthe-graphql/absinthe/pull/1135)
- Bug Fix: [Fix check unknown types to also cover wrapped types](https://github.com/absinthe-graphql/absinthe/pull/1138)
- Bug Fix: [Validate field names are unique to an object, interface or an input object](https://github.com/absinthe-graphql/absinthe/pull/1135)
- Bug Fix: [Validate variable usage in according to spec](https://github.com/absinthe-graphql/absinthe/pull/1141)

## 1.6.6
Expand Down
26 changes: 22 additions & 4 deletions lib/absinthe/phase/validation/known_type_names.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ defmodule Absinthe.Phase.Validation.KnownTypeNames do
# ```

alias Absinthe.{Blueprint, Phase}
alias Absinthe.Phase.Document.Validation.Utils

use Absinthe.Phase
use Absinthe.Phase.Validation
Expand All @@ -33,29 +34,46 @@ defmodule Absinthe.Phase.Validation.KnownTypeNames do
|> put_error(error(node, name))
end

defp handle_node(%Blueprint.Document.VariableDefinition{schema_node: nil} = node, schema) do
defp handle_node(%Blueprint.Document.VariableDefinition{} = node, schema) do
name = Blueprint.TypeReference.unwrap(node.type).name
inner_schema_type = schema.__absinthe_lookup__(name)

if inner_schema_type do
node
else
suggestions = suggested_type_names(schema, name)

node
|> flag_invalid(:bad_type_name)
|> put_error(error(node, name))
|> put_error(error(node, name, suggestions))
end
end

defp handle_node(node, _) do
node
end

defp suggested_type_names(schema, name) do
schema
|> Absinthe.Schema.referenced_types()
|> Enum.map(& &1.name)
|> Absinthe.Utils.Suggestion.sort_list(name)
end

@spec error(Blueprint.node_t(), String.t()) :: Phase.Error.t()
defp error(node, name) do
defp error(node, name, suggestions \\ []) do
%Phase.Error{
phase: __MODULE__,
message: ~s(Unknown type "#{name}".),
message: message(name, suggestions),
locations: [node.source_location]
}
end

defp message(name, []) do
~s(Unknown type "#{name}".)
end

defp message(name, suggestions) do
~s(Unknown type "#{name}".) <> Utils.MessageSuggestions.suggest_message(suggestions)
end
end
21 changes: 15 additions & 6 deletions test/absinthe/phase/validation/known_type_names_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,26 @@ defmodule Absinthe.Phase.Validation.KnownTypeNamesTest do

alias Absinthe.Blueprint

def unknown_type(:variable_definition, name, line) do
def unknown_type(type, name, line, custom_error_message \\ nil)

def unknown_type(:variable_definition, name, line, custom_error_message) do
bad_value(
Blueprint.Document.VariableDefinition,
error_message(name),
custom_error_message || error_message(name),
line,
&(Blueprint.TypeReference.unwrap(&1.type).name == name)
)
end

def unknown_type(:named_type_condition, name, line) do
def unknown_type(:named_type_condition, name, line, _) do
unknown_type_condition(Blueprint.Document.Fragment.Named, name, line)
end

def unknown_type(:spread_type_condition, name, line) do
def unknown_type(:spread_type_condition, name, line, _) do
unknown_type_condition(Blueprint.Document.Fragment.Spread, name, line)
end

def unknown_type(:inline_type_condition, name, line) do
def unknown_type(:inline_type_condition, name, line, _) do
unknown_type_condition(Blueprint.Document.Fragment.Inline, name, line)
end

Expand Down Expand Up @@ -61,7 +63,7 @@ defmodule Absinthe.Phase.Validation.KnownTypeNamesTest do
test "unknown type names are invalid" do
assert_fails_validation(
"""
query Foo($var: JumbledUpLetters) {
query Foo($var: JumbledUpLetters, $foo: Boolen!, $bar: [Bar!]) {
user(id: 4) {
name
pets { ... on Badger { name }, ...PetFields }
Expand All @@ -74,6 +76,13 @@ defmodule Absinthe.Phase.Validation.KnownTypeNamesTest do
[],
[
unknown_type(:variable_definition, "JumbledUpLetters", 1),
unknown_type(
:variable_definition,
"Boolen",
1,
~s(Unknown type "Boolen". Did you mean "Alien" or "Boolean"?)
),
unknown_type(:variable_definition, "Bar", 1),
unknown_type(:inline_type_condition, "Badger", 4),
unknown_type(:named_type_condition, "Peettt", 7)
]
Expand Down