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(URLCodec urlCodec) { 049 // no tests for now. 050 } 051 052 private String constructString(int [] unicodeChars) { 053 StringBuilder buffer = new StringBuilder(); 054 if (unicodeChars != null) { 055 for (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 String ru_msg = constructString(RUSSIAN_STUFF_UNICODE); 066 String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE); 067 068 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 URLCodec urlCodec = new URLCodec(); 085 String plain = "Hello there!"; 086 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 URLCodec urlCodec = new URLCodec(); 098 String plain = "abc123_-.*"; 099 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 URLCodec urlCodec = new URLCodec(); 111 String plain = "~!@#$%^&()+{}\"\\;:`,/[]"; 112 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 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 URLCodec urlCodec = new URLCodec(); 135 try { 136 urlCodec.decode("%"); 137 fail("DecoderException should have been thrown"); 138 } catch (DecoderException e) { 139 // Expected. Move on 140 } 141 try { 142 urlCodec.decode("%A"); 143 fail("DecoderException should have been thrown"); 144 } catch (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 (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 (DecoderException e) { 159 // Expected. Move on 160 } 161 this.validateState(urlCodec); 162 } 163 164 @Test 165 public void testDecodeInvalidContent() throws UnsupportedEncodingException, DecoderException { 166 String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE); 167 URLCodec urlCodec = new URLCodec(); 168 byte[] input = ch_msg.getBytes("ISO-8859-1"); 169 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 URLCodec urlCodec = new URLCodec(); 180 byte[] plain = null; 181 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 URLCodec urlCodec = new URLCodec(); 190 String plain = "Hello there!"; 191 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 byte[] plain = null; 202 byte[] result = URLCodec.decodeUrl( plain ); 203 assertEquals("Result should be null", null, result); 204 } 205 206 @Test 207 public void testEncodeStringWithNull() throws Exception { 208 URLCodec urlCodec = new URLCodec(); 209 String test = null; 210 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 URLCodec urlCodec = new URLCodec(); 217 String test = null; 218 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 URLCodec urlCodec = new URLCodec(); 225 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 byte[] plainBA = plain.getBytes(Charsets.UTF_8); 231 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 Object result = urlCodec.encode((Object) null); 237 assertEquals( "Encoding a null Object should return null", null, result); 238 239 try { 240 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 (EncoderException ee) { 244 // Exception expected, test segment passes. 245 } 246 this.validateState(urlCodec); 247 } 248 249 @Test 250 public void testInvalidEncoding() { 251 URLCodec urlCodec = new URLCodec("NONSENSE"); 252 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 (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 (DecoderException ee) { 263 // Exception expected, test segment passes. 264 } 265 this.validateState(urlCodec); 266 } 267 268 @Test 269 public void testDecodeObjects() throws Exception { 270 URLCodec urlCodec = new URLCodec(); 271 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 byte[] plainBA = plain.getBytes(Charsets.UTF_8); 277 byte[] decodedBA = (byte[]) urlCodec.decode((Object) plainBA); 278 decoded = new String(decodedBA); 279 assertEquals("Basic URL decoding test", 280 "Hello there!", decoded); 281 282 Object result = urlCodec.decode((Object) null); 283 assertEquals( "Decoding a null Object should return null", null, result); 284 285 try { 286 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 (DecoderException ee) { 290 // Exception expected, test segment passes. 291 } 292 this.validateState(urlCodec); 293 } 294 295 @Test 296 public void testDefaultEncoding() throws Exception { 297 String plain = "Hello there!"; 298 URLCodec urlCodec = new URLCodec("UnicodeBig"); 299 urlCodec.encode(plain); // To work around a weird quirk in Java 1.2.2 300 String encoded1 = urlCodec.encode(plain, "UnicodeBig"); 301 String encoded2 = urlCodec.encode(plain); 302 assertEquals(encoded1, encoded2); 303 this.validateState(urlCodec); 304 } 305 }