1 /*
2  * Copyright 2022 Google LLC
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 package com.google.android.libraries.mobiledatadownload.file.common.internal;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import android.net.Uri;
21 import com.google.android.libraries.mobiledatadownload.file.common.Fragment;
22 import com.google.common.collect.ImmutableList;
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.robolectric.RobolectricTestRunner;
26 
27 @RunWith(RobolectricTestRunner.class)
28 public final class LiteTransformFragmentsTest {
29 
30   @Test
parseAbsentTransformFragment_yieldsEmpty()31   public void parseAbsentTransformFragment_yieldsEmpty() throws Exception {
32     Uri uri = Uri.parse("scheme:path");
33     assertThat(LiteTransformFragments.parseTransformNames(uri)).isEmpty();
34   }
35 
36   @Test
parseEmptyTransformFragment_yieldsEmpty()37   public void parseEmptyTransformFragment_yieldsEmpty() throws Exception {
38     Uri uri = Uri.parse("scheme:path#");
39     assertThat(LiteTransformFragments.parseTransformNames(uri)).isEmpty();
40   }
41 
42   @Test
parseNonTransformFragment_yieldsEmpty()43   public void parseNonTransformFragment_yieldsEmpty() throws Exception {
44     Uri uri = Uri.parse("scheme:path#nontransform");
45     assertThat(LiteTransformFragments.parseTransformNames(uri)).isEmpty();
46   }
47 
48   @Test
parseSimpleTransformFragment_yieldsSpec()49   public void parseSimpleTransformFragment_yieldsSpec() throws Exception {
50     Uri uri = Uri.parse("scheme:path#transform=simple");
51     assertThat(LiteTransformFragments.parseTransformNames(uri)).containsExactly("simple");
52   }
53 
54   @Test
parseMixedTransformFragment_yieldsSpec()55   public void parseMixedTransformFragment_yieldsSpec() throws Exception {
56     Uri uri = Uri.parse("scheme:path#transform=M1X_d");
57     assertThat(LiteTransformFragments.parseTransformNames(uri)).containsExactly("M1X_d");
58   }
59 
60   @Test
parseEncodedTransformFragment_yieldsInvalidSpec()61   public void parseEncodedTransformFragment_yieldsInvalidSpec() throws Exception {
62     // Trailing "%3D" is ignored.
63     Uri uri = Uri.parse("scheme:path#transform=INVALID%3D");
64     assertThat(LiteTransformFragments.parseTransformNames(uri)).containsExactly("INVALID");
65   }
66 
67   @Test
parseTransformBeforeOtherFragment_yieldsSpec()68   public void parseTransformBeforeOtherFragment_yieldsSpec() throws Exception {
69     Uri uri = Uri.parse("scheme:path#transform=beforeother&other");
70     assertThat(LiteTransformFragments.parseTransformNames(uri)).containsExactly("beforeother");
71   }
72 
73   @Test
parseTransformAfterOtherFragment_yieldsEmpty()74   public void parseTransformAfterOtherFragment_yieldsEmpty() throws Exception {
75     Uri uri = Uri.parse("scheme:path#nontransform&transform=afterother");
76     assertThat(LiteTransformFragments.parseTransformNames(uri)).isEmpty();
77   }
78 
79   @Test
parseMultipleTransformFragments_yieldsAllSpecs()80   public void parseMultipleTransformFragments_yieldsAllSpecs() throws Exception {
81     Uri uri = Uri.parse("scheme:path#transform=first+second+third");
82     assertThat(LiteTransformFragments.parseTransformNames(uri))
83         .containsExactly("first", "second", "third");
84   }
85 
86   @Test
parseTransformFragmentWithSubparams_yieldsJustName()87   public void parseTransformFragmentWithSubparams_yieldsJustName() throws Exception {
88     Uri uri = Uri.parse("scheme:path#transform=withparams(foo=bar)");
89     assertThat(LiteTransformFragments.parseTransformNames(uri)).containsExactly("withparams");
90   }
91 
92   @Test
parseMultipleTransformFragmentsWithSubparams_yieldsAllNames()93   public void parseMultipleTransformFragmentsWithSubparams_yieldsAllNames() throws Exception {
94     Uri uri = Uri.parse("scheme:path#transform=first(foo=bar)+second(yada=yada,x=y)+third(xxx)");
95     assertThat(LiteTransformFragments.parseTransformNames(uri))
96         .containsExactly("first", "second", "third");
97   }
98 
99   @Test
parseTransformFragmentWithEncodedSubparams_yieldsJustName()100   public void parseTransformFragmentWithEncodedSubparams_yieldsJustName() throws Exception {
101     Uri uri = Uri.parse("scheme:path#transform=withencoded(k%3D=%28v%29)");
102     assertThat(LiteTransformFragments.parseTransformNames(uri)).containsExactly("withencoded");
103   }
104 
105   @Test
joinEmpty_yieldNil()106   public void joinEmpty_yieldNil() throws Exception {
107     String encodedFragment = LiteTransformFragments.joinTransformSpecs(ImmutableList.of());
108     assertThat(encodedFragment).isNull();
109 
110     // NOTE: Android Uri treats null as removing the fragment.
111     Uri uri = Uri.parse("scheme:path#REMOVED").buildUpon().encodedFragment(encodedFragment).build();
112     assertThat(uri.toString()).isEqualTo("scheme:path");
113   }
114 
115   @Test
joinSimple_yieldFragment()116   public void joinSimple_yieldFragment() throws Exception {
117     assertThat(LiteTransformFragments.joinTransformSpecs(ImmutableList.of("simple")))
118         .isEqualTo("transform=simple");
119   }
120 
121   @Test
joinMultiple_yieldFragment()122   public void joinMultiple_yieldFragment() throws Exception {
123     assertThat(LiteTransformFragments.joinTransformSpecs(ImmutableList.of("first", "second")))
124         .isEqualTo("transform=first+second");
125   }
126 
127   @Test
joinMultipleWithParams_yieldEncodedFragment()128   public void joinMultipleWithParams_yieldEncodedFragment() throws Exception {
129     String fragment =
130         LiteTransformFragments.joinTransformSpecs(
131             ImmutableList.of("first(foo=bar)", "second(k%3D=%28v%29)"));
132     assertThat(fragment).isEqualTo("transform=first(foo=bar)+second(k%3D=%28v%29)");
133     Uri uri = Uri.parse("scheme:path").buildUpon().encodedFragment(fragment).build();
134 
135     // Run it through the full fragment parser to ensure output is valid.
136     Fragment fullFragment = Fragment.parse(uri);
137     Fragment.Param transform = fullFragment.params().get(0);
138     assertThat(transform.key()).isEqualTo("transform");
139 
140     Fragment.ParamValue first = transform.values().get(0);
141     assertThat(first.name()).isEqualTo("first");
142     Fragment.SubParam foo = first.subParams().get(0);
143     assertThat(foo.key()).isEqualTo("foo");
144     assertThat(foo.value()).isEqualTo("bar");
145 
146     Fragment.ParamValue second = transform.values().get(1);
147     assertThat(second.name()).isEqualTo("second");
148     Fragment.SubParam kequal = second.subParams().get(0);
149     assertThat(kequal.key()).isEqualTo("k=");
150     assertThat(kequal.value()).isEqualTo("(v)");
151   }
152 }
153