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  
18  package org.apache.commons.codec.net;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertNull;
22  import static org.junit.Assert.fail;
23  
24  import java.io.UnsupportedEncodingException;
25  
26  import org.apache.commons.codec.CharEncoding;
27  import org.apache.commons.codec.Charsets;
28  import org.apache.commons.codec.DecoderException;
29  import org.apache.commons.codec.EncoderException;
30  import org.junit.Test;
31  
32  /**
33   * URL codec test cases
34   *
35   * @version $Id: URLCodecTest.java 1429868 2013-01-07 16:08:05Z ggregory $
36   */
37  public class URLCodecTest {
38  
39      static final int SWISS_GERMAN_STUFF_UNICODE [] = {
40          0x47, 0x72, 0xFC, 0x65, 0x7A, 0x69, 0x5F, 0x7A, 0xE4, 0x6D, 0xE4
41      };
42  
43      static final int RUSSIAN_STUFF_UNICODE [] = {
44          0x412, 0x441, 0x435, 0x43C, 0x5F, 0x43F, 0x440, 0x438,
45          0x432, 0x435, 0x442
46      };
47  
48      private void validateState(final URLCodec urlCodec) {
49          // no tests for now.
50      }
51  
52      private String constructString(final int [] unicodeChars) {
53          final StringBuilder buffer = new StringBuilder();
54          if (unicodeChars != null) {
55              for (final int unicodeChar : unicodeChars) {
56                  buffer.append((char)unicodeChar);
57              }
58          }
59          return buffer.toString();
60      }
61  
62      @Test
63      public void testUTF8RoundTrip() throws Exception {
64  
65          final String ru_msg = constructString(RUSSIAN_STUFF_UNICODE);
66          final String ch_msg = constructString(SWISS_GERMAN_STUFF_UNICODE);
67  
68          final URLCodec urlCodec = new URLCodec();
69          this.validateState(urlCodec);
70  
71          assertEquals(
72              "%D0%92%D1%81%D0%B5%D0%BC_%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82",
73              urlCodec.encode(ru_msg, CharEncoding.UTF_8)
74          );
75          assertEquals("Gr%C3%BCezi_z%C3%A4m%C3%A4", urlCodec.encode(ch_msg, CharEncoding.UTF_8));
76  
77          assertEquals(ru_msg, urlCodec.decode(urlCodec.encode(ru_msg, CharEncoding.UTF_8), CharEncoding.UTF_8));
78          assertEquals(ch_msg, urlCodec.decode(urlCodec.encode(ch_msg, CharEncoding.UTF_8), CharEncoding.UTF_8));
79          this.validateState(urlCodec);
80      }
81  
82      @Test
83      public void testBasicEncodeDecode() throws Exception {
84          final URLCodec urlCodec = new URLCodec();
85          final String plain = "Hello there!";
86          final String encoded = urlCodec.encode(plain);
87          assertEquals("Basic URL encoding test",
88              "Hello+there%21", encoded);
89          assertEquals("Basic URL decoding test",
90              plain, urlCodec.decode(encoded));
91          this.validateState(urlCodec);
92      }
93  
94  
95      @Test
96      public void testSafeCharEncodeDecode() throws Exception {
97          final URLCodec urlCodec = new URLCodec();
98          final String plain = "abc123_-.*";
99          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 }