Home | History | Annotate | Download | only in net
      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 
     17 package android.net;
     18 
     19 import android.content.ContentUris;
     20 import android.os.Parcel;
     21 import android.test.suitebuilder.annotation.SmallTest;
     22 
     23 import junit.framework.TestCase;
     24 
     25 import java.io.File;
     26 import java.util.Arrays;
     27 import java.util.Iterator;
     28 import java.util.List;
     29 import java.util.Set;
     30 
     31 public class UriTest extends TestCase {
     32 
     33     @SmallTest
     34     public void testToStringWithPathOnly() {
     35         Uri.Builder builder = new Uri.Builder();
     36 
     37         // Not a valid path, but this came from a user's test case.
     38         builder.path("//foo");
     39         Uri uri = builder.build();
     40         assertEquals("//foo", uri.toString());
     41     }
     42 
     43     @SmallTest
     44     public void testParcelling() {
     45         parcelAndUnparcel(Uri.parse("foo:bob%20lee"));
     46         parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment"));
     47         parcelAndUnparcel(new Uri.Builder()
     48             .scheme("http")
     49             .authority("crazybob.org")
     50             .path("/rss/")
     51             .encodedQuery("a=b")
     52             .fragment("foo")
     53             .build());
     54     }
     55 
     56     private void parcelAndUnparcel(Uri u) {
     57         Parcel p = Parcel.obtain();
     58         try {
     59             Uri.writeToParcel(p, u);
     60             p.setDataPosition(0);
     61             assertEquals(u, Uri.CREATOR.createFromParcel(p));
     62 
     63             p.setDataPosition(0);
     64             u = u.buildUpon().build();
     65             Uri.writeToParcel(p, u);
     66             p.setDataPosition(0);
     67             assertEquals(u, Uri.CREATOR.createFromParcel(p));
     68         }
     69         finally {
     70             p.recycle();
     71         }
     72     }
     73 
     74     @SmallTest
     75     public void testBuildUponOpaqueStringUri() {
     76         Uri u = Uri.parse("bob:lee").buildUpon().scheme("robert").build();
     77         assertEquals("robert", u.getScheme());
     78         assertEquals("lee", u.getEncodedSchemeSpecificPart());
     79         assertEquals("lee", u.getSchemeSpecificPart());
     80         assertNull(u.getQuery());
     81         assertNull(u.getPath());
     82         assertNull(u.getAuthority());
     83         assertNull(u.getHost());
     84     }
     85 
     86     @SmallTest
     87     public void testStringUri() {
     88         assertEquals("bob lee",
     89                 Uri.parse("foo:bob%20lee").getSchemeSpecificPart());
     90         assertEquals("bob%20lee",
     91                 Uri.parse("foo:bob%20lee").getEncodedSchemeSpecificPart());
     92         assertEquals("/bob%20lee",
     93                 Uri.parse("foo:/bob%20lee").getEncodedPath());
     94         assertNull(Uri.parse("foo:bob%20lee").getPath());
     95         assertEquals("bob%20lee",
     96                 Uri.parse("foo:?bob%20lee").getEncodedQuery());
     97         assertNull(Uri.parse("foo:bar#?bob%20lee").getQuery());
     98         assertEquals("bob%20lee",
     99                 Uri.parse("foo:#bob%20lee").getEncodedFragment());
    100     }
    101 
    102     @SmallTest
    103     public void testStringUriIsHierarchical() {
    104         assertTrue(Uri.parse("bob").isHierarchical());
    105         assertFalse(Uri.parse("bob:").isHierarchical());
    106     }
    107 
    108     @SmallTest
    109     public void testNullUriString() {
    110         try {
    111             Uri.parse(null);
    112             fail();
    113         } catch (NullPointerException e) {}
    114     }
    115 
    116     @SmallTest
    117     public void testNullFile() {
    118         try {
    119             Uri.fromFile(null);
    120             fail();
    121         } catch (NullPointerException e) {}
    122     }
    123 
    124     @SmallTest
    125     public void testCompareTo() {
    126         Uri a = Uri.parse("foo:a");
    127         Uri b = Uri.parse("foo:b");
    128         Uri b2 = Uri.parse("foo:b");
    129 
    130         assertTrue(a.compareTo(b) < 0);
    131         assertTrue(b.compareTo(a) > 0);
    132         assertEquals(0, b.compareTo(b2));
    133     }
    134 
    135     @SmallTest
    136     public void testEqualsAndHashCode() {
    137 
    138         Uri a = Uri.parse("http://crazybob.org/test/?foo=bar#tee");
    139 
    140         Uri b = new Uri.Builder()
    141                 .scheme("http")
    142                 .authority("crazybob.org")
    143                 .path("/test/")
    144                 .encodedQuery("foo=bar")
    145                 .fragment("tee")
    146                 .build();
    147 
    148         // Try alternate builder methods.
    149         Uri c = new Uri.Builder()
    150                 .scheme("http")
    151                 .encodedAuthority("crazybob.org")
    152                 .encodedPath("/test/")
    153                 .encodedQuery("foo=bar")
    154                 .encodedFragment("tee")
    155                 .build();
    156 
    157         assertFalse(Uri.EMPTY.equals(null));
    158 
    159         assertEquals(a, b);
    160         assertEquals(b, c);
    161         assertEquals(c, a);
    162 
    163         assertEquals(a.hashCode(), b.hashCode());
    164         assertEquals(b.hashCode(), c.hashCode());
    165     }
    166 
    167     @SmallTest
    168     public void testAuthorityParsing() {
    169         Uri uri = Uri.parse("http://localhost:42");
    170         assertEquals("localhost", uri.getHost());
    171         assertEquals(42, uri.getPort());
    172 
    173         uri = Uri.parse("http://bob@localhost:42");
    174         assertEquals("bob", uri.getUserInfo());
    175         assertEquals("localhost", uri.getHost());
    176         assertEquals(42, uri.getPort());
    177 
    178         uri = Uri.parse("http://bob%20lee@localhost:42");
    179         assertEquals("bob lee", uri.getUserInfo());
    180         assertEquals("bob%20lee", uri.getEncodedUserInfo());
    181 
    182         uri = Uri.parse("http://bob%40lee%3ajr@local%68ost:4%32");
    183         assertEquals("bob@lee:jr", uri.getUserInfo());
    184         assertEquals("localhost", uri.getHost());
    185         assertEquals(42, uri.getPort());
    186 
    187         uri = Uri.parse("http://localhost");
    188         assertEquals("localhost", uri.getHost());
    189         assertEquals(-1, uri.getPort());
    190 
    191         uri = Uri.parse("http://a:a@example.com:a@example2.com/path");
    192         assertEquals("a:a (at) example.com:a (at) example2.com", uri.getAuthority());
    193         assertEquals("example2.com", uri.getHost());
    194         assertEquals(-1, uri.getPort());
    195         assertEquals("/path", uri.getPath());
    196 
    197         uri = Uri.parse("http://a.foo.com\\.example.com/path");
    198         assertEquals("a.foo.com", uri.getHost());
    199         assertEquals(-1, uri.getPort());
    200         assertEquals("\\.example.com/path", uri.getPath());
    201     }
    202 
    203     @SmallTest
    204     public void testBuildUponOpaqueUri() {
    205         Uri a = Uri.fromParts("foo", "bar", "tee");
    206         Uri b = a.buildUpon().fragment("new").build();
    207         assertEquals("new", b.getFragment());
    208         assertEquals("bar", b.getSchemeSpecificPart());
    209         assertEquals("foo", b.getScheme());
    210     }
    211 
    212     @SmallTest
    213     public void testBuildUponEncodedOpaqueUri() {
    214         Uri a = new Uri.Builder()
    215                 .scheme("foo")
    216                 .encodedOpaquePart("bar")
    217                 .fragment("tee")
    218                 .build();
    219         Uri b = a.buildUpon().fragment("new").build();
    220         assertEquals("new", b.getFragment());
    221         assertEquals("bar", b.getSchemeSpecificPart());
    222         assertEquals("foo", b.getScheme());
    223     }
    224 
    225     @SmallTest
    226     public void testPathSegmentDecoding() {
    227         Uri uri = Uri.parse("foo://bar/a%20a/b%20b");
    228         assertEquals("a a", uri.getPathSegments().get(0));
    229         assertEquals("b b", uri.getPathSegments().get(1));
    230     }
    231 
    232     @SmallTest
    233     public void testSms() {
    234         Uri base = Uri.parse("content://sms");
    235         Uri appended = base.buildUpon()
    236                 .appendEncodedPath("conversations/addr=555-1212")
    237                 .build();
    238         assertEquals("content://sms/conversations/addr=555-1212",
    239                 appended.toString());
    240         assertEquals(2, appended.getPathSegments().size());
    241         assertEquals("conversations", appended.getPathSegments().get(0));
    242         assertEquals("addr=555-1212", appended.getPathSegments().get(1));
    243     }
    244 
    245     @SmallTest
    246     public void testEncodeWithAllowedChars() {
    247         String encoded = Uri.encode("Bob:/", "/");
    248         assertEquals(-1, encoded.indexOf(':'));
    249         assertTrue(encoded.indexOf('/') > -1);
    250     }
    251 
    252     @SmallTest
    253     public void testEncodeDecode() {
    254         code(null);
    255         code("");
    256         code("Bob");
    257         code(":Bob");
    258         code("::Bob");
    259         code("Bob::Lee");
    260         code("Bob:Lee");
    261         code("Bob::");
    262         code("Bob:");
    263         code("::Bob::");
    264     }
    265 
    266     private void code(String s) {
    267         assertEquals(s, Uri.decode(Uri.encode(s, null)));
    268     }
    269 
    270     @SmallTest
    271     public void testFile() {
    272         File f = new File("/tmp/bob");
    273 
    274         Uri uri = Uri.fromFile(f);
    275 
    276         assertEquals("file:///tmp/bob", uri.toString());
    277     }
    278 
    279     @SmallTest
    280     public void testQueryParameters() {
    281         Uri uri = Uri.parse("content://user");
    282 
    283         assertEquals(null, uri.getQueryParameter("a"));
    284 
    285         uri = uri.buildUpon().appendQueryParameter("a", "b").build();
    286 
    287         assertEquals("b", uri.getQueryParameter("a"));
    288 
    289         uri = uri.buildUpon().appendQueryParameter("a", "b2").build();
    290 
    291         assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a"));
    292 
    293         uri = uri.buildUpon().appendQueryParameter("c", "d").build();
    294 
    295         assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a"));
    296         assertEquals("d", uri.getQueryParameter("c"));
    297     }
    298 
    299     // http://b/2337042
    300     @SmallTest
    301     public void testHostWithTrailingDot() {
    302         Uri uri = Uri.parse("http://google.com./b/c/g");
    303         assertEquals("google.com.", uri.getHost());
    304         assertEquals("/b/c/g", uri.getPath());
    305     }
    306 
    307     @SmallTest
    308     public void testSchemeOnly() {
    309         Uri uri = Uri.parse("empty:");
    310         assertEquals("empty", uri.getScheme());
    311         assertTrue(uri.isAbsolute());
    312         assertNull(uri.getPath());
    313     }
    314 
    315     @SmallTest
    316     public void testEmptyPath() {
    317         Uri uri = Uri.parse("content://user");
    318         assertEquals(0, uri.getPathSegments().size());
    319     }
    320 
    321     @SmallTest
    322     public void testPathOperations() {
    323         Uri uri = Uri.parse("content://user/a/b");
    324 
    325         assertEquals(2, uri.getPathSegments().size());
    326         assertEquals("b", uri.getLastPathSegment());
    327 
    328         Uri first = uri;
    329         uri = uri.buildUpon().appendPath("c").build();
    330 
    331         assertEquals(3, uri.getPathSegments().size());
    332         assertEquals("c", uri.getLastPathSegment());
    333         assertEquals("content://user/a/b/c", uri.toString());
    334 
    335         uri = ContentUris.withAppendedId(uri, 100);
    336 
    337         assertEquals(4, uri.getPathSegments().size());
    338         assertEquals("100", uri.getLastPathSegment());
    339         assertEquals(100, ContentUris.parseId(uri));
    340         assertEquals("content://user/a/b/c/100", uri.toString());
    341 
    342         // Make sure the original URI is still intact.
    343         assertEquals(2, first.getPathSegments().size());
    344         assertEquals("b", first.getLastPathSegment());
    345 
    346         try {
    347             first.getPathSegments().get(2);
    348             fail();
    349         } catch (IndexOutOfBoundsException e) {}
    350 
    351         assertEquals(null, Uri.EMPTY.getLastPathSegment());
    352 
    353         Uri withC = Uri.parse("foo:/a/b/").buildUpon().appendPath("c").build();
    354         assertEquals("/a/b/c", withC.getPath());
    355     }
    356 
    357     @SmallTest
    358     public void testOpaqueUri() {
    359         Uri uri = Uri.parse("mailto:nobody");
    360         testOpaqueUri(uri);
    361 
    362         uri = uri.buildUpon().build();
    363         testOpaqueUri(uri);
    364 
    365         uri = Uri.fromParts("mailto", "nobody", null);
    366         testOpaqueUri(uri);
    367 
    368         uri = uri.buildUpon().build();
    369         testOpaqueUri(uri);
    370 
    371         uri = new Uri.Builder()
    372                 .scheme("mailto")
    373                 .opaquePart("nobody")
    374                 .build();
    375         testOpaqueUri(uri);
    376 
    377         uri = uri.buildUpon().build();
    378         testOpaqueUri(uri);
    379     }
    380 
    381     private void testOpaqueUri(Uri uri) {
    382         assertEquals("mailto", uri.getScheme());
    383         assertEquals("nobody", uri.getSchemeSpecificPart());
    384         assertEquals("nobody", uri.getEncodedSchemeSpecificPart());
    385 
    386         assertNull(uri.getFragment());
    387         assertTrue(uri.isAbsolute());
    388         assertTrue(uri.isOpaque());
    389         assertFalse(uri.isRelative());
    390         assertFalse(uri.isHierarchical());
    391 
    392         assertNull(uri.getAuthority());
    393         assertNull(uri.getEncodedAuthority());
    394         assertNull(uri.getPath());
    395         assertNull(uri.getEncodedPath());
    396         assertNull(uri.getUserInfo());
    397         assertNull(uri.getEncodedUserInfo());
    398         assertNull(uri.getQuery());
    399         assertNull(uri.getEncodedQuery());
    400         assertNull(uri.getHost());
    401         assertEquals(-1, uri.getPort());
    402 
    403         assertTrue(uri.getPathSegments().isEmpty());
    404         assertNull(uri.getLastPathSegment());
    405 
    406         assertEquals("mailto:nobody", uri.toString());
    407 
    408         Uri withFragment = uri.buildUpon().fragment("top").build();
    409         assertEquals("mailto:nobody#top", withFragment.toString());
    410     }
    411 
    412     @SmallTest
    413     public void testHierarchicalUris() {
    414         testHierarchical("http", "google.com", "/p1/p2", "query", "fragment");
    415         testHierarchical("file", null, "/p1/p2", null, null);
    416         testHierarchical("content", "contact", "/p1/p2", null, null);
    417         testHierarchical("http", "google.com", "/p1/p2", null, "fragment");
    418         testHierarchical("http", "google.com", "", null, "fragment");
    419         testHierarchical("http", "google.com", "", "query", "fragment");
    420         testHierarchical("http", "google.com", "", "query", null);
    421         testHierarchical("http", null, "/", "query", null);
    422     }
    423 
    424     private static void testHierarchical(String scheme, String authority,
    425             String path, String query, String fragment) {
    426         StringBuilder sb = new StringBuilder();
    427 
    428         if (authority != null) {
    429             sb.append("//").append(authority);
    430         }
    431         if (path != null) {
    432             sb.append(path);
    433         }
    434         if (query != null) {
    435             sb.append('?').append(query);
    436         }
    437 
    438         String ssp = sb.toString();
    439 
    440         if (scheme != null) {
    441             sb.insert(0, scheme + ":");
    442         }
    443         if (fragment != null) {
    444             sb.append('#').append(fragment);
    445         }
    446 
    447         String uriString = sb.toString();
    448 
    449         Uri uri = Uri.parse(uriString);
    450 
    451         // Run these twice to test caching.
    452         compareHierarchical(
    453                 uriString, ssp, uri, scheme, authority, path, query, fragment);
    454         compareHierarchical(
    455                 uriString, ssp, uri, scheme, authority, path, query, fragment);
    456 
    457         // Test rebuilt version.
    458         uri = uri.buildUpon().build();
    459 
    460         // Run these twice to test caching.
    461         compareHierarchical(
    462                 uriString, ssp, uri, scheme, authority, path, query, fragment);
    463         compareHierarchical(
    464                 uriString, ssp, uri, scheme, authority, path, query, fragment);
    465 
    466         // The decoded and encoded versions of the inputs are all the same.
    467         // We'll test the actual encoding decoding separately.
    468 
    469         // Test building with encoded versions.
    470         Uri built = new Uri.Builder()
    471                 .scheme(scheme)
    472                 .encodedAuthority(authority)
    473                 .encodedPath(path)
    474                 .encodedQuery(query)
    475                 .encodedFragment(fragment)
    476                 .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         // Test building with decoded versions.
    484         built = new Uri.Builder()
    485                 .scheme(scheme)
    486                 .authority(authority)
    487                 .path(path)
    488                 .query(query)
    489                 .fragment(fragment)
    490                 .build();
    491 
    492         compareHierarchical(
    493                 uriString, ssp, built, scheme, authority, path, query, fragment);
    494         compareHierarchical(
    495                 uriString, ssp, built, scheme, authority, path, query, fragment);
    496 
    497         // Rebuild.
    498         built = built.buildUpon().build();
    499 
    500         compareHierarchical(
    501                 uriString, ssp, built, scheme, authority, path, query, fragment);
    502         compareHierarchical(
    503                 uriString, ssp, built, scheme, authority, path, query, fragment);
    504     }
    505 
    506     private static void compareHierarchical(String uriString, String ssp,
    507             Uri uri,
    508             String scheme, String authority, String path, String query,
    509             String fragment) {
    510         assertEquals(scheme, uri.getScheme());
    511         assertEquals(authority, uri.getAuthority());
    512         assertEquals(authority, uri.getEncodedAuthority());
    513         assertEquals(path, uri.getPath());
    514         assertEquals(path, uri.getEncodedPath());
    515         assertEquals(query, uri.getQuery());
    516         assertEquals(query, uri.getEncodedQuery());
    517         assertEquals(fragment, uri.getFragment());
    518         assertEquals(fragment, uri.getEncodedFragment());
    519         assertEquals(ssp, uri.getSchemeSpecificPart());
    520 
    521         if (scheme != null) {
    522             assertTrue(uri.isAbsolute());
    523             assertFalse(uri.isRelative());
    524         } else {
    525             assertFalse(uri.isAbsolute());
    526             assertTrue(uri.isRelative());
    527         }
    528 
    529         assertFalse(uri.isOpaque());
    530         assertTrue(uri.isHierarchical());
    531 
    532         assertEquals(uriString, uri.toString());
    533     }
    534 
    535     public void testEmptyToStringNotNull() {
    536         assertNotNull(Uri.EMPTY.toString());
    537     }
    538 
    539     @SmallTest
    540     public void testParcellingWithoutFragment() {
    541         parcelAndUnparcel(Uri.parse("foo:bob%20lee"));
    542         parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment"));
    543         parcelAndUnparcel(new Uri.Builder()
    544             .scheme("http")
    545             .authority("crazybob.org")
    546             .path("/rss/")
    547             .encodedQuery("a=b")
    548             .build());
    549     }
    550 
    551     public void testGetQueryParameter() {
    552         String nestedUrl = "http://crazybob.org/?a=1&b=2";
    553         Uri uri = Uri.parse("http://test/").buildUpon()
    554                 .appendQueryParameter("foo", "bar")
    555                 .appendQueryParameter("nested", nestedUrl).build();
    556         assertEquals(nestedUrl, uri.getQueryParameter("nested"));
    557         assertEquals(nestedUrl, uri.getQueryParameters("nested").get(0));
    558     }
    559 
    560     public void testGetQueryParameterWorkaround() {
    561         // This was a workaround for a bug where getQueryParameter called
    562         // getQuery() instead of getEncodedQuery().
    563         String nestedUrl = "http://crazybob.org/?a=1&b=2";
    564         Uri uri = Uri.parse("http://test/").buildUpon()
    565                 .appendQueryParameter("foo", "bar")
    566                 .appendQueryParameter("nested", Uri.encode(nestedUrl)).build();
    567         assertEquals(nestedUrl, Uri.decode(uri.getQueryParameter("nested")));
    568         assertEquals(nestedUrl,
    569                 Uri.decode(uri.getQueryParameters("nested").get(0)));
    570     }
    571 
    572     public void testGetQueryParameterEdgeCases() {
    573         Uri uri;
    574 
    575         // key at beginning of URL
    576         uri = Uri.parse("http://test/").buildUpon()
    577             .appendQueryParameter("key", "a b")
    578             .appendQueryParameter("keya", "c d")
    579             .appendQueryParameter("bkey", "e f")
    580             .build();
    581         assertEquals("a b", uri.getQueryParameter("key"));
    582 
    583         // key in middle of URL
    584         uri = Uri.parse("http://test/").buildUpon()
    585             .appendQueryParameter("akeyb", "a b")
    586             .appendQueryParameter("keya", "c d")
    587             .appendQueryParameter("key", "e f")
    588             .appendQueryParameter("bkey", "g h")
    589             .build();
    590         assertEquals("e f", uri.getQueryParameter("key"));
    591 
    592         // key at end of URL
    593         uri = Uri.parse("http://test/").buildUpon()
    594             .appendQueryParameter("akeyb", "a b")
    595             .appendQueryParameter("keya", "c d")
    596             .appendQueryParameter("key", "y z")
    597             .build();
    598         assertEquals("y z", uri.getQueryParameter("key"));
    599 
    600         // key is a substring of parameters, but not present
    601         uri = Uri.parse("http://test/").buildUpon()
    602             .appendQueryParameter("akeyb", "a b")
    603             .appendQueryParameter("keya", "c d")
    604             .appendQueryParameter("bkey", "e f")
    605             .build();
    606         assertNull(uri.getQueryParameter("key"));
    607 
    608         // key is a prefix or suffix of the query
    609         uri = Uri.parse("http://test/?qq=foo");
    610         assertNull(uri.getQueryParameter("q"));
    611         assertNull(uri.getQueryParameter("oo"));
    612 
    613         // escaped keys
    614         uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d=");
    615         assertEquals("foo", uri.getQueryParameter("a b"));
    616         assertEquals("", uri.getQueryParameter("c d"));
    617         assertNull(uri.getQueryParameter("e f"));
    618         assertNull(uri.getQueryParameter("b"));
    619         assertNull(uri.getQueryParameter("c"));
    620         assertNull(uri.getQueryParameter(" d"));
    621 
    622         // empty values
    623         uri = Uri.parse("http://www.google.com/?a=&b=&&c=");
    624         assertEquals("", uri.getQueryParameter("a"));
    625         assertEquals("", uri.getQueryParameter("b"));
    626         assertEquals("", uri.getQueryParameter("c"));
    627     }
    628 
    629     public void testGetQueryParameterEmptyKey() {
    630         Uri uri = Uri.parse("http://www.google.com/?=b");
    631         assertEquals("b", uri.getQueryParameter(""));
    632     }
    633 
    634     public void testGetQueryParameterEmptyKey2() {
    635       Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d");
    636       assertEquals("", uri.getQueryParameter(""));
    637     }
    638 
    639     public void testGetQueryParameterEmptyKey3() {
    640       Uri uri = Uri.parse("http://www.google.com?");
    641       assertEquals("", uri.getQueryParameter(""));
    642     }
    643 
    644     public void testGetQueryParameterEmptyKey4() {
    645       Uri uri = Uri.parse("http://www.google.com?a=b&");
    646       assertEquals("", uri.getQueryParameter(""));
    647     }
    648 
    649     public void testGetQueryParametersEmptyKey() {
    650         Uri uri = Uri.parse("http://www.google.com/?=b&");
    651         List<String> values = uri.getQueryParameters("");
    652         assertEquals(2, values.size());
    653         assertEquals("b", values.get(0));
    654         assertEquals("", values.get(1));
    655     }
    656 
    657     public void testGetQueryParametersEmptyKey2() {
    658         Uri uri = Uri.parse("http://www.google.com?");
    659         List<String> values = uri.getQueryParameters("");
    660         assertEquals(1, values.size());
    661         assertEquals("", values.get(0));
    662     }
    663 
    664     public void testGetQueryParametersEmptyKey3() {
    665       Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d");
    666       List<String> values = uri.getQueryParameters("");
    667       assertEquals(1, values.size());
    668       assertEquals("", values.get(0));
    669     }
    670 
    671     public void testGetQueryParameterNames() {
    672         Uri uri = Uri.parse("http://test?a=1");
    673         Set<String> names = uri.getQueryParameterNames();
    674         assertEquals(1, names.size());
    675         assertEquals("a", names.iterator().next());
    676     }
    677 
    678     public void testGetQueryParameterNamesEmptyKey() {
    679         Uri uri = Uri.parse("http://www.google.com/?a=x&&c=z");
    680         Set<String> names = uri.getQueryParameterNames();
    681         Iterator<String> iter = names.iterator();
    682         assertEquals(3, names.size());
    683         assertEquals("a", iter.next());
    684         assertEquals("", iter.next());
    685         assertEquals("c", iter.next());
    686     }
    687 
    688     public void testGetQueryParameterNamesEmptyKey2() {
    689         Uri uri = Uri.parse("http://www.google.com/?a=x&=d&c=z");
    690         Set<String> names = uri.getQueryParameterNames();
    691         Iterator<String> iter = names.iterator();
    692         assertEquals(3, names.size());
    693         assertEquals("a", iter.next());
    694         assertEquals("", iter.next());
    695         assertEquals("c", iter.next());
    696     }
    697 
    698     public void testGetQueryParameterNamesEmptyValues() {
    699         Uri uri = Uri.parse("http://www.google.com/?a=foo&b=&c=");
    700         Set<String> names = uri.getQueryParameterNames();
    701         Iterator<String> iter = names.iterator();
    702         assertEquals(3, names.size());
    703         assertEquals("a", iter.next());
    704         assertEquals("b", iter.next());
    705         assertEquals("c", iter.next());
    706     }
    707 
    708     public void testGetQueryParameterNamesEdgeCases() {
    709         Uri uri = Uri.parse("http://foo?a=bar&b=bar&c=&&d=baz&e&f&g=buzz&&&a&b=bar&h");
    710         Set<String> names = uri.getQueryParameterNames();
    711         Iterator<String> iter = names.iterator();
    712         assertEquals(9, names.size());
    713         assertEquals("a", iter.next());
    714         assertEquals("b", iter.next());
    715         assertEquals("c", iter.next());
    716         assertEquals("", iter.next());
    717         assertEquals("d", iter.next());
    718         assertEquals("e", iter.next());
    719         assertEquals("f", iter.next());
    720         assertEquals("g", iter.next());
    721         assertEquals("h", iter.next());
    722     }
    723 
    724     public void testGetQueryParameterNamesEscapedKeys() {
    725         Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d=");
    726         Set<String> names = uri.getQueryParameterNames();
    727         assertEquals(2, names.size());
    728         Iterator<String> iter = names.iterator();
    729         assertEquals("a b", iter.next());
    730         assertEquals("c d", iter.next());
    731     }
    732 
    733     public void testGetQueryParameterEscapedKeys() {
    734         Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d=");
    735         String value = uri.getQueryParameter("a b");
    736         assertEquals("foo", value);
    737     }
    738 
    739     public void testClearQueryParameters() {
    740         Uri uri = Uri.parse("http://www.google.com/?a=x&b=y&c=z").buildUpon()
    741             .clearQuery().appendQueryParameter("foo", "bar").build();
    742         Set<String> names = uri.getQueryParameterNames();
    743         assertEquals(1, names.size());
    744         assertEquals("foo", names.iterator().next());
    745     }
    746 
    747     /**
    748      * Query parameters may omit the '='. http://b/3124097
    749      */
    750     public void testGetQueryParametersEmptyValue() {
    751         assertEquals(Arrays.asList(""),
    752                 Uri.parse("http://foo/path?abc").getQueryParameters("abc"));
    753         assertEquals(Arrays.asList(""),
    754                 Uri.parse("http://foo/path?foo=bar&abc").getQueryParameters("abc"));
    755         assertEquals(Arrays.asList(""),
    756                 Uri.parse("http://foo/path?abcd=abc&abc").getQueryParameters("abc"));
    757         assertEquals(Arrays.asList("a", "", ""),
    758                 Uri.parse("http://foo/path?abc=a&abc=&abc").getQueryParameters("abc"));
    759         assertEquals(Arrays.asList("a", "", ""),
    760                 Uri.parse("http://foo/path?abc=a&abc=&abc=").getQueryParameters("abc"));
    761     }
    762 
    763     // http://code.google.com/p/android/issues/detail?id=21064
    764     public void testPlusCharacterInQuery() {
    765         assertEquals("d e", Uri.parse("http://a/b?c=d%20e").getQueryParameter("c"));
    766         assertEquals("d e", Uri.parse("http://a/b?c=d+e").getQueryParameter("c"));
    767     }
    768 
    769     public void testPathPrefixMatch() {
    770         // Exact match
    771         assertTrue(Uri.parse("content://com.example/path").isPathPrefixMatch(
    772                 Uri.parse("content://com.example/path/")));
    773         assertTrue(Uri.parse("content://com.example/path").isPathPrefixMatch(
    774                 Uri.parse("content://com.example/path")));
    775         assertTrue(Uri.parse("content://com.example///path///").isPathPrefixMatch(
    776                 Uri.parse("content://com.example/path/")));
    777         assertTrue(Uri.parse("content://com.example/path").isPathPrefixMatch(
    778                 Uri.parse("content://com.example///path///")));
    779 
    780         // Child match
    781         assertTrue(Uri.parse("content://com.example/path/to/child").isPathPrefixMatch(
    782                 Uri.parse("content://com.example/path/")));
    783         assertTrue(Uri.parse("content://com.example/path/to/child").isPathPrefixMatch(
    784                 Uri.parse("content://com.example/path")));
    785 
    786         // Extra parameters
    787         assertTrue(Uri.parse("content://com.example/path#fragment").isPathPrefixMatch(
    788                 Uri.parse("content://com.example/path/")));
    789         assertTrue(Uri.parse("content://com.example/path?q=v").isPathPrefixMatch(
    790                 Uri.parse("content://com.example/path/")));
    791         assertTrue(Uri.parse("content://com.example/path/?q=v").isPathPrefixMatch(
    792                 Uri.parse("content://com.example/path/")));
    793 
    794         // Different path
    795         assertFalse(Uri.parse("content://com.example/path").isPathPrefixMatch(
    796                 Uri.parse("content://com.example/path/deeper/")));
    797         assertFalse(Uri.parse("content://com.example/path2").isPathPrefixMatch(
    798                 Uri.parse("content://com.example/path")));
    799 
    800         // Top-level match
    801         assertTrue(Uri.parse("content://com.example/path/").isPathPrefixMatch(
    802                 Uri.parse("content://com.example/")));
    803         assertTrue(Uri.parse("content://com.example/path/").isPathPrefixMatch(
    804                 Uri.parse("content://com.example")));
    805 
    806         // Different prefixes
    807         assertFalse(Uri.parse("content://com.example/path/").isPathPrefixMatch(
    808                 Uri.parse("file://com.example/path/")));
    809         assertFalse(Uri.parse("content://com.example/path/").isPathPrefixMatch(
    810                 Uri.parse("content://org.example/path/")));
    811 
    812         // Escaping
    813         assertTrue(Uri.parse("content://com.example/path path/").isPathPrefixMatch(
    814                 Uri.parse("content://com.example/path%20path/")));
    815         assertFalse(Uri.parse("content://com.example/path/path").isPathPrefixMatch(
    816                 Uri.parse("content://com.example/path%2Fpath")));
    817     }
    818 
    819     public void testToSafeString() {
    820         checkToSafeString("tel:xxxxxx", "tel:Google");
    821         checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");
    822         checkToSafeString("tEl:xxx.xxx-xxxx", "tEl:123.456-7890");
    823 
    824         checkToSafeString("sms:xxxxxx", "sms:123abc");
    825         checkToSafeString("smS:xxx.xxx-xxxx", "smS:123.456-7890");
    826 
    827         checkToSafeString("smsto:xxxxxx", "smsto:123abc");
    828         checkToSafeString("SMSTo:xxx.xxx-xxxx", "SMSTo:123.456-7890");
    829 
    830         checkToSafeString("mailto:xxxxxxx (at) xxxxxxx.xxx", "mailto:android (at) android.com");
    831         checkToSafeString("Mailto:xxxxxxx (at) xxxxxxx.xxxxxxxxxx",
    832                 "Mailto:android (at) android.com/secret");
    833 
    834         checkToSafeString("sip:xxxxxxx (at) xxxxxxx.xxxxxxxx", "sip:android (at) android.com:1234");
    835         checkToSafeString("sIp:xxxxxxx (at) xxxxxxx.xxx", "sIp:android (at) android.com");
    836 
    837         checkToSafeString("http://www.android.com/...", "http://www.android.com");
    838         checkToSafeString("HTTP://www.android.com/...", "HTTP://www.android.com");
    839         checkToSafeString("http://www.android.com/...", "http://www.android.com/");
    840         checkToSafeString("http://www.android.com/...", "http://www.android.com/secretUrl?param");
    841         checkToSafeString("http://www.android.com/...",
    842                 "http://user:pwd@www.android.com/secretUrl?param");
    843         checkToSafeString("http://www.android.com/...",
    844                 "http://user@www.android.com/secretUrl?param");
    845         checkToSafeString("http://www.android.com/...", "http://www.android.com/secretUrl?param");
    846         checkToSafeString("http:///...", "http:///path?param");
    847         checkToSafeString("http:///...", "http://");
    848         checkToSafeString("http://:12345/...", "http://:12345/");
    849 
    850         checkToSafeString("https://www.android.com/...", "https://www.android.com/secretUrl?param");
    851         checkToSafeString("https://www.android.com:8443/...",
    852                 "https://user:pwd@www.android.com:8443/secretUrl?param");
    853         checkToSafeString("https://www.android.com/...", "https://user:pwd@www.android.com");
    854         checkToSafeString("Https://www.android.com/...", "Https://user:pwd@www.android.com");
    855 
    856         checkToSafeString("ftp://ftp.android.com/...", "ftp://ftp.android.com/");
    857         checkToSafeString("ftP://ftp.android.com/...", "ftP://anonymous@ftp.android.com/");
    858         checkToSafeString("ftp://ftp.android.com:2121/...",
    859                 "ftp://root:love@ftp.android.com:2121/");
    860 
    861         checkToSafeString("unsupported://ajkakjah/askdha/secret?secret",
    862                 "unsupported://ajkakjah/askdha/secret?secret");
    863         checkToSafeString("unsupported:ajkakjah/askdha/secret?secret",
    864                 "unsupported:ajkakjah/askdha/secret?secret");
    865     }
    866 
    867     private void checkToSafeString(String expectedSafeString, String original) {
    868         assertEquals(expectedSafeString, Uri.parse(original).toSafeString());
    869     }
    870 }
    871