UrlEncodingTest.java revision 9773c9ed094e164ace98757bb6d54964ca8978fd
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package libcore.java.net;
18
19import java.io.UnsupportedEncodingException;
20import java.net.URI;
21import java.net.URISyntaxException;
22import java.net.URLDecoder;
23import java.net.URLEncoder;
24import junit.framework.TestCase;
25
26public final class UrlEncodingTest extends TestCase {
27
28    public void testUriRetainsOriginalEncoding() throws Exception {
29        assertEquals("%61", new URI("http://foo#%61").getRawFragment());
30    }
31
32    /**
33     * URLDecoder and URI disagree on what '+' should decode to.
34     */
35    public void testDecodingPlus() throws Exception {
36        assertEquals("a b", URLDecoder.decode("a+b"));
37        assertEquals("a b", URLDecoder.decode("a+b", "UTF-8"));
38        assertEquals("a+b", new URI("http://foo#a+b").getFragment());
39    }
40
41    public void testEncodingPlus() throws Exception {
42        assertEquals("a%2Bb", URLEncoder.encode("a+b"));
43        assertEquals("a%2Bb", URLEncoder.encode("a+b", "UTF-8"));
44        assertEquals("a+b", new URI("http", "foo", "/", "a+b").getRawFragment());
45    }
46
47    public void testDecodingSpace() throws Exception {
48        assertEquals("a b", URLDecoder.decode("a b"));
49        assertEquals("a b", URLDecoder.decode("a b", "UTF-8"));
50        try {
51            new URI("http://foo#a b");
52            fail();
53        } catch (URISyntaxException expected) {
54        }
55    }
56
57    public void testEncodingSpace() throws Exception {
58        assertEquals("a+b", URLEncoder.encode("a b"));
59        assertEquals("a+b", URLEncoder.encode("a b", "UTF-8"));
60        assertEquals("a%20b", new URI("http", "foo", "/", "a b").getRawFragment());
61    }
62
63    public void testUriDecodingPartial() throws Exception {
64        try {
65            new URI("http://foo#%");
66            fail();
67        } catch (URISyntaxException expected) {
68        }
69        try {
70            new URI("http://foo#%0");
71            fail();
72        } catch (URISyntaxException expected) {
73        }
74    }
75
76    public void testUrlDecoderDecodingPartial() throws Exception {
77        try {
78            URLDecoder.decode("%");
79            fail();
80        } catch (IllegalArgumentException expected) {
81        }
82        try {
83            URLDecoder.decode("%0");
84            fail();
85        } catch (IllegalArgumentException expected) {
86        }
87    }
88
89    public void testUriDecodingInvalid() {
90        try {
91            new URI("http://foo#%0g");
92            fail();
93        } catch (URISyntaxException expected) {
94        }
95    }
96
97    public void testUrlDecoderDecodingInvalid() {
98        try {
99            URLDecoder.decode("%0g");
100            fail();
101        } catch (IllegalArgumentException expected) {
102        }
103    }
104
105    public void testUrlDecoderFailsOnNullCharset() throws Exception {
106        try {
107            URLDecoder.decode("ab", null);
108            fail();
109        } catch (NullPointerException expected) {
110        }
111    }
112
113    public void testUrlEncoderFailsOnNullCharset() throws Exception {
114        try {
115            URLEncoder.encode("ab", null);
116            fail();
117        } catch (NullPointerException expected) {
118        }
119    }
120
121    public void testUrlDecoderIgnoresUnnecessaryCharset() throws Exception {
122        assertEquals("ab", URLDecoder.decode("ab", "no such charset"));
123    }
124
125    public void testUrlEncoderFailsOnInvalidCharset() throws Exception {
126        try {
127            URLEncoder.encode("ab", "no such charset");
128            fail();
129        } catch (UnsupportedEncodingException expected) {
130        }
131    }
132
133    public void testDecoding() throws Exception {
134        assertDecoded("a\u0000b", "a%00b");
135        assertDecoded("a b", "a%20b");
136        assertDecoded("a+b", "a%2bb");
137        assertDecoded("a%b", "a%25b");
138        assertDecoded("a\u007fb", "a%7fb");
139    }
140
141    public void testEncoding() throws Exception {
142        assertEncoded("a%25b", "a%b");
143        assertEncoded("a%7Fb", "a\u007fb");
144    }
145
146    public void testDecodingLiterals() throws Exception {
147        assertDecoded("\ud842\udf9f", "\ud842\udf9f");
148    }
149
150    public void testDecodingBrokenUtf8SequenceYieldsReplacementCharacter() throws Exception {
151        assertDecoded("a\ufffdb", "a%ffb");
152    }
153
154    public void testDecodingUtf8Octets() throws Exception {
155        assertDecoded("\u20AC", "%e2%82%ac");
156        assertDecoded("\ud842\udf9f", "%f0%a0%ae%9f");
157    }
158
159    /**
160     * Android's URLEncoder.encode() failed for surrogate pairs, encoding them
161     * as two replacement characters ("??"). http://b/3436051
162     */
163    public void testUrlEncoderEncodesNonPrintableNonAsciiCharacters() throws Exception {
164        assertEquals("%00", URLEncoder.encode("\u0000", "UTF-8"));
165        assertEquals("%00", URLEncoder.encode("\u0000"));
166        assertEquals("%E2%82%AC", URLEncoder.encode("\u20AC", "UTF-8"));
167        assertEquals("%E2%82%AC", URLEncoder.encode("\u20AC"));
168        assertEquals("%F0%A0%AE%9F", URLEncoder.encode("\ud842\udf9f", "UTF-8"));
169        assertEquals("%F0%A0%AE%9F", URLEncoder.encode("\ud842\udf9f"));
170    }
171
172    public void testUriDoesNotEncodeNonPrintableNonAsciiCharacters() throws Exception {
173        assertEquals("\u0000", new URI("http", "foo", "/", "\u0000").getRawFragment());
174        assertEquals("\u20AC", new URI("http", "foo", "/", "\u20AC").getRawFragment());
175        assertEquals("\ud842\udf9f", new URI("http", "foo", "/", "\ud842\udf9f").getRawFragment());
176    }
177
178    /**
179     * Asserts that {@code original} decodes to {@code decoded} using both URI
180     * and UrlDecoder.
181     */
182    private void assertDecoded(String decoded, String original) throws Exception {
183        assertEquals(decoded, new URI("http://foo#" + original).getFragment());
184        assertEquals(decoded, URLDecoder.decode(original));
185        assertEquals(decoded, URLDecoder.decode(original, "UTF-8"));
186    }
187
188    /**
189     * Asserts that {@code original} encodes to {@code encoded} using both URI
190     * and URLEncoder.
191     */
192    private void assertEncoded(String encoded, String original) throws Exception {
193        assertEquals(encoded, URLEncoder.encode(original, "UTF-8"));
194        assertEquals(encoded, URLEncoder.encode(original));
195        assertEquals(encoded, new URI("http", "foo", "/", original).getRawFragment());
196    }
197}
198