1 /*
2  * Copyright (C) 2022 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 com.android.settingslib.mobile;
18 
19 import static com.android.settingslib.mobile.MobileIconCarrierIdOverridesImpl.parseNetworkIconOverrideTypedArray;
20 
21 import static com.google.common.truth.Truth.assertThat;
22 
23 import static org.mockito.ArgumentMatchers.anyInt;
24 import static org.mockito.Mockito.doAnswer;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.when;
27 
28 import android.content.res.TypedArray;
29 
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.junit.runner.RunWith;
33 import org.robolectric.RobolectricTestRunner;
34 
35 import java.util.Map;
36 
37 @RunWith(RobolectricTestRunner.class)
38 public final class MobileIconCarrierIdOverridesTest {
39     private static final String OVERRIDE_ICON_1_NAME = "name_1";
40     private static final int OVERRIDE_ICON_1_RES = 1;
41 
42     private static final String OVERRIDE_ICON_2_NAME = "name_2";
43     private static final int OVERRIDE_ICON_2_RES = 2;
44 
45     NetworkOverrideTypedArrayMock mResourceMock;
46 
47     @Before
setUp()48     public void setUp() {
49         mResourceMock = new NetworkOverrideTypedArrayMock(
50                 new String[] { OVERRIDE_ICON_1_NAME, OVERRIDE_ICON_2_NAME },
51                 new int[] { OVERRIDE_ICON_1_RES, OVERRIDE_ICON_2_RES }
52         );
53     }
54 
55     @Test
testParse_singleOverride()56     public void testParse_singleOverride() {
57         mResourceMock.setOverrides(
58                 new String[] { OVERRIDE_ICON_1_NAME },
59                 new int[] { OVERRIDE_ICON_1_RES }
60         );
61 
62         Map<String, Integer> parsed = parseNetworkIconOverrideTypedArray(mResourceMock.getMock());
63 
64         assertThat(parsed.get(OVERRIDE_ICON_1_NAME)).isEqualTo(OVERRIDE_ICON_1_RES);
65     }
66 
67     @Test
testParse_multipleOverrides()68     public void testParse_multipleOverrides() {
69         mResourceMock.setOverrides(
70                 new String[] { OVERRIDE_ICON_1_NAME, OVERRIDE_ICON_2_NAME },
71                 new int[] { OVERRIDE_ICON_1_RES, OVERRIDE_ICON_2_RES }
72         );
73 
74         Map<String, Integer> parsed = parseNetworkIconOverrideTypedArray(mResourceMock.getMock());
75 
76         assertThat(parsed.get(OVERRIDE_ICON_2_NAME)).isEqualTo(OVERRIDE_ICON_2_RES);
77         assertThat(parsed.get(OVERRIDE_ICON_1_NAME)).isEqualTo(OVERRIDE_ICON_1_RES);
78     }
79 
80     @Test
testParse_nonexistentKey_isNull()81     public void testParse_nonexistentKey_isNull() {
82         mResourceMock.setOverrides(
83                 new String[] { OVERRIDE_ICON_1_NAME },
84                 new int[] { OVERRIDE_ICON_1_RES }
85         );
86 
87         Map<String, Integer> parsed = parseNetworkIconOverrideTypedArray(mResourceMock.getMock());
88 
89         assertThat(parsed.get(OVERRIDE_ICON_2_NAME)).isNull();
90     }
91 
92     static class NetworkOverrideTypedArrayMock {
93         private Object[] mInterleaved;
94 
95         private final TypedArray mMockTypedArray = mock(TypedArray.class);
96 
NetworkOverrideTypedArrayMock( String[] networkTypes, int[] iconOverrides)97         NetworkOverrideTypedArrayMock(
98                 String[] networkTypes,
99                 int[] iconOverrides) {
100 
101             mInterleaved = interleaveTypes(networkTypes, iconOverrides);
102 
103             doAnswer(invocation -> {
104                 return mInterleaved[(int) invocation.getArgument(0)];
105             }).when(mMockTypedArray).getString(/* index */ anyInt());
106 
107             doAnswer(invocation -> {
108                 return mInterleaved[(int) invocation.getArgument(0)];
109             }).when(mMockTypedArray).getResourceId(/* index */ anyInt(), /* default */ anyInt());
110 
111             when(mMockTypedArray.length()).thenAnswer(invocation -> {
112                 return mInterleaved.length;
113             });
114         }
115 
getMock()116         TypedArray getMock() {
117             return mMockTypedArray;
118         }
119 
setOverrides(String[] types, int[] resIds)120         void setOverrides(String[] types, int[] resIds) {
121             mInterleaved = interleaveTypes(types, resIds);
122         }
123 
interleaveTypes(String[] strs, int[] ints)124         private Object[] interleaveTypes(String[] strs, int[] ints) {
125             assertThat(strs.length).isEqualTo(ints.length);
126 
127             Object[] ret = new Object[strs.length * 2];
128 
129             // Keep track of where we are in the interleaved array, but iterate the overrides
130             int interleavedIndex = 0;
131             for (int i = 0; i < strs.length; i++) {
132                 ret[interleavedIndex] = strs[i];
133                 interleavedIndex += 1;
134                 ret[interleavedIndex] = ints[i];
135                 interleavedIndex += 1;
136             }
137             return ret;
138         }
139     }
140 }
141