1 /*
2  * Copyright (C) 2018 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 package com.android.settings.datausage;
17 
18 import static com.google.common.truth.Truth.assertThat;
19 
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.spy;
22 import static org.mockito.Mockito.verify;
23 
24 import android.app.Activity;
25 import android.util.SparseIntArray;
26 import android.view.LayoutInflater;
27 import android.view.View;
28 import android.widget.TextView;
29 
30 import androidx.preference.PreferenceViewHolder;
31 
32 import com.android.settings.R;
33 import com.android.settings.datausage.ChartDataUsagePreference.DataUsageSummaryNode;
34 import com.android.settings.datausage.lib.NetworkCycleChartData;
35 import com.android.settings.datausage.lib.NetworkUsageData;
36 import com.android.settings.widget.UsageView;
37 
38 import org.junit.Before;
39 import org.junit.Ignore;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 import org.mockito.ArgumentCaptor;
43 import org.mockito.MockitoAnnotations;
44 import org.robolectric.Robolectric;
45 import org.robolectric.RobolectricTestRunner;
46 
47 import java.util.ArrayList;
48 import java.util.List;
49 import java.util.concurrent.TimeUnit;
50 
51 @RunWith(RobolectricTestRunner.class)
52 public class ChartDataUsagePreferenceTest {
53 
54     // Test cycle start date, 20 Mar 2018 22:00: GMT
55     private static final long TIMESTAMP_START = 1521583200000L;
56     // Test bucket end date, 22 Mar 2018 00:00:00
57     private static final long TIMESTAMP_END = 1521676800000L;
58 
59     private List<NetworkUsageData> mNetworkCycleData;
60     private NetworkCycleChartData mNetworkCycleChartData;
61     private ChartDataUsagePreference mPreference;
62     private Activity mActivity;
63     private PreferenceViewHolder mHolder;
64 
65     @Before
setUp()66     public void setUp() {
67         MockitoAnnotations.initMocks(this);
68 
69         mActivity = spy(Robolectric.setupActivity(Activity.class));
70         mPreference = new ChartDataUsagePreference(mActivity, null /* attrs */);
71         LayoutInflater inflater = LayoutInflater.from(mActivity);
72         View view = inflater.inflate(mPreference.getLayoutResource(), null /* root */,
73                 false /* attachToRoot */);
74         mHolder = spy(PreferenceViewHolder.createInstanceForTests(view));
75     }
76 
77     @Test
calcPoints_dataAvailableFromCycleStart_shouldAddDataPointsOnly()78     public void calcPoints_dataAvailableFromCycleStart_shouldAddDataPointsOnly() {
79         final UsageView usageView = mock(UsageView.class);
80         final ArgumentCaptor<SparseIntArray> pointsCaptor =
81                 ArgumentCaptor.forClass(SparseIntArray.class);
82         createTestNetworkData();
83         mPreference.setTime(
84                 mNetworkCycleChartData.getTotal().getStartTime(),
85                 mNetworkCycleChartData.getTotal().getEndTime());
86         mPreference.setNetworkCycleData(mNetworkCycleChartData);
87 
88         mPreference.calcPoints(usageView, mNetworkCycleData.subList(0, 5));
89 
90         verify(usageView).addPath(pointsCaptor.capture());
91         final SparseIntArray points = pointsCaptor.getValue();
92         // the point should be normal usage data
93         assertThat(points.valueAt(1)).isNotEqualTo(-1);
94     }
95 
96     @Ignore("b/313568482")
97     @Test
calcPoints_dataNotAvailableAtCycleStart_shouldIndicateStartOfData()98     public void calcPoints_dataNotAvailableAtCycleStart_shouldIndicateStartOfData() {
99         final UsageView usageView = mock(UsageView.class);
100         final ArgumentCaptor<SparseIntArray> pointsCaptor =
101                 ArgumentCaptor.forClass(SparseIntArray.class);
102         createTestNetworkData();
103         mPreference.setTime(
104                 mNetworkCycleChartData.getTotal().getStartTime(),
105                 mNetworkCycleChartData.getTotal().getEndTime());
106         mPreference.setNetworkCycleData(mNetworkCycleChartData);
107 
108         mPreference.calcPoints(usageView, mNetworkCycleData.subList(2, 7));
109 
110         verify(usageView).addPath(pointsCaptor.capture());
111         final SparseIntArray points = pointsCaptor.getValue();
112         // indicator that no data is available
113         assertThat(points.keyAt(1)).isEqualTo(points.keyAt(2) - 1);
114         assertThat(points.valueAt(1)).isEqualTo(-1);
115     }
116 
117     @Ignore("b/313568482")
118     @Test
calcPoints_shouldNotDrawPointForFutureDate()119     public void calcPoints_shouldNotDrawPointForFutureDate() {
120         final UsageView usageView = mock(UsageView.class);
121         final ArgumentCaptor<SparseIntArray> pointsCaptor =
122                 ArgumentCaptor.forClass(SparseIntArray.class);
123         final long tonight = System.currentTimeMillis() + TimeUnit.HOURS.toMillis(12);
124         mNetworkCycleData = new ArrayList<>();
125         // add test usage data for last 5 days
126         mNetworkCycleData.add(new NetworkUsageData(
127                 tonight - TimeUnit.DAYS.toMillis(5),
128                 tonight - TimeUnit.DAYS.toMillis(4),
129                 743823454L));
130         mNetworkCycleData.add(new NetworkUsageData(
131                 tonight - TimeUnit.DAYS.toMillis(4),
132                 tonight - TimeUnit.DAYS.toMillis(3),
133                 64396L));
134         mNetworkCycleData.add(new NetworkUsageData(
135                 tonight - TimeUnit.DAYS.toMillis(3),
136                 tonight - TimeUnit.DAYS.toMillis(2),
137                 2832L));
138         mNetworkCycleData.add(new NetworkUsageData(
139                 tonight - TimeUnit.DAYS.toMillis(2),
140                 tonight - TimeUnit.DAYS.toMillis(1),
141                 83849690L));
142         mNetworkCycleData.add(new NetworkUsageData(
143                 tonight - TimeUnit.DAYS.toMillis(1), tonight, 1883657L));
144         // add test usage data for next 5 days
145         mNetworkCycleData.add(new NetworkUsageData(
146                 tonight, tonight + TimeUnit.DAYS.toMillis(1), 0L));
147         mNetworkCycleData.add(new NetworkUsageData(
148                 tonight + TimeUnit.DAYS.toMillis(1),
149                 tonight + TimeUnit.DAYS.toMillis(2),
150                 0L));
151         mNetworkCycleData.add(new NetworkUsageData(
152                 tonight + TimeUnit.DAYS.toMillis(2),
153                 tonight + TimeUnit.DAYS.toMillis(3),
154                 0L));
155         mNetworkCycleData.add(new NetworkUsageData(
156                 tonight + TimeUnit.DAYS.toMillis(3),
157                 tonight + TimeUnit.DAYS.toMillis(4),
158                 0L));
159         mNetworkCycleData.add(new NetworkUsageData(
160                 tonight + TimeUnit.DAYS.toMillis(4),
161                 tonight + TimeUnit.DAYS.toMillis(5),
162                 0L));
163         mNetworkCycleData.add(new NetworkUsageData(
164                 tonight + TimeUnit.DAYS.toMillis(5),
165                 tonight + TimeUnit.DAYS.toMillis(6),
166                 0L));
167 
168         mNetworkCycleChartData = new NetworkCycleChartData(
169                 new NetworkUsageData(
170                         tonight - TimeUnit.DAYS.toMillis(5),
171                         tonight + TimeUnit.DAYS.toMillis(6),
172                         0),
173                 mNetworkCycleData
174         );
175         mPreference.setTime(
176                 mNetworkCycleChartData.getTotal().getStartTime(),
177                 mNetworkCycleChartData.getTotal().getEndTime());
178         mPreference.setNetworkCycleData(mNetworkCycleChartData);
179 
180         mPreference.calcPoints(usageView, mNetworkCycleData);
181 
182         verify(usageView).addPath(pointsCaptor.capture());
183         final SparseIntArray points = pointsCaptor.getValue();
184         // should only have 7 points: 1 test point indicating the start of data, starting point 0,
185         // and 5 actual data point for each day
186         assertThat(points.size()).isEqualTo(7);
187         assertThat(points.keyAt(0)).isEqualTo(-1);
188         assertThat(points.keyAt(1)).isEqualTo(0);
189         assertThat(points.keyAt(2)).isEqualTo(TimeUnit.DAYS.toMinutes(1));
190         assertThat(points.keyAt(3)).isEqualTo(TimeUnit.DAYS.toMinutes(2));
191         assertThat(points.keyAt(4)).isEqualTo(TimeUnit.DAYS.toMinutes(3));
192         assertThat(points.keyAt(5)).isEqualTo(TimeUnit.DAYS.toMinutes(4));
193         assertThat(points.keyAt(6)).isEqualTo(TimeUnit.DAYS.toMinutes(5));
194     }
195 
196     @Test
notifyChange_nonEmptyDataUsage_shouldHaveSingleContentDescription()197     public void notifyChange_nonEmptyDataUsage_shouldHaveSingleContentDescription() {
198         final UsageView chart = (UsageView) mHolder.findViewById(R.id.data_usage);
199         final TextView labelTop = (TextView) mHolder.findViewById(R.id.label_top);
200         final TextView labelMiddle = (TextView) mHolder.findViewById(R.id.label_middle);
201         final TextView labelBottom = (TextView) mHolder.findViewById(R.id.label_bottom);
202         final TextView labelStart = (TextView) mHolder.findViewById(R.id.label_start);
203         final TextView labelEnd = (TextView) mHolder.findViewById(R.id.label_end);
204         createTestNetworkData();
205         mPreference.setTime(
206                 mNetworkCycleChartData.getTotal().getStartTime(),
207                 mNetworkCycleChartData.getTotal().getEndTime());
208         mPreference.setNetworkCycleData(mNetworkCycleChartData);
209 
210         mPreference.onBindViewHolder(mHolder);
211 
212         assertThat(chart.getContentDescription()).isNotNull();
213         assertThat(labelTop.getContentDescription()).isNull();
214         assertThat(labelMiddle.getContentDescription()).isNull();
215         assertThat(labelBottom.getContentDescription()).isNull();
216         assertThat(labelStart.getContentDescription()).isNull();
217         assertThat(labelEnd.getContentDescription()).isNull();
218     }
219 
220     @Test
getDensedStatsData_someSamePercentageNodes_getDifferentPercentageNodes()221     public void getDensedStatsData_someSamePercentageNodes_getDifferentPercentageNodes() {
222         createSomeSamePercentageNetworkData();
223         final List<DataUsageSummaryNode> densedStatsData =
224                 mPreference.getDensedStatsData(mNetworkCycleData);
225 
226         assertThat(mNetworkCycleData.size()).isEqualTo(8);
227         assertThat(densedStatsData.size()).isEqualTo(3);
228         assertThat(densedStatsData.get(0).getDataUsagePercentage()).isEqualTo(33);
229         assertThat(densedStatsData.get(1).getDataUsagePercentage()).isEqualTo(99);
230         assertThat(densedStatsData.get(2).getDataUsagePercentage()).isEqualTo(100);
231     }
232 
createTestNetworkData()233     private void createTestNetworkData() {
234         mNetworkCycleData = new ArrayList<>();
235         // create 10 arbitrary network data
236         mNetworkCycleData.add(new NetworkUsageData(1521583200000L, 1521586800000L, 743823454L));
237         mNetworkCycleData.add(new NetworkUsageData(1521586800000L, 1521590400000L, 64396L));
238         mNetworkCycleData.add(new NetworkUsageData(1521590400000L, 1521655200000L, 2832L));
239         mNetworkCycleData.add(new NetworkUsageData(1521655200000L, 1521658800000L, 83849690L));
240         mNetworkCycleData.add(new NetworkUsageData(1521658800000L, 1521662400000L, 1883657L));
241         mNetworkCycleData.add(new NetworkUsageData(1521662400000L, 1521666000000L, 705259L));
242         mNetworkCycleData.add(new NetworkUsageData(1521666000000L, 1521669600000L, 216169L));
243         mNetworkCycleData.add(new NetworkUsageData(1521669600000L, 1521673200000L, 6069175L));
244         mNetworkCycleData.add(new NetworkUsageData(1521673200000L, 1521676800000L, 120389L));
245         mNetworkCycleData.add(new NetworkUsageData(1521676800000L, 1521678800000L, 29947L));
246 
247         mNetworkCycleChartData = new NetworkCycleChartData(
248                 new NetworkUsageData(TIMESTAMP_START, TIMESTAMP_END, 0),
249                 mNetworkCycleData
250         );
251     }
252 
createSomeSamePercentageNetworkData()253     private void createSomeSamePercentageNetworkData() {
254         mNetworkCycleData = new ArrayList<>();
255         mNetworkCycleData.add(new NetworkUsageData(1521583200000L, 1521586800000L, 100)); //33%
256         mNetworkCycleData.add(new NetworkUsageData(1521586800000L, 1521590400000L, 1));   //33%
257         mNetworkCycleData.add(new NetworkUsageData(1521590400000L, 1521655200000L, 0));   //33%
258         mNetworkCycleData.add(new NetworkUsageData(1521655200000L, 1521658800000L, 0));   //33%
259         mNetworkCycleData.add(new NetworkUsageData(1521658800000L, 1521662400000L, 200)); //99%
260         mNetworkCycleData.add(new NetworkUsageData(1521662400000L, 1521666000000L, 1));   //99%
261         mNetworkCycleData.add(new NetworkUsageData(1521666000000L, 1521669600000L, 1));   //100
262         mNetworkCycleData.add(new NetworkUsageData(1521669600000L, 1521673200000L, 0));   //100%
263     }
264 
265 }
266