Skip to content

Commit 7bb90f7

Browse files
committed
test: add format keyword validation tests for uuid, date, date-time, uri, email, ipv4, hostname
1 parent 9967522 commit 7bb90f7

1 file changed

Lines changed: 217 additions & 0 deletions

File tree

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
#!/usr/bin/env resty
2+
--- Conformance tests for format keyword validation.
3+
-- Covers uuid, date, date-time, uri, email, ipv4, ipv6, 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+
if not v then
48+
return nil, "compile failed: " .. tostring(err)
49+
end
50+
return v:validate_request({
51+
method = "POST",
52+
path = "/test",
53+
body = cjson.encode({ value = value }),
54+
content_type = "application/json",
55+
})
56+
end
57+
58+
59+
-- uuid
60+
T.describe("format uuid: valid lowercase", function()
61+
local ok, err = validate_format("uuid", "550e8400-e29b-41d4-a716-446655440000")
62+
T.ok(ok, "should pass: " .. tostring(err))
63+
end)
64+
65+
T.describe("format uuid: valid uppercase", function()
66+
local ok, err = validate_format("uuid", "550E8400-E29B-41D4-A716-446655440000")
67+
T.ok(ok, "should pass: " .. tostring(err))
68+
end)
69+
70+
T.describe("format uuid: invalid - missing segment", function()
71+
local ok = validate_format("uuid", "550e8400-e29b-41d4-a716")
72+
T.ok(not ok, "should fail")
73+
end)
74+
75+
T.describe("format uuid: invalid - no hyphens", function()
76+
local ok = validate_format("uuid", "550e8400e29b41d4a716446655440000")
77+
T.ok(not ok, "should fail")
78+
end)
79+
80+
T.describe("format uuid: invalid - random string", function()
81+
local ok = validate_format("uuid", "not-a-uuid")
82+
T.ok(not ok, "should fail")
83+
end)
84+
85+
86+
-- date
87+
T.describe("format date: valid", function()
88+
local ok, err = validate_format("date", "2024-01-15")
89+
T.ok(ok, "should pass: " .. tostring(err))
90+
end)
91+
92+
T.describe("format date: valid - end of month", function()
93+
local ok, err = validate_format("date", "2024-12-31")
94+
T.ok(ok, "should pass: " .. tostring(err))
95+
end)
96+
97+
T.describe("format date: invalid - wrong separator", function()
98+
local ok = validate_format("date", "2024/01/15")
99+
T.ok(not ok, "should fail")
100+
end)
101+
102+
T.describe("format date: invalid - month 13", function()
103+
local ok = validate_format("date", "2024-13-01")
104+
T.ok(not ok, "should fail")
105+
end)
106+
107+
T.describe("format date: invalid - day 32", function()
108+
local ok = validate_format("date", "2024-01-32")
109+
T.ok(not ok, "should fail")
110+
end)
111+
112+
T.describe("format date: invalid - incomplete", function()
113+
local ok = validate_format("date", "2024-01")
114+
T.ok(not ok, "should fail")
115+
end)
116+
117+
118+
-- date-time
119+
T.describe("format date-time: valid UTC", function()
120+
local ok, err = validate_format("date-time", "2024-01-15T10:30:00Z")
121+
T.ok(ok, "should pass: " .. tostring(err))
122+
end)
123+
124+
T.describe("format date-time: valid with offset", function()
125+
local ok, err = validate_format("date-time", "2024-01-15T10:30:00+08:00")
126+
T.ok(ok, "should pass: " .. tostring(err))
127+
end)
128+
129+
T.describe("format date-time: valid with fractional seconds", function()
130+
local ok, err = validate_format("date-time", "2024-01-15T10:30:00.123Z")
131+
T.ok(ok, "should pass: " .. tostring(err))
132+
end)
133+
134+
T.describe("format date-time: invalid - no timezone", function()
135+
local ok = validate_format("date-time", "2024-01-15T10:30:00")
136+
T.ok(not ok, "should fail")
137+
end)
138+
139+
T.describe("format date-time: invalid - date only", function()
140+
local ok = validate_format("date-time", "2024-01-15")
141+
T.ok(not ok, "should fail")
142+
end)
143+
144+
T.describe("format date-time: invalid - random string", function()
145+
local ok = validate_format("date-time", "not-a-datetime")
146+
T.ok(not ok, "should fail")
147+
end)
148+
149+
150+
-- uri
151+
T.describe("format uri: valid https", function()
152+
local ok, err = validate_format("uri", "https://example.com/path")
153+
T.ok(ok, "should pass: " .. tostring(err))
154+
end)
155+
156+
T.describe("format uri: valid mailto", function()
157+
local ok, err = validate_format("uri", "mailto:user@example.com")
158+
T.ok(ok, "should pass: " .. tostring(err))
159+
end)
160+
161+
T.describe("format uri: valid urn", function()
162+
local ok, err = validate_format("uri", "urn:isbn:0451450523")
163+
T.ok(ok, "should pass: " .. tostring(err))
164+
end)
165+
166+
T.describe("format uri: invalid - no scheme", function()
167+
local ok = validate_format("uri", "example.com/path")
168+
T.ok(not ok, "should fail")
169+
end)
170+
171+
T.describe("format uri: invalid - just a path", function()
172+
local ok = validate_format("uri", "/just/a/path")
173+
T.ok(not ok, "should fail")
174+
end)
175+
176+
177+
-- email (already supported, but add reject test)
178+
T.describe("format email: valid", function()
179+
local ok, err = validate_format("email", "user@example.com")
180+
T.ok(ok, "should pass: " .. tostring(err))
181+
end)
182+
183+
T.describe("format email: invalid - no @", function()
184+
local ok = validate_format("email", "userexample.com")
185+
T.ok(not ok, "should fail")
186+
end)
187+
188+
T.describe("format email: invalid - no domain", function()
189+
local ok = validate_format("email", "user@")
190+
T.ok(not ok, "should fail")
191+
end)
192+
193+
194+
-- ipv4 (already supported)
195+
T.describe("format ipv4: valid", function()
196+
local ok, err = validate_format("ipv4", "192.168.1.1")
197+
T.ok(ok, "should pass: " .. tostring(err))
198+
end)
199+
200+
T.describe("format ipv4: invalid - out of range", function()
201+
local ok = validate_format("ipv4", "256.1.1.1")
202+
T.ok(not ok, "should fail")
203+
end)
204+
205+
206+
-- hostname (already supported)
207+
T.describe("format hostname: valid", function()
208+
local ok, err = validate_format("hostname", "example.com")
209+
T.ok(ok, "should pass: " .. tostring(err))
210+
end)
211+
212+
T.describe("format hostname: invalid - has space", function()
213+
local ok = validate_format("hostname", "exam ple.com")
214+
T.ok(not ok, "should fail")
215+
end)
216+
217+
T.done()

0 commit comments

Comments
 (0)