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 
    192     @SmallTest
    193     public void testBuildUponOpaqueUri() {
    194         Uri a = Uri.fromParts("foo", "bar", "tee");
    195         Uri b = a.buildUpon().fragment("new").build();
    196         assertEquals("new", b.getFragment());
    197         assertEquals("bar", b.getSchemeSpecificPart());
    198         assertEquals("foo", b.getScheme());
    199     }
    200 
    201     @SmallTest
    202     public void testBuildUponEncodedOpaqueUri() {
    203         Uri a = new Uri.Builder()
    204                 .scheme("foo")
    205                 .encodedOpaquePart("bar")
    206                 .fragment("tee")
    207                 .build();
    208         Uri b = a.buildUpon().fragment("new").build();
    209         assertEquals("new", b.getFragment());
    210         assertEquals("bar", b.getSchemeSpecificPart());
    211         assertEquals("foo", b.getScheme());
    212     }
    213 
    214     @SmallTest
    215     public void testPathSegmentDecoding() {
    216         Uri uri = Uri.parse("foo://bar/a%20a/b%20b");
    217         assertEquals("a a", uri.getPathSegments().get(0));
    218         assertEquals("b b", uri.getPathSegments().get(1));
    219     }
    220 
    221     @SmallTest
    222     public void testSms() {
    223         Uri base = Uri.parse("content://sms");
    224         Uri appended = base.buildUpon()
    225                 .appendEncodedPath("conversations/addr=555-1212")
    226                 .build();
    227         assertEquals("content://sms/conversations/addr=555-1212",
    228                 appended.toString());
    229         assertEquals(2, appended.getPathSegments().size());
    230         assertEquals("conversations", appended.getPathSegments().get(0));
    231         assertEquals("addr=555-1212", appended.getPathSegments().get(1));
    232     }
    233 
    234     @SmallTest
    235     public void testEncodeWithAllowedChars() {
    236         String encoded = Uri.encode("Bob:/", "/");
    237         assertEquals(-1, encoded.indexOf(':'));
    238         assertTrue(encoded.indexOf('/') > -1);
    239     }
    240 
    241     @SmallTest
    242     public void testEncodeDecode() {
    243         code(null);
    244         code("");
    245         code("Bob");
    246         code(":Bob");
    247         code("::Bob");
    248         code("Bob::Lee");
    249         code("Bob:Lee");
    250         code("Bob::");
    251         code("Bob:");
    252         code("::Bob::");
    253     }
    254 
    255     private void code(String s) {
    256         assertEquals(s, Uri.decode(Uri.encode(s, null)));
    257     }
    258 
    259     @SmallTest
    260     public void testFile() {
    261         File f = new File("/tmp/bob");
    262 
    263         Uri uri = Uri.fromFile(f);
    264 
    265         assertEquals("file:///tmp/bob", uri.toString());
    266     }
    267 
    268     @SmallTest
    269     public void testQueryParameters() {
    270         Uri uri = Uri.parse("content://user");
    271 
    272         assertEquals(null, uri.getQueryParameter("a"));
    273 
    274         uri = uri.buildUpon().appendQueryParameter("a", "b").build();
    275 
    276         assertEquals("b", uri.getQueryParameter("a"));
    277 
    278         uri = uri.buildUpon().appendQueryParameter("a", "b2").build();
    279 
    280         assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a"));
    281 
    282         uri = uri.buildUpon().appendQueryParameter("c", "d").build();
    283 
    284         assertEquals(Arrays.asList("b", "b2"), uri.getQueryParameters("a"));
    285         assertEquals("d", uri.getQueryParameter("c"));
    286     }
    287 
    288     // http://b/2337042
    289     @SmallTest
    290     public void testHostWithTrailingDot() {
    291         Uri uri = Uri.parse("http://google.com./b/c/g");
    292         assertEquals("google.com.", uri.getHost());
    293         assertEquals("/b/c/g", uri.getPath());
    294     }
    295 
    296     @SmallTest
    297     public void testSchemeOnly() {
    298         Uri uri = Uri.parse("empty:");
    299         assertEquals("empty", uri.getScheme());
    300         assertTrue(uri.isAbsolute());
    301         assertNull(uri.getPath());
    302     }
    303 
    304     @SmallTest
    305     public void testEmptyPath() {
    306         Uri uri = Uri.parse("content://user");
    307         assertEquals(0, uri.getPathSegments().size());
    308     }
    309 
    310     @SmallTest
    311     public void testPathOperations() {
    312         Uri uri = Uri.parse("content://user/a/b");
    313 
    314         assertEquals(2, uri.getPathSegments().size());
    315         assertEquals("b", uri.getLastPathSegment());
    316 
    317         Uri first = uri;
    318         uri = uri.buildUpon().appendPath("c").build();
    319 
    320         assertEquals(3, uri.getPathSegments().size());
    321         assertEquals("c", uri.getLastPathSegment());
    322         assertEquals("content://user/a/b/c", uri.toString());
    323 
    324         uri = ContentUris.withAppendedId(uri, 100);
    325 
    326         assertEquals(4, uri.getPathSegments().size());
    327         assertEquals("100", uri.getLastPathSegment());
    328         assertEquals(100, ContentUris.parseId(uri));
    329         assertEquals("content://user/a/b/c/100", uri.toString());
    330 
    331         // Make sure the original URI is still intact.
    332         assertEquals(2, first.getPathSegments().size());
    333         assertEquals("b", first.getLastPathSegment());
    334 
    335         try {
    336             first.getPathSegments().get(2);
    337             fail();
    338         } catch (IndexOutOfBoundsException e) {}
    339 
    340         assertEquals(null, Uri.EMPTY.getLastPathSegment());
    341 
    342         Uri withC = Uri.parse("foo:/a/b/").buildUpon().appendPath("c").build();
    343         assertEquals("/a/b/c", withC.getPath());
    344     }
    345 
    346     @SmallTest
    347     public void testOpaqueUri() {
    348         Uri uri = Uri.parse("mailto:nobody");
    349         testOpaqueUri(uri);
    350 
    351         uri = uri.buildUpon().build();
    352         testOpaqueUri(uri);
    353 
    354         uri = Uri.fromParts("mailto", "nobody", null);
    355         testOpaqueUri(uri);
    356 
    357         uri = uri.buildUpon().build();
    358         testOpaqueUri(uri);
    359 
    360         uri = new Uri.Builder()
    361                 .scheme("mailto")
    362                 .opaquePart("nobody")
    363                 .build();
    364         testOpaqueUri(uri);
    365 
    366         uri = uri.buildUpon().build();
    367         testOpaqueUri(uri);
    368     }
    369 
    370     private void testOpaqueUri(Uri uri) {
    371         assertEquals("mailto", uri.getScheme());
    372         assertEquals("nobody", uri.getSchemeSpecificPart());
    373         assertEquals("nobody", uri.getEncodedSchemeSpecificPart());
    374 
    375         assertNull(uri.getFragment());
    376         assertTrue(uri.isAbsolute());
    377         assertTrue(uri.isOpaque());
    378         assertFalse(uri.isRelative());
    379         assertFalse(uri.isHierarchical());
    380 
    381         assertNull(uri.getAuthority());
    382         assertNull(uri.getEncodedAuthority());
    383         assertNull(uri.getPath());
    384         assertNull(uri.getEncodedPath());
    385         assertNull(uri.getUserInfo());
    386         assertNull(uri.getEncodedUserInfo());
    387         assertNull(uri.getQuery());
    388         assertNull(uri.getEncodedQuery());
    389         assertNull(uri.getHost());
    390         assertEquals(-1, uri.getPort());
    391 
    392         assertTrue(uri.getPathSegments().isEmpty());
    393         assertNull(uri.getLastPathSegment());
    394 
    395         assertEquals("mailto:nobody", uri.toString());
    396 
    397         Uri withFragment = uri.buildUpon().fragment("top").build();
    398         assertEquals("mailto:nobody#top", withFragment.toString());
    399     }
    400 
    401     @SmallTest
    402     public void testHierarchicalUris() {
    403         testHierarchical("http", "google.com", "/p1/p2", "query", "fragment");
    404         testHierarchical("file", null, "/p1/p2", null, null);
    405         testHierarchical("content", "contact", "/p1/p2", null, null);
    406         testHierarchical("http", "google.com", "/p1/p2", null, "fragment");
    407         testHierarchical("http", "google.com", "", null, "fragment");
    408         testHierarchical("http", "google.com", "", "query", "fragment");
    409         testHierarchical("http", "google.com", "", "query", null);
    410         testHierarchical("http", null, "/", "query", null);
    411     }
    412 
    413     private static void testHierarchical(String scheme, String authority,
    414             String path, String query, String fragment) {
    415         StringBuilder sb = new StringBuilder();
    416 
    417         if (authority != null) {
    418             sb.append("//").append(authority);
    419         }
    420         if (path != null) {
    421             sb.append(path);
    422         }
    423         if (query != null) {
    424             sb.append('?').append(query);
    425         }
    426 
    427         String ssp = sb.toString();
    428 
    429         if (scheme != null) {
    430             sb.insert(0, scheme + ":");
    431         }
    432         if (fragment != null) {
    433             sb.append('#').append(fragment);
    434         }
    435 
    436         String uriString = sb.toString();
    437 
    438         Uri uri = Uri.parse(uriString);
    439 
    440         // Run these twice to test caching.
    441         compareHierarchical(
    442                 uriString, ssp, uri, scheme, authority, path, query, fragment);
    443         compareHierarchical(
    444                 uriString, ssp, uri, scheme, authority, path, query, fragment);
    445 
    446         // Test rebuilt version.
    447         uri = uri.buildUpon().build();
    448 
    449         // Run these twice to test caching.
    450         compareHierarchical(
    451                 uriString, ssp, uri, scheme, authority, path, query, fragment);
    452         compareHierarchical(
    453                 uriString, ssp, uri, scheme, authority, path, query, fragment);
    454 
    455         // The decoded and encoded versions of the inputs are all the same.
    456         // We'll test the actual encoding decoding separately.
    457 
    458         // Test building with encoded versions.
    459         Uri built = new Uri.Builder()
    460                 .scheme(scheme)
    461                 .encodedAuthority(authority)
    462                 .encodedPath(path)
    463                 .encodedQuery(query)
    464                 .encodedFragment(fragment)
    465                 .build();
    466 
    467         compareHierarchical(
    468                 uriString, ssp, built, scheme, authority, path, query, fragment);
    469         compareHierarchical(
    470                 uriString, ssp, built, scheme, authority, path, query, fragment);
    471 
    472         // Test building with decoded versions.
    473         built = new Uri.Builder()
    474                 .scheme(scheme)
    475                 .authority(authority)
    476                 .path(path)
    477                 .query(query)
    478                 .fragment(fragment)
    479                 .build();
    480 
    481         compareHierarchical(
    482                 uriString, ssp, built, scheme, authority, path, query, fragment);
    483         compareHierarchical(
    484                 uriString, ssp, built, scheme, authority, path, query, fragment);
    485 
    486         // Rebuild.
    487         built = built.buildUpon().build();
    488 
    489         compareHierarchical(
    490                 uriString, ssp, built, scheme, authority, path, query, fragment);
    491         compareHierarchical(
    492                 uriString, ssp, built, scheme, authority, path, query, fragment);
    493     }
    494 
    495     private static void compareHierarchical(String uriString, String ssp,
    496             Uri uri,
    497             String scheme, String authority, String path, String query,
    498             String fragment) {
    499         assertEquals(scheme, uri.getScheme());
    500         assertEquals(authority, uri.getAuthority());
    501         assertEquals(authority, uri.getEncodedAuthority());
    502         assertEquals(path, uri.getPath());
    503         assertEquals(path, uri.getEncodedPath());
    504         assertEquals(query, uri.getQuery());
    505         assertEquals(query, uri.getEncodedQuery());
    506         assertEquals(fragment, uri.getFragment());
    507         assertEquals(fragment, uri.getEncodedFragment());
    508         assertEquals(ssp, uri.getSchemeSpecificPart());
    509 
    510         if (scheme != null) {
    511             assertTrue(uri.isAbsolute());
    512             assertFalse(uri.isRelative());
    513         } else {
    514             assertFalse(uri.isAbsolute());
    515             assertTrue(uri.isRelative());
    516         }
    517 
    518         assertFalse(uri.isOpaque());
    519         assertTrue(uri.isHierarchical());
    520 
    521         assertEquals(uriString, uri.toString());
    522     }
    523 
    524     public void testEmptyToStringNotNull() {
    525         assertNotNull(Uri.EMPTY.toString());
    526     }
    527 
    528     @SmallTest
    529     public void testParcellingWithoutFragment() {
    530         parcelAndUnparcel(Uri.parse("foo:bob%20lee"));
    531         parcelAndUnparcel(Uri.fromParts("foo", "bob lee", "fragment"));
    532         parcelAndUnparcel(new Uri.Builder()
    533             .scheme("http")
    534             .authority("crazybob.org")
    535             .path("/rss/")
    536             .encodedQuery("a=b")
    537             .build());
    538     }
    539 
    540     public void testGetQueryParameter() {
    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", nestedUrl).build();
    545         assertEquals(nestedUrl, uri.getQueryParameter("nested"));
    546         assertEquals(nestedUrl, uri.getQueryParameters("nested").get(0));
    547     }
    548 
    549     public void testGetQueryParameterWorkaround() {
    550         // This was a workaround for a bug where getQueryParameter called
    551         // getQuery() instead of getEncodedQuery().
    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", Uri.encode(nestedUrl)).build();
    556         assertEquals(nestedUrl, Uri.decode(uri.getQueryParameter("nested")));
    557         assertEquals(nestedUrl,
    558                 Uri.decode(uri.getQueryParameters("nested").get(0)));
    559     }
    560 
    561     public void testGetQueryParameterEdgeCases() {
    562         Uri uri;
    563 
    564         // key at beginning of URL
    565         uri = Uri.parse("http://test/").buildUpon()
    566             .appendQueryParameter("key", "a b")
    567             .appendQueryParameter("keya", "c d")
    568             .appendQueryParameter("bkey", "e f")
    569             .build();
    570         assertEquals("a b", uri.getQueryParameter("key"));
    571 
    572         // key in middle of URL
    573         uri = Uri.parse("http://test/").buildUpon()
    574             .appendQueryParameter("akeyb", "a b")
    575             .appendQueryParameter("keya", "c d")
    576             .appendQueryParameter("key", "e f")
    577             .appendQueryParameter("bkey", "g h")
    578             .build();
    579         assertEquals("e f", uri.getQueryParameter("key"));
    580 
    581         // key at end of URL
    582         uri = Uri.parse("http://test/").buildUpon()
    583             .appendQueryParameter("akeyb", "a b")
    584             .appendQueryParameter("keya", "c d")
    585             .appendQueryParameter("key", "y z")
    586             .build();
    587         assertEquals("y z", uri.getQueryParameter("key"));
    588 
    589         // key is a substring of parameters, but not present
    590         uri = Uri.parse("http://test/").buildUpon()
    591             .appendQueryParameter("akeyb", "a b")
    592             .appendQueryParameter("keya", "c d")
    593             .appendQueryParameter("bkey", "e f")
    594             .build();
    595         assertNull(uri.getQueryParameter("key"));
    596 
    597         // key is a prefix or suffix of the query
    598         uri = Uri.parse("http://test/?qq=foo");
    599         assertNull(uri.getQueryParameter("q"));
    600         assertNull(uri.getQueryParameter("oo"));
    601 
    602         // escaped keys
    603         uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d=");
    604         assertEquals("foo", uri.getQueryParameter("a b"));
    605         assertEquals("", uri.getQueryParameter("c d"));
    606         assertNull(uri.getQueryParameter("e f"));
    607         assertNull(uri.getQueryParameter("b"));
    608         assertNull(uri.getQueryParameter("c"));
    609         assertNull(uri.getQueryParameter(" d"));
    610 
    611         // empty values
    612         uri = Uri.parse("http://www.google.com/?a=&b=&&c=");
    613         assertEquals("", uri.getQueryParameter("a"));
    614         assertEquals("", uri.getQueryParameter("b"));
    615         assertEquals("", uri.getQueryParameter("c"));
    616     }
    617 
    618     public void testGetQueryParameterEmptyKey() {
    619         Uri uri = Uri.parse("http://www.google.com/?=b");
    620         assertEquals("b", uri.getQueryParameter(""));
    621     }
    622 
    623     public void testGetQueryParameterEmptyKey2() {
    624       Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d");
    625       assertEquals("", uri.getQueryParameter(""));
    626     }
    627 
    628     public void testGetQueryParameterEmptyKey3() {
    629       Uri uri = Uri.parse("http://www.google.com?");
    630       assertEquals("", uri.getQueryParameter(""));
    631     }
    632 
    633     public void testGetQueryParameterEmptyKey4() {
    634       Uri uri = Uri.parse("http://www.google.com?a=b&");
    635       assertEquals("", uri.getQueryParameter(""));
    636     }
    637 
    638     public void testGetQueryParametersEmptyKey() {
    639         Uri uri = Uri.parse("http://www.google.com/?=b&");
    640         List<String> values = uri.getQueryParameters("");
    641         assertEquals(2, values.size());
    642         assertEquals("b", values.get(0));
    643         assertEquals("", values.get(1));
    644     }
    645 
    646     public void testGetQueryParametersEmptyKey2() {
    647         Uri uri = Uri.parse("http://www.google.com?");
    648         List<String> values = uri.getQueryParameters("");
    649         assertEquals(1, values.size());
    650         assertEquals("", values.get(0));
    651     }
    652 
    653     public void testGetQueryParametersEmptyKey3() {
    654       Uri uri = Uri.parse("http://www.google.com/?a=b&&c=d");
    655       List<String> values = uri.getQueryParameters("");
    656       assertEquals(1, values.size());
    657       assertEquals("", values.get(0));
    658     }
    659 
    660     public void testGetQueryParameterNames() {
    661         Uri uri = Uri.parse("http://test?a=1");
    662         Set<String> names = uri.getQueryParameterNames();
    663         assertEquals(1, names.size());
    664         assertEquals("a", names.iterator().next());
    665     }
    666 
    667     public void testGetQueryParameterNamesEmptyKey() {
    668         Uri uri = Uri.parse("http://www.google.com/?a=x&&c=z");
    669         Set<String> names = uri.getQueryParameterNames();
    670         Iterator<String> iter = names.iterator();
    671         assertEquals(3, names.size());
    672         assertEquals("a", iter.next());
    673         assertEquals("", iter.next());
    674         assertEquals("c", iter.next());
    675     }
    676 
    677     public void testGetQueryParameterNamesEmptyKey2() {
    678         Uri uri = Uri.parse("http://www.google.com/?a=x&=d&c=z");
    679         Set<String> names = uri.getQueryParameterNames();
    680         Iterator<String> iter = names.iterator();
    681         assertEquals(3, names.size());
    682         assertEquals("a", iter.next());
    683         assertEquals("", iter.next());
    684         assertEquals("c", iter.next());
    685     }
    686 
    687     public void testGetQueryParameterNamesEmptyValues() {
    688         Uri uri = Uri.parse("http://www.google.com/?a=foo&b=&c=");
    689         Set<String> names = uri.getQueryParameterNames();
    690         Iterator<String> iter = names.iterator();
    691         assertEquals(3, names.size());
    692         assertEquals("a", iter.next());
    693         assertEquals("b", iter.next());
    694         assertEquals("c", iter.next());
    695     }
    696 
    697     public void testGetQueryParameterNamesEdgeCases() {
    698         Uri uri = Uri.parse("http://foo?a=bar&b=bar&c=&&d=baz&e&f&g=buzz&&&a&b=bar&h");
    699         Set<String> names = uri.getQueryParameterNames();
    700         Iterator<String> iter = names.iterator();
    701         assertEquals(9, names.size());
    702         assertEquals("a", iter.next());
    703         assertEquals("b", iter.next());
    704         assertEquals("c", iter.next());
    705         assertEquals("", iter.next());
    706         assertEquals("d", iter.next());
    707         assertEquals("e", iter.next());
    708         assertEquals("f", iter.next());
    709         assertEquals("g", iter.next());
    710         assertEquals("h", iter.next());
    711     }
    712 
    713     public void testGetQueryParameterNamesEscapedKeys() {
    714         Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d=");
    715         Set<String> names = uri.getQueryParameterNames();
    716         assertEquals(2, names.size());
    717         Iterator<String> iter = names.iterator();
    718         assertEquals("a b", iter.next());
    719         assertEquals("c d", iter.next());
    720     }
    721 
    722     public void testGetQueryParameterEscapedKeys() {
    723         Uri uri = Uri.parse("http://www.google.com/?a%20b=foo&c%20d=");
    724         String value = uri.getQueryParameter("a b");
    725         assertEquals("foo", value);
    726     }
    727 
    728     public void testClearQueryParameters() {
    729         Uri uri = Uri.parse("http://www.google.com/?a=x&b=y&c=z").buildUpon()
    730             .clearQuery().appendQueryParameter("foo", "bar").build();
    731         Set<String> names = uri.getQueryParameterNames();
    732         assertEquals(1, names.size());
    733         assertEquals("foo", names.iterator().next());
    734     }
    735 
    736     /**
    737      * Query parameters may omit the '='. http://b/3124097
    738      */
    739     public void testGetQueryParametersEmptyValue() {
    740         assertEquals(Arrays.asList(""),
    741                 Uri.parse("http://foo/path?abc").getQueryParameters("abc"));
    742         assertEquals(Arrays.asList(""),
    743                 Uri.parse("http://foo/path?foo=bar&abc").getQueryParameters("abc"));
    744         assertEquals(Arrays.asList(""),
    745                 Uri.parse("http://foo/path?abcd=abc&abc").getQueryParameters("abc"));
    746         assertEquals(Arrays.asList("a", "", ""),
    747                 Uri.parse("http://foo/path?abc=a&abc=&abc").getQueryParameters("abc"));
    748         assertEquals(Arrays.asList("a", "", ""),
    749                 Uri.parse("http://foo/path?abc=a&abc=&abc=").getQueryParameters("abc"));
    750     }
    751 
    752     // http://code.google.com/p/android/issues/detail?id=21064
    753     public void testPlusCharacterInQuery() {
    754         assertEquals("d e", Uri.parse("http://a/b?c=d%20e").getQueryParameter("c"));
    755         assertEquals("d e", Uri.parse("http://a/b?c=d+e").getQueryParameter("c"));
    756     }
    757 
    758     public void testPathPrefixMatch() {
    759         // Exact match
    760         assertTrue(Uri.parse("content://com.example/path").isPathPrefixMatch(
    761                 Uri.parse("content://com.example/path/")));
    762         assertTrue(Uri.parse("content://com.example/path").isPathPrefixMatch(
    763                 Uri.parse("content://com.example/path")));
    764         assertTrue(Uri.parse("content://com.example///path///").isPathPrefixMatch(
    765                 Uri.parse("content://com.example/path/")));
    766         assertTrue(Uri.parse("content://com.example/path").isPathPrefixMatch(
    767                 Uri.parse("content://com.example///path///")));
    768 
    769         // Child match
    770         assertTrue(Uri.parse("content://com.example/path/to/child").isPathPrefixMatch(
    771                 Uri.parse("content://com.example/path/")));
    772         assertTrue(Uri.parse("content://com.example/path/to/child").isPathPrefixMatch(
    773                 Uri.parse("content://com.example/path")));
    774 
    775         // Extra parameters
    776         assertTrue(Uri.parse("content://com.example/path#fragment").isPathPrefixMatch(
    777                 Uri.parse("content://com.example/path/")));
    778         assertTrue(Uri.parse("content://com.example/path?q=v").isPathPrefixMatch(
    779                 Uri.parse("content://com.example/path/")));
    780         assertTrue(Uri.parse("content://com.example/path/?q=v").isPathPrefixMatch(
    781                 Uri.parse("content://com.example/path/")));
    782 
    783         // Different path
    784         assertFalse(Uri.parse("content://com.example/path").isPathPrefixMatch(
    785                 Uri.parse("content://com.example/path/deeper/")));
    786         assertFalse(Uri.parse("content://com.example/path2").isPathPrefixMatch(
    787                 Uri.parse("content://com.example/path")));
    788 
    789         // Top-level match
    790         assertTrue(Uri.parse("content://com.example/path/").isPathPrefixMatch(
    791                 Uri.parse("content://com.example/")));
    792         assertTrue(Uri.parse("content://com.example/path/").isPathPrefixMatch(
    793                 Uri.parse("content://com.example")));
    794 
    795         // Different prefixes
    796         assertFalse(Uri.parse("content://com.example/path/").isPathPrefixMatch(
    797                 Uri.parse("file://com.example/path/")));
    798         assertFalse(Uri.parse("content://com.example/path/").isPathPrefixMatch(
    799                 Uri.parse("content://org.example/path/")));
    800 
    801         // Escaping
    802         assertTrue(Uri.parse("content://com.example/path path/").isPathPrefixMatch(
    803                 Uri.parse("content://com.example/path%20path/")));
    804         assertFalse(Uri.parse("content://com.example/path/path").isPathPrefixMatch(
    805                 Uri.parse("content://com.example/path%2Fpath")));
    806     }
    807 
    808     public void testToSafeString() {
    809         checkToSafeString("tel:xxxxxx", "tel:Google");
    810         checkToSafeString("tel:xxxxxxxxxx", "tel:1234567890");
    811         checkToSafeString("tEl:xxx.xxx-xxxx", "tEl:123.456-7890");
    812 
    813         checkToSafeString("sms:xxxxxx", "sms:123abc");
    814         checkToSafeString("smS:xxx.xxx-xxxx", "smS:123.456-7890");
    815 
    816         checkToSafeString("smsto:xxxxxx", "smsto:123abc");
    817         checkToSafeString("SMSTo:xxx.xxx-xxxx", "SMSTo:123.456-7890");
    818 
    819         checkToSafeString("mailto:xxxxxxx (at) xxxxxxx.xxx", "mailto:android (at) android.com");
    820         checkToSafeString("Mailto:xxxxxxx (at) xxxxxxx.xxxxxxxxxx",
    821                 "Mailto:android (at) android.com/secret");
    822 
    823         checkToSafeString("sip:xxxxxxx (at) xxxxxxx.xxxxxxxx", "sip:android (at) android.com:1234");
    824         checkToSafeString("sIp:xxxxxxx (at) xxxxxxx.xxx", "sIp:android (at) android.com");
    825 
    826         checkToSafeString("http://www.android.com/...", "http://www.android.com");
    827         checkToSafeString("HTTP://www.android.com/...", "HTTP://www.android.com");
    828         checkToSafeString("http://www.android.com/...", "http://www.android.com/");
    829         checkToSafeString("http://www.android.com/...", "http://www.android.com/secretUrl?param");
    830         checkToSafeString("http://www.android.com/...",
    831                 "http://user:pwd@www.android.com/secretUrl?param");
    832         checkToSafeString("http://www.android.com/...",
    833                 "http://user@www.android.com/secretUrl?param");
    834         checkToSafeString("http://www.android.com/...", "http://www.android.com/secretUrl?param");
    835         checkToSafeString("http:///...", "http:///path?param");
    836         checkToSafeString("http:///...", "http://");
    837         checkToSafeString("http://:12345/...", "http://:12345/");
    838 
    839         checkToSafeString("https://www.android.com/...", "https://www.android.com/secretUrl?param");
    840         checkToSafeString("https://www.android.com:8443/...",
    841                 "https://user:pwd@www.android.com:8443/secretUrl?param");
    842         checkToSafeString("https://www.android.com/...", "https://user:pwd@www.android.com");
    843         checkToSafeString("Https://www.android.com/...", "Https://user:pwd@www.android.com");
    844 
    845         checkToSafeString("ftp://ftp.android.com/...", "ftp://ftp.android.com/");
    846         checkToSafeString("ftP://ftp.android.com/...", "ftP://anonymous@ftp.android.com/");
    847         checkToSafeString("ftp://ftp.android.com:2121/...",
    848                 "ftp://root:love@ftp.android.com:2121/");
    849 
    850         checkToSafeString("unsupported://ajkakjah/askdha/secret?secret",
    851                 "unsupported://ajkakjah/askdha/secret?secret");
    852         checkToSafeString("unsupported:ajkakjah/askdha/secret?secret",
    853                 "unsupported:ajkakjah/askdha/secret?secret");
    854     }
    855 
    856     private void checkToSafeString(String expectedSafeString, String original) {
    857         assertEquals(expectedSafeString, Uri.parse(original).toSafeString());
    858     }
    859 }
    860