1 package graphqlhelpers
2
3 import (
4 "bytes"
5 "strings"
6 "testing"
7
8 "github.com/99designs/gqlgen/graphql"
9 "github.com/stretchr/testify/assert"
10 "github.com/vektah/gqlparser/v2/ast"
11 "github.com/vektah/gqlparser/v2/formatter"
12 "github.com/vektah/gqlparser/v2/gqlerror"
13 )
14
15 func TestGetOperation(t *testing.T) {
16 queryOp := ast.Query
17 mutationOp := ast.Mutation
18 subscriptionOp := ast.Subscription
19 testCases := []struct {
20 title string
21 rctx *graphql.OperationContext
22 op *ast.Operation
23 }{
24 {
25 title: "Test Case One - Empty Context",
26 rctx: &graphql.OperationContext{},
27 op: nil,
28 },
29 {
30 title: "Test Case Two - Nil Context",
31 rctx: nil,
32 op: nil,
33 },
34 {
35 title: "Test Case Three - Query Context",
36 rctx: &graphql.OperationContext{
37 Operation: &ast.OperationDefinition{
38 Operation: ast.Query,
39 Name: "GetUsersQuery",
40 },
41 },
42 op: &queryOp,
43 },
44 {
45 title: "Test Case Four - Mutation Context",
46 rctx: &graphql.OperationContext{
47 Operation: &ast.OperationDefinition{
48 Operation: ast.Mutation,
49 Name: "LoginUserMutation",
50 },
51 },
52 op: &mutationOp,
53 },
54 {
55 title: "Test Case Five - Subscription Context",
56 rctx: &graphql.OperationContext{
57 Operation: &ast.OperationDefinition{
58 Operation: ast.Subscription,
59 Name: "GetPollsSubscription",
60 },
61 },
62 op: &subscriptionOp,
63 },
64 }
65 for _, testCase := range testCases {
66 t.Run(testCase.title, func(t *testing.T) {
67 op := GetOperation(testCase.rctx)
68 assert.Equal(t, testCase.op, op)
69 })
70 }
71 }
72
73 func TestGetRawQuery(t *testing.T) {
74 queryOp := ast.Query
75 mutationOp := ast.Mutation
76 testCases := []struct {
77 title string
78 rctx *graphql.OperationContext
79 op *ast.Operation
80 }{
81 {
82 title: "Test Case One - Query Raw Query",
83 rctx: &graphql.OperationContext{
84 Operation: &ast.OperationDefinition{
85 Operation: ast.Query,
86 Name: "GetUsersQuery",
87 },
88 RawQuery: `
89 query GetUsersQuery {
90 users {
91 email
92 username
93 fullName
94 familyName
95 givenName
96 status
97 }
98 }
99 `,
100 },
101 op: &queryOp,
102 },
103 {
104 title: "Test Case Two - Mutation Raw Query",
105 rctx: &graphql.OperationContext{
106 Operation: &ast.OperationDefinition{
107 Operation: ast.Mutation,
108 Name: "LoginUserMutation",
109 },
110 RawQuery: `
111 mutation MyMutation {
112 login(organization: "test-org", password: "123456", username: "test") {
113 firstName
114 fullName
115 roles
116 organization
117 credentialsExpired
118 sessionTime
119 token
120 }
121 }
122 `,
123 },
124 op: &mutationOp,
125 },
126 }
127 for _, testCase := range testCases {
128 t.Run(testCase.title, func(t *testing.T) {
129 query := GetRawQuery(testCase.rctx)
130 assert.Equal(t, testCase.rctx.RawQuery, query)
131 })
132 }
133 }
134
135 func TestGetResponseStatus(t *testing.T) {
136 testCases := []struct {
137 title string
138 resp *graphql.Response
139 status string
140 }{
141 {
142 title: "Test Case One - Nil Response",
143 resp: nil,
144 status: "Unknown",
145 },
146 {
147 title: "Test Case Two - Empty Response",
148 resp: &graphql.Response{},
149 status: "Success",
150 },
151 {
152 title: "Test Case Three - Errors and No Data Response",
153 resp: &graphql.Response{
154 Errors: gqlerror.List{
155 &gqlerror.Error{
156 Message: "error no rows found for banners",
157 },
158 &gqlerror.Error{
159 Message: "error no rows found for clusters",
160 },
161 },
162 Data: []byte("null"),
163 },
164 status: "Failure",
165 },
166 {
167 title: "Test Case Four - Errors and Data Response",
168 resp: &graphql.Response{
169 Errors: gqlerror.List{
170 &gqlerror.Error{
171 Message: "error no rows found for banners",
172 },
173 &gqlerror.Error{
174 Message: "error no rows found for clusters",
175 },
176 },
177 Data: []byte("hello"),
178 },
179 status: "Partial Failure",
180 },
181 {
182 title: "Test Case Five - Data and No Error Response",
183 resp: &graphql.Response{
184 Data: []byte("hello"),
185 },
186 status: "Success",
187 },
188 }
189 for _, testCase := range testCases {
190 t.Run(testCase.title, func(t *testing.T) {
191 status := GetResponseStatus(testCase.resp)
192 assert.Equal(t, testCase.status, status)
193 })
194 }
195 }
196
197 func TestUpdateQueryWithVariables(t *testing.T) {
198 testcases := []struct {
199 title string
200 variables map[string]interface{}
201 rawquery string
202 expected string
203 queryNames []string
204 }{
205 {
206 title: "Test Case 1 - String Variables",
207 rawquery: "mutation login($username: String!, $password: String!, $organization: String!) {\n login(username: $username, password: $password, organization: $organization) {\n fullName\n firstName\n credentialsExpired\n token\n __typename\n }\n}\n",
208 expected: `{"organization":"\"test-org\"","password":"\"123456\"","username":"\"test-user\""}`,
209 variables: map[string]interface{}{
210 "USERNAME": "test-user",
211 "PASSWORD": "123456",
212 "ORGANIZATION": "test-org",
213 },
214 queryNames: []string{
215 "login",
216 },
217 },
218 {
219 title: "Test Case 2 - Object Variables",
220 rawquery: "mutation createLabel($newLabel: LabelInput!) {\n createLabel(newLabel: $newLabel)\n}\n",
221 expected: `{"newLabel":"{color:\"#000\",visible:true,editable:true,unique:false,bannerEdgeId:\"4ba7b765-68e2-453e-a2f5-787dca9b30f7\",description:\"\",type:\"\",key:\"test\"}"}`,
222 variables: map[string]interface{}{
223 "NEWLABEL": map[string]interface{}{
224 "key": "test",
225 "color": "#000",
226 "visible": true,
227 "editable": true,
228 "unique": false,
229 "bannerEdgeId": "4ba7b765-68e2-453e-a2f5-787dca9b30f7",
230 "description": "",
231 "type": "",
232 },
233 },
234 queryNames: []string{
235 "createLabel",
236 },
237 },
238 {
239 title: "Test Case 3 - Array Variables",
240 rawquery: "mutation assignUserRoles($roles: RoleInput!) {\n assignUserRoles(roles: $roles)\n}\n",
241 expected: `{"roles":"[\"EDGE_ORG_ADMIN\",\"EDGE_BANNER_ADMIN\"]"}`,
242 variables: map[string]interface{}{
243 "ROLES": []string{
244 "EDGE_ORG_ADMIN",
245 "EDGE_BANNER_ADMIN",
246 },
247 },
248 queryNames: []string{
249 "assignUserRoles",
250 },
251 },
252 {
253 title: "Test Case 4 - Object Variables with Sub List",
254 rawquery: "mutation createLabel($newLabel: LabelInput!) {\n createLabel(newLabel: $newLabel)\n}\n",
255 expected: `{"newLabel":"{unique:false,bannerEdgeId:\"4ba7b765-68e2-453e-a2f5-787dca9b30f7\",description:\"\",parent:{labelEdgeId:\"4ba7b765-68e2-453e-a2f5-787dca9b32B1\"},key:\"test\",color:\"#000\",visible:true,editable:true}"}`,
256 variables: map[string]interface{}{
257 "NEWLABEL": map[string]interface{}{
258 "key": "test",
259 "color": "#000",
260 "visible": true,
261 "editable": true,
262 "unique": false,
263 "bannerEdgeId": "4ba7b765-68e2-453e-a2f5-787dca9b30f7",
264 "description": "",
265 "parent": map[string]interface{}{
266 "labelEdgeId": "4ba7b765-68e2-453e-a2f5-787dca9b32B1",
267 },
268 },
269 },
270 queryNames: []string{
271 "createLabel",
272 },
273 },
274 {
275 title: "Test Case 5 - Multiple Variable Types",
276 rawquery: "mutation user($username: String!, $age: String!, $nickname: String, $roles: RoleInput, $pins: PinInput, $extra: ExtraInput) {\n user(username: $username, age: $age, nickname: $nickname, roles: $roles, pins: $pins, extra: $extra) {\n fullName\n firstName\n credentialsExpired\n token\n __typename\n }\n}\n",
277 expected: `{"age":"10","extra":"[1,\"hello\",2.4,{one:\"two\",two:3},[1,2,3],[\"hello\",[23,43],[\"Colors\",[\"Yellow\",\"Red\",\"Blue\"]]]]","nickname":"nickname","pins":"[20,30,40]","roles":"[\"EDGE_ORG_ADMIN\",\"EDGE_BANNER_ADMIN\"]","username":"\"test-user\""}`,
278 variables: map[string]interface{}{
279 "USERNAME": "test-user",
280 "AGE": 10,
281 "NICKNAME": nil,
282 "ROLES": []string{
283 "EDGE_ORG_ADMIN",
284 "EDGE_BANNER_ADMIN",
285 },
286 "PINS": []int{
287 20,
288 30,
289 40,
290 },
291 "EXTRA": []any{
292 1,
293 "hello",
294 2.4,
295 nil,
296 map[string]interface{}{
297 "one": "two",
298 "two": 3,
299 },
300 []int{
301 1,
302 2,
303 3,
304 },
305 []any{
306 "hello",
307 []int{
308 23,
309 43,
310 },
311 []any{
312 "Colors",
313 []string{
314 "Yellow",
315 "Red",
316 "Blue",
317 },
318 },
319 },
320 },
321 },
322 queryNames: []string{
323 "user",
324 },
325 },
326 }
327 for _, testcase := range testcases {
328 t.Run(testcase.title, func(t *testing.T) {
329 schema, err := ParseQuery(testcase.rawquery)
330 assert.NoError(t, err)
331 UpdateQueryWithVariables(schema, testcase.variables)
332 buf := bytes.NewBuffer(nil)
333 formatter.NewFormatter(buf).FormatQueryDocument(schema)
334 updatedschema, err := ParseQuery(buf.String())
335 assert.NoError(t, err)
336 queryNames := GetQueryNames(updatedschema)
337 assert.Equal(t, testcase.queryNames, queryNames)
338 params := GetParams(nil, updatedschema)
339 for k := range params {
340 _, exists := testcase.variables[strings.ToUpper(k)]
341 assert.True(t, exists)
342 }
343 })
344 }
345 }
346
View as plain text