View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.rest.util;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.common.utils.StringUtils.*;
21  import static org.apache.juneau.rest.util.RestUtils.*;
22  import static org.junit.jupiter.api.Assertions.*;
23  
24  import org.apache.juneau.*;
25  import org.apache.juneau.urlencoding.*;
26  import org.junit.jupiter.api.*;
27  
28  class RestUtils_Test extends TestBase {
29  
30  	//------------------------------------------------------------------------------------------------------------------
31  	// decode(String)
32  	//------------------------------------------------------------------------------------------------------------------
33  
34  	@Test void a01_testDecode() {
35  		assertNull(urlDecode(null));
36  		assertEquals("foo/bar baz  bing", urlDecode("foo%2Fbar+baz++bing"));
37  	}
38  
39  	//------------------------------------------------------------------------------------------------------------------
40  	// encode(String)
41  	//------------------------------------------------------------------------------------------------------------------
42  
43  	@Test void b01_testEncode() {
44  		assertNull(urlEncode(null));
45  		assertEquals("foo%2Fbar+baz++bing", urlEncode("foo/bar baz  bing"));
46  		assertEquals("foobar", urlEncode("foobar"));
47  		assertEquals("+", urlEncode(" "));
48  		assertEquals("%2F", urlEncode("/"));
49  	}
50  
51  	//------------------------------------------------------------------------------------------------------------------
52  	// trimPathInfo(String,String)
53  	//------------------------------------------------------------------------------------------------------------------
54  
55  	@Test void c01_testGetServletURI() {
56  		var e = "http://hostname";
57  		var sp = "";
58  		var cp = "";
59  
60  		for (var s : a("http://hostname", "http://hostname/foo", "http://hostname?foo", "http://hostname/?foo"))
61  			assertEquals(e, trimPathInfo(new StringBuffer(s), cp, sp).toString());
62  
63  		for (var s : a("http:/hostname?foo")) {
64  			assertThrows(Exception.class, ()->trimPathInfo(new StringBuffer(s), "", ""));
65  		}
66  
67  		e = "http://hostname";
68  		sp = "/";
69  		cp = "/";
70  
71  		for (var s : a("http://hostname", "http://hostname/foo", "http://hostname?foo", "http://hostname/?foo"))
72  			assertEquals(e, trimPathInfo(new StringBuffer(s), cp, sp).toString());
73  
74  		e = "http://hostname/foo";
75  		sp = "/foo";
76  		cp = "/";
77  
78  		for (var s : a("http://hostname/foo", "http://hostname/foo/bar", "http://hostname/foo?bar"))
79  			assertEquals(e, trimPathInfo(new StringBuffer(s), cp, sp).toString());
80  
81  		for (var s : a("http://hostname/foo2", "http://hostname/fo2", "http://hostname?foo", "http://hostname/fo?bar", "http:/hostname/foo")) {
82  			assertThrows(Exception.class, ()->trimPathInfo(new StringBuffer(s), "/", "/foo"));
83  		}
84  
85  		e = "http://hostname/foo/bar";
86  		sp = "/foo/bar";
87  		cp = "/";
88  
89  		for (var s : a("http://hostname/foo/bar", "http://hostname/foo/bar/baz", "http://hostname/foo/bar?baz"))
90  			assertEquals(e, trimPathInfo(new StringBuffer(s), cp, sp).toString());
91  
92  		for (var s : a("http://hostname/foo2/bar", "http://hostname/foo/bar2")) {
93  			assertThrows(Exception.class, ()->trimPathInfo(new StringBuffer(s), "/foo/bar", "/foo/bar"));
94  		}
95  
96  		e = "http://hostname/foo/bar";
97  		sp = "/bar";
98  		cp = "/foo";
99  
100 		for (var s : a("http://hostname/foo/bar", "http://hostname/foo/bar/baz", "http://hostname/foo/bar?baz"))
101 			assertEquals(e, trimPathInfo(new StringBuffer(s), cp, sp).toString());
102 
103 		for (var s : a("http://hostname/foo2/bar", "http://hostname/foo/bar2")) {
104 			assertThrows(Exception.class, ()->trimPathInfo(new StringBuffer(s), "/foo", "/bar"));
105 		}
106 	}
107 
108 	//------------------------------------------------------------------------------------------------------------------
109 	// trimSlashes(String)
110 	//------------------------------------------------------------------------------------------------------------------
111 
112 	@Test void d01_testTrimSlashes() {
113 		assertNull(trimSlashes(null));
114 		assertEquals("", trimSlashes(""));
115 		assertEquals("", trimSlashes("/"));
116 		assertEquals("", trimSlashes("//"));
117 		assertEquals("foo/bar", trimSlashes("foo/bar"));
118 		assertEquals("foo/bar", trimSlashes("foo/bar//"));
119 		assertEquals("foo/bar", trimSlashes("/foo/bar//"));
120 		assertEquals("foo/bar", trimSlashes("//foo/bar//"));
121 	}
122 
123 	//------------------------------------------------------------------------------------------------------------------
124 	// trimTrailingSlashes(String)
125 	//------------------------------------------------------------------------------------------------------------------
126 
127 	@Test void e01_testTrimTrailingSlashes() {
128 		assertNull(trimTrailingSlashes((String)null));
129 		assertEquals("", trimTrailingSlashes(""));
130 		assertEquals("", trimTrailingSlashes("/"));
131 		assertEquals("", trimTrailingSlashes("//"));
132 		assertEquals("foo/bar", trimTrailingSlashes("foo/bar"));
133 		assertEquals("foo/bar", trimTrailingSlashes("foo/bar//"));
134 		assertEquals("/foo/bar", trimTrailingSlashes("/foo/bar//"));
135 		assertEquals("//foo/bar", trimTrailingSlashes("//foo/bar//"));
136 	}
137 
138 	//------------------------------------------------------------------------------------------------------------------
139 	// Test URL-encoded strings parsed into plain-text values using UrlEncodingParser.parseIntoSimpleMap().
140 	//------------------------------------------------------------------------------------------------------------------
141 
142 	@Test void g01_testParseIntoSimpleMap() {
143 		var s = "?f1=,()=&f2a=$b(true)&f2b=true&f3a=$n(123)&f3b=123&f4=$s(foo)";
144 		var m = parseQuery(s);
145 		assertEquals(",()=", m.get("f1")[0]);
146 		assertEquals("$b(true)", m.get("f2a")[0]);
147 		assertEquals("true", m.get("f2b")[0]);
148 		assertEquals("$n(123)", m.get("f3a")[0]);
149 		assertEquals("123", m.get("f3b")[0]);
150 		assertEquals("$s(foo)", m.get("f4")[0]);
151 
152 		s = "f1=v1&=";
153 		m = parseQuery(s);
154 		assertEquals("v1", m.get("f1")[0]);
155 		assertEquals("", m.get("")[0]);
156 
157 		s = "f1=v1&f2&f3";
158 		m = parseQuery(s);
159 		assertEquals("v1", m.get("f1")[0]);
160 		assertTrue(m.containsKey("f2"));
161 		assertTrue(m.containsKey("f3"));
162 		assertNull(m.get("f2"));
163 		assertNull(m.get("f3"));
164 	}
165 
166 	//------------------------------------------------------------------------------------------------------------------
167 	// Test parsing URL-encoded strings with multiple values.
168 	//------------------------------------------------------------------------------------------------------------------
169 
170 	@Test void h01_testParseIntoSimpleMapMultiValues() {
171 		var s = "?f1&f1&f2&f2=abc&f2=def&f2";
172 		var m = parseQuery(s);
173 		assertBean(m, "f1,f2", "<null>,[abc,def]");
174 	}
175 
176 	@Test void h02_testEmptyString() throws Exception {
177 		var p = UrlEncodingParser.DEFAULT;
178 
179 		var s = "";
180 		var b = p.parse(s, B.class);
181 		assertEquals("f1", b.f1);
182 	}
183 
184 	public static class B {
185 		public String f1 = "f1";
186 	}
187 
188 	//------------------------------------------------------------------------------------------------------------------
189 	// Other tests
190 	//------------------------------------------------------------------------------------------------------------------
191 
192 	@Test void i01_testTrimContextPath() {
193 		assertEquals("/bar", trimContextPath("/foo", "/bar"));
194 		assertEquals("/", trimContextPath("/foo", "/"));
195 		assertEquals("", trimContextPath("/foo", ""));
196 		assertEquals(null, trimContextPath("/foo", null));
197 
198 		assertEquals("/bar", trimContextPath("/foo", "/foo/bar"));
199 		assertEquals("/bar/baz", trimContextPath("/foo", "/foo/bar/baz"));
200 		assertEquals("/bar/", trimContextPath("/foo", "/foo/bar/"));
201 		assertEquals("/", trimContextPath("/foo", "/foo/"));
202 		assertEquals("/", trimContextPath("/foo", "/foo"));
203 	}
204 
205 	@Test void i02_testIsValidContextPath() {
206 		assertTrue(isValidContextPath(""));
207 		assertTrue(isValidContextPath("/foo"));
208 		assertFalse(isValidContextPath("/"));
209 		assertFalse(isValidContextPath("/foo/"));
210 		assertFalse(isValidContextPath(null));
211 		assertFalse(isValidContextPath("foo"));
212 	}
213 
214 	@Test void i03_testIsValidServletPath() {
215 		assertTrue(isValidServletPath(""));
216 		assertTrue(isValidServletPath("/foo"));
217 		assertFalse(isValidServletPath("/"));
218 		assertFalse(isValidServletPath("/foo/"));
219 		assertFalse(isValidServletPath(null));
220 		assertFalse(isValidServletPath("foo"));
221 	}
222 
223 	@Test void i04_testIsValidPathInfo() {
224 		assertFalse(isValidPathInfo(""));
225 		assertTrue(isValidPathInfo("/foo"));
226 		assertTrue(isValidPathInfo("/"));
227 		assertTrue(isValidPathInfo("/foo/"));
228 		assertTrue(isValidPathInfo(null));
229 		assertFalse(isValidPathInfo("foo"));
230 	}
231 }