Skip to content

Commit 9eda6b7

Browse files
authored
test: add parameter serialization matrix and format validation tests (#5)
1 parent 1b3c53d commit 9eda6b7

2 files changed

Lines changed: 543 additions & 0 deletions

File tree

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
#!/usr/bin/env resty
2+
--- Conformance tests for format keyword validation.
3+
-- Covers uuid, date, date-time, uri, email, ipv4, hostname formats.
4+
-- Each format has positive and negative cases.
5+
dofile("t/lib/test_bootstrap.lua")
6+
7+
local T = require("test_helper")
8+
local cjson = require("cjson.safe")
9+
local ov = require("resty.openapi_validator")
10+
11+
12+
local function make_format_spec(format_name)
13+
return cjson.encode({
14+
openapi = "3.0.0",
15+
info = { title = "FormatTest", version = "0.1" },
16+
paths = {
17+
["/test"] = {
18+
post = {
19+
requestBody = {
20+
required = true,
21+
content = {
22+
["application/json"] = {
23+
schema = {
24+
type = "object",
25+
required = { "value" },
26+
properties = {
27+
value = {
28+
type = "string",
29+
format = format_name,
30+
},
31+
},
32+
},
33+
},
34+
},
35+
},
36+
responses = { ["200"] = { description = "OK" } },
37+
},
38+
},
39+
},
40+
})
41+
end
42+
43+
44+
local function validate_format(format_name, value)
45+
local spec = make_format_spec(format_name)
46+
local v, err = ov.compile(spec)
47+
assert(v, "compile failed for format '" .. format_name .. "': " .. tostring(err))
48+
return v:validate_request({
49+
method = "POST",
50+
path = "/test",
51+
body = cjson.encode({ value = value }),
52+
content_type = "application/json",
53+
})
54+
end
55+
56+
57+
-- uuid
58+
T.describe("format uuid: valid lowercase", function()
59+
local ok, err = validate_format("uuid", "550e8400-e29b-41d4-a716-446655440000")
60+
T.ok(ok, "should pass: " .. tostring(err))
61+
end)
62+
63+
T.describe("format uuid: valid uppercase", function()
64+
local ok, err = validate_format("uuid", "550E8400-E29B-41D4-A716-446655440000")
65+
T.ok(ok, "should pass: " .. tostring(err))
66+
end)
67+
68+
T.describe("format uuid: invalid - missing segment", function()
69+
local ok = validate_format("uuid", "550e8400-e29b-41d4-a716")
70+
T.ok(not ok, "should fail")
71+
end)
72+
73+
T.describe("format uuid: invalid - no hyphens", function()
74+
local ok = validate_format("uuid", "550e8400e29b41d4a716446655440000")
75+
T.ok(not ok, "should fail")
76+
end)
77+
78+
T.describe("format uuid: invalid - random string", function()
79+
local ok = validate_format("uuid", "not-a-uuid")
80+
T.ok(not ok, "should fail")
81+
end)
82+
83+
84+
-- date
85+
T.describe("format date: valid", function()
86+
local ok, err = validate_format("date", "2024-01-15")
87+
T.ok(ok, "should pass: " .. tostring(err))
88+
end)
89+
90+
T.describe("format date: valid - end of month", function()
91+
local ok, err = validate_format("date", "2024-12-31")
92+
T.ok(ok, "should pass: " .. tostring(err))
93+
end)
94+
95+
T.describe("format date: invalid - wrong separator", function()
96+
local ok = validate_format("date", "2024/01/15")
97+
T.ok(not ok, "should fail")
98+
end)
99+
100+
T.describe("format date: invalid - month 13", function()
101+
local ok = validate_format("date", "2024-13-01")
102+
T.ok(not ok, "should fail")
103+
end)
104+
105+
T.describe("format date: invalid - day 32", function()
106+
local ok = validate_format("date", "2024-01-32")
107+
T.ok(not ok, "should fail")
108+
end)
109+
110+
T.describe("format date: invalid - incomplete", function()
111+
local ok = validate_format("date", "2024-01")
112+
T.ok(not ok, "should fail")
113+
end)
114+
115+
116+
-- date-time
117+
T.describe("format date-time: valid UTC", function()
118+
local ok, err = validate_format("date-time", "2024-01-15T10:30:00Z")
119+
T.ok(ok, "should pass: " .. tostring(err))
120+
end)
121+
122+
T.describe("format date-time: valid with offset", function()
123+
local ok, err = validate_format("date-time", "2024-01-15T10:30:00+08:00")
124+
T.ok(ok, "should pass: " .. tostring(err))
125+
end)
126+
127+
T.describe("format date-time: valid with fractional seconds", function()
128+
local ok, err = validate_format("date-time", "2024-01-15T10:30:00.123Z")
129+
T.ok(ok, "should pass: " .. tostring(err))
130+
end)
131+
132+
T.describe("format date-time: invalid - no timezone", function()
133+
local ok = validate_format("date-time", "2024-01-15T10:30:00")
134+
T.ok(not ok, "should fail")
135+
end)
136+
137+
T.describe("format date-time: invalid - date only", function()
138+
local ok = validate_format("date-time", "2024-01-15")
139+
T.ok(not ok, "should fail")
140+
end)
141+
142+
T.describe("format date-time: invalid - random string", function()
143+
local ok = validate_format("date-time", "not-a-datetime")
144+
T.ok(not ok, "should fail")
145+
end)
146+
147+
148+
-- uri
149+
T.describe("format uri: valid https", function()
150+
local ok, err = validate_format("uri", "https://example.com/path")
151+
T.ok(ok, "should pass: " .. tostring(err))
152+
end)
153+
154+
T.describe("format uri: valid mailto", function()
155+
local ok, err = validate_format("uri", "mailto:user@example.com")
156+
T.ok(ok, "should pass: " .. tostring(err))
157+
end)
158+
159+
T.describe("format uri: valid urn", function()
160+
local ok, err = validate_format("uri", "urn:isbn:0451450523")
161+
T.ok(ok, "should pass: " .. tostring(err))
162+
end)
163+
164+
T.describe("format uri: invalid - no scheme", function()
165+
local ok = validate_format("uri", "example.com/path")
166+
T.ok(not ok, "should fail")
167+
end)
168+
169+
T.describe("format uri: invalid - just a path", function()
170+
local ok = validate_format("uri", "/just/a/path")
171+
T.ok(not ok, "should fail")
172+
end)
173+
174+
175+
-- email (already supported, but add reject test)
176+
T.describe("format email: valid", function()
177+
local ok, err = validate_format("email", "user@example.com")
178+
T.ok(ok, "should pass: " .. tostring(err))
179+
end)
180+
181+
T.describe("format email: invalid - no @", function()
182+
local ok = validate_format("email", "userexample.com")
183+
T.ok(not ok, "should fail")
184+
end)
185+
186+
T.describe("format email: invalid - no domain", function()
187+
local ok = validate_format("email", "user@")
188+
T.ok(not ok, "should fail")
189+
end)
190+
191+
192+
-- ipv4 (already supported)
193+
T.describe("format ipv4: valid", function()
194+
local ok, err = validate_format("ipv4", "192.168.1.1")
195+
T.ok(ok, "should pass: " .. tostring(err))
196+
end)
197+
198+
T.describe("format ipv4: invalid - out of range", function()
199+
local ok = validate_format("ipv4", "256.1.1.1")
200+
T.ok(not ok, "should fail")
201+
end)
202+
203+
204+
-- hostname (already supported)
205+
T.describe("format hostname: valid", function()
206+
local ok, err = validate_format("hostname", "example.com")
207+
T.ok(ok, "should pass: " .. tostring(err))
208+
end)
209+
210+
T.describe("format hostname: invalid - has space", function()
211+
local ok = validate_format("hostname", "exam ple.com")
212+
T.ok(not ok, "should fail")
213+
end)
214+
215+
T.done()

0 commit comments

Comments
 (0)