| /* |
| * Copyright 2022 Google LLC |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.google.android.libraries.mobiledatadownload.file.common; |
| |
| import static com.google.common.truth.Truth.assertThat; |
| import static org.junit.Assert.assertThrows; |
| |
| import android.net.Uri; |
| import com.google.thirdparty.robolectric.GoogleRobolectricTestRunner; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| @RunWith(GoogleRobolectricTestRunner.class) |
| public final class FragmentTest { |
| |
| @Test |
| public void builder_empty() throws Exception { |
| Fragment.Builder fragment = Fragment.builder(); |
| assertThat(fragment.build().toString()).isEmpty(); |
| } |
| |
| @Test |
| public void parse_empty() throws Exception { |
| Fragment fragment = Fragment.parse(""); |
| assertThat(fragment.toString()).isEmpty(); |
| } |
| |
| @Test |
| public void parse_simpleParam() throws Exception { |
| Fragment fragment = Fragment.parse("simple=true"); |
| assertThat(fragment.toString()).isEqualTo("simple=true"); |
| assertThat(fragment.params().get(0).key()).isEqualTo("simple"); |
| } |
| |
| @Test |
| public void builder() throws Exception { |
| Fragment fragment = |
| Fragment.builder() |
| .addParam( |
| Fragment.Param.builder("paramKey") |
| .addValue( |
| Fragment.ParamValue.builder("paramValue") |
| .addSubParam("subparamKey", "subparamValue"))) |
| .build(); |
| |
| assertThat(fragment.toString()).isEqualTo("paramKey=paramValue(subparamKey=subparamValue)"); |
| } |
| |
| @Test |
| public void parse() throws Exception { |
| Fragment fragment = Fragment.parse("paramKey=paramValue(subparamKey=subparamValue)"); |
| |
| assertThat(fragment.toString()).isEqualTo("paramKey=paramValue(subparamKey=subparamValue)"); |
| |
| Fragment.Param param = fragment.params().get(0); |
| assertThat(param.key()).isEqualTo("paramKey"); |
| Fragment.ParamValue value = param.values().get(0); |
| assertThat(value.name()).isEqualTo("paramValue"); |
| Fragment.SubParam subparam = value.subParams().get(0); |
| assertThat(subparam.key()).isEqualTo("subparamKey"); |
| assertThat(subparam.value()).isEqualTo("subparamValue"); |
| } |
| |
| @Test |
| public void parse_multipleParamsAndsubParams() throws Exception { |
| Fragment fragment = Fragment.parse("k1=v1&k2=v2(sk1=sv1)&k3=v3(sk1=sv1,sk2=sv2,sk3)"); |
| |
| assertThat(fragment.toString()).isEqualTo("k1=v1&k2=v2(sk1=sv1)&k3=v3(sk1=sv1,sk2=sv2,sk3)"); |
| |
| Fragment.Param p1 = fragment.params().get(0); |
| assertThat(p1.key()).isEqualTo("k1"); |
| Fragment.ParamValue v1 = p1.values().get(0); |
| assertThat(v1.name()).isEqualTo("v1"); |
| assertThat(v1.subParams().size()).isEqualTo(0); |
| |
| Fragment.Param p2 = fragment.params().get(1); |
| assertThat(p2.key()).isEqualTo("k2"); |
| Fragment.ParamValue v2 = p2.values().get(0); |
| assertThat(v2.name()).isEqualTo("v2"); |
| assertThat(v2.subParams().size()).isEqualTo(1); |
| Fragment.SubParam p2s = v2.subParams().get(0); |
| assertThat(p2s.key()).isEqualTo("sk1"); |
| assertThat(p2s.value()).isEqualTo("sv1"); |
| |
| Fragment.Param p3 = fragment.params().get(2); |
| assertThat(p3.key()).isEqualTo("k3"); |
| Fragment.ParamValue v3 = p3.values().get(0); |
| assertThat(v3.name()).isEqualTo("v3"); |
| assertThat(v3.subParams().size()).isEqualTo(3); |
| Fragment.SubParam p3s1 = v3.subParams().get(0); |
| assertThat(p3s1.key()).isEqualTo("sk1"); |
| assertThat(p3s1.hasValue()).isTrue(); |
| assertThat(p3s1.value()).isEqualTo("sv1"); |
| Fragment.SubParam p3s2 = v3.subParams().get(1); |
| assertThat(p3s2.key()).isEqualTo("sk2"); |
| assertThat(p3s2.hasValue()).isTrue(); |
| assertThat(p3s2.value()).isEqualTo("sv2"); |
| Fragment.SubParam p3s3 = v3.subParams().get(2); |
| assertThat(p3s3.key()).isEqualTo("sk3"); |
| assertThat(p3s3.hasValue()).isFalse(); |
| assertThat(p3s3.value()).isNull(); |
| } |
| |
| @Test |
| public void builder_multipleValues() throws Exception { |
| Fragment fragment = |
| Fragment.builder() |
| .addParam("unset") |
| .addParam(Fragment.Param.builder("k1").addValue("v1")) |
| .addParam( |
| Fragment.Param.builder("k2") |
| .addValue("v2") |
| .addValue("v2a") |
| .addValue(Fragment.ParamValue.builder("v2b").addSubParam("sk1", "sv1"))) |
| .build(); |
| |
| assertThat(fragment.toString()).isEqualTo("k1=v1&k2=v2+v2a+v2b(sk1=sv1)"); |
| } |
| |
| @Test |
| public void builder_nestedMutation() throws Exception { |
| Fragment.Builder fragment = Fragment.parse("k0=v0a&k1=v1&k2=v2+v2a+v2b(sk1=sv1)").toBuilder(); |
| |
| fragment.findParam("k0").addValue("v0b"); |
| fragment.findParam("k1").findValue("v1").addSubParam("sk1", "sv1"); |
| fragment.findParam("k2").findValue("v2b").addSubParam("sk2", "sv2"); |
| |
| assertThat(fragment.build().toString()) |
| .isEqualTo("k0=v0a+v0b&k1=v1(sk1=sv1)&k2=v2+v2a+v2b(sk1=sv1,sk2=sv2)"); |
| } |
| |
| @Test |
| public void parse_multipleValues() throws Exception { |
| Fragment fragment = Fragment.parse("k0=v0&k1=v1&k2=v2+v2a+v2b(sk1=sv1)"); |
| |
| Fragment.Param p0 = fragment.params().get(0); |
| assertThat(p0.key()).isEqualTo("k0"); |
| Fragment.ParamValue v0 = p0.values().get(0); |
| assertThat(v0.name()).isEqualTo("v0"); |
| assertThat(v0.subParams().isEmpty()).isTrue(); |
| |
| Fragment.Param p1 = fragment.params().get(1); |
| assertThat(p1.key()).isEqualTo("k1"); |
| Fragment.ParamValue v1 = p1.values().get(0); |
| assertThat(v1.name()).isEqualTo("v1"); |
| assertThat(v1.subParams().isEmpty()).isTrue(); |
| |
| Fragment.Param p2 = fragment.params().get(2); |
| assertThat(p2.key()).isEqualTo("k2"); |
| Fragment.ParamValue v2 = p2.values().get(0); |
| assertThat(v2.name()).isEqualTo("v2"); |
| assertThat(v2.subParams().isEmpty()).isTrue(); |
| |
| Fragment.ParamValue v2a = p2.values().get(1); |
| assertThat(v2a.name()).isEqualTo("v2a"); |
| assertThat(v2a.subParams().isEmpty()).isTrue(); |
| |
| Fragment.ParamValue v2b = p2.values().get(2); |
| assertThat(v2b.name()).isEqualTo("v2b"); |
| assertThat(v2b.subParams().size()).isEqualTo(1); |
| Fragment.SubParam v2bs1 = v2b.subParams().get(0); |
| assertThat(v2bs1.key()).isEqualTo("sk1"); |
| assertThat(v2bs1.value()).isEqualTo("sv1"); |
| } |
| |
| @Test |
| public void parse_duplicateParams() throws Exception { |
| Fragment fragment = Fragment.parse("k=1&k=2"); |
| assertThat(fragment.params().get(0).values().get(0).name()).isEqualTo("2"); |
| } |
| |
| @Test |
| public void parse_duplicateParamValues() throws Exception { |
| Fragment fragment = Fragment.parse("k=1+1(x=y)"); |
| assertThat(fragment.params().get(0).values().get(0).findSubParamValue("x")).isEqualTo("y"); |
| } |
| |
| @Test |
| public void parse_duplicatesubParams() throws Exception { |
| Fragment fragment = Fragment.parse("k=1(x=y,x=z)"); |
| assertThat(fragment.params().get(0).values().get(0).findSubParamValue("x")).isEqualTo("z"); |
| } |
| |
| @Test |
| public void parse_duplicateUnsetSubParams() throws Exception { |
| Fragment fragment = Fragment.parse("k=1(x=y,x)"); |
| assertThat(fragment.params().get(0).values().get(0).findSubParam("x")).isNotNull(); |
| assertThat(fragment.params().get(0).values().get(0).findSubParam("x").hasValue()).isFalse(); |
| assertThat(fragment.params().get(0).values().get(0).findSubParamValue("x")).isNull(); |
| } |
| |
| @Test |
| public void parse_unsetSubParam() throws Exception { |
| Fragment fragment = Fragment.parse("p=v(sp1)"); |
| assertThat(fragment.findParam("p").findValue("v").findSubParam("sp1")).isNotNull(); |
| assertThat(fragment.findParam("p").findValue("v").findSubParam("sp1").hasValue()).isFalse(); |
| assertThat(fragment.findParam("p").findValue("v").findSubParamValue("sp1")).isNull(); |
| } |
| |
| @Test |
| public void roundTrip() throws Exception { |
| Fragment fragment = Fragment.parse("a=b&c=d(e=f,g=h,i=j)+e+f"); |
| |
| assertThat(fragment.toString()).isEqualTo("a=b&c=d(e=f,g=h,i=j)+e+f"); |
| } |
| |
| @Test |
| public void parse_illegal() throws Exception { |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("x")); |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("x=")); |
| |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("=")); |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("==")); |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("=x")); |
| |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("x=y(")); |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("x=y)")); |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("x=y()")); |
| |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("x=y(=)")); |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("x=y(==)")); |
| assertThrows(IllegalArgumentException.class, () -> Fragment.parse("x=y(=z)")); |
| } |
| |
| @Test |
| public void parse_weirdButNotIllegal() throws Exception { |
| // Unencoded chars gets encoded |
| assertThat(Fragment.parse(" =y").toString()).isEqualTo("+=y"); |
| assertThat(Fragment.parse(" x=y ").toString()).isEqualTo("+x=y+"); |
| assertThat(Fragment.parse("()=y").toString()).isEqualTo("%28%29=y"); |
| assertThat(Fragment.parse("x==y").toString()).isEqualTo("x=%3Dy"); |
| assertThat(Fragment.parse("x=y(z==)").toString()).isEqualTo("x=y(z=%3D)"); |
| |
| assertThat(Fragment.parse("x=y(z=)").toString()).isEqualTo("x=y(z)"); |
| assertThat(Fragment.parse("+=y").toString()).isEqualTo("+=y"); |
| assertThat(Fragment.parse("").toString()).isEmpty(); |
| assertThat(Fragment.parse((String) null).toString()).isEmpty(); |
| } |
| |
| @Test |
| public void build_escapingInvalidCharacters() throws Exception { |
| Fragment fragment = |
| Fragment.builder() |
| .addParam( |
| Fragment.Param.builder("m&m") |
| .addValue(Fragment.ParamValue.builder("2+2").addSubParam("k=", "(v)"))) |
| .build(); |
| assertThat(fragment.toString()).isEqualTo("m%26m=2%2B2(k%3D=%28v%29)"); |
| |
| Fragment roundtrip = Fragment.parse(fragment.toString()); |
| Fragment.Param mnm = roundtrip.params().get(0); |
| assertThat(mnm.key()).isEqualTo("m&m"); |
| Fragment.ParamValue twoptwo = mnm.values().get(0); |
| assertThat(twoptwo.name()).isEqualTo("2+2"); |
| Fragment.SubParam pqp = twoptwo.subParams().get(0); |
| assertThat(pqp.key()).isEqualTo("k="); |
| assertThat(pqp.value()).isEqualTo("(v)"); |
| } |
| |
| @Test |
| public void toBuilder_shouldMakeDefensiveCopy() throws Exception { |
| Fragment fragment = Fragment.parse("a=b(c=d)"); |
| Fragment.Builder fragmentBuilder = fragment.toBuilder(); |
| assertThat(fragment.toString()).isEqualTo("a=b(c=d)"); |
| assertThat(fragmentBuilder.build().toString()).isEqualTo("a=b(c=d)"); |
| |
| fragmentBuilder.addParam(Fragment.Param.builder("X").addValue("XX")); |
| fragmentBuilder.findParam("a").addValue("Y"); |
| fragmentBuilder.findParam("a").findValue("b").addSubParam("Z", "ZZ"); |
| |
| assertThat(fragment.toString()).isEqualTo("a=b(c=d)"); |
| assertThat(fragmentBuilder.build().toString()).isEqualTo("a=b(c=d,Z=ZZ)+Y&X=XX"); |
| } |
| |
| @Test |
| public void uri_withValidCharacters() throws Exception { |
| String encodedFragmentString = "a=b+c(d=e)"; |
| Uri uri = Uri.parse("a://b/c").buildUpon().encodedFragment(encodedFragmentString).build(); |
| assertThat(uri.toString()).isEqualTo("a://b/c#a=b+c(d=e)"); |
| assertThat(uri.getEncodedFragment()).isEqualTo(encodedFragmentString); |
| Fragment roundtrip = Fragment.parse(uri); |
| Fragment.Param a = roundtrip.params().get(0); |
| assertThat(a.key()).isEqualTo("a"); |
| Fragment.ParamValue b = a.values().get(0); |
| assertThat(b.name()).isEqualTo("b"); |
| Fragment.ParamValue c = a.values().get(1); |
| assertThat(c.name()).isEqualTo("c"); |
| Fragment.SubParam de = c.subParams().get(0); |
| assertThat(de.key()).isEqualTo("d"); |
| assertThat(de.value()).isEqualTo("e"); |
| } |
| |
| @Test |
| public void uri_withInvalidCharacters() throws Exception { |
| String encodedFragmentString = "m%26m=2%2B2(k%3D=%28v%29)"; |
| Uri uri = Uri.parse("a://b/c").buildUpon().encodedFragment(encodedFragmentString).build(); |
| assertThat(uri.toString()).isEqualTo("a://b/c#m%26m=2%2B2(k%3D=%28v%29)"); |
| assertThat(uri.getEncodedFragment()).isEqualTo(encodedFragmentString); |
| Fragment roundtrip = Fragment.parse(uri); |
| Fragment.Param mnm = roundtrip.params().get(0); |
| assertThat(mnm.key()).isEqualTo("m&m"); |
| Fragment.ParamValue twoptwo = mnm.values().get(0); |
| assertThat(twoptwo.name()).isEqualTo("2+2"); |
| Fragment.SubParam pqp = twoptwo.subParams().get(0); |
| assertThat(pqp.key()).isEqualTo("k="); |
| assertThat(pqp.value()).isEqualTo("(v)"); |
| } |
| } |