1package graphql_test 2 3import ( 4 "context" 5 "reflect" 6 "testing" 7 8 "github.com/graphql-go/graphql" 9 "github.com/graphql-go/graphql/testutil" 10) 11 12type T struct { 13 Query string 14 Schema graphql.Schema 15 Expected interface{} 16 Variables map[string]interface{} 17} 18 19var Tests = []T{} 20 21func init() { 22 Tests = []T{ 23 { 24 Query: ` 25 query HeroNameQuery { 26 hero { 27 name 28 } 29 } 30 `, 31 Schema: testutil.StarWarsSchema, 32 Expected: &graphql.Result{ 33 Data: map[string]interface{}{ 34 "hero": map[string]interface{}{ 35 "name": "R2-D2", 36 }, 37 }, 38 }, 39 }, 40 { 41 Query: ` 42 query HeroNameAndFriendsQuery { 43 hero { 44 id 45 name 46 friends { 47 name 48 } 49 } 50 } 51 `, 52 Schema: testutil.StarWarsSchema, 53 Expected: &graphql.Result{ 54 Data: map[string]interface{}{ 55 "hero": map[string]interface{}{ 56 "id": "2001", 57 "name": "R2-D2", 58 "friends": []interface{}{ 59 map[string]interface{}{ 60 "name": "Luke Skywalker", 61 }, 62 map[string]interface{}{ 63 "name": "Han Solo", 64 }, 65 map[string]interface{}{ 66 "name": "Leia Organa", 67 }, 68 }, 69 }, 70 }, 71 }, 72 }, 73 { 74 Query: ` 75 query HumanByIdQuery($id: String!) { 76 human(id: $id) { 77 name 78 } 79 } 80 `, 81 Schema: testutil.StarWarsSchema, 82 Expected: &graphql.Result{ 83 Data: map[string]interface{}{ 84 "human": map[string]interface{}{ 85 "name": "Darth Vader", 86 }, 87 }, 88 }, 89 Variables: map[string]interface{}{ 90 "id": "1001", 91 }, 92 }, 93 } 94} 95 96func TestQuery(t *testing.T) { 97 for _, test := range Tests { 98 params := graphql.Params{ 99 Schema: test.Schema, 100 RequestString: test.Query, 101 VariableValues: test.Variables, 102 } 103 testGraphql(test, params, t) 104 } 105} 106 107func testGraphql(test T, p graphql.Params, t *testing.T) { 108 result := graphql.Do(p) 109 if len(result.Errors) > 0 { 110 t.Fatalf("wrong result, unexpected errors: %v", result.Errors) 111 } 112 if !reflect.DeepEqual(result, test.Expected) { 113 t.Fatalf("wrong result, query: %v, graphql result diff: %v", test.Query, testutil.Diff(test.Expected, result)) 114 } 115} 116 117func TestBasicGraphQLExample(t *testing.T) { 118 // taken from `graphql-js` README 119 120 helloFieldResolved := func(p graphql.ResolveParams) (interface{}, error) { 121 return "world", nil 122 } 123 124 schema, err := graphql.NewSchema(graphql.SchemaConfig{ 125 Query: graphql.NewObject(graphql.ObjectConfig{ 126 Name: "RootQueryType", 127 Fields: graphql.Fields{ 128 "hello": &graphql.Field{ 129 Description: "Returns `world`", 130 Type: graphql.String, 131 Resolve: helloFieldResolved, 132 }, 133 }, 134 }), 135 }) 136 if err != nil { 137 t.Fatalf("wrong result, unexpected errors: %v", err.Error()) 138 } 139 query := "{ hello }" 140 var expected interface{} 141 expected = map[string]interface{}{ 142 "hello": "world", 143 } 144 145 result := graphql.Do(graphql.Params{ 146 Schema: schema, 147 RequestString: query, 148 }) 149 if len(result.Errors) > 0 { 150 t.Fatalf("wrong result, unexpected errors: %v", result.Errors) 151 } 152 if !reflect.DeepEqual(result.Data, expected) { 153 t.Fatalf("wrong result, query: %v, graphql result diff: %v", query, testutil.Diff(expected, result)) 154 } 155 156} 157 158func TestThreadsContextFromParamsThrough(t *testing.T) { 159 extractFieldFromContextFn := func(p graphql.ResolveParams) (interface{}, error) { 160 return p.Context.Value(p.Args["key"]), nil 161 } 162 163 schema, err := graphql.NewSchema(graphql.SchemaConfig{ 164 Query: graphql.NewObject(graphql.ObjectConfig{ 165 Name: "Query", 166 Fields: graphql.Fields{ 167 "value": &graphql.Field{ 168 Type: graphql.String, 169 Args: graphql.FieldConfigArgument{ 170 "key": &graphql.ArgumentConfig{Type: graphql.String}, 171 }, 172 Resolve: extractFieldFromContextFn, 173 }, 174 }, 175 }), 176 }) 177 if err != nil { 178 t.Fatalf("wrong result, unexpected errors: %v", err.Error()) 179 } 180 query := `{ value(key:"a") }` 181 182 result := graphql.Do(graphql.Params{ 183 Schema: schema, 184 RequestString: query, 185 Context: context.WithValue(context.TODO(), "a", "xyz"), 186 }) 187 if len(result.Errors) > 0 { 188 t.Fatalf("wrong result, unexpected errors: %v", result.Errors) 189 } 190 expected := map[string]interface{}{"value": "xyz"} 191 if !reflect.DeepEqual(result.Data, expected) { 192 t.Fatalf("wrong result, query: %v, graphql result diff: %v", query, testutil.Diff(expected, result)) 193 } 194 195} 196 197func TestNewErrorChecksNilNodes(t *testing.T) { 198 schema, err := graphql.NewSchema(graphql.SchemaConfig{ 199 Query: graphql.NewObject(graphql.ObjectConfig{ 200 Name: "Query", 201 Fields: graphql.Fields{ 202 "graphql_is": &graphql.Field{ 203 Type: graphql.String, 204 Resolve: func(p graphql.ResolveParams) (interface{}, error) { 205 return "", nil 206 }, 207 }, 208 }, 209 }), 210 }) 211 if err != nil { 212 t.Fatalf("unexpected errors: %v", err.Error()) 213 } 214 query := `{graphql_is:great(sort:ByPopularity)}{stars}` 215 result := graphql.Do(graphql.Params{ 216 Schema: schema, 217 RequestString: query, 218 }) 219 if len(result.Errors) == 0 { 220 t.Fatalf("expected errors, got: %v", result) 221 } 222} 223 224func TestEmptyStringIsNotNull(t *testing.T) { 225 checkForEmptyString := func(p graphql.ResolveParams) (interface{}, error) { 226 arg := p.Args["arg"] 227 if arg == nil || arg.(string) != "" { 228 t.Errorf("Expected empty string for input arg, got %#v", arg) 229 } 230 return "yay", nil 231 } 232 returnEmptyString := func(p graphql.ResolveParams) (interface{}, error) { 233 return "", nil 234 } 235 236 schema, err := graphql.NewSchema(graphql.SchemaConfig{ 237 Query: graphql.NewObject(graphql.ObjectConfig{ 238 Name: "Query", 239 Fields: graphql.Fields{ 240 "checkEmptyArg": &graphql.Field{ 241 Type: graphql.String, 242 Args: graphql.FieldConfigArgument{ 243 "arg": &graphql.ArgumentConfig{Type: graphql.String}, 244 }, 245 Resolve: checkForEmptyString, 246 }, 247 "checkEmptyResult": &graphql.Field{ 248 Type: graphql.String, 249 Resolve: returnEmptyString, 250 }, 251 }, 252 }), 253 }) 254 if err != nil { 255 t.Fatalf("wrong result, unexpected errors: %v", err.Error()) 256 } 257 query := `{ checkEmptyArg(arg:"") checkEmptyResult }` 258 259 result := graphql.Do(graphql.Params{ 260 Schema: schema, 261 RequestString: query, 262 }) 263 if len(result.Errors) > 0 { 264 t.Fatalf("wrong result, unexpected errors: %v", result.Errors) 265 } 266 expected := map[string]interface{}{"checkEmptyArg": "yay", "checkEmptyResult": ""} 267 if !reflect.DeepEqual(result.Data, expected) { 268 t.Errorf("wrong result, query: %v, graphql result diff: %v", query, testutil.Diff(expected, result)) 269 } 270} 271