Skip to content

Commit

Permalink
Fix invalid AST returned by IntrospectAPI
Browse files Browse the repository at this point in the history
Fixes #35
  • Loading branch information
JohnStarich committed Nov 17, 2023
1 parent 6a52571 commit 331789b
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 2 deletions.
6 changes: 4 additions & 2 deletions introspection.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func IntrospectAPI(queryer Queryer, opts ...*IntrospectOptions) (*ast.Schema, er

// if we are looking at an enum
if len(remoteType.PossibleTypes) > 0 {
// build up an empty list of types
// build up an empty list of union types
storedType.Types = []string{}

// each union value needs to be added to the list
Expand All @@ -230,7 +230,9 @@ func IntrospectAPI(queryer Queryer, opts ...*IntrospectOptions) (*ast.Schema, er
if possibleType.Name == storedType.Name {
continue
}
storedType.Types = append(storedType.Types, possibleType.Name)
if storedType.Kind == ast.Union {
storedType.Types = append(storedType.Types, possibleType.Name)
}

// add the possible type to the schema
schema.AddPossibleType(remoteType.Name, possibleTypeDef)
Expand Down
134 changes: 134 additions & 0 deletions introspection_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package graphql

import (
"bytes"
"context"
"encoding/json"
"errors"
Expand All @@ -10,7 +11,9 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/vektah/gqlparser/v2"
"github.com/vektah/gqlparser/v2/ast"
"github.com/vektah/gqlparser/v2/formatter"
)

func TestIntrospectAPI(t *testing.T) {
Expand Down Expand Up @@ -1231,3 +1234,134 @@ func TestIntrospectAPI_retry(t *testing.T) {
}, schema)
})
}

// Tests fix for https://github.com/nautilus/graphql/issues/35
func TestIntrospectAPI_valid_interface_implementation(t *testing.T) {
t.Parallel()
schema, err := IntrospectAPI(&mockJSONQueryer{
JSONResult: `{
"__schema": {
"queryType": {
"name": "Query"
},
"types": [
{
"description": null,
"enumValues": [],
"fields": [
{
"args": [
{
"defaultValue": null,
"description": null,
"name": "id",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
}
],
"deprecationReason": null,
"description": "Find a Node for the given ID. Use fragments to select additional fields.",
"isDeprecated": false,
"name": "node",
"type": {
"kind": "INTERFACE",
"name": "Node",
"ofType": null
}
}
],
"inputFields": [],
"interfaces": [],
"kind": "OBJECT",
"name": "Query",
"possibleTypes": []
},
{
"description": "A resource.",
"enumValues": [],
"fields": [
{
"args": [],
"deprecationReason": null,
"description": "The ID of this resource.",
"isDeprecated": false,
"name": "id",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
}
],
"inputFields": [],
"interfaces": [
{
"kind": "INTERFACE",
"name": "Node",
"ofType": null
}
],
"kind": "OBJECT",
"name": "Resource",
"possibleTypes": []
},
{
"description": "Fetches an object given its ID.",
"enumValues": [],
"fields": [
{
"args": [],
"deprecationReason": null,
"description": "The globally unique object ID.",
"isDeprecated": false,
"name": "id",
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
}
}
],
"inputFields": [],
"interfaces": [],
"kind": "INTERFACE",
"name": "Node",
"possibleTypes": [
{
"kind": "INTERFACE",
"name": "Node",
"ofType": null
},
{
"kind": "OBJECT",
"name": "Resource",
"ofType": null
}
]
}
]
}
}`,
})
assert.NoError(t, err)

var schemaBuffer bytes.Buffer
formatter.NewFormatter(&schemaBuffer).FormatSchema(schema)
_, err = gqlparser.LoadSchema(&ast.Source{Name: "input.graphql", Input: schemaBuffer.String()})
assert.Nil(t, err, "Type should implement an interface without formatting/re-parsing failures.")
}

0 comments on commit 331789b

Please sign in to comment.