Skip to content

Commit

Permalink
graphql: add validations and tests for @Custom graphql on fields (hyp…
Browse files Browse the repository at this point in the history
…ermodeinc#5283)

This PR adds validations and tests for @Custom graphql on fields
  • Loading branch information
abhimanyusinghgaur authored and dna2github committed Jul 18, 2020
1 parent a46b829 commit 92d2b5a
Show file tree
Hide file tree
Showing 10 changed files with 1,287 additions and 351 deletions.
411 changes: 398 additions & 13 deletions graphql/e2e/custom_logic/cmd/main.go

Large diffs are not rendered by default.

222 changes: 211 additions & 11 deletions graphql/e2e/custom_logic/custom_logic_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -851,8 +851,8 @@ func TestForInvalidCustomQuery(t *testing.T) {
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:61: Type Query"+
"; Field getCountry: @custom directive: graphql; given query: country is not present in"+
" remote schema.\n", res.Errors[0].Error())
"; Field getCountry: inside graphql in @custom directive, query `country` is not present"+
" in remote schema.\n", res.Errors[0].Error())
}

func TestForInvalidArgument(t *testing.T) {
Expand All @@ -869,8 +869,8 @@ func TestForInvalidArgument(t *testing.T) {
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:61: Type Query"+
"; Field getCountry: @custom directive: graphql; given query: country: arg code not"+
" present in remote query.\n", res.Errors[0].Error())
"; Field getCountry: inside graphql in @custom directive, argument `code` is not present"+
" in remote query `country`.\n", res.Errors[0].Error())
}

func TestForInvalidType(t *testing.T) {
Expand All @@ -887,8 +887,8 @@ func TestForInvalidType(t *testing.T) {
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:61: Type Query"+
"; Field getCountry: @custom directive: graphql; given query: country: type mismatch for"+
" variable $id; expected: Int!, got: ID!.\n", res.Errors[0].Error())
"; Field getCountry: inside graphql in @custom directive, found type mismatch for "+
"variable `$id` in query `country`, expected `ID!`, got `Int!`.\n", res.Errors[0].Error())
}

func TestCustomLogicGraphql(t *testing.T) {
Expand Down Expand Up @@ -1368,6 +1368,74 @@ func TestCustomMutationShouldForwardHeaders(t *testing.T) {
require.JSONEq(t, expected, string(result.Data))
}

func TestCustomGraphqlNullQueryType(t *testing.T) {
schema := customTypes + `
type Query {
getCountry(id: ID!): Country! @custom(http: {
url: "http://mock:8888/nullQueryAndMutationType",
method: "POST",
graphql: "query { getCountry(id: $id) }"
})
}`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:60: Type Query"+
"; Field getCountry: inside graphql in @custom directive, remote schema doesn't have any"+
" queries.\n", res.Errors[0].Error())
}

func TestCustomGraphqlNullMutationType(t *testing.T) {
schema := customTypes + `
type Mutation {
addCountry(input: CountryInput!): Country! @custom(http: {
url: "http://mock:8888/nullQueryAndMutationType",
method: "POST",
graphql: "mutation { putCountry(country: $input) }"
})
}`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:60: Type Mutation"+
"; Field addCountry: inside graphql in @custom directive, remote schema doesn't have any"+
" mutations.\n", res.Errors[0].Error())
}

func TestCustomGraphqlMissingQueryType(t *testing.T) {
schema := customTypes + `
type Query {
getCountry(id: ID!): Country! @custom(http: {
url: "http://mock:8888/missingQueryAndMutationType",
method: "POST",
graphql: "query { getCountry(id: $id) }"
})
}`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:60: Type Query"+
"; Field getCountry: inside graphql in @custom directive, remote schema doesn't have any "+
"type named Query.\n", res.Errors[0].Error())
}

func TestCustomGraphqlMissingMutationType(t *testing.T) {
schema := customTypes + `
type Mutation {
addCountry(input: CountryInput!): Country! @custom(http: {
url: "http://mock:8888/missingQueryAndMutationType",
method: "POST",
graphql: "mutation { putCountry(country: $input) }"
})
}`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:60: Type Mutation"+
"; Field addCountry: inside graphql in @custom directive, remote schema doesn't have any"+
" type named Mutation.\n", res.Errors[0].Error())
}

func TestCustomGraphqlMissingMutation(t *testing.T) {
schema := customTypes + `
type Mutation {
Expand All @@ -1381,7 +1449,7 @@ func TestCustomGraphqlMissingMutation(t *testing.T) {
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:60: Type Mutation"+
"; Field addCountry: @custom directive: graphql; given mutation: putCountry is not"+
"; Field addCountry: inside graphql in @custom directive, mutation `putCountry` is not"+
" present in remote schema.\n", res.Errors[0].Error())
}

Expand All @@ -1398,8 +1466,119 @@ func TestCustomGraphqlReturnTypeMismatch(t *testing.T) {
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:60: Type Mutation"+
"; Field addCountry: @custom directive: graphql; given mutation: setCountry: return type"+
" mismatch; expected: Country!, got: Movie!.\n", res.Errors[0].Error())
"; Field addCountry: inside graphql in @custom directive, found return type mismatch for"+
" mutation `setCountry`, expected `Movie!`, got `Country!`.\n", res.Errors[0].Error())
}

func TestCustomGraphqlReturnTypeMismatchForBatchedField(t *testing.T) {
schema := `
type Author {
id: ID!
name: String!
}
type Post {
id: ID!
text: String
author: Author! @custom(http: {
url: "http://mock:8888/getPosts",
method: "POST",
operation: "batch"
graphql: "query { getPosts(input: [{id: $id}]) }"
})
}
`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:13: Type Post"+
"; Field author: inside graphql in @custom directive, found return type mismatch for "+
"query `getPosts`, expected `[Author!]`, got `[Post!]`.\n", res.Errors[0].Error())
}

func TestCustomGraphqlInvalidInputFormatForBatchedField(t *testing.T) {
schema := `
type Post {
id: ID!
text: String
comments: Post! @custom(http: {
url: "http://mock:8888/invalidInputForBatchedField",
method: "POST",
operation: "batch"
graphql: "query { getPosts(input: [{id: $id}]) }"
})
}
`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:9: Type Post"+
"; Field comments: inside graphql in @custom directive, argument `input` for given query"+
" `getPosts` must be of the form `[{param1: $var1, param2: $var2, ...}]` for batch "+
"operations in remote query.\n", res.Errors[0].Error())
}

func TestCustomGraphqlMissingTypeForBatchedFieldInput(t *testing.T) {
schema := `
type Post {
id: ID!
text: String
comments: Post! @custom(http: {
url: "http://mock:8888/missingTypeForBatchedFieldInput",
method: "POST",
operation: "batch"
graphql: "query { getPosts(input: [{id: $id}]) }"
})
}
`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:9: Type Post"+
"; Field comments: inside graphql in @custom directive, remote schema doesn't have any "+
"type named PostFilterInput.\n", res.Errors[0].Error())
}

func TestCustomGraphqlInvalidArgForBatchedField(t *testing.T) {
schema := `
type Post {
id: ID!
text: String
comments: Post! @custom(http: {
url: "http://mock:8888/getPosts",
method: "POST",
operation: "batch"
graphql: "query { getPosts(input: [{name: $id}]) }"
})
}
`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:9: Type Post"+
"; Field comments: inside graphql in @custom directive, argument `name` is not present "+
"in remote query `getPosts`.\n", res.Errors[0].Error())
}

func TestCustomGraphqlArgTypeMismatchForBatchedField(t *testing.T) {
schema := `
type Post {
id: ID!
likes: Int
text: String
comments: Post! @custom(http: {
url: "http://mock:8888/getPosts",
method: "POST",
operation: "batch"
graphql: "query { getPosts(input: [{id: $id, text: $likes}]) }"
})
}
`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:10: Type Post"+
"; Field comments: inside graphql in @custom directive, found type mismatch for variable"+
" `$likes` in query `getPosts`, expected `Int`, got `String!`.\n", res.Errors[0].Error())
}

func TestCustomGraphqlMissingRequiredArgument(t *testing.T) {
Expand All @@ -1415,8 +1594,29 @@ func TestCustomGraphqlMissingRequiredArgument(t *testing.T) {
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:60: Type Mutation"+
"; Field addCountry: @custom directive: graphql; given mutation: setCountry: required arg"+
" country is missing.\n", res.Errors[0].Error())
"; Field addCountry: inside graphql in @custom directive, argument `country` in mutation"+
" `setCountry` is missing, it is required by remote mutation.\n", res.Errors[0].Error())
}

func TestCustomGraphqlMissingRequiredArgumentForBatchedField(t *testing.T) {
schema := `
type Post {
id: ID!
text: String
comments: Post! @custom(http: {
url: "http://mock:8888/getPosts",
method: "POST",
operation: "batch"
graphql: "query { getPosts(input: [{id: $id}]) }"
})
}
`
res := updateSchema(t, schema)
require.Equal(t, `{"updateGQLSchema":null}`, string(res.Data))
require.Len(t, res.Errors, 1)
require.Equal(t, "couldn't rewrite mutation updateGQLSchema because input:9: Type Post"+
"; Field comments: inside graphql in @custom directive, argument `text` in query "+
"`getPosts` is missing, it is required by remote query.\n", res.Errors[0].Error())
}

// this one accepts an object and returns an object
Expand Down
8 changes: 4 additions & 4 deletions graphql/e2e/custom_logic/schemas/batch-mode-graphql.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type User {
url: "http://mock:8888/gqlCars"
method: "POST"
operation: "batch"
graphql: "query { cars(input: [{ id: $id}]) }"
graphql: "query { cars(input: [{ id: $id, age: $age}]) }"
}
)
schools: [School]
Expand All @@ -36,7 +36,7 @@ type School {
url: "http://mock:8888/gqlSchoolNames"
method: "POST"
operation: "batch"
graphql: "query { schoolNames(input: [{ id: $id}]) }"
graphql: "query { schoolNames(input: [{ id: $id, age: $established}]) }"
}
)
classes: [Class]
Expand All @@ -45,7 +45,7 @@ type School {
url: "http://mock:8888/gqlClasses"
method: "POST"
operation: "batch"
graphql: "query { classes(input: [{ id: $id}]) }"
graphql: "query { classes(input: [{ id: $id, age: $established}]) }"
}
)
teachers: [Teacher]
Expand All @@ -65,7 +65,7 @@ type Teacher {
url: "http://mock:8888/gqlTeacherNames"
method: "POST"
operation: "batch"
graphql: "query { teacherNames(input: [{ xid: $tid}]) }"
graphql: "query { teacherNames(input: [{ id: $tid, age: $age}]) }"
}
)
}
2 changes: 1 addition & 1 deletion graphql/e2e/custom_logic/schemas/mixed-modes.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type Teacher {
url: "http://mock:8888/gqlTeacherNames"
method: "POST"
operation: "batch"
graphql: "query { teacherNames(input: [{ xid: $tid}]) }"
graphql: "query { teacherNames(input: [{ id: $tid, age: $age}]) }"
}
)
}
6 changes: 3 additions & 3 deletions graphql/schema/gqlschema.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ func completeSchema(sch *ast.Schema, definitions []string) {
}

for _, key := range definitions {
if key == "Query" || key == "Mutation" {
if isQueryOrMutation(key) {
continue
}
defn := sch.Types[key]
Expand Down Expand Up @@ -1459,7 +1459,7 @@ func Stringify(schema *ast.Schema, originalTypes []string) string {
// original defs can only be types and enums, print those in the same order
// as the original schema.
for _, typName := range originalTypes {
if typName == "Query" || typName == "Mutation" {
if isQueryOrMutation(typName) {
// These would be printed later in schema.Query and schema.Mutation
continue
}
Expand Down Expand Up @@ -1494,7 +1494,7 @@ func Stringify(schema *ast.Schema, originalTypes []string) string {
// left to be printed.
typeNames := make([]string, 0, len(schema.Types)-len(printed))
for typName, typDef := range schema.Types {
if typName == "Query" || typName == "Mutation" {
if isQueryOrMutation(typName) {
// These would be printed later in schema.Query and schema.Mutation
continue
}
Expand Down
Loading

0 comments on commit 92d2b5a

Please sign in to comment.