From 48439ee9656a2bc7d4f0389f69b97c7bd97f1149 Mon Sep 17 00:00:00 2001 From: Robert Pospisil Date: Thu, 7 Sep 2023 15:27:08 +0200 Subject: [PATCH] add tests for federation batch resolving --- .../deployment/federation/batch/Foo.java | 16 ++++ .../deployment/federation/batch/FooApi.java | 22 +++++ .../batch/GraphQLFederationBatchTest.java | 80 ++++++++++++++++ .../federation/batch/uni/FooApiUni.java | 26 +++++ .../uni/GraphQLFederationBatchUniTest.java | 81 ++++++++++++++++ .../deployment/federation/complex/Bar.java | 19 ++++ .../deployment/federation/complex/Foo.java | 16 ++++ .../deployment/federation/complex/FooApi.java | 36 +++++++ .../complex/GraphQLFederationComplexTest.java | 96 +++++++++++++++++++ 9 files changed, 392 insertions(+) create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/Foo.java create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/FooApi.java create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/GraphQLFederationBatchTest.java create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/uni/FooApiUni.java create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/uni/GraphQLFederationBatchUniTest.java create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/Bar.java create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/Foo.java create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/FooApi.java create mode 100644 extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/GraphQLFederationComplexTest.java diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/Foo.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/Foo.java new file mode 100644 index 00000000000000..a29b125bf2710f --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/Foo.java @@ -0,0 +1,16 @@ +package io.quarkus.smallrye.graphql.deployment.federation.batch; + +import io.smallrye.graphql.api.federation.Extends; +import io.smallrye.graphql.api.federation.External; +import io.smallrye.graphql.api.federation.Key; + +@Key(fields = "id") +@Extends +public class Foo { + + @External + public int id; + + public String name; + +} diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/FooApi.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/FooApi.java new file mode 100644 index 00000000000000..3e9f498c88d7a6 --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/FooApi.java @@ -0,0 +1,22 @@ +package io.quarkus.smallrye.graphql.deployment.federation.batch; + +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.microprofile.graphql.GraphQLApi; +import org.eclipse.microprofile.graphql.Query; + +@GraphQLApi +public class FooApi { + @Query + public List foos(List id) { + return id.stream().map(this::foo).collect(Collectors.toList()); + } + + private Foo foo(int id) { + var foo = new Foo(); + foo.id = id; + foo.name = "Name of " + id; + return foo; + } +} diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/GraphQLFederationBatchTest.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/GraphQLFederationBatchTest.java new file mode 100644 index 00000000000000..03b4c608bd6b3b --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/GraphQLFederationBatchTest.java @@ -0,0 +1,80 @@ +package io.quarkus.smallrye.graphql.deployment.federation.batch; + +import static org.hamcrest.Matchers.containsString; + +import org.hamcrest.CoreMatchers; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.smallrye.graphql.deployment.AbstractGraphQLTest; +import io.quarkus.test.QuarkusUnitTest; +import io.restassured.RestAssured; + +public class GraphQLFederationBatchTest extends AbstractGraphQLTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(FooApi.class, Foo.class) + .addAsResource(new StringAsset("quarkus.smallrye-graphql.schema-include-directives=true\n" + + "quarkus.smallrye-graphql.federation.batch-resolving-enabled=true"), + "application.properties") + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); + + @Test + public void checkServiceDeclarationInSchema() { + RestAssured.given() + .get("/graphql/schema.graphql") + .then() + .body(containsString("type _Service {")); + } + + @Test + public void checkFederationDirectivesInSchema() { + RestAssured.given() + .get("/graphql/schema.graphql") + .then() + .body(containsString("id: Int! @external")) + .body(containsString("type Foo @extends @key(fields : \"id\")")); + ; + } + + @Test + public void resolvePerFederation() { + String query = "query federation($representations: [_Any!]!) {\n" + + " _entities(representations: $representations) {\n" + + " ... on Foo {\n" + + " id\n" + + " name\n" + + " }\n" + + " }\n" + + "}"; + String variables = "{\n" + + " \"representations\": [\n" + + " {\n" + + " \"__typename\": \"Foo\",\n" + + " \"id\": 1\n" + + " },\n" + + " {\n" + + " \"__typename\": \"Foo\",\n" + + " \"id\": 2\n" + + " }\n" + + " ]\n" + + "}"; + + String request = getPayload(query, variables); + RestAssured.given().when() + .accept(MEDIATYPE_JSON) + .contentType(MEDIATYPE_JSON) + .body(request) + .post("/graphql") + .then() + .assertThat() + .statusCode(200) + .and() + .body(CoreMatchers.is( + "{\"data\":{\"_entities\":[{\"id\":1,\"name\":\"Name of 1\"},{\"id\":2,\"name\":\"Name of 2\"}]}}")); + } +} diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/uni/FooApiUni.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/uni/FooApiUni.java new file mode 100644 index 00000000000000..e20992948b3ba6 --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/uni/FooApiUni.java @@ -0,0 +1,26 @@ +package io.quarkus.smallrye.graphql.deployment.federation.batch.uni; + +import java.util.List; +import java.util.stream.Collectors; + +import org.eclipse.microprofile.graphql.GraphQLApi; +import org.eclipse.microprofile.graphql.Query; + +import io.quarkus.smallrye.graphql.deployment.federation.batch.Foo; +import io.smallrye.mutiny.Uni; + +@GraphQLApi +public class FooApiUni { + + @Query + public Uni> foos(List id) { + return Uni.join().all(id.stream().map(this::foo).collect(Collectors.toList())).andFailFast(); + } + + private Uni foo(int id) { + var foo = new Foo(); + foo.id = id; + foo.name = "Name of " + id; + return Uni.createFrom().item(foo); + } +} diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/uni/GraphQLFederationBatchUniTest.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/uni/GraphQLFederationBatchUniTest.java new file mode 100644 index 00000000000000..f91192188a2f3f --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/batch/uni/GraphQLFederationBatchUniTest.java @@ -0,0 +1,81 @@ +package io.quarkus.smallrye.graphql.deployment.federation.batch.uni; + +import static org.hamcrest.Matchers.containsString; + +import org.hamcrest.CoreMatchers; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.smallrye.graphql.deployment.AbstractGraphQLTest; +import io.quarkus.smallrye.graphql.deployment.federation.batch.Foo; +import io.quarkus.test.QuarkusUnitTest; +import io.restassured.RestAssured; + +public class GraphQLFederationBatchUniTest extends AbstractGraphQLTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(FooApiUni.class, Foo.class) + .addAsResource(new StringAsset("quarkus.smallrye-graphql.schema-include-directives=true\n" + + "quarkus.smallrye-graphql.federation.batch-resolving-enabled=true"), + "application.properties") + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); + + @Test + public void checkServiceDeclarationInSchema() { + RestAssured.given() + .get("/graphql/schema.graphql") + .then() + .body(containsString("type _Service {")); + } + + @Test + public void checkFederationDirectivesInSchema() { + RestAssured.given() + .get("/graphql/schema.graphql") + .then() + .body(containsString("id: Int! @external")) + .body(containsString("type Foo @extends @key(fields : \"id\")")); + ; + } + + @Test + public void resolvePerFederation() { + String query = "query federation($representations: [_Any!]!) {\n" + + " _entities(representations: $representations) {\n" + + " ... on Foo {\n" + + " id\n" + + " name\n" + + " }\n" + + " }\n" + + "}"; + String variables = "{\n" + + " \"representations\": [\n" + + " {\n" + + " \"__typename\": \"Foo\",\n" + + " \"id\": 1\n" + + " },\n" + + " {\n" + + " \"__typename\": \"Foo\",\n" + + " \"id\": 2\n" + + " }\n" + + " ]\n" + + "}"; + + String request = getPayload(query, variables); + RestAssured.given().when() + .accept(MEDIATYPE_JSON) + .contentType(MEDIATYPE_JSON) + .body(request) + .post("/graphql") + .then() + .assertThat() + .statusCode(200) + .and() + .body(CoreMatchers.is( + "{\"data\":{\"_entities\":[{\"id\":1,\"name\":\"Name of 1\"},{\"id\":2,\"name\":\"Name of 2\"}]}}")); + } +} diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/Bar.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/Bar.java new file mode 100644 index 00000000000000..86c15193df4951 --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/Bar.java @@ -0,0 +1,19 @@ +package io.quarkus.smallrye.graphql.deployment.federation.complex; + +import io.smallrye.graphql.api.federation.Extends; +import io.smallrye.graphql.api.federation.External; +import io.smallrye.graphql.api.federation.Key; + +@Key(fields = "id") +@Key(fields = "otherId") +@Extends +public class Bar { + + @External + public int id; + @External + public String otherId; + + public String name; + +} diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/Foo.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/Foo.java new file mode 100644 index 00000000000000..3ebaa016a1129c --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/Foo.java @@ -0,0 +1,16 @@ +package io.quarkus.smallrye.graphql.deployment.federation.complex; + +import io.smallrye.graphql.api.federation.Extends; +import io.smallrye.graphql.api.federation.External; +import io.smallrye.graphql.api.federation.Key; + +@Key(fields = "id") +@Extends +public class Foo { + + @External + public int id; + + public String name; + +} diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/FooApi.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/FooApi.java new file mode 100644 index 00000000000000..24cd2594bd3198 --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/FooApi.java @@ -0,0 +1,36 @@ +package io.quarkus.smallrye.graphql.deployment.federation.complex; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +import org.eclipse.microprofile.graphql.GraphQLApi; +import org.eclipse.microprofile.graphql.Query; + +import io.smallrye.mutiny.Uni; + +@GraphQLApi +public class FooApi { + @Query + public Foo foo(int id) { + var foo = new Foo(); + foo.id = id; + foo.name = "Name of " + id; + return foo; + } + + @Query + public Uni> bars(List id, List otherId) { + return Uni.join().all( + IntStream.range(0, id.size()).boxed().map(i -> bar(id.get(i), otherId.get(i))).collect(Collectors.toList())) + .andFailFast(); + } + + private Uni bar(int id, String otherId) { + var bar = new Bar(); + bar.id = id; + bar.otherId = otherId; + bar.name = id + otherId; + return Uni.createFrom().item(bar); + } +} diff --git a/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/GraphQLFederationComplexTest.java b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/GraphQLFederationComplexTest.java new file mode 100644 index 00000000000000..9481279424f6dc --- /dev/null +++ b/extensions/smallrye-graphql/deployment/src/test/java/io/quarkus/smallrye/graphql/deployment/federation/complex/GraphQLFederationComplexTest.java @@ -0,0 +1,96 @@ +package io.quarkus.smallrye.graphql.deployment.federation.complex; + +import static org.hamcrest.Matchers.containsString; + +import org.hamcrest.CoreMatchers; +import org.jboss.shrinkwrap.api.asset.EmptyAsset; +import org.jboss.shrinkwrap.api.asset.StringAsset; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.smallrye.graphql.deployment.AbstractGraphQLTest; +import io.quarkus.test.QuarkusUnitTest; +import io.restassured.RestAssured; + +public class GraphQLFederationComplexTest extends AbstractGraphQLTest { + + @RegisterExtension + static QuarkusUnitTest test = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar + .addClasses(FooApi.class, Foo.class, Bar.class) + .addAsResource(new StringAsset("quarkus.smallrye-graphql.schema-include-directives=true\n" + + "quarkus.smallrye-graphql.federation.batch-resolving-enabled=true"), + "application.properties") + .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); + + @Test + public void checkServiceDeclarationInSchema() { + RestAssured.given() + .get("/graphql/schema.graphql") + .then() + .body(containsString("type _Service {")); + } + + @Test + public void checkFederationDirectivesInSchema() { + RestAssured.given() + .get("/graphql/schema.graphql") + .then() + .body(containsString("id: Int! @external")) + .body(containsString("type Foo @extends @key(fields : \"id\")")); + ; + } + + @Test + public void resolvePerFederation() { + String query = "query federation($representations: [_Any!]!) { \n" + + " _entities(representations: $representations) {\n" + + " ... on Foo {\n" + + " __typename\n" + + " id\n" + + " name\n" + + " }\n" + + " ... on Bar{\n" + + " __typename\n" + + " id\n" + + " otherId\n" + + " name\n" + + " }\n" + + " }\n" + + "}"; + String variables = "{ \n" + + " \"representations\": [ \n" + + " { \n" + + " \"__typename\": \"Bar\", \n" + + " \"id\": \"2\", \n" + + " \"otherId\": \"???\" \n" + + " }, \n" + + " { \n" + + " \"__typename\": \"Foo\", \n" + + " \"id\": 1\n" + + " }, \n" + + " { \n" + + " \"__typename\": \"Bar\", \n" + + " \"id\": \"3\", \n" + + " \"otherId\": \"!!!\" \n" + + " }, \n" + + " { \n" + + " \"__typename\": \"Foo\", \n" + + " \"id\": 0\n" + + " } \n" + + " ] \n" + + "}"; + String request = getPayload(query, variables); + RestAssured.given().when() + .accept(MEDIATYPE_JSON) + .contentType(MEDIATYPE_JSON) + .body(request) + .post("/graphql") + .then() + .assertThat() + .statusCode(200) + .and() + .body(CoreMatchers.is( + "{\"data\":{\"_entities\":[{\"__typename\":\"Bar\",\"id\":2,\"otherId\":\"???\",\"name\":\"2???\"},{\"__typename\":\"Foo\",\"id\":1,\"name\":\"Name of 1\"},{\"__typename\":\"Bar\",\"id\":3,\"otherId\":\"!!!\",\"name\":\"3!!!\"},{\"__typename\":\"Foo\",\"id\":0,\"name\":\"Name of 0\"}]}}")); + } +}