github.com/dgraph-io/dgraph@v1.2.8/graphql/schema/introspection_test.go (about)

     1  package schema
     2  
     3  import (
     4  	"io/ioutil"
     5  	"path/filepath"
     6  	"testing"
     7  
     8  	"github.com/dgraph-io/dgraph/testutil"
     9  	"github.com/stretchr/testify/require"
    10  	"github.com/vektah/gqlparser"
    11  	"github.com/vektah/gqlparser/ast"
    12  	"github.com/vektah/gqlparser/parser"
    13  	"github.com/vektah/gqlparser/validator"
    14  )
    15  
    16  const introspectionQuery = `
    17    query {
    18      __schema {
    19        queryType { name }
    20        mutationType { name }
    21        subscriptionType { name }
    22        types {
    23          ...FullType
    24        }
    25        directives {
    26          name
    27          locations
    28          args {
    29            ...InputValue
    30          }
    31        }
    32      }
    33    }
    34    fragment FullType on __Type {
    35      kind
    36      name
    37      fields(includeDeprecated: true) {
    38        name
    39        args {
    40          ...InputValue
    41        }
    42        type {
    43          ...TypeRef
    44        }
    45        isDeprecated
    46        deprecationReason
    47      }
    48      inputFields {
    49        ...InputValue
    50      }
    51      interfaces {
    52        ...TypeRef
    53      }
    54      enumValues(includeDeprecated: true) {
    55        name
    56        isDeprecated
    57        deprecationReason
    58      }
    59      possibleTypes {
    60        ...TypeRef
    61      }
    62    }
    63    fragment InputValue on __InputValue {
    64      name
    65      type { ...TypeRef }
    66      defaultValue
    67    }
    68    fragment TypeRef on __Type {
    69      kind
    70      name
    71      ofType {
    72        kind
    73        name
    74        ofType {
    75          kind
    76          name
    77          ofType {
    78            kind
    79            name
    80            ofType {
    81              kind
    82              name
    83              ofType {
    84                kind
    85                name
    86                ofType {
    87                  kind
    88                  name
    89                  ofType {
    90                    kind
    91                    name
    92                  }
    93                }
    94              }
    95            }
    96          }
    97        }
    98      }
    99    }
   100  `
   101  
   102  const complexSchema = `schema {
   103  	query: TestType
   104    }
   105  
   106    input TestInputObject {
   107  	a: String = test
   108  	b: [String]
   109  	c: String = null
   110    }
   111  
   112  
   113    input TestType {
   114  	complex: TestInputObject
   115    }
   116    `
   117  
   118  func TestIntrospectionQuery(t *testing.T) {
   119  	simpleSchema := `schema {
   120  		query: QueryRoot
   121  	}
   122  
   123  	type QueryRoot {
   124  		onlyField: String
   125  	}`
   126  
   127  	iprefix := "testdata/introspection/input"
   128  	oprefix := "testdata/introspection/output"
   129  
   130  	var tests = []struct {
   131  		name       string
   132  		schema     string
   133  		queryFile  string
   134  		outputFile string
   135  	}{
   136  		{
   137  			"Filter on __type",
   138  			simpleSchema,
   139  			filepath.Join(iprefix, "type_filter.txt"),
   140  			filepath.Join(oprefix, "type_filter.json"),
   141  		},
   142  		{"Filter __Schema on __type",
   143  			simpleSchema,
   144  			filepath.Join(iprefix, "type_schema_filter.txt"),
   145  			filepath.Join(oprefix, "type_schema_filter.json"),
   146  		},
   147  		{"Filter object type __type",
   148  			simpleSchema,
   149  			filepath.Join(iprefix, "type_object_name_filter.txt"),
   150  			filepath.Join(oprefix, "type_object_name_filter.json"),
   151  		},
   152  		{"Filter complex object type __type",
   153  			complexSchema,
   154  			filepath.Join(iprefix, "type_complex_object_name_filter.txt"),
   155  			filepath.Join(oprefix, "type_complex_object_name_filter.json"),
   156  		},
   157  	}
   158  
   159  	for _, tt := range tests {
   160  		sch := gqlparser.MustLoadSchema(
   161  			&ast.Source{Name: "schema.graphql", Input: tt.schema})
   162  
   163  		q, err := ioutil.ReadFile(tt.queryFile)
   164  		require.NoError(t, err)
   165  
   166  		doc, gqlErr := parser.ParseQuery(&ast.Source{Input: string(q)})
   167  		require.Nil(t, gqlErr)
   168  		listErr := validator.Validate(sch, doc)
   169  		require.Equal(t, 0, len(listErr))
   170  
   171  		op := doc.Operations.ForName("")
   172  		oper := &operation{op: op,
   173  			vars:     map[string]interface{}{},
   174  			query:    string(q),
   175  			doc:      doc,
   176  			inSchema: &schema{schema: sch},
   177  		}
   178  		require.NotNil(t, op)
   179  
   180  		queries := oper.Queries()
   181  		resp, err := Introspect(queries[0])
   182  		require.NoError(t, err)
   183  
   184  		expectedBuf, err := ioutil.ReadFile(tt.outputFile)
   185  		require.NoError(t, err)
   186  		testutil.CompareJSON(t, string(expectedBuf), string(resp))
   187  	}
   188  }
   189  
   190  func TestIntrospectionQueryWithVars(t *testing.T) {
   191  	sch := gqlparser.MustLoadSchema(
   192  		&ast.Source{Name: "schema.graphql", Input: complexSchema})
   193  
   194  	q := `query filterNameOnType($name: String!) {
   195  			__type(name: $name) {
   196  				kind
   197  				name
   198  				inputFields {
   199  					name
   200  					type { ...TypeRef }
   201  					defaultValue
   202  				}
   203  			}
   204  		}
   205  
   206  		fragment TypeRef on __Type {
   207  			kind
   208  			name
   209  			ofType {
   210  				kind
   211  				name
   212  				ofType {
   213  					kind
   214  					name
   215  					ofType {
   216  						kind
   217  						name
   218  					}
   219  				}
   220  			}
   221  		}`
   222  
   223  	doc, gqlErr := parser.ParseQuery(&ast.Source{Input: q})
   224  	require.Nil(t, gqlErr)
   225  	listErr := validator.Validate(sch, doc)
   226  	require.Equal(t, 0, len(listErr))
   227  
   228  	op := doc.Operations.ForName("")
   229  	oper := &operation{op: op,
   230  		vars:     map[string]interface{}{"name": "TestInputObject"},
   231  		query:    q,
   232  		doc:      doc,
   233  		inSchema: &schema{schema: sch},
   234  	}
   235  	require.NotNil(t, op)
   236  
   237  	queries := oper.Queries()
   238  	resp, err := Introspect(queries[0])
   239  	require.NoError(t, err)
   240  
   241  	fname := "testdata/introspection/output/type_complex_object_name_filter.json"
   242  	expectedBuf, err := ioutil.ReadFile(fname)
   243  	require.NoError(t, err)
   244  	testutil.CompareJSON(t, string(expectedBuf), string(resp))
   245  }
   246  
   247  func TestFullIntrospectionQuery(t *testing.T) {
   248  	// The output doesn't quite match the output in the graphql-js repo. Look into this later.
   249  	// https://github.com/graphql/graphql-js/blob/master/src/type/__tests__/introspection-test.js#L35
   250  	sch := gqlparser.MustLoadSchema(
   251  		&ast.Source{Name: "schema.graphql", Input: `
   252  	schema {
   253  		query: TestType
   254  	}
   255  
   256  	type TestType {
   257  		testField: String
   258  	}
   259  `})
   260  
   261  	doc, gqlErr := parser.ParseQuery(&ast.Source{Input: introspectionQuery})
   262  	require.Nil(t, gqlErr)
   263  
   264  	listErr := validator.Validate(sch, doc)
   265  	require.Equal(t, 0, len(listErr))
   266  
   267  	op := doc.Operations.ForName("")
   268  	require.NotNil(t, op)
   269  	oper := &operation{op: op,
   270  		vars:     map[string]interface{}{},
   271  		query:    string(introspectionQuery),
   272  		doc:      doc,
   273  		inSchema: &schema{schema: sch},
   274  	}
   275  
   276  	queries := oper.Queries()
   277  	resp, err := Introspect(queries[0])
   278  	require.NoError(t, err)
   279  
   280  	expectedBuf, err := ioutil.ReadFile("testdata/introspection/output/full_query.json")
   281  	require.NoError(t, err)
   282  	testutil.CompareJSON(t, string(expectedBuf), string(resp))
   283  }