Skip to content

Commit

Permalink
test: add asserts for outgoing query in integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
irintu committed Oct 25, 2023
1 parent 4d36e18 commit dce3d3f
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,19 @@ class AliasFragmentSpreadWithNestedSpec extends BaseIntegrationTestSpecification
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
//query QUERY {
// a {b {foo:c(a:"foo") {d {f1}}}}
// a {b {bar:c(a:"bar") {d {f2}}}}
// }
compareQueryToExecutionInput(null,
"queryQUERY{a{b{foo:c(a:\"foo\"){d{f1}}bar:c(a:\"bar\"){d{f2}}}}}", service1)
compareQueryToExecutionInput(null,null, service2)

executionResult.getErrors().isEmpty()
Map<String, Object> data = executionResult.getData()
data.a?.b?.foo?.d?.f1 instanceof String && data.a?.b?.foo?.d?.f1 == "foo1"
data.a?.b?.bar?.d?.f2 instanceof String && data.a?.b?.bar?.d?.f2 == "bar2"

//query QUERY {
// a {b {foo:c(a:"foo") {d {f1}}}}
// a {b {bar:c(a:"bar") {d {f2}}}}
// }
}

def "Fragments used at the type-merge level with arguments"() {
Expand All @@ -92,6 +96,15 @@ class AliasFragmentSpreadWithNestedSpec extends BaseIntegrationTestSpecification
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
// fragment fr on C {d {f1 f2}}
//
// query QUERY {
// a {b {foo:c(a:"foo") {...fr}}}
// a {b {bar:c(a:"bar") {...fr}}}
// }
compareQueryToExecutionInput(null,
"fragmentfronC{d{f1f2}}queryQUERY{a{b{foo:c(a:\"foo\"){...fr}bar:c(a:\"bar\"){...fr}}}}", service1)
compareQueryToExecutionInput(null,null, service2)
executionResult.getErrors().isEmpty()
Map<String, Object> data = executionResult.getData()
data.a?.b?.foo?.d?.f1 instanceof String && data.a?.b?.foo?.d?.f1 == "foo1"
Expand All @@ -100,12 +113,7 @@ class AliasFragmentSpreadWithNestedSpec extends BaseIntegrationTestSpecification
data.a?.b?.bar?.d?.f2 instanceof String && data.a?.b?.bar?.d?.f2 == "bar2"
}

// fragment fr on C {d {f1 f2}}
//
// query QUERY {
// a {b {foo:c(a:"foo") {...fr}}}
// a {b {bar:c(a:"bar") {...fr}}}
// }

def "Basic Nested"() {
given:
def mockServiceResponseBasic1 = [
Expand Down Expand Up @@ -150,6 +158,15 @@ class AliasFragmentSpreadWithNestedSpec extends BaseIntegrationTestSpecification
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
// fragment fr on C {d {f1 f2}}
//
// query QUERY {
// a {b {foo:c(a:"foo") {...fr}}}
// a {b {bar:c(a:"bar") {...fr}}}
// }
compareQueryToExecutionInput(null,
"queryQUERY{a{b{c(a:\"foo\"){d{f1f2}}}e{f1}}}", service1)
compareQueryToExecutionInput(null,"queryQUERY{a{b{c(a:\"foo\"){f{f1f2}}}}}", service2)
executionResult.getErrors().isEmpty()
Map<String, Object> data = executionResult.getData()
data.a?.b?.c?.d?.f1 instanceof String && data.a?.b?.c?.d?.f1 == "foo1"
Expand All @@ -158,11 +175,5 @@ class AliasFragmentSpreadWithNestedSpec extends BaseIntegrationTestSpecification
data.a?.b?.c?.f?.f2 instanceof String && data.a?.b?.c?.f?.f2 == "bar2"
data.a?.e?.f1 instanceof String && data.a?.e?.f1 == "eoo"
}

// fragment fr on C {d {f1 f2}}
//
// query QUERY {
// a {b {foo:c(a:"foo") {...fr}}}
// a {b {bar:c(a:"bar") {...fr}}}
// }

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.intuit.graphql.orchestrator.integration

import com.intuit.graphql.orchestrator.GraphQLOrchestrator
import com.intuit.graphql.orchestrator.testhelpers.SimpleMockServiceProvider
import graphql.ExecutionInput
import graphql.ExecutionResult
import graphql.schema.GraphQLInterfaceType
Expand Down Expand Up @@ -130,6 +131,9 @@ class InterfaceImplementInterfaceSpec extends BaseIntegrationTestSpecification {
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
compareQueryToExecutionInput(null,
"queryQUERY{pets{edges{...onDogEdge{node{idnameisServiceDog__typename}__typename}__typename}__typename}}",
(SimpleMockServiceProvider) testService)
executionResult.getErrors().isEmpty()
Map<String, Object> data = executionResult.getData()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.intuit.graphql.orchestrator.integration

import com.intuit.graphql.orchestrator.GraphQLOrchestrator
import com.intuit.graphql.orchestrator.schema.Operation
import com.intuit.graphql.orchestrator.testhelpers.SimpleMockServiceProvider
import graphql.ExecutionInput
import graphql.ExecutionResult
import helpers.BaseIntegrationTestSpecification
Expand Down Expand Up @@ -57,6 +59,7 @@ class JavaPrimitiveScalarSpec extends BaseIntegrationTestSpecification {
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
compareQueryToExecutionInput(Operation.QUERY, graphqlQuery, (SimpleMockServiceProvider) testService);
executionResult.getErrors().isEmpty()
Map<String, Object> data = executionResult.getData()
data.a instanceof Long && data.a == Long.MAX_VALUE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,14 @@ class NestedFieldResolverSpec extends BaseIntegrationTestSpecification {
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
specUnderTest.runtimeGraph.codeRegistry.dataFetcherMap.size() == 6
checkIfKeyExistsInDataFetcherMap(specUnderTest, "BObjectType.bObjectField")
checkIfKeyExistsInDataFetcherMap(specUnderTest, "Query.cTopField")
checkIfKeyExistsInDataFetcherMap(specUnderTest, "Query._namespace")
checkIfKeyExistsInDataFetcherMap(specUnderTest, "Query.arootField")
checkIfKeyExistsInDataFetcherMap(specUnderTest, "Query.bTopField")
checkIfKeyExistsInDataFetcherMap(specUnderTest, "AObjectType.cTopField")

executionResult.getErrors().isEmpty()
executionResult?.data?.bTopField?.size() == 2
executionResult?.data?.bTopField[0]?.size() == 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import com.google.common.collect.ImmutableMap
import com.intuit.graphql.orchestrator.ServiceProvider
import com.intuit.graphql.orchestrator.TestHelper
import com.intuit.graphql.orchestrator.TestServiceProvider
import com.intuit.graphql.orchestrator.schema.Operation
import com.intuit.graphql.orchestrator.stitching.StitchingException
import com.intuit.graphql.orchestrator.testhelpers.SimpleMockServiceProvider
import graphql.ExecutionInput
import graphql.ExecutionResult
import helpers.BaseIntegrationTestSpecification
Expand Down Expand Up @@ -85,6 +87,8 @@ class TopLevelStitchingSpec extends BaseIntegrationTestSpecification {
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
compareQueryToExecutionInput(Operation.QUERY, graphqlQuery, (SimpleMockServiceProvider) personService)
compareQueryToExecutionInput(null, null, (SimpleMockServiceProvider) epsService)
executionResult.getErrors().isEmpty()
Map<String, Object> data = executionResult.getData()
data.person?.name instanceof String && data.person?.name == "Test Name"
Expand All @@ -104,25 +108,31 @@ class TopLevelStitchingSpec extends BaseIntegrationTestSpecification {
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
compareQueryToExecutionInput(Operation.QUERY, graphqlQuery, (SimpleMockServiceProvider) epsService)
compareQueryToExecutionInput(null, null, (SimpleMockServiceProvider) personService)
executionResult.getErrors().isEmpty()
Map<String, Object> data = executionResult.getData()
data.Profile?.prefFirstName instanceof String && data.Profile?.prefFirstName == "First Name"
data.Profile?.prefLastName instanceof String && data.Profile?.prefLastName == "Last Name"
data.Profile?.version instanceof Integer && data.Profile?.version == Short.MAX_VALUE

}

def "Eps service is stitched and mutation query is successful"() {
given:
specUnderTest = createGraphQLOrchestrator([epsMutationService, personService])

def graphqlQuery = "mutation { upsertProfile(corpId: \"test corp\", input: {version: ${Short.MAX_VALUE}}) { prefFirstName prefLastName version } }"
def baseGraphqlQuery = "{ upsertProfile(corpId: \"test corp\", input: {version: ${Short.MAX_VALUE}}) { prefFirstName prefLastName version } }"
def graphqlQuery = "mutation " + baseGraphqlQuery

ExecutionInput executionInput = createExecutionInput(graphqlQuery)

when:
ExecutionResult executionResult = specUnderTest.execute(executionInput).get()

then:
compareQueryToExecutionInput(Operation.MUTATION, baseGraphqlQuery, (SimpleMockServiceProvider) epsMutationService)
compareQueryToExecutionInput(null, null, (SimpleMockServiceProvider) personService)
executionResult.getErrors().isEmpty()
Map<String, Object> data = executionResult.getData()
data.upsertProfile?.prefFirstName instanceof String && data.upsertProfile?.prefFirstName == "First Name"
Expand Down
38 changes: 38 additions & 0 deletions src/test/groovy/helpers/BaseIntegrationTestSpecification.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package helpers

import com.intuit.graphql.orchestrator.GraphQLOrchestrator
import com.intuit.graphql.orchestrator.ServiceProvider
import com.intuit.graphql.orchestrator.schema.Operation
import com.intuit.graphql.orchestrator.schema.RuntimeGraph
import com.intuit.graphql.orchestrator.stitching.SchemaStitcher
import com.intuit.graphql.orchestrator.testhelpers.MockServiceProvider
Expand Down Expand Up @@ -110,6 +111,43 @@ class BaseIntegrationTestSpecification extends Specification {
createExecutionInput(graphqlQuery, Collections.emptyMap())
}

static boolean compareQueryToExecutionInput(Operation operation, String query,
SimpleMockServiceProvider simpleMockServiceProvider) {
if (query == null) {
return getExecutionInputQueryNoSpace(simpleMockServiceProvider) == null
}
else {
String graphQuery = (operation != null) ? operation.toString().toLowerCase() +
operation.toString().toUpperCase() + query
: query
graphQuery = graphQuery.replaceAll("\\s", "");
return (graphQuery) == getExecutionInputQueryNoSpace(simpleMockServiceProvider)
}
}

static String getExecutionInputQueryNoSpace(SimpleMockServiceProvider simpleMockServiceProvider) {
String query = getExecutionInputQuery(simpleMockServiceProvider)
return query != null ? query.replaceAll("\\s", "") : null
}

static String getExecutionInputQuery(SimpleMockServiceProvider simpleMockServiceProvider) {
try {
Object executionInputArgs = simpleMockServiceProvider.executionInputArgumentCaptor.capturingMatcher.arguments
return (executionInputArgs != null && !executionInputArgs.isEmpty())
? executionInputArgs.get(0).query
: null;
} catch (NullPointerException e) {
return null; // NPE hidden as its expected to be thrown
}
}

static String checkIfKeyExistsInDataFetcherMap(GraphQLOrchestrator graphQLOrchestrator, String key){
return graphQLOrchestrator.runtimeGraph.codeRegistry.dataFetcherMap.entrySet().stream().anyMatch(
{ entry ->
(String.format("%s.%s", entry.getKey().getTypeName(), entry.getKey().getFieldName().toString())
!= key) })
}

ExecutionInput getCapturedDownstreamExecutionInput() {
return testService.getExecutionInputArgumentCaptor().getValue()
}
Expand Down

0 comments on commit dce3d3f

Please sign in to comment.