From 62c3d9404bbfcfdc2d71cf1d85b0aa7929275047 Mon Sep 17 00:00:00 2001 From: Doruk Gurleyen Date: Mon, 17 Jun 2024 11:23:02 -0400 Subject: [PATCH 1/2] Add additional tests for resolving data alongside errors --- .../federation/schema/entities_field_test.exs | 78 +++++++++++++++++++ ...rsistent_term_schema_entity_field_test.exs | 56 +++++++++++-- 2 files changed, 129 insertions(+), 5 deletions(-) diff --git a/test/absinthe/federation/schema/entities_field_test.exs b/test/absinthe/federation/schema/entities_field_test.exs index b3a477d..2cfa2bd 100644 --- a/test/absinthe/federation/schema/entities_field_test.exs +++ b/test/absinthe/federation/schema/entities_field_test.exs @@ -55,6 +55,13 @@ defmodule Absinthe.Federation.Schema.EntitiesFieldTest do object :product do key_fields("upc") field :upc, non_null(:string) + + field :name, :string, + resolve: fn + %{upc: "789-erroneous-name"}, _, _ -> {:error, "arbitrary name error"} + %{upc: upc}, _, _ -> {:ok, "product #{upc}"} + end + field :foo, non_null(:string), resolve: fn _, _, _ -> {:ok, "bar"} end field :_resolve_reference, :product do @@ -63,6 +70,7 @@ defmodule Absinthe.Federation.Schema.EntitiesFieldTest do case upc do "123" -> {:ok, args} "456" -> {:ok, args} + "789-erroneous-name" -> {:ok, args} "nil" <> _ -> {:ok, nil} _ -> {:error, "Couldn't find product with upc #{upc}"} end @@ -146,6 +154,43 @@ defmodule Absinthe.Federation.Schema.EntitiesFieldTest do } = resp end + test "handles errors alongside data" do + query = """ + query { + _entities(representations: [ + { + __typename: "Product", + upc: "789-erroneous-name" + }, + { + __typename: "Product", + upc: "456" + } + ]) { + ...on Product { + upc + foo + name + } + } + } + """ + + {:ok, resp} = Absinthe.run(query, ResolverSchema, variables: %{}) + + assert %{ + data: %{ + "_entities" => [ + %{"foo" => "bar", "name" => nil, "upc" => "789-erroneous-name"}, + %{"foo" => "bar", "name" => "product 456", "upc" => "456"} + ] + }, + errors: [ + %{message: "arbitrary name error", path: ["_entities", 0, "name"], locations: [%{column: 9, line: 15}]} + ] + } == resp + end + test "Handles missing data" do query = """ query { @@ -175,6 +220,39 @@ defmodule Absinthe.Federation.Schema.EntitiesFieldTest do } = resp end + test "Handles missing data alongside existing data" do + query = """ + query { + _entities(representations: [ + { + __typename: "Product", + upc: "nil1" + }, + { + __typename: "Product", + upc: "nil22" + }, + { + __typename: "Product", + upc: "456" + } + ]) { + __typename + ...on Product { + upc + foo + } + } + } + """ + + {:ok, resp} = Absinthe.run(query, ResolverSchema, variables: %{}) + + assert %{ + data: %{"_entities" => [nil, nil, %{"__typename" => "Product", "foo" => "bar", "upc" => "456"}]} + } = resp + end + test "falls back to default _resolve_reference implementation" do query = """ query { diff --git a/test/absinthe/federation/schema/persistent_term_schema_entity_field_test.exs b/test/absinthe/federation/schema/persistent_term_schema_entity_field_test.exs index 4172b6c..5ee9b20 100644 --- a/test/absinthe/federation/schema/persistent_term_schema_entity_field_test.exs +++ b/test/absinthe/federation/schema/persistent_term_schema_entity_field_test.exs @@ -15,16 +15,15 @@ defmodule Absinthe.Federation.Schema.PersistentTermSchemaEntityFieldTest do key_fields("name") field :name, :string do - resolve(fn %{name: name}, _, _ -> - {:ok, name} - end) + resolve(fn %{name: name}, _, _ -> {:ok, name} end) end resolve_type(&resolve_type/2) field :_resolve_reference, :named_entity do resolve(fn - _, %{name: "John"}, _ -> {:ok, %{__typename: "Person", name: "John", age: 20}} + _, %{name: "John"}, _ -> {:ok, %{__typename: "Person", name: "John"}} + _, %{name: "error on age" <> _ = name}, _ -> {:ok, %{__typename: "Person", name: name}} _, %{name: "Acme"}, _ -> {:ok, %{__typename: "Business", name: "Acme", employee_count: 10}} _, %{name: "nil" <> _}, _ -> {:ok, nil} end) @@ -40,7 +39,13 @@ defmodule Absinthe.Federation.Schema.PersistentTermSchemaEntityFieldTest do interface :named_entity import_fields(:named_entity, [:name, :_resolve_reference]) - field :age, :integer + + field :age, :integer do + resolve(fn + %{name: "error on age" <> _ = error}, _, _ -> {:error, error} + %{name: _name}, _, _ -> {:ok, 20} + end) + end end object :business do @@ -119,4 +124,45 @@ defmodule Absinthe.Federation.Schema.PersistentTermSchemaEntityFieldTest do } } = resp end + + test "Handles errors alongside data" do + query = """ + query { + _entities(representations: [ + { __typename: "NamedEntity", name: "John" }, + { __typename: "NamedEntity", name: "error on age 1" }, + { __typename: "NamedEntity", name: "error on age 2" } + ]) { + ...on NamedEntity { + __typename + name + ... on Person { + age + } + ... on Business { + employeeCount + } + } + } + } + """ + + {:ok, resp} = Absinthe.run(query, EntitySchemaWithPersistentTermProvider, variables: %{}) + + assert %{ + data: %{ + "_entities" => [ + %{"__typename" => "Person", "age" => 20, "name" => "John"}, + %{"__typename" => "Person", "age" => nil, "name" => "error on age 1"}, + %{"__typename" => "Person", "age" => nil, "name" => "error on age 2"} + ] + }, + errors: errors + } = resp + + assert errors == [ + %{message: "error on age 2", path: ["_entities", 2, "age"], locations: [%{line: 11, column: 11}]}, + %{message: "error on age 1", path: ["_entities", 1, "age"], locations: [%{line: 11, column: 11}]} + ] + end end From 751a6c5b102592aa9ecd97bec5ed219f94f6cd6c Mon Sep 17 00:00:00 2001 From: Doruk Gurleyen Date: Mon, 17 Jun 2024 11:25:44 -0400 Subject: [PATCH 2/2] Release v0.5.3 --- CHANGELOG.md | 4 ++++ mix.exs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 94998ed..7ce1fb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.5.3 + +- Bug Fix: [Handle resolving `nil` for entity references](https://github.com/DivvyPayHQ/absinthe_federation/pull/98) + ## 0.5.2 - Feature: [Support `@interfaceObject` directive](https://github.com/DivvyPayHQ/absinthe_federation/pull/96) diff --git a/mix.exs b/mix.exs index 729367e..9a16b23 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule Absinthe.Federation.MixProject do use Mix.Project @source_url "https://github.com/DivvyPayHQ/absinthe_federation" - @version "0.5.2" + @version "0.5.3" def project do [