Skip to content

Commit 16b4bc8

Browse files
committed
graphql: handle nested inputObjects properly
Closes #223
1 parent 41e544a commit 16b4bc8

File tree

3 files changed

+135
-7
lines changed

3 files changed

+135
-7
lines changed

cartridge/graphql/rules.lua

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,6 @@ function rules.variableDefaultValuesHaveCorrectType(node, context)
413413
end
414414

415415
function rules.variablesAreUsed(node, context)
416-
local operationName = node.name and node.name.value or ''
417-
if context.skipVariableUseCheck[operationName] then
418-
return
419-
end
420-
421416
if node.variableDefinitions then
422417
for _, definition in ipairs(node.variableDefinitions) do
423418
local variableName = definition.variable.name.value

cartridge/graphql/validate.lua

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,10 @@ local visitors = {
260260

261261
children = function(node)
262262
return util.map(node.value.values or {}, function(value)
263-
return value.value
263+
if value.value ~= nil then
264+
return value.value
265+
end
266+
return value
264267
end)
265268
end,
266269

@@ -277,6 +280,12 @@ local visitors = {
277280
rules = { rules.uniqueInputObjectFields }
278281
},
279282

283+
list = {
284+
children = function(node)
285+
return node.values
286+
end,
287+
},
288+
280289
variable = {
281290
enter = function(node, context)
282291
context.variableReferences[node.name.value] = true
@@ -300,7 +309,6 @@ local function validate(schema, tree)
300309
objects = {},
301310
currentOperation = nil,
302311
variableReferences = nil,
303-
skipVariableUseCheck = {}, -- operation name -> boolean
304312
}
305313

306314
local function visit(node)

test/integration/graphql_test.lua

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ g.before_all = function()
2525
})
2626
cluster:start()
2727
end
28+
2829
g.after_all = function()
2930
cluster:stop()
3031
fio.rmtree(cluster.datadir)
@@ -170,6 +171,130 @@ function g.test_reread_request()
170171
server:graphql({ query = '{}' })
171172
end
172173

174+
g.test_nested_input = function()
175+
local server = cluster.main_server
176+
177+
server.net_box:eval([[
178+
package.loaded['test'] = {}
179+
package.loaded['test']['test_nested_InputObject'] = function(root, args)
180+
return args.servers[1].field
181+
end
182+
183+
package.loaded['test']['test_nested_list'] = function(root, args)
184+
return args.servers[1]
185+
end
186+
187+
package.loaded['test']['test_nested_InputObject_complex'] = function(root, args)
188+
return ('%s+%s+%s'):format(args.upvalue, args.servers.field2, args.servers.test.field[1])
189+
end
190+
191+
local graphql = require('cartridge.graphql')
192+
local types = require('cartridge.graphql.types')
193+
194+
local nested_InputObject = types.inputObject {
195+
name = 'nested_InputObject',
196+
fields = {
197+
field = types.string.nonNull,
198+
}
199+
}
200+
201+
graphql.add_mutation({
202+
name = 'test_nested_InputObject',
203+
args = {
204+
servers = types.list(nested_InputObject),
205+
},
206+
kind = types.string,
207+
callback = 'test.test_nested_InputObject',
208+
})
209+
210+
graphql.add_mutation({
211+
name = 'test_nested_list',
212+
args = {
213+
servers = types.list(types.string),
214+
},
215+
kind = types.string,
216+
callback = 'test.test_nested_list',
217+
})
218+
219+
graphql.add_callback({
220+
name = 'test_nested_InputObject_complex',
221+
args = {
222+
upvalue = types.string,
223+
servers = types.inputObject({
224+
name = 'ComplexInputObject',
225+
fields = {
226+
field2 = types.string,
227+
test = types.inputObject({
228+
name = 'ComplexNestedInputObject',
229+
fields = {
230+
field = types.list(types.string)
231+
}
232+
}),
233+
}
234+
}),
235+
},
236+
kind = types.string,
237+
callback = 'test.test_nested_InputObject_complex',
238+
})
239+
]])
240+
241+
t.assert_equals(
242+
server:graphql({
243+
query = [[
244+
mutation($field: String!) {
245+
test_nested_InputObject(
246+
servers: [{ field: $field }]
247+
)
248+
}
249+
]],
250+
variables = {field = 'echo'}}
251+
).data.test_nested_InputObject, 'echo'
252+
)
253+
254+
t.assert_error_msg_contains('Unused variable "field"', function()
255+
server:graphql({
256+
query = [[
257+
mutation($field: String!) {
258+
test_nested_InputObject(
259+
servers: [{ field: "not-variable" }]
260+
)
261+
}
262+
]],
263+
variables = {field = 'echo'}}
264+
)
265+
end)
266+
267+
t.assert_equals(
268+
server:graphql({
269+
query = [[
270+
mutation($field: String!) {
271+
test_nested_list(
272+
servers: [$field]
273+
)
274+
}
275+
]],
276+
variables = {field = 'echo'}}
277+
).data.test_nested_list, 'echo'
278+
)
279+
280+
t.assert_equals(
281+
server:graphql({
282+
query = [[
283+
query($field: String! $field2: String! $upvalue: String!) {
284+
test_nested_InputObject_complex(
285+
upvalue: $upvalue,
286+
servers: {
287+
field2: $field2
288+
test: { field: [$field] }
289+
}
290+
)
291+
}
292+
]],
293+
variables = {field = 'echo', field2 = 'field', upvalue = 'upvalue'}}
294+
).data.test_nested_InputObject_complex, 'upvalue+field+echo'
295+
)
296+
end
297+
173298
function g.test_fail_validate()
174299
t.assert_error_msg_contains('Scalar field "uri" cannot have subselections', function()
175300
cluster.main_server:graphql({

0 commit comments

Comments
 (0)