001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.commons.codec.net;
019
020 import static org.junit.Assert.assertEquals;
021 import static org.junit.Assert.assertNull;
022 import static org.junit.Assert.fail;
023
024 import java.io.UnsupportedEncodingException;
025
026 import org.apache.commons.codec.CharEncoding;
027 import org.apache.commons.codec.Charsets;
028 import org.apache.commons.codec.DecoderException;
029 import org.apache.commons.codec.EncoderException;
030 import org.junit.Test;
031
032 /**
033 * URL codec test cases
034 *
035 * @version $Id: URLCodecTest.html 889935 2013-12-11 05:05:13Z ggregory $
036 */
037 public class URLCodecTest {
038
039 static final int SWISS_GERMAN_STUFF_UNICODE [] = {
040 0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
041 };
042
043 static final int RUSSIAN_STUFF_UNICODE [] = {
044 0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
045 0x432, 0x435, 0x442
046 };
047
048 private void validateState(final URLCodec urlCodec) {
049 // no tests for now.
050 }
051
052 private String constructString(final int [] unicodeChars) {
053 final StringBuilder buffer = new StringBuilder();
054 if (unicodeChars != null) {
055 for (final int unicodeChar : unicodeChars) {
056 buffer.append((char)unicodeChar);
057 }
058 }
059 return buffer.toString();
060 }
061
062 @Test
063 public void testUTF8RoundTrip() throws Exception {
064
065 final String ru_msg = constructString(RUSSIAN_STUFF_UNICODE);
066 final String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
067
068 final URLCodec urlCodec = new URLCodec();
069 this.validateState(urlCodec);
070
071 assertEquals(
072 "%D0%92%D1%81%D0%B5%D0%BC_%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82",
073 urlCodec.encode(ru_msg, CharEncoding.UTF_8)
074 );
075 assertEquals("Gr%C3%BCezi_z%C3%A4m%C3%A4", urlCodec.encode(ch_msg, CharEncoding.UTF_8));
076
077 assertEquals(ru_msg, urlCodec.decode(urlCodec.encode(ru_msg, CharEncoding.UTF_8), CharEncoding.UTF_8));
078 assertEquals(ch_msg, urlCodec.decode(urlCodec.encode(ch_msg, CharEncoding.UTF_8), CharEncoding.UTF_8));
079 this.validateState(urlCodec);
080 }
081
082 @Test
083 public void testBasicEncodeDecode() throws Exception {
084 final URLCodec urlCodec = new URLCodec();
085 final String plain = "Hello there!";
086 final String encoded = urlCodec.encode(plain);
087 assertEquals("Basic URL encoding test",
088 "Hello+there%21", encoded);
089 assertEquals("Basic URL decoding test",
090 plain, urlCodec.decode(encoded));
091 this.validateState(urlCodec);
092 }
093
094
095 @Test
096 public void testSafeCharEncodeDecode() throws Exception {
097 final URLCodec urlCodec = new URLCodec();
098 final String plain = "abc123_-.*";
099 final String encoded = urlCodec.encode(plain);
100 assertEquals("Safe chars URL encoding test",
101 plain, encoded);
102 assertEquals("Safe chars URL decoding test",
103 plain, urlCodec.decode(encoded));
104 this.validateState(urlCodec);
105 }
106
107
108 @Test
109 public void testUnsafeEncodeDecode() throws Exception {
110 final URLCodec urlCodec = new URLCodec();
111 final String plain = "~!@#$%^&()+{}\"\\;:`,/[]";
112 final String encoded = urlCodec.encode(plain);
113 assertEquals("Unsafe chars URL encoding test",
114 "%7E%21%40%23%24%25%5E%26%28%29%2B%7B%7D%22%5C%3B%3A%60%2C%2F%5B%5D", encoded);
115 assertEquals("Unsafe chars URL decoding test",
116 plain, urlCodec.decode(encoded));
117 this.validateState(urlCodec);
118 }
119
120
121 @Test
122 public void testEncodeDecodeNull() throws Exception {
123 final URLCodec urlCodec = new URLCodec();
124 assertNull("Null string URL encoding test",
125 urlCodec.encode((String)null));
126 assertNull("Null string URL decoding test",
127 urlCodec.decode((String)null));
128 this.validateState(urlCodec);
129 }
130
131
132 @Test
133 public void testDecodeInvalid() throws Exception {
134 final URLCodec urlCodec = new URLCodec();
135 try {
136 urlCodec.decode("%");
137 fail("DecoderException should have been thrown");
138 } catch (final DecoderException e) {
139 // Expected. Move on
140 }
141 try {
142 urlCodec.decode("%A");
143 fail("DecoderException should have been thrown");
144 } catch (final DecoderException e) {
145 // Expected. Move on
146 }
147 try {
148 // Bad 1st char after %
149 urlCodec.decode("%WW");
150 fail("DecoderException should have been thrown");
151 } catch (final DecoderException e) {
152 // Expected. Move on
153 }
154 try {
155 // Bad 2nd char after %
156 urlCodec.decode("%0W");
157 fail("DecoderException should have been thrown");
158 } catch (final DecoderException e) {
159 // Expected. Move on
160 }
161 this.validateState(urlCodec);
162 }
163
164 @Test
165 public void testDecodeInvalidContent() throws UnsupportedEncodingException, DecoderException {
166 final String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
167 final URLCodec urlCodec = new URLCodec();
168 final byte[] input = ch_msg.getBytes("ISO-8859-1");
169 final byte[] output = urlCodec.decode(input);
170 assertEquals(input.length, output.length);
171 for (int i = 0; i < input.length; i++) {
172 assertEquals(input[i], output[i]);
173 }
174 this.validateState(urlCodec);
175 }
176
177 @Test
178 public void testEncodeNull() throws Exception {
179 final URLCodec urlCodec = new URLCodec();
180 final byte[] plain = null;
181 final byte[] encoded = urlCodec.encode(plain);
182 assertEquals("Encoding a null string should return null",
183 null, encoded);
184 this.validateState(urlCodec);
185 }
186
187 @Test
188 public void testEncodeUrlWithNullBitSet() throws Exception {
189 final URLCodec urlCodec = new URLCodec();
190 final String plain = "Hello there!";
191 final String encoded = new String( URLCodec.encodeUrl(null, plain.getBytes(Charsets.UTF_8)));
192 assertEquals("Basic URL encoding test",
193 "Hello+there%21", encoded);
194 assertEquals("Basic URL decoding test",
195 plain, urlCodec.decode(encoded));
196 this.validateState(urlCodec);
197 }
198
199 @Test
200 public void testDecodeWithNullArray() throws Exception {
201 final byte[] plain = null;
202 final byte[] result = URLCodec.decodeUrl( plain );
203 assertEquals("Result should be null", null, result);
204 }
205
206 @Test
207 public void testEncodeStringWithNull() throws Exception {
208 final URLCodec urlCodec = new URLCodec();
209 final String test = null;
210 final String result = urlCodec.encode( test, "charset" );
211 assertEquals("Result should be null", null, result);
212 }
213
214 @Test
215 public void testDecodeStringWithNull() throws Exception {
216 final URLCodec urlCodec = new URLCodec();
217 final String test = null;
218 final String result = urlCodec.decode( test, "charset" );
219 assertEquals("Result should be null", null, result);
220 }
221
222 @Test
223 public void testEncodeObjects() throws Exception {
224 final URLCodec urlCodec = new URLCodec();
225 final String plain = "Hello there!";
226 String encoded = (String) urlCodec.encode((Object) plain);
227 assertEquals("Basic URL encoding test",
228 "Hello+there%21", encoded);
229
230 final byte[] plainBA = plain.getBytes(Charsets.UTF_8);
231 final byte[] encodedBA = (byte[]) urlCodec.encode((Object) plainBA);
232 encoded = new String(encodedBA);
233 assertEquals("Basic URL encoding test",
234 "Hello+there%21", encoded);
235
236 final Object result = urlCodec.encode((Object) null);
237 assertEquals( "Encoding a null Object should return null", null, result);
238
239 try {
240 final Object dObj = new Double(3.0);
241 urlCodec.encode( dObj );
242 fail( "Trying to url encode a Double object should cause an exception.");
243 } catch (final EncoderException ee) {
244 // Exception expected, test segment passes.
245 }
246 this.validateState(urlCodec);
247 }
248
249 @Test
250 public void testInvalidEncoding() {
251 final URLCodec urlCodec = new URLCodec("NONSENSE");
252 final String plain = "Hello there!";
253 try {
254 urlCodec.encode(plain);
255 fail("We set the encoding to a bogus NONSENSE vlaue, this shouldn't have worked.");
256 } catch (final EncoderException ee) {
257 // Exception expected, test segment passes.
258 }
259 try {
260 urlCodec.decode(plain);
261 fail("We set the encoding to a bogus NONSENSE vlaue, this shouldn't have worked.");
262 } catch (final DecoderException ee) {
263 // Exception expected, test segment passes.
264 }
265 this.validateState(urlCodec);
266 }
267
268 @Test
269 public void testDecodeObjects() throws Exception {
270 final URLCodec urlCodec = new URLCodec();
271 final String plain = "Hello+there%21";
272 String decoded = (String) urlCodec.decode((Object) plain);
273 assertEquals("Basic URL decoding test",
274 "Hello there!", decoded);
275
276 final byte[] plainBA = plain.getBytes(Charsets.UTF_8);
277 final byte[] decodedBA = (byte[]) urlCodec.decode((Object) plainBA);
278 decoded = new String(decodedBA);
279 assertEquals("Basic URL decoding test",
280 "Hello there!", decoded);
281
282 final Object result = urlCodec.decode((Object) null);
283 assertEquals( "Decoding a null Object should return null", null, result);
284
285 try {
286 final Object dObj = new Double(3.0);
287 urlCodec.decode( dObj );
288 fail( "Trying to url encode a Double object should cause an exception.");
289 } catch (final DecoderException ee) {
290 // Exception expected, test segment passes.
291 }
292 this.validateState(urlCodec);
293 }
294
295 @Test
296 public void testDefaultEncoding() throws Exception {
297 final String plain = "Hello there!";
298 final URLCodec urlCodec = new URLCodec("UnicodeBig");
299 urlCodec.encode(plain); // To work around a weird quirk in Java 1.2.2
300 final String encoded1 = urlCodec.encode(plain, "UnicodeBig");
301 final String encoded2 = urlCodec.encode(plain);
302 assertEquals(encoded1, encoded2);
303 this.validateState(urlCodec);
304 }
305 }