Skip to content

Commit ff1fab3

Browse files
committed
address review: simplify scalar branch + add oneOf and negative regression tests
- Replace the per-branch coerce_value loop with a single coerce_value call against the full anyOf/oneOf schema. coerce_value returns the input as-is on failed coercion, so picking the first 'non-nil' result was meaningless; the downstream jsonschema validator already evaluates every branch. - Add deepObject + oneOf object/integer regression tests (mirror anyOf). - Add negative regression: deepObject anyOf with an unmatched scalar value must be rejected.
1 parent 54a1348 commit ff1fab3

2 files changed

Lines changed: 57 additions & 10 deletions

File tree

lib/resty/openapi_validator/params.lua

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,9 @@ local function deserialize_param(raw_value, param, query_args)
256256
local stype = schema.type
257257

258258
-- deepObject style with anyOf/oneOf: try the object branch via parse_deep_object;
259-
-- if no param[...] keys are present, try a scalar branch against the bare param value.
259+
-- if no param[...] keys are present, coerce the bare param value against the
260+
-- full schema (collect_types handles anyOf/oneOf branches) and let the
261+
-- downstream jsonschema validator pick the matching branch.
260262
if style == "deepObject" and stype ~= "object"
261263
and (schema.anyOf or schema.oneOf) then
262264
local branches = schema.anyOf or schema.oneOf
@@ -273,15 +275,7 @@ local function deserialize_param(raw_value, param, query_args)
273275
if type(scalar_raw) == "table" then
274276
scalar_raw = scalar_raw[1]
275277
end
276-
for _, branch in ipairs(branches) do
277-
if branch.type and branch.type ~= "object" then
278-
local v = coerce_value(scalar_raw, branch)
279-
if v ~= nil then
280-
return v
281-
end
282-
end
283-
end
284-
return scalar_raw
278+
return coerce_value(scalar_raw, schema)
285279
end
286280
return nil
287281
end

t/unit/test_params.lua

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,4 +219,57 @@ T.describe("params: deepObject anyOf integer branch", function()
219219
T.ok(not errs or #errs == 0, "no errors")
220220
end)
221221

222+
-- Same shape as the anyOf cases but using oneOf, to lock in both branches
223+
-- of the runtime path.
224+
T.describe("params: deepObject oneOf object branch", function()
225+
local route = make_route({
226+
{ name = "created", ["in"] = "query", required = false,
227+
style = "deepObject", explode = true,
228+
schema = { oneOf = {
229+
{ type = "object", properties = {
230+
gt = { type = "integer" }, lte = { type = "integer" },
231+
} },
232+
{ type = "integer" },
233+
} } },
234+
}, "query")
235+
236+
local ok, errs = params_mod.validate(route,
237+
{}, { ["created[gt]"] = "1700000000" }, {})
238+
T.ok(ok, "deepObject oneOf object form accepted")
239+
T.ok(not errs or #errs == 0, "no errors")
240+
end)
241+
242+
T.describe("params: deepObject oneOf integer branch", function()
243+
local route = make_route({
244+
{ name = "created", ["in"] = "query", required = false,
245+
style = "deepObject", explode = true,
246+
schema = { oneOf = {
247+
{ type = "object", properties = { gt = { type = "integer" } } },
248+
{ type = "integer" },
249+
} } },
250+
}, "query")
251+
252+
local ok, errs = params_mod.validate(route,
253+
{}, { ["created"] = "1700000000" }, {})
254+
T.ok(ok, "deepObject oneOf scalar (integer branch) accepted")
255+
T.ok(not errs or #errs == 0, "no errors")
256+
end)
257+
258+
-- Negative: a value that matches none of the anyOf branches must be rejected.
259+
T.describe("params: deepObject anyOf rejects unmatched scalar", function()
260+
local route = make_route({
261+
{ name = "created", ["in"] = "query", required = false,
262+
style = "deepObject", explode = true,
263+
schema = { anyOf = {
264+
{ type = "object", properties = { gt = { type = "integer" } } },
265+
{ type = "integer" },
266+
} } },
267+
}, "query")
268+
269+
local ok, errs = params_mod.validate(route,
270+
{}, { ["created"] = "not-a-number" }, {})
271+
T.ok(not ok, "non-integer scalar rejected")
272+
T.ok(errs and #errs >= 1, "error reported")
273+
end)
274+
222275
T.done()

0 commit comments

Comments
 (0)