1 package graphql_test
2
3 import (
4 "context"
5 "io"
6 "io/ioutil"
7 "net/http"
8 "net/http/httptest"
9 "testing"
10
11 "github.com/shurcooL/graphql"
12 )
13
14 func TestClient_Query_partialDataWithErrorResponse(t *testing.T) {
15 mux := http.NewServeMux()
16 mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
17 w.Header().Set("Content-Type", "application/json")
18 mustWrite(w, `{
19 "data": {
20 "node1": {
21 "id": "MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng=="
22 },
23 "node2": null
24 },
25 "errors": [
26 {
27 "message": "Could not resolve to a node with the global id of 'NotExist'",
28 "type": "NOT_FOUND",
29 "path": [
30 "node2"
31 ],
32 "locations": [
33 {
34 "line": 10,
35 "column": 4
36 }
37 ]
38 }
39 ]
40 }`)
41 })
42 client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})
43
44 var q struct {
45 Node1 *struct {
46 ID graphql.ID
47 } `graphql:"node1: node(id: \"MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng==\")"`
48 Node2 *struct {
49 ID graphql.ID
50 } `graphql:"node2: node(id: \"NotExist\")"`
51 }
52 err := client.Query(context.Background(), &q, nil)
53 if err == nil {
54 t.Fatal("got error: nil, want: non-nil")
55 }
56 if got, want := err.Error(), "Could not resolve to a node with the global id of 'NotExist'"; got != want {
57 t.Errorf("got error: %v, want: %v", got, want)
58 }
59 if q.Node1 == nil || q.Node1.ID != "MDEyOklzc3VlQ29tbWVudDE2OTQwNzk0Ng==" {
60 t.Errorf("got wrong q.Node1: %v", q.Node1)
61 }
62 if q.Node2 != nil {
63 t.Errorf("got non-nil q.Node2: %v, want: nil", *q.Node2)
64 }
65 }
66
67 func TestClient_Query_noDataWithErrorResponse(t *testing.T) {
68 mux := http.NewServeMux()
69 mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
70 w.Header().Set("Content-Type", "application/json")
71 mustWrite(w, `{
72 "errors": [
73 {
74 "message": "Field 'user' is missing required arguments: login",
75 "locations": [
76 {
77 "line": 7,
78 "column": 3
79 }
80 ]
81 }
82 ]
83 }`)
84 })
85 client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})
86
87 var q struct {
88 User struct {
89 Name graphql.String
90 }
91 }
92 err := client.Query(context.Background(), &q, nil)
93 if err == nil {
94 t.Fatal("got error: nil, want: non-nil")
95 }
96 if got, want := err.Error(), "Field 'user' is missing required arguments: login"; got != want {
97 t.Errorf("got error: %v, want: %v", got, want)
98 }
99 if q.User.Name != "" {
100 t.Errorf("got non-empty q.User.Name: %v", q.User.Name)
101 }
102 }
103
104 func TestClient_Query_errorStatusCode(t *testing.T) {
105 mux := http.NewServeMux()
106 mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
107 http.Error(w, "important message", http.StatusInternalServerError)
108 })
109 client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})
110
111 var q struct {
112 User struct {
113 Name graphql.String
114 }
115 }
116 err := client.Query(context.Background(), &q, nil)
117 if err == nil {
118 t.Fatal("got error: nil, want: non-nil")
119 }
120 if got, want := err.Error(), `non-200 OK status code: 500 Internal Server Error body: "important message\n"`; got != want {
121 t.Errorf("got error: %v, want: %v", got, want)
122 }
123 if q.User.Name != "" {
124 t.Errorf("got non-empty q.User.Name: %v", q.User.Name)
125 }
126 }
127
128
129
130 func TestClient_Query_emptyVariables(t *testing.T) {
131 mux := http.NewServeMux()
132 mux.HandleFunc("/graphql", func(w http.ResponseWriter, req *http.Request) {
133 body := mustRead(req.Body)
134 if got, want := body, `{"query":"{user{name}}"}`+"\n"; got != want {
135 t.Errorf("got body: %v, want %v", got, want)
136 }
137 w.Header().Set("Content-Type", "application/json")
138 mustWrite(w, `{"data": {"user": {"name": "Gopher"}}}`)
139 })
140 client := graphql.NewClient("/graphql", &http.Client{Transport: localRoundTripper{handler: mux}})
141
142 var q struct {
143 User struct {
144 Name string
145 }
146 }
147 err := client.Query(context.Background(), &q, map[string]interface{}{})
148 if err != nil {
149 t.Fatal(err)
150 }
151 if got, want := q.User.Name, "Gopher"; got != want {
152 t.Errorf("got q.User.Name: %q, want: %q", got, want)
153 }
154 }
155
156
157
158 type localRoundTripper struct {
159 handler http.Handler
160 }
161
162 func (l localRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
163 w := httptest.NewRecorder()
164 l.handler.ServeHTTP(w, req)
165 return w.Result(), nil
166 }
167
168 func mustRead(r io.Reader) string {
169 b, err := ioutil.ReadAll(r)
170 if err != nil {
171 panic(err)
172 }
173 return string(b)
174 }
175
176 func mustWrite(w io.Writer, s string) {
177 _, err := io.WriteString(w, s)
178 if err != nil {
179 panic(err)
180 }
181 }
182
View as plain text