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