1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.rest.annotation;
18
19 import static org.junit.jupiter.api.Assertions.*;
20
21 import java.util.*;
22
23 import org.apache.juneau.*;
24 import org.apache.juneau.http.annotation.*;
25 import org.apache.juneau.json.*;
26 import org.apache.juneau.rest.mock.*;
27 import org.apache.juneau.testutils.pojos.*;
28 import org.junit.jupiter.api.*;
29
30 class PathRemainder_Test extends TestBase {
31
32
33
34
35
36 @Rest
37 public static class A {
38 @RestOp(path="/a/*")
39 public String a(@Path("/*") String remainder) {
40 return ""+remainder;
41 }
42 @RestGet(path="/b/*")
43 public String b(@Path("/*") String remainder) {
44 return ""+remainder;
45 }
46 @RestPut(path="/c/*")
47 public String c(@Path("/*") String remainder) {
48 return ""+remainder;
49 }
50 @RestPost(path="/d/*")
51 public String d(@Path("/*") String remainder) {
52 return ""+remainder;
53 }
54 @RestDelete(path="/e/*")
55 public String e(@Path("/*") String remainder) {
56 return ""+remainder;
57 }
58 }
59
60 @Test void a01_basic() throws Exception {
61 var a = MockRestClient.build(A.class);
62
63 a.get("/a").run().assertContent("null");
64 a.get("/a/").run().assertContent("");
65 a.get("/a/foo").run().assertContent("foo");
66 a.get("/a/foo/bar").run().assertContent("foo/bar");
67
68 a.get("/b").run().assertContent("null");
69 a.get("/b/").run().assertContent("");
70 a.get("/b/foo").run().assertContent("foo");
71 a.get("/b/foo/bar").run().assertContent("foo/bar");
72
73 a.put("/c").run().assertContent("null");
74 a.put("/c/").run().assertContent("");
75 a.put("/c/foo").run().assertContent("foo");
76 a.put("/c/foo/bar").run().assertContent("foo/bar");
77
78 a.post("/d").run().assertContent("null");
79 a.post("/d/").run().assertContent("");
80 a.post("/d/foo").run().assertContent("foo");
81 a.post("/d/foo/bar").run().assertContent("foo/bar");
82
83 a.delete("/e").run().assertContent("null");
84 a.delete("/e/").run().assertContent("");
85 a.delete("/e/foo").run().assertContent("foo");
86 a.delete("/e/foo/bar").run().assertContent("foo/bar");
87 }
88
89
90
91
92
93 @Rest(serializers=Json5Serializer.class)
94 public static class B {
95 @RestGet(path="/a/*")
96 public Object a(@Path("/*") Optional<Integer> f1) {
97 assertNotNull(f1);
98 return f1;
99 }
100 @RestPut(path="/b/*")
101 public Object b(@Path("/*") Optional<ABean> f1) {
102 assertNotNull(f1);
103 return f1;
104 }
105 @RestPost(path="/c/*")
106 public Object c(@Path("/*") Optional<List<ABean>> f1) {
107 assertNotNull(f1);
108 return f1;
109 }
110 @RestDelete(path="/d/*")
111 public Object d(@Path("/*") List<Optional<ABean>> f1) {
112 return f1;
113 }
114 }
115
116 @Test void b01_optionalParam() throws Exception {
117 var b = MockRestClient.buildJson(B.class);
118 b.get("/a/123")
119 .run()
120 .assertStatus(200)
121 .assertContent("123");
122 b.put("/b/a=1,b=foo")
123 .run()
124 .assertStatus(200)
125 .assertContent("{a:1,b:'foo'}");
126 b.post("/c/@((a=1,b=foo))")
127 .run()
128 .assertStatus(200)
129 .assertContent("[{a:1,b:'foo'}]");
130 b.delete("/d/@((a=1,b=foo))")
131 .run()
132 .assertStatus(200)
133 .assertContent("[{a:1,b:'foo'}]");
134 }
135
136
137
138
139
140 @Rest
141 public static class C {
142 @RestOp(path="/a/*")
143 public String a(@PathRemainder String remainder) {
144 return ""+remainder;
145 }
146 @RestGet(path="/b/*")
147 public String b(@PathRemainder String remainder) {
148 return ""+remainder;
149 }
150 @RestPut(path="/c/*")
151 public String c(@PathRemainder String remainder) {
152 return ""+remainder;
153 }
154 @RestPost(path="/d/*")
155 public String d(@PathRemainder String remainder) {
156 return ""+remainder;
157 }
158 @RestDelete(path="/e/*")
159 public String e(@PathRemainder String remainder) {
160 return ""+remainder;
161 }
162 }
163
164 @Test void c01_pathRemainderAnnotation() throws Exception {
165 var c = MockRestClient.build(C.class);
166
167
168 c.get("/a").run().assertContent("null");
169 c.get("/a/").run().assertContent("");
170 c.get("/a/foo").run().assertContent("foo");
171 c.get("/a/foo/bar").run().assertContent("foo/bar");
172
173 c.get("/b").run().assertContent("null");
174 c.get("/b/").run().assertContent("");
175 c.get("/b/foo").run().assertContent("foo");
176 c.get("/b/foo/bar").run().assertContent("foo/bar");
177
178 c.put("/c").run().assertContent("null");
179 c.put("/c/").run().assertContent("");
180 c.put("/c/foo").run().assertContent("foo");
181 c.put("/c/foo/bar").run().assertContent("foo/bar");
182
183 c.post("/d").run().assertContent("null");
184 c.post("/d/").run().assertContent("");
185 c.post("/d/foo").run().assertContent("foo");
186 c.post("/d/foo/bar").run().assertContent("foo/bar");
187
188 c.delete("/e").run().assertContent("null");
189 c.delete("/e/").run().assertContent("");
190 c.delete("/e/foo").run().assertContent("foo");
191 c.delete("/e/foo/bar").run().assertContent("foo/bar");
192 }
193
194
195
196
197
198 @Rest(serializers=Json5Serializer.class)
199 public static class D {
200 @RestGet(path="/a/*")
201 public Object a(@PathRemainder Optional<Integer> f1) {
202 assertNotNull(f1);
203 return f1;
204 }
205 @RestPut(path="/b/*")
206 public Object b(@PathRemainder Optional<ABean> f1) {
207 assertNotNull(f1);
208 return f1;
209 }
210 @RestPost(path="/c/*")
211 public Object c(@PathRemainder Optional<List<ABean>> f1) {
212 assertNotNull(f1);
213 return f1;
214 }
215 @RestDelete(path="/d/*")
216 public Object d(@PathRemainder List<Optional<ABean>> f1) {
217 return f1;
218 }
219 }
220
221 @Test void d01_pathRemainderWithOptional() throws Exception {
222 var d = MockRestClient.buildJson(D.class);
223 d.get("/a/123")
224 .run()
225 .assertStatus(200)
226 .assertContent("123");
227 d.put("/b/a=1,b=foo")
228 .run()
229 .assertStatus(200)
230 .assertContent("{a:1,b:'foo'}");
231 d.post("/c/@((a=1,b=foo))")
232 .run()
233 .assertStatus(200)
234 .assertContent("[{a:1,b:'foo'}]");
235 d.delete("/d/@((a=1,b=foo))")
236 .run()
237 .assertStatus(200)
238 .assertContent("[{a:1,b:'foo'}]");
239 }
240
241
242
243
244
245 @Rest
246 public static class E {
247 @RestGet(path="/a/{foo}/{bar}/*")
248 public String a(@Path("foo") String foo, @Path("bar") int bar, @PathRemainder String remainder) {
249 return "foo="+foo+",bar="+bar+",remainder="+remainder;
250 }
251 @RestPost(path="/b/{id}/*")
252 public String b(@Path("id") String id, @PathRemainder String remainder) {
253 return "id="+id+",remainder="+remainder;
254 }
255 }
256
257 @Test void e01_pathRemainderWithOtherPathParams() throws Exception {
258 var e = MockRestClient.build(E.class);
259 e.get("/a/x/123/extra/path")
260 .run()
261 .assertContent("foo=x,bar=123,remainder=extra/path");
262 e.get("/a/hello/456")
263 .run()
264 .assertContent("foo=hello,bar=456,remainder=null");
265 e.post("/b/myId/more/stuff")
266 .run()
267 .assertContent("id=myId,remainder=more/stuff");
268 }
269
270
271
272
273
274 @Rest
275 public static class F {
276 @RestGet(path="/a/*")
277 public String a(@PathRemainder(def="defaultValue") String remainder) {
278 return ""+remainder;
279 }
280 }
281
282 @Test void f01_pathRemainderWithDefault() throws Exception {
283 var f = MockRestClient.build(F.class);
284 f.get("/a").run().assertContent("defaultValue");
285 f.get("/a/").run().assertContent("");
286 f.get("/a/custom").run().assertContent("custom");
287 }
288 }