1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.rest.util;
18
19 import static org.apache.juneau.commons.utils.StringUtils.*;
20 import static org.apache.juneau.junit.bct.BctAssertions.*;
21 import static org.apache.juneau.rest.util.RestUtils.*;
22 import static org.junit.jupiter.api.Assertions.*;
23
24 import java.io.*;
25 import java.util.*;
26
27 import org.apache.juneau.*;
28 import org.apache.juneau.parser.ParseException;
29 import org.apache.juneau.rest.mock.*;
30 import org.apache.juneau.urlencoding.*;
31 import org.junit.jupiter.api.*;
32
33 class RestUtils_Test extends TestBase {
34
35
36
37
38
39 @Test void a01_testDecode() {
40 assertNull(urlDecode(null));
41 assertEquals("foo/bar baz bing", urlDecode("foo%2Fbar+baz++bing"));
42 }
43
44
45
46
47
48 @Test void b01_testEncode() {
49 assertNull(urlEncode(null));
50 assertEquals("foo%2Fbar+baz++bing", urlEncode("foo/bar baz bing"));
51 assertEquals("foobar", urlEncode("foobar"));
52 assertEquals("+", urlEncode(" "));
53 assertEquals("%2F", urlEncode("/"));
54 }
55
56
57
58
59
60 @Test void d01_testTrimSlashes() {
61 assertNull(trimSlashes(null));
62 assertEquals("", trimSlashes(""));
63 assertEquals("", trimSlashes("/"));
64 assertEquals("", trimSlashes("//"));
65 assertEquals("foo/bar", trimSlashes("foo/bar"));
66 assertEquals("foo/bar", trimSlashes("foo/bar//"));
67 assertEquals("foo/bar", trimSlashes("/foo/bar//"));
68 assertEquals("foo/bar", trimSlashes("//foo/bar//"));
69 }
70
71
72
73
74
75 @Test void e01_testTrimTrailingSlashes() {
76 assertNull(trimTrailingSlashes((String)null));
77 assertEquals("", trimTrailingSlashes(""));
78 assertEquals("", trimTrailingSlashes("/"));
79 assertEquals("", trimTrailingSlashes("//"));
80 assertEquals("foo/bar", trimTrailingSlashes("foo/bar"));
81 assertEquals("foo/bar", trimTrailingSlashes("foo/bar//"));
82 assertEquals("/foo/bar", trimTrailingSlashes("/foo/bar//"));
83 assertEquals("//foo/bar", trimTrailingSlashes("//foo/bar//"));
84 }
85
86
87
88
89
90 @Test void i01_testGetHttpResponseText() {
91 assertEquals("OK", getHttpResponseText(200));
92 assertEquals("Created", getHttpResponseText(201));
93 assertEquals("Accepted", getHttpResponseText(202));
94 assertEquals("No Content", getHttpResponseText(204));
95 assertEquals("Moved Permanently", getHttpResponseText(301));
96 assertEquals("Temporary Redirect", getHttpResponseText(302));
97 assertEquals("Not Modified", getHttpResponseText(304));
98 assertEquals("Bad Request", getHttpResponseText(400));
99 assertEquals("Unauthorized", getHttpResponseText(401));
100 assertEquals("Forbidden", getHttpResponseText(403));
101 assertEquals("Not Found", getHttpResponseText(404));
102 assertEquals("Method Not Allowed", getHttpResponseText(405));
103 assertEquals("Internal Server Error", getHttpResponseText(500));
104 assertEquals("Not Implemented", getHttpResponseText(501));
105 assertEquals("Service Unavailable", getHttpResponseText(503));
106 assertEquals("Gateway Timeout", getHttpResponseText(504));
107 }
108
109 @Test void i02_testGetHttpResponseTextInvalid() {
110 assertNull(getHttpResponseText(0));
111 assertNull(getHttpResponseText(99));
112 assertNull(getHttpResponseText(600));
113 assertNull(getHttpResponseText(-1));
114 }
115
116
117
118
119
120 @Test void j01_testGetPathInfoUndecoded_basic() {
121 var req = MockServletRequest.create("GET", "/foo/bar");
122 assertEquals("/foo/bar", getPathInfoUndecoded(req));
123 }
124
125 @Test void j02_testGetPathInfoUndecoded_withContextPath() {
126 var req = MockServletRequest.create("GET", "http://localhost:8080/context/foo/bar")
127 .contextPath("/context");
128 assertEquals("/foo/bar", getPathInfoUndecoded(req));
129 }
130
131 @Test void j03_testGetPathInfoUndecoded_withServletPath() {
132 var req = MockServletRequest.create("GET", "http://localhost:8080/api/foo/bar")
133 .servletPath("/api");
134 assertEquals("/foo/bar", getPathInfoUndecoded(req));
135 }
136
137 @Test void j04_testGetPathInfoUndecoded_withContextAndServletPath() {
138 var req = MockServletRequest.create("GET", "http://localhost:8080/context/api/foo/bar")
139 .contextPath("/context")
140 .servletPath("/api");
141 assertEquals("/foo/bar", getPathInfoUndecoded(req));
142 }
143
144 @Test void j05_testGetPathInfoUndecoded_noPathInfo() {
145 var req = MockServletRequest.create("GET", "http://localhost:8080/context/api")
146 .contextPath("/context")
147 .servletPath("/api");
148 assertNull(getPathInfoUndecoded(req));
149 }
150
151 @Test void j06_testGetPathInfoUndecoded_encodedCharacters() {
152 var req = MockServletRequest.create("GET", "/foo%2Fbar%20baz");
153 assertEquals("/foo%2Fbar%20baz", getPathInfoUndecoded(req));
154 }
155
156 @Test void j07_testGetPathInfoUndecoded_rootPath() {
157 var req = MockServletRequest.create("GET", "/");
158 assertEquals("/", getPathInfoUndecoded(req));
159 }
160
161 @Test void j08_testGetPathInfoUndecoded_emptyContextAndServlet() {
162 var req = MockServletRequest.create("GET", "/foo/bar")
163 .contextPath("")
164 .servletPath("");
165 assertEquals("/foo/bar", getPathInfoUndecoded(req));
166 }
167
168
169
170
171
172 @Test void k01_testParseIfJson_null() throws Exception {
173 assertNull(parseIfJson(null));
174 }
175
176 @Test void k02_testParseIfJson_plainString() throws Exception {
177 assertEquals("hello world", parseIfJson("hello world"));
178 assertEquals("foo", parseIfJson("foo"));
179 assertEquals("", parseIfJson(""));
180 assertEquals("123abc", parseIfJson("123abc"));
181 }
182
183 @Test void k03_testParseIfJson_jsonObject() throws Exception {
184 var result = parseIfJson("{\"name\":\"John\",\"age\":30}");
185 assertTrue(result instanceof Map);
186 var map = (Map<String, Object>) result;
187 assertEquals("John", map.get("name"));
188 assertEquals(30, map.get("age"));
189 }
190
191 @Test void k04_testParseIfJson_jsonObjectEmpty() throws Exception {
192 var result = parseIfJson("{}");
193 assertTrue(result instanceof Map);
194 var map = (Map<String, Object>) result;
195 assertTrue(map.isEmpty());
196 }
197
198 @Test void k05_testParseIfJson_jsonArray() throws Exception {
199 var result = parseIfJson("[1,2,3]");
200 assertTrue(result instanceof List);
201 var list = (List<Object>) result;
202 assertEquals(3, list.size());
203 assertEquals(1, list.get(0));
204 assertEquals(2, list.get(1));
205 assertEquals(3, list.get(2));
206 }
207
208 @Test void k06_testParseIfJson_jsonArrayEmpty() throws Exception {
209 var result = parseIfJson("[]");
210 assertTrue(result instanceof List);
211 var list = (List<Object>) result;
212 assertTrue(list.isEmpty());
213 }
214
215 @Test void k07_testParseIfJson_jsonBoolean() throws Exception {
216 assertEquals(true, parseIfJson("true"));
217 assertEquals(false, parseIfJson("false"));
218 }
219
220 @Test void k08_testParseIfJson_jsonNull() throws Exception {
221 assertNull(parseIfJson("null"));
222 }
223
224 @Test void k09_testParseIfJson_jsonNumber() throws Exception {
225 assertEquals(123, parseIfJson("123"));
226 var result = parseIfJson("123.45");
227 assertTrue(result instanceof Number);
228 assertEquals(123.45, ((Number)result).doubleValue(), 0.001);
229 assertEquals(-42, parseIfJson("-42"));
230 }
231
232 @Test void k10_testParseIfJson_jsonWithWhitespace() throws Exception {
233 var result = parseIfJson(" {\"key\":\"value\"} ");
234 assertTrue(result instanceof Map);
235 var map = (Map<String, Object>) result;
236 assertEquals("value", map.get("key"));
237 }
238
239 @Test void k11_testParseIfJson_invalidJson() {
240
241 assertThrows(ParseException.class, () -> parseIfJson("{key:xxx}"));
242 assertThrows(ParseException.class, () -> parseIfJson("{key:invalid value}"));
243 }
244
245 @Test void k12_testParseIfJson_nestedStructures() throws Exception {
246 var result = parseIfJson("{\"items\":[1,2,3],\"nested\":{\"a\":1,\"b\":2}}");
247 assertTrue(result instanceof Map);
248 var map = (Map<String, Object>) result;
249 assertTrue(map.get("items") instanceof List);
250 assertTrue(map.get("nested") instanceof Map);
251 }
252
253 @Test void k13_testParseIfJson_singleQuotedString() throws Exception {
254 var result = parseIfJson("'test string'");
255 assertEquals("test string", result);
256 }
257
258
259
260
261
262 @Test void g01_testParseQuery_null() {
263 var m = parseQuery((String)null);
264 assertTrue(m.isEmpty());
265 }
266
267 @Test void g02_testParseQuery_emptyString() {
268 var m = parseQuery("");
269 assertTrue(m.isEmpty());
270 }
271
272 @Test void g03_testParseQuery_whitespaceOnly() {
273 var m = parseQuery(" ");
274 assertTrue(m.isEmpty());
275 }
276
277
278
279
280
281 @Test void g04_testParseQuery_readerNull() {
282 var m = parseQuery((Reader)null);
283 assertTrue(m.isEmpty());
284 }
285
286 @Test void g05_testParseQuery_readerEmpty() throws Exception {
287 var m = parseQuery(new StringReader(""));
288 assertTrue(m.isEmpty());
289 }
290
291 @Test void g06_testParseQuery_readerWhitespaceOnly() throws Exception {
292 var m = parseQuery(new StringReader(" "));
293 assertTrue(m.isEmpty());
294 }
295
296 @Test void g07_testParseQuery_readerValid() throws Exception {
297 var m = parseQuery(new StringReader("f1=v1&f2=v2"));
298 assertEquals("v1", m.get("f1").get(0));
299 assertEquals("v2", m.get("f2").get(0));
300 }
301
302
303
304
305
306 @Test void g04_testParseIntoSimpleMap() {
307 var s = "?f1=,()=&f2a=$b(true)&f2b=true&f3a=$n(123)&f3b=123&f4=$s(foo)";
308 var m = parseQuery(s);
309 assertEquals(",()=", m.get("f1").get(0));
310 assertEquals("$b(true)", m.get("f2a").get(0));
311 assertEquals("true", m.get("f2b").get(0));
312 assertEquals("$n(123)", m.get("f3a").get(0));
313 assertEquals("123", m.get("f3b").get(0));
314 assertEquals("$s(foo)", m.get("f4").get(0));
315
316 s = "f1=v1&=";
317 m = parseQuery(s);
318 assertEquals("v1", m.get("f1").get(0));
319 assertEquals("", m.get("").get(0));
320
321 s = "f1=v1&f2&f3";
322 m = parseQuery(s);
323 assertEquals("v1", m.get("f1").get(0));
324 assertTrue(m.containsKey("f2"));
325 assertTrue(m.containsKey("f3"));
326 assertNull(m.get("f2"));
327 assertNull(m.get("f3"));
328 }
329
330
331
332
333
334 @Test void h01_testParseIntoSimpleMapMultiValues() {
335 var s = "?f1&f1&f2&f2=abc&f2=def&f2";
336 var m = parseQuery(s);
337 assertBean(m, "f1,f2", "<null>,[abc,def]");
338 }
339
340 @Test void h02_testEmptyString() throws Exception {
341 var p = UrlEncodingParser.DEFAULT;
342
343 var s = "";
344 var b = p.parse(s, B.class);
345 assertEquals("f1", b.f1);
346 }
347
348 public static class B {
349 public String f1 = "f1";
350 }
351
352
353
354
355
356 @Test void m01_testToValidContextPath_null() {
357 assertEquals("", toValidContextPath(null));
358 }
359
360 @Test void m02_testToValidContextPath_empty() {
361 assertEquals("", toValidContextPath(""));
362 }
363
364 @Test void m03_testToValidContextPath_root() {
365 assertEquals("", toValidContextPath("/"));
366 }
367
368 @Test void m04_testToValidContextPath_noLeadingSlash() {
369 assertEquals("/api", toValidContextPath("api"));
370 }
371
372 @Test void m05_testToValidContextPath_withLeadingSlash() {
373 assertEquals("/api", toValidContextPath("/api"));
374 }
375
376 @Test void m06_testToValidContextPath_trailingSlash() {
377 assertEquals("/api", toValidContextPath("api/"));
378 }
379
380 @Test void m07_testToValidContextPath_bothSlashes() {
381 assertEquals("/api", toValidContextPath("/api/"));
382 }
383
384 @Test void m08_testToValidContextPath_multipleTrailingSlashes() {
385 assertEquals("/api", toValidContextPath("/api///"));
386 }
387
388 @Test void m09_testToValidContextPath_nestedPath() {
389 assertEquals("/api/users", toValidContextPath("/api/users"));
390 }
391
392 @Test void m10_testToValidContextPath_nestedPathTrailingSlash() {
393 assertEquals("/api/users", toValidContextPath("/api/users/"));
394 }
395
396 @Test void m11_testToValidContextPath_onlySlashes() {
397 assertEquals("", toValidContextPath("///"));
398 }
399
400
401
402
403
404 @Test void n01_testValidatePathInfo_null() {
405 assertNull(validatePathInfo(null));
406 }
407
408 @Test void n02_testValidatePathInfo_valid() {
409 assertEquals("/users", validatePathInfo("/users"));
410 }
411
412 @Test void n03_testValidatePathInfo_validNested() {
413 assertEquals("/users/123", validatePathInfo("/users/123"));
414 }
415
416 @Test void n04_testValidatePathInfo_empty() {
417 assertThrows(RuntimeException.class, () -> validatePathInfo(""));
418 }
419
420 @Test void n05_testValidatePathInfo_noLeadingSlash() {
421 assertThrows(RuntimeException.class, () -> validatePathInfo("users"));
422 }
423
424 @Test void n06_testValidatePathInfo_noLeadingSlashNested() {
425 assertThrows(RuntimeException.class, () -> validatePathInfo("users/123"));
426 }
427
428
429
430
431
432 @Test void o01_testValidateServletPath_empty() {
433 assertEquals("", validateServletPath(""));
434 }
435
436 @Test void o02_testValidateServletPath_valid() {
437 assertEquals("/api", validateServletPath("/api"));
438 }
439
440 @Test void o03_testValidateServletPath_validNested() {
441 assertEquals("/api/users", validateServletPath("/api/users"));
442 }
443
444 @Test void o04_testValidateServletPath_null() {
445 assertThrows(RuntimeException.class, () -> validateServletPath(null));
446 }
447
448 @Test void o05_testValidateServletPath_root() {
449 assertThrows(RuntimeException.class, () -> validateServletPath("/"));
450 }
451
452 @Test void o06_testValidateServletPath_noLeadingSlash() {
453 assertThrows(RuntimeException.class, () -> validateServletPath("api"));
454 }
455
456 @Test void o07_testValidateServletPath_trailingSlash() {
457 assertThrows(RuntimeException.class, () -> validateServletPath("/api/"));
458 }
459
460 @Test void o08_testValidateServletPath_noLeadingSlashTrailingSlash() {
461 assertThrows(RuntimeException.class, () -> validateServletPath("api/"));
462 }
463
464 @Test void o09_testValidateServletPath_nestedTrailingSlash() {
465 assertThrows(RuntimeException.class, () -> validateServletPath("/api/users/"));
466 }
467 }