UriTest.java revision 1a44d5dcabc18cd5ef111f732ccff91683a1a093
1/* 2 * Copyright (C) 2007 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 android.net; 18 19import android.net.Uri; 20import android.content.ContentUris; 21import android.os.Parcel; 22import android.test.suitebuilder.annotation.SmallTest; 23import junit.framework.TestCase; 24 25import java.io.File; 26import java.util.Arrays; 27 28public class UriTest extends TestCase { 29 30 @SmallTest 31 public void testToStringWithPathOnly() { 32 Uri.Builder builder = new Uri.Builder(); 33 34 // Not a valid path, but this came from a user's test case. 35 builder.path("//foo"); 36 Uri uri = builder.build(); 37 assertEquals("//foo", uri.toString()); 38 } 39 40 @SmallTest 41 public void testParcelling() { 42 parcelAndUnparcel(Uri.parse("foo:bob%20lee")); 43 parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment")); 44 parcelAndUnparcel(new Uri.Builder() 45 .scheme("http") 46 .authority("crazybob.org") 47 .path("/rss/") 48 .encodedQuery("a=b") 49 .fragment("foo") 50 .build()); 51 } 52 53 private void parcelAndUnparcel(Uri u) { 54 Parcel p = Parcel.obtain(); 55 try { 56 Uri.writeToParcel(p, u); 57 p.setDataPosition(0); 58 assertEquals(u, Uri.CREATOR.createFromParcel(p)); 59 60 p.setDataPosition(0); 61 u = u.buildUpon().build(); 62 Uri.writeToParcel(p, u); 63 p.setDataPosition(0); 64 assertEquals(u, Uri.CREATOR.createFromParcel(p)); 65 } 66 finally { 67 p.recycle(); 68 } 69 } 70 71 @SmallTest 72 public void testBuildUponOpaqueStringUri() { 73 Uri u = Uri.parse("bob:lee").buildUpon().scheme("robert").build(); 74 assertEquals("robert", u.getScheme()); 75 assertEquals("lee", u.getEncodedSchemeSpecificPart()); 76 assertEquals("lee", u.getSchemeSpecificPart()); 77 assertNull(u.getQuery()); 78 assertNull(u.getPath()); 79 assertNull(u.getAuthority()); 80 assertNull(u.getHost()); 81 } 82 83 @SmallTest 84 public void testStringUri() { 85 assertEquals("bob lee", 86 Uri.parse("foo:bob%20lee").getSchemeSpecificPart()); 87 assertEquals("bob%20lee", 88 Uri.parse("foo:bob%20lee").getEncodedSchemeSpecificPart()); 89 assertEquals("/bob%20lee", 90 Uri.parse("foo:/bob%20lee").getEncodedPath()); 91 assertNull(Uri.parse("foo:bob%20lee").getPath()); 92 assertEquals("bob%20lee", 93 Uri.parse("foo:?bob%20lee").getEncodedQuery()); 94 assertNull(Uri.parse("foo:bar#?bob%20lee").getQuery()); 95 assertEquals("bob%20lee", 96 Uri.parse("foo:#bob%20lee").getEncodedFragment()); 97 } 98 99 @SmallTest 100 public void testStringUriIsHierarchical() { 101 assertTrue(Uri.parse("bob").isHierarchical()); 102 assertFalse(Uri.parse("bob:").isHierarchical()); 103 } 104 105 @SmallTest 106 public void testNullUriString() { 107 try { 108 Uri.parse(null); 109 fail(); 110 } catch (NullPointerException e) {} 111 } 112 113 @SmallTest 114 public void testNullFile() { 115 try { 116 Uri.fromFile(null); 117 fail(); 118 } catch (NullPointerException e) {} 119 } 120 121 @SmallTest 122 public void testCompareTo() { 123 Uri a = Uri.parse("foo:a"); 124 Uri b = Uri.parse("foo:b"); 125 Uri b2 = Uri.parse("foo:b"); 126 127 assertTrue(a.compareTo(b) < 0); 128 assertTrue(b.compareTo(a) > 0); 129 assertEquals(0, b.compareTo(b2)); 130 } 131 132 @SmallTest 133 public void testEqualsAndHashCode() { 134 135 Uri a = Uri.parse("http://crazybob.org/test/?foo=bar#tee"); 136 137 Uri b = new Uri.Builder() 138 .scheme("http") 139 .authority("crazybob.org") 140 .path("/test/") 141 .encodedQuery("foo=bar") 142 .fragment("tee") 143 .build(); 144 145 // Try alternate builder methods. 146 Uri c = new Uri.Builder() 147 .scheme("http") 148 .encodedAuthority("crazybob.org") 149 .encodedPath("/test/") 150 .encodedQuery("foo=bar") 151 .encodedFragment("tee") 152 .build(); 153 154 assertFalse(Uri.EMPTY.equals(null)); 155 156 assertEquals(a, b); 157 assertEquals(b, c); 158 assertEquals(c, a); 159 160 assertEquals(a.hashCode(), b.hashCode()); 161 assertEquals(b.hashCode(), c.hashCode()); 162 } 163 164 @SmallTest 165 public void testAuthorityParsing() { 166 Uri uri = Uri.parse("http://localhost:42"); 167 assertEquals("localhost", uri.getHost()); 168 assertEquals(42, uri.getPort()); 169 170 uri = Uri.parse("http://bob@localhost:42"); 171 assertEquals("bob", uri.getUserInfo()); 172 assertEquals("localhost", uri.getHost()); 173 assertEquals(42, uri.getPort()); 174 175 uri = Uri.parse("http://bob%20lee@localhost:42"); 176 assertEquals("bob lee", uri.getUserInfo()); 177 assertEquals("bob%20lee", uri.getEncodedUserInfo()); 178 179 uri = Uri.parse("http://bob%40lee%3ajr@local%68ost:4%32"); 180 assertEquals("bob@lee:jr", uri.getUserInfo()); 181 assertEquals("localhost", uri.getHost()); 182 assertEquals(42, uri.getPort()); 183 184 uri = Uri.parse("http://localhost"); 185 assertEquals("localhost", uri.getHost()); 186 assertEquals(-1, uri.getPort()); 187 } 188 189 @SmallTest 190 public void testBuildUponOpaqueUri() { 191 Uri a = Uri.fromParts("foo", "bar", "tee"); 192 Uri b = a.buildUpon().fragment("new").build(); 193 assertEquals("new", b.getFragment()); 194 assertEquals("bar", b.getSchemeSpecificPart()); 195 assertEquals("foo", b.getScheme()); 196 } 197 198 @SmallTest 199 public void testBuildUponEncodedOpaqueUri() { 200 Uri a = new Uri.Builder() 201 .scheme("foo") 202 .encodedOpaquePart("bar") 203 .fragment("tee") 204 .build(); 205 Uri b = a.buildUpon().fragment("new").build(); 206 assertEquals("new", b.getFragment()); 207 assertEquals("bar", b.getSchemeSpecificPart()); 208 assertEquals("foo", b.getScheme()); 209 } 210 211 @SmallTest 212 public void testPathSegmentDecoding() { 213 Uri uri = Uri.parse("foo://bar/a%20a/b%20b"); 214 assertEquals("a a", uri.getPathSegments().get(0)); 215 assertEquals("b b", uri.getPathSegments().get(1)); 216 } 217 218 @SmallTest 219 public void testSms() { 220 Uri base = Uri.parse("content://sms"); 221 Uri appended = base.buildUpon() 222 .appendEncodedPath("conversations/addr=555-1212") 223 .build(); 224 assertEquals("content://sms/conversations/addr=555-1212", 225 appended.toString()); 226 assertEquals(2, appended.getPathSegments().size()); 227 assertEquals("conversations", appended.getPathSegments().get(0)); 228 assertEquals("addr=555-1212", appended.getPathSegments().get(1)); 229 } 230 231 @SmallTest 232 public void testEncodeWithAllowedChars() { 233 String encoded = Uri.encode("Bob:/", "/"); 234 assertEquals(-1, encoded.indexOf(':')); 235 assertTrue(encoded.indexOf('/') > -1); 236 } 237 238 @SmallTest 239 public void testEncodeDecode() { 240 code(null); 241 code(""); 242 code("Bob"); 243 code(":Bob"); 244 code("::Bob"); 245 code("Bob::Lee"); 246 code("Bob:Lee"); 247 code("Bob::"); 248 code("Bob:"); 249 code("::Bob::"); 250 } 251 252 private void code(String s) { 253 assertEquals(s, Uri.decode(Uri.encode(s, null))); 254 } 255 256 @SmallTest 257 public void testFile() { 258 File f = new File("/tmp/bob"); 259 260 Uri uri = Uri.fromFile(f); 261 262 assertEquals("file:///tmp/bob", uri.toString()); 263 } 264 265 @SmallTest 266 public void testQueryParameters() { 267 Uri uri = Uri.parse("content://user"); 268 269 assertEquals(null, uri.getQueryParameter("a")); 270 271 uri = uri.buildUpon().appendQueryParameter("a", "b").build(); 272 273 assertEquals("b", uri.getQueryParameter("a")); 274 275 uri = uri.buildUpon().appendQueryParameter("a", "b2").build(); 276 277 assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a")); 278 279 uri = uri.buildUpon().appendQueryParameter("c", "d").build(); 280 281 assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a")); 282 assertEquals("d", uri.getQueryParameter("c")); 283 } 284 285 @SmallTest 286 public void testSchemeOnly() { 287 Uri uri = Uri.parse("empty:"); 288 assertEquals("empty", uri.getScheme()); 289 assertTrue(uri.isAbsolute()); 290 assertNull(uri.getPath()); 291 } 292 293 @SmallTest 294 public void testEmptyPath() { 295 Uri uri = Uri.parse("content://user"); 296 assertEquals(0, uri.getPathSegments().size()); 297 } 298 299 @SmallTest 300 public void testPathOperations() { 301 Uri uri = Uri.parse("content://user/a/b"); 302 303 assertEquals(2, uri.getPathSegments().size()); 304 assertEquals("b", uri.getLastPathSegment()); 305 306 Uri first = uri; 307 uri = uri.buildUpon().appendPath("c").build(); 308 309 assertEquals(3, uri.getPathSegments().size()); 310 assertEquals("c", uri.getLastPathSegment()); 311 assertEquals("content://user/a/b/c", uri.toString()); 312 313 uri = ContentUris.withAppendedId(uri, 100); 314 315 assertEquals(4, uri.getPathSegments().size()); 316 assertEquals("100", uri.getLastPathSegment()); 317 assertEquals(100, ContentUris.parseId(uri)); 318 assertEquals("content://user/a/b/c/100", uri.toString()); 319 320 // Make sure the original URI is still intact. 321 assertEquals(2, first.getPathSegments().size()); 322 assertEquals("b", first.getLastPathSegment()); 323 324 try { 325 first.getPathSegments().get(2); 326 fail(); 327 } catch (IndexOutOfBoundsException e) {} 328 329 assertEquals(null, Uri.EMPTY.getLastPathSegment()); 330 331 Uri withC = Uri.parse("foo:/a/b/").buildUpon().appendPath("c").build(); 332 assertEquals("/a/b/c", withC.getPath()); 333 } 334 335 @SmallTest 336 public void testOpaqueUri() { 337 Uri uri = Uri.parse("mailto:nobody"); 338 testOpaqueUri(uri); 339 340 uri = uri.buildUpon().build(); 341 testOpaqueUri(uri); 342 343 uri = Uri.fromParts("mailto", "nobody", null); 344 testOpaqueUri(uri); 345 346 uri = uri.buildUpon().build(); 347 testOpaqueUri(uri); 348 349 uri = new Uri.Builder() 350 .scheme("mailto") 351 .opaquePart("nobody") 352 .build(); 353 testOpaqueUri(uri); 354 355 uri = uri.buildUpon().build(); 356 testOpaqueUri(uri); 357 } 358 359 private void testOpaqueUri(Uri uri) { 360 assertEquals("mailto", uri.getScheme()); 361 assertEquals("nobody", uri.getSchemeSpecificPart()); 362 assertEquals("nobody", uri.getEncodedSchemeSpecificPart()); 363 364 assertNull(uri.getFragment()); 365 assertTrue(uri.isAbsolute()); 366 assertTrue(uri.isOpaque()); 367 assertFalse(uri.isRelative()); 368 assertFalse(uri.isHierarchical()); 369 370 assertNull(uri.getAuthority()); 371 assertNull(uri.getEncodedAuthority()); 372 assertNull(uri.getPath()); 373 assertNull(uri.getEncodedPath()); 374 assertNull(uri.getUserInfo()); 375 assertNull(uri.getEncodedUserInfo()); 376 assertNull(uri.getQuery()); 377 assertNull(uri.getEncodedQuery()); 378 assertNull(uri.getHost()); 379 assertEquals(-1, uri.getPort()); 380 381 assertTrue(uri.getPathSegments().isEmpty()); 382 assertNull(uri.getLastPathSegment()); 383 384 assertEquals("mailto:nobody", uri.toString()); 385 386 Uri withFragment = uri.buildUpon().fragment("top").build(); 387 assertEquals("mailto:nobody#top", withFragment.toString()); 388 } 389 390 @SmallTest 391 public void testHierarchicalUris() { 392 testHierarchical("http", "google.com", "/p1/p2", "query", "fragment"); 393 testHierarchical("file", null, "/p1/p2", null, null); 394 testHierarchical("content", "contact", "/p1/p2", null, null); 395 testHierarchical("http", "google.com", "/p1/p2", null, "fragment"); 396 testHierarchical("http", "google.com", "", null, "fragment"); 397 testHierarchical("http", "google.com", "", "query", "fragment"); 398 testHierarchical("http", "google.com", "", "query", null); 399 testHierarchical("http", null, "/", "query", null); 400 } 401 402 private static void testHierarchical(String scheme, String authority, 403 String path, String query, String fragment) { 404 StringBuilder sb = new StringBuilder(); 405 406 if (authority != null) { 407 sb.append("//").append(authority); 408 } 409 if (path != null) { 410 sb.append(path); 411 } 412 if (query != null) { 413 sb.append('?').append(query); 414 } 415 416 String ssp = sb.toString(); 417 418 if (scheme != null) { 419 sb.insert(0, scheme + ":"); 420 } 421 if (fragment != null) { 422 sb.append('#').append(fragment); 423 } 424 425 String uriString = sb.toString(); 426 427 Uri uri = Uri.parse(uriString); 428 429 // Run these twice to test caching. 430 compareHierarchical( 431 uriString, ssp, uri, scheme, authority, path, query, fragment); 432 compareHierarchical( 433 uriString, ssp, uri, scheme, authority, path, query, fragment); 434 435 // Test rebuilt version. 436 uri = uri.buildUpon().build(); 437 438 // Run these twice to test caching. 439 compareHierarchical( 440 uriString, ssp, uri, scheme, authority, path, query, fragment); 441 compareHierarchical( 442 uriString, ssp, uri, scheme, authority, path, query, fragment); 443 444 // The decoded and encoded versions of the inputs are all the same. 445 // We'll test the actual encoding decoding separately. 446 447 // Test building with encoded versions. 448 Uri built = new Uri.Builder() 449 .scheme(scheme) 450 .encodedAuthority(authority) 451 .encodedPath(path) 452 .encodedQuery(query) 453 .encodedFragment(fragment) 454 .build(); 455 456 compareHierarchical( 457 uriString, ssp, built, scheme, authority, path, query, fragment); 458 compareHierarchical( 459 uriString, ssp, built, scheme, authority, path, query, fragment); 460 461 // Test building with decoded versions. 462 built = new Uri.Builder() 463 .scheme(scheme) 464 .authority(authority) 465 .path(path) 466 .query(query) 467 .fragment(fragment) 468 .build(); 469 470 compareHierarchical( 471 uriString, ssp, built, scheme, authority, path, query, fragment); 472 compareHierarchical( 473 uriString, ssp, built, scheme, authority, path, query, fragment); 474 475 // Rebuild. 476 built = built.buildUpon().build(); 477 478 compareHierarchical( 479 uriString, ssp, built, scheme, authority, path, query, fragment); 480 compareHierarchical( 481 uriString, ssp, built, scheme, authority, path, query, fragment); 482 } 483 484 private static void compareHierarchical(String uriString, String ssp, 485 Uri uri, 486 String scheme, String authority, String path, String query, 487 String fragment) { 488 assertEquals(scheme, uri.getScheme()); 489 assertEquals(authority, uri.getAuthority()); 490 assertEquals(authority, uri.getEncodedAuthority()); 491 assertEquals(path, uri.getPath()); 492 assertEquals(path, uri.getEncodedPath()); 493 assertEquals(query, uri.getQuery()); 494 assertEquals(query, uri.getEncodedQuery()); 495 assertEquals(fragment, uri.getFragment()); 496 assertEquals(fragment, uri.getEncodedFragment()); 497 assertEquals(ssp, uri.getSchemeSpecificPart()); 498 499 if (scheme != null) { 500 assertTrue(uri.isAbsolute()); 501 assertFalse(uri.isRelative()); 502 } else { 503 assertFalse(uri.isAbsolute()); 504 assertTrue(uri.isRelative()); 505 } 506 507 assertFalse(uri.isOpaque()); 508 assertTrue(uri.isHierarchical()); 509 510 assertEquals(uriString, uri.toString()); 511 } 512 513 public void testEmptyToStringNotNull() { 514 assertNotNull(Uri.EMPTY.toString()); 515 } 516 517 @SmallTest 518 public void testParcellingWithoutFragment() { 519 parcelAndUnparcel(Uri.parse("foo:bob%20lee")); 520 parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment")); 521 parcelAndUnparcel(new Uri.Builder() 522 .scheme("http") 523 .authority("crazybob.org") 524 .path("/rss/") 525 .encodedQuery("a=b") 526 .build()); 527 } 528 529 public void testGetQueryParameter() { 530 String nestedUrl = "http://crazybob.org/?a=1&b=2"; 531 Uri uri = Uri.parse("http://test/").buildUpon() 532 .appendQueryParameter("foo", "bar") 533 .appendQueryParameter("nested", nestedUrl).build(); 534 assertEquals(nestedUrl, uri.getQueryParameter("nested")); 535 assertEquals(nestedUrl, uri.getQueryParameters("nested").get(0)); 536 } 537 538 public void testGetQueryParameterWorkaround() { 539 // This was a workaround for a bug where getQueryParameter called 540 // getQuery() instead of getEncodedQuery(). 541 String nestedUrl = "http://crazybob.org/?a=1&b=2"; 542 Uri uri = Uri.parse("http://test/").buildUpon() 543 .appendQueryParameter("foo", "bar") 544 .appendQueryParameter("nested", Uri.encode(nestedUrl)).build(); 545 assertEquals(nestedUrl, Uri.decode(uri.getQueryParameter("nested"))); 546 assertEquals(nestedUrl, 547 Uri.decode(uri.getQueryParameters("nested").get(0))); 548 } 549 550 public void testGetQueryParameterEdgeCases() { 551 Uri uri; 552 553 // key at beginning of URL 554 uri = Uri.parse("http://test/").buildUpon() 555 .appendQueryParameter("key", "a b") 556 .appendQueryParameter("keya", "c d") 557 .appendQueryParameter("bkey", "e f") 558 .build(); 559 assertEquals("a b", uri.getQueryParameter("key")); 560 561 // key in middle of URL 562 uri = Uri.parse("http://test/").buildUpon() 563 .appendQueryParameter("akeyb", "a b") 564 .appendQueryParameter("keya", "c d") 565 .appendQueryParameter("key", "e f") 566 .appendQueryParameter("bkey", "g h") 567 .build(); 568 assertEquals("e f", uri.getQueryParameter("key")); 569 570 // key at end of URL 571 uri = Uri.parse("http://test/").buildUpon() 572 .appendQueryParameter("akeyb", "a b") 573 .appendQueryParameter("keya", "c d") 574 .appendQueryParameter("key", "y z") 575 .build(); 576 assertEquals("y z", uri.getQueryParameter("key")); 577 } 578} 579