Skip to content

Commit

Permalink
Merge pull request #1200 from maartenvanvliet/improve_unique_field_va…
Browse files Browse the repository at this point in the history
…lidation

Ensure an object has unique fields
  • Loading branch information
benwilson512 authored Nov 28, 2022
2 parents 81622a3 + b3b899d commit 759c938
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 7 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Changelog

## Unreleased

- Bug Fix: [Validate field identifier uniqueness](https://github.com/absinthe-graphql/absinthe/pull/1200)
- Bug Fix: [Validate type references for invalid wrapped types](https://github.com/absinthe-graphql/absinthe/pull/1195)
- Breaking Bugfix: [Validate repeatable directives on schemas](https://github.com/absinthe-graphql/absinthe/pull/1179)
- Bug Fix: Adds **optional fix** for non compliant built-in scalar Int type. `use Absinthe.Schema, use_spec_compliant_int_scalar: true` in your schema to use the fixed Int type. It is also advisable to upgrade for custom types if you are leveraging the use of integers outside the GraphQl standard. [#1131](https://github.com/absinthe-graphql/absinthe/pull/1131).
Expand Down
17 changes: 13 additions & 4 deletions lib/absinthe/phase/schema/validation/unique_field_names.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ defmodule Absinthe.Phase.Schema.Validation.UniqueFieldNames do
bp =
bp
|> Blueprint.prewalk(&handle_schemas(&1, :name))
|> Blueprint.prewalk(&handle_schemas(&1, :identifier))

{:ok, bp}
end
Expand All @@ -32,7 +33,7 @@ defmodule Absinthe.Phase.Schema.Validation.UniqueFieldNames do
name_counts = Enum.frequencies_by(object.fields, &Map.get(&1, key))

if duplicate?(name_counts, field, key) do
Absinthe.Phase.put_error(field, error(field, object))
Absinthe.Phase.put_error(field, error(field, object, key))
else
field
end
Expand All @@ -50,20 +51,28 @@ defmodule Absinthe.Phase.Schema.Validation.UniqueFieldNames do
Map.get(name_counts, field_identifier, 0) > 1
end

defp error(field, object) do
defp error(field, object, key) do
%Absinthe.Phase.Error{
message: explanation(field, object),
message: explanation(field, object, key),
locations: [field.__reference__.location],
phase: __MODULE__,
extra: field
}
end

def explanation(field, object) do
def explanation(field, object, :name) do
"""
The field #{inspect(field.name)} is not unique in type #{inspect(object.name)}.
The field must have a unique name within that Object type; no two fields may share the same name.
"""
end

def explanation(field, object, :identifier) do
"""
The field identifier #{inspect(field.identifier)} is not unique in type #{inspect(object.name)}.
The field must have a unique identifier within that Object type; no two fields may share the same identifier.
"""
end
end
26 changes: 24 additions & 2 deletions test/absinthe/schema/rule/unique_field_names_test.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
defmodule Absinthe.Schema.Rule.UniqueFieldNamesTest do
use Absinthe.Case, async: true

@duplicate_object_fields ~S(
@duplicate_object_fields_macro ~S(
defmodule DuplicateObjectFields do
use Absinthe.Schema
query do
end
object :dog do
field :name, :string
field :name, :integer, name: "dogName"
end
end
)

@duplicate_object_fields_sdl ~S(
defmodule DuplicateObjectFields do
use Absinthe.Schema
Expand Down Expand Up @@ -49,11 +63,19 @@ defmodule Absinthe.Schema.Rule.UniqueFieldNamesTest do
end
)

test "errors on non unique object field identifier" do
error = ~r/The field identifier :name is not unique in type \"Dog\"./

assert_raise(Absinthe.Schema.Error, error, fn ->
Code.eval_string(@duplicate_object_fields_macro)
end)
end

test "errors on non unique object field names" do
error = ~r/The field \"name\" is not unique in type \"Dog\"./

assert_raise(Absinthe.Schema.Error, error, fn ->
Code.eval_string(@duplicate_object_fields)
Code.eval_string(@duplicate_object_fields_sdl)
end)
end

Expand Down

0 comments on commit 759c938

Please sign in to comment.