1 /*
2  * Copyright (C) 2008 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 
17 package android.net.cts;
18 
19 import android.content.ContentUris;
20 import android.net.Uri;
21 import android.os.Parcel;
22 import android.test.AndroidTestCase;
23 import java.io.File;
24 import java.util.Arrays;
25 
26 public class UriTest extends AndroidTestCase {
testParcelling()27     public void testParcelling() {
28         parcelAndUnparcel(Uri.parse("foo:bob%20lee"));
29         parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment"));
30         parcelAndUnparcel(new Uri.Builder()
31              .scheme("http")
32             .authority("crazybob.org")
33             .path("/rss/")
34             .encodedQuery("a=b")
35             .fragment("foo")
36             .build());
37      }
38 
parcelAndUnparcel(Uri u)39     private void parcelAndUnparcel(Uri u) {
40         Parcel p = Parcel.obtain();
41         Uri.writeToParcel(p, u);
42         p.setDataPosition(0);
43         assertEquals(u, Uri.CREATOR.createFromParcel(p));
44 
45         p.setDataPosition(0);
46         u = u.buildUpon().build();
47         Uri.writeToParcel(p, u);
48         p.setDataPosition(0);
49         assertEquals(u, Uri.CREATOR.createFromParcel(p));
50     }
51 
testBuildUpon()52     public void testBuildUpon() {
53         Uri u = Uri.parse("bob:lee").buildUpon().scheme("robert").build();
54         assertEquals("robert", u.getScheme());
55         assertEquals("lee", u.getEncodedSchemeSpecificPart());
56         assertEquals("lee", u.getSchemeSpecificPart());
57         assertNull(u.getQuery());
58         assertNull(u.getPath());
59         assertNull(u.getAuthority());
60         assertNull(u.getHost());
61 
62         Uri a = Uri.fromParts("foo", "bar", "tee");
63         Uri b = a.buildUpon().fragment("new").build();
64         assertEquals("new", b.getFragment());
65         assertEquals("bar", b.getSchemeSpecificPart());
66         assertEquals("foo", b.getScheme());
67         a = new Uri.Builder()
68                 .scheme("foo")
69                 .encodedOpaquePart("bar")
70                 .fragment("tee")
71                 .build();
72         b = a.buildUpon().fragment("new").build();
73         assertEquals("new", b.getFragment());
74         assertEquals("bar", b.getSchemeSpecificPart());
75         assertEquals("foo", b.getScheme());
76     }
77 
testStringUri()78     public void testStringUri() {
79         assertEquals("bob lee",
80                 Uri.parse("foo:bob%20lee").getSchemeSpecificPart());
81         assertEquals("bob%20lee",
82                 Uri.parse("foo:bob%20lee").getEncodedSchemeSpecificPart());
83 
84         assertEquals("/bob%20lee",
85                 Uri.parse("foo:/bob%20lee").getEncodedPath());
86         assertNull(Uri.parse("foo:bob%20lee").getPath());
87 
88         assertEquals("bob%20lee",
89                 Uri.parse("foo:?bob%20lee").getEncodedQuery());
90         assertNull(Uri.parse("foo:bob%20lee").getEncodedQuery());
91         assertNull(Uri.parse("foo:bar#?bob%20lee").getQuery());
92 
93         assertEquals("bob%20lee",
94                 Uri.parse("foo:#bob%20lee").getEncodedFragment());
95 
96         Uri uri = Uri.parse("http://localhost:42");
97         assertEquals("localhost", uri.getHost());
98         assertEquals(42, uri.getPort());
99 
100         uri = Uri.parse("http://bob@localhost:42");
101         assertEquals("bob", uri.getUserInfo());
102         assertEquals("localhost", uri.getHost());
103         assertEquals(42, uri.getPort());
104 
105         uri = Uri.parse("http://bob%20lee@localhost:42");
106         assertEquals("bob lee", uri.getUserInfo());
107         assertEquals("bob%20lee", uri.getEncodedUserInfo());
108 
109         uri = Uri.parse("http://localhost");
110         assertEquals("localhost", uri.getHost());
111         assertEquals(-1, uri.getPort());
112     }
113 
testCompareTo()114     public void testCompareTo() {
115         Uri a = Uri.parse("foo:a");
116         Uri b = Uri.parse("foo:b");
117         Uri b2 = Uri.parse("foo:b");
118 
119         assertTrue(a.compareTo(b) < 0);
120         assertTrue(b.compareTo(a) > 0);
121         assertEquals(0, b.compareTo(b2));
122     }
123 
testEqualsAndHashCode()124     public void testEqualsAndHashCode() {
125         Uri a = Uri.parse("http://crazybob.org/test/?foo=bar#tee");
126 
127         Uri b = new Uri.Builder()
128                 .scheme("http")
129                 .authority("crazybob.org")
130                 .path("/test/")
131                 .encodedQuery("foo=bar")
132                 .fragment("tee")
133                 .build();
134 
135         // Try alternate builder methods.
136         Uri c = new Uri.Builder()
137                 .scheme("http")
138                 .encodedAuthority("crazybob.org")
139                 .encodedPath("/test/")
140                 .encodedQuery("foo=bar")
141                 .encodedFragment("tee")
142                 .build();
143 
144         assertFalse(Uri.EMPTY.equals(null));
145         assertEquals(a, b);
146         assertEquals(b, c);
147         assertEquals(c, a);
148         assertEquals(a.hashCode(), b.hashCode());
149         assertEquals(b.hashCode(), c.hashCode());
150     }
151 
testEncodeAndDecode()152     public void testEncodeAndDecode() {
153         String encoded = Uri.encode("Bob:/", "/");
154         assertEquals(-1, encoded.indexOf(':'));
155         assertTrue(encoded.indexOf('/') > -1);
156         assertDecode(null);
157         assertDecode("");
158         assertDecode("Bob");
159         assertDecode(":Bob");
160         assertDecode("::Bob");
161         assertDecode("Bob::Lee");
162         assertDecode("Bob:Lee");
163         assertDecode("Bob::");
164         assertDecode("Bob:");
165         assertDecode("::Bob::");
166     }
167 
assertDecode(String s)168     private void assertDecode(String s) {
169         assertEquals(s, Uri.decode(Uri.encode(s, null)));
170     }
171 
testFromFile()172     public void testFromFile() {
173         File f = new File("/tmp/bob");
174         Uri uri = Uri.fromFile(f);
175         assertEquals("file:///tmp/bob", uri.toString());
176         try {
177             Uri.fromFile(null);
178             fail("testFile fail");
179             } catch (NullPointerException e) {}
180     }
181 
testQueryParameters()182     public void testQueryParameters() {
183         Uri uri = Uri.parse("content://user");
184         assertEquals(null, uri.getQueryParameter("a"));
185 
186         uri = uri.buildUpon().appendQueryParameter("a", "b").build();
187         assertEquals("b", uri.getQueryParameter("a"));
188 
189         uri = uri.buildUpon().appendQueryParameter("a", "b2").build();
190         assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a"));
191 
192         uri = uri.buildUpon().appendQueryParameter("c", "d").build();
193         assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a"));
194         assertEquals("d", uri.getQueryParameter("c"));
195     }
196 
testPathOperations()197     public void testPathOperations() {
198         Uri uri = Uri.parse("content://user/a/b");
199 
200         assertEquals(2, uri.getPathSegments().size());
201         assertEquals("a", uri.getPathSegments().get(0));
202         assertEquals("b", uri.getPathSegments().get(1));
203         assertEquals("b", uri.getLastPathSegment());
204 
205         Uri first = uri;
206         uri = uri.buildUpon().appendPath("c").build();
207         assertEquals(3, uri.getPathSegments().size());
208         assertEquals("c", uri.getPathSegments().get(2));
209         assertEquals("c", uri.getLastPathSegment());
210         assertEquals("content://user/a/b/c", uri.toString());
211 
212         uri = ContentUris.withAppendedId(uri, 100);
213         assertEquals(4, uri.getPathSegments().size());
214         assertEquals("100", uri.getPathSegments().get(3));
215         assertEquals("100", uri.getLastPathSegment());
216         assertEquals(100, ContentUris.parseId(uri));
217         assertEquals("content://user/a/b/c/100", uri.toString());
218 
219         // Make sure the original URI is still intact.
220         assertEquals(2, first.getPathSegments().size());
221         assertEquals("b", first.getLastPathSegment());
222 
223         try {
224         first.getPathSegments().get(2);
225         fail("test path operations");
226         } catch (IndexOutOfBoundsException e) {}
227 
228         assertEquals(null, Uri.EMPTY.getLastPathSegment());
229 
230         Uri withC = Uri.parse("foo:/a/b/").buildUpon().appendPath("c").build();
231         assertEquals("/a/b/c", withC.getPath());
232     }
233 
testOpaqueUri()234     public void testOpaqueUri() {
235         Uri uri = Uri.parse("mailto:nobody");
236         testOpaqueUri(uri);
237 
238         uri = uri.buildUpon().build();
239         testOpaqueUri(uri);
240 
241         uri = Uri.fromParts("mailto", "nobody", null);
242         testOpaqueUri(uri);
243 
244         uri = uri.buildUpon().build();
245         testOpaqueUri(uri);
246 
247         uri = new Uri.Builder()
248                 .scheme("mailto")
249                 .opaquePart("nobody")
250                 .build();
251         testOpaqueUri(uri);
252 
253         uri = uri.buildUpon().build();
254         testOpaqueUri(uri);
255     }
256 
testOpaqueUri(Uri uri)257     private void testOpaqueUri(Uri uri) {
258         assertEquals("mailto", uri.getScheme());
259         assertEquals("nobody", uri.getSchemeSpecificPart());
260         assertEquals("nobody", uri.getEncodedSchemeSpecificPart());
261 
262         assertNull(uri.getFragment());
263         assertTrue(uri.isAbsolute());
264         assertTrue(uri.isOpaque());
265         assertFalse(uri.isRelative());
266         assertFalse(uri.isHierarchical());
267 
268         assertNull(uri.getAuthority());
269         assertNull(uri.getEncodedAuthority());
270         assertNull(uri.getPath());
271         assertNull(uri.getEncodedPath());
272         assertNull(uri.getUserInfo());
273         assertNull(uri.getEncodedUserInfo());
274         assertNull(uri.getQuery());
275         assertNull(uri.getEncodedQuery());
276         assertNull(uri.getHost());
277         assertEquals(-1, uri.getPort());
278 
279         assertTrue(uri.getPathSegments().isEmpty());
280         assertNull(uri.getLastPathSegment());
281 
282         assertEquals("mailto:nobody", uri.toString());
283 
284         Uri withFragment = uri.buildUpon().fragment("top").build();
285         assertEquals("mailto:nobody#top", withFragment.toString());
286     }
287 
testHierarchicalUris()288     public void testHierarchicalUris() {
289         testHierarchical("http", "google.com", "/p1/p2", "query", "fragment");
290         testHierarchical("file", null, "/p1/p2", null, null);
291         testHierarchical("content", "contact", "/p1/p2", null, null);
292         testHierarchical("http", "google.com", "/p1/p2", null, "fragment");
293         testHierarchical("http", "google.com", "", null, "fragment");
294         testHierarchical("http", "google.com", "", "query", "fragment");
295         testHierarchical("http", "google.com", "", "query", null);
296         testHierarchical("http", null, "/", "query", null);
297     }
298 
testHierarchical(String scheme, String authority, String path, String query, String fragment)299     private static void testHierarchical(String scheme, String authority,
300         String path, String query, String fragment) {
301         StringBuilder sb = new StringBuilder();
302 
303         if (authority != null) {
304             sb.append("//").append(authority);
305         }
306         if (path != null) {
307             sb.append(path);
308         }
309         if (query != null) {
310             sb.append('?').append(query);
311         }
312 
313         String ssp = sb.toString();
314 
315         if (scheme != null) {
316             sb.insert(0, scheme + ":");
317         }
318         if (fragment != null) {
319             sb.append('#').append(fragment);
320         }
321 
322         String uriString = sb.toString();
323 
324         Uri uri = Uri.parse(uriString);
325 
326         // Run these twice to test caching.
327         compareHierarchical(
328         uriString, ssp, uri, scheme, authority, path, query, fragment);
329         compareHierarchical(
330         uriString, ssp, uri, scheme, authority, path, query, fragment);
331 
332         // Test rebuilt version.
333         uri = uri.buildUpon().build();
334 
335         // Run these twice to test caching.
336         compareHierarchical(
337                 uriString, ssp, uri, scheme, authority, path, query, fragment);
338         compareHierarchical(
339                 uriString, ssp, uri, scheme, authority, path, query, fragment);
340 
341         // The decoded and encoded versions of the inputs are all the same.
342         // We'll test the actual encoding decoding separately.
343 
344         // Test building with encoded versions.
345         Uri built = new Uri.Builder()
346             .scheme(scheme)
347                 .encodedAuthority(authority)
348                 .encodedPath(path)
349                 .encodedQuery(query)
350                 .encodedFragment(fragment)
351                 .build();
352 
353         compareHierarchical(
354                 uriString, ssp, built, scheme, authority, path, query, fragment);
355         compareHierarchical(
356                 uriString, ssp, built, scheme, authority, path, query, fragment);
357 
358         // Test building with decoded versions.
359         built = new Uri.Builder()
360                 .scheme(scheme)
361                 .authority(authority)
362                 .path(path)
363                 .query(query)
364                 .fragment(fragment)
365                 .build();
366 
367         compareHierarchical(
368                 uriString, ssp, built, scheme, authority, path, query, fragment);
369         compareHierarchical(
370                 uriString, ssp, built, scheme, authority, path, query, fragment);
371 
372         // Rebuild.
373         built = built.buildUpon().build();
374 
375         compareHierarchical(
376                 uriString, ssp, built, scheme, authority, path, query, fragment);
377         compareHierarchical(
378                 uriString, ssp, built, scheme, authority, path, query, fragment);
379     }
380 
compareHierarchical(String uriString, String ssp, Uri uri, String scheme, String authority, String path, String query, String fragment)381     private static void compareHierarchical(String uriString, String ssp,
382         Uri uri,
383         String scheme, String authority, String path, String query,
384         String fragment) {
385         assertEquals(scheme, uri.getScheme());
386         assertEquals(authority, uri.getAuthority());
387         assertEquals(authority, uri.getEncodedAuthority());
388         assertEquals(path, uri.getPath());
389         assertEquals(path, uri.getEncodedPath());
390         assertEquals(query, uri.getQuery());
391         assertEquals(query, uri.getEncodedQuery());
392         assertEquals(fragment, uri.getFragment());
393         assertEquals(fragment, uri.getEncodedFragment());
394         assertEquals(ssp, uri.getSchemeSpecificPart());
395 
396         if (scheme != null) {
397             assertTrue(uri.isAbsolute());
398             assertFalse(uri.isRelative());
399         } else {
400             assertFalse(uri.isAbsolute());
401             assertTrue(uri.isRelative());
402         }
403 
404         assertFalse(uri.isOpaque());
405         assertTrue(uri.isHierarchical());
406         assertEquals(uriString, uri.toString());
407     }
408 
testNormalizeScheme()409     public void testNormalizeScheme() {
410         assertEquals(Uri.parse(""), Uri.parse("").normalizeScheme());
411         assertEquals(Uri.parse("http://www.android.com"),
412                 Uri.parse("http://www.android.com").normalizeScheme());
413         assertEquals(Uri.parse("http://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c"),
414                 Uri.parse("HTTP://USER@WWW.ANDROID.COM:100/ABOUT?foo=blah@bar=bleh#c")
415                         .normalizeScheme());
416     }
417 }
418