• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.retaildemo;
18 
19 import android.app.DownloadManager;
20 import android.app.ProgressDialog;
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.database.Cursor;
26 import android.database.MatrixCursor;
27 import android.net.ConnectivityManager;
28 import android.net.NetworkInfo;
29 import android.net.Uri;
30 import android.os.Build;
31 import android.os.Environment;
32 import android.os.Handler;
33 import android.os.Looper;
34 import android.support.test.filters.SmallTest;
35 import android.support.test.runner.AndroidJUnit4;
36 
37 import com.android.retaildemo.DemoPlayer;
38 import com.android.retaildemo.DownloadVideoTask;
39 import com.android.retaildemo.DownloadVideoTask.ResultListener;
40 
41 import org.junit.After;
42 import org.junit.Before;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 import org.mockito.ArgumentCaptor;
46 import org.mockito.Mock;
47 import org.mockito.Mockito;
48 import org.mockito.MockitoAnnotations;
49 
50 import java.io.File;
51 import java.lang.reflect.Field;
52 import java.net.HttpURLConnection;
53 
54 import static android.support.test.InstrumentationRegistry.getTargetContext;
55 
56 import static org.junit.Assert.assertEquals;
57 import static org.mockito.Matchers.any;
58 import static org.mockito.Matchers.anyLong;
59 import static org.mockito.Mockito.times;
60 import static org.mockito.Mockito.verify;
61 import static org.mockito.Mockito.verifyNoMoreInteractions;
62 import static org.mockito.Mockito.verifyZeroInteractions;
63 import static org.mockito.Mockito.when;
64 
65 @RunWith(AndroidJUnit4.class)
66 @SmallTest
67 public class DownloadVideoTaskTest {
68 
69     private static final String TEST_URL = "https://example.com/demo.mp4";
70     private static final long TEST_DOWNLOAD_ID = 1000;
71 
72     private @Mock Context mContext;
73     private @Mock DownloadManager mDownloadManager;
74     private @Mock ResultListener mResultListener;
75     private @Mock ConnectivityManager mConnectivityManager;
76     private @Mock ProgressDialog mProgressDialog;
77     private @Mock HttpURLConnection mConnection;
78 
79     private String mDownloadPath;
80     private File mPreloadedVideo;
81 
82     @Before
setUp()83     public void setUp() throws Exception {
84         MockitoAnnotations.initMocks(this);
85 
86         final String videoFileName = getTargetContext().getString(
87                 R.string.retail_demo_video_file_name);
88         mDownloadPath = getTargetContext().getObbDir().getPath() + File.separator
89                 + videoFileName;
90         clearIfFileExists(mDownloadPath);
91         mPreloadedVideo = new File(Environment.getDataPreloadsDemoDirectory(), videoFileName);
92         setNetworkConnected(true);
93     }
94 
95     @After
tearDown()96     public void tearDown() throws Exception {
97         clearIfFileExists(mDownloadPath);
98     }
99 
clearIfFileExists(String path)100     private void clearIfFileExists(String path) {
101         final File file = new File(path);
102         if (file.exists()) {
103             file.delete();
104         }
105     }
106 
107     @Test
testDownloadVideo()108     public void testDownloadVideo() throws Exception {
109         final DownloadVideoTask task = new DownloadVideoTask(mContext,
110                 mDownloadPath, mPreloadedVideo, mResultListener, new TestInjector(mContext));
111         when(mDownloadManager.enqueue(any(DownloadManager.Request.class)))
112                 .thenReturn(TEST_DOWNLOAD_ID);
113 
114         task.run();
115 
116         final ArgumentCaptor<BroadcastReceiver> downloadReceiver =
117                 verifyIfDownloadCompleteReceiverRegistered();
118 
119         verify(mProgressDialog, times(1)).show();
120 
121         final Cursor cursor = createCursor(DownloadManager.STATUS_SUCCESSFUL, mDownloadPath);
122         when(mDownloadManager.query(any(DownloadManager.Query.class))).thenReturn(cursor);
123 
124         final Intent downloadCompleteIntent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
125                 .putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, TEST_DOWNLOAD_ID);
126         downloadReceiver.getValue().onReceive(mContext, downloadCompleteIntent);
127 
128         verify(mContext).unregisterReceiver(downloadReceiver.getValue());
129 
130         verify(mResultListener, times(1)).onFileDownloaded(mDownloadPath);
131         verifyNoMoreInteractions(mResultListener);
132 
133         verify(mProgressDialog, times(1)).dismiss();
134     }
135 
136     @Test
testDownloadVideo_noNetwork()137     public void testDownloadVideo_noNetwork() throws Exception {
138         setNetworkConnected(false);
139         final DownloadVideoTask task = new DownloadVideoTask(mContext,
140                 mDownloadPath, mPreloadedVideo, mResultListener, new TestInjector(mContext));
141 
142         task.run();
143 
144         verify(mResultListener, times(1)).onError();
145         // Verify that broadcast receivers are registered for ACTION_DOWNLOAD_COMPLETE and
146         // ConnectivityManager.CONNECTIVITY_ACTION.
147         final ArgumentCaptor<BroadcastReceiver> broadcastReceiver =
148                 ArgumentCaptor.forClass(BroadcastReceiver.class);
149         final ArgumentCaptor<IntentFilter> intentFilter =
150                 ArgumentCaptor.forClass(IntentFilter.class);
151         verify(mContext, times(2)).registerReceiver(
152                 broadcastReceiver.capture(), intentFilter.capture());
153         final BroadcastReceiver downloadReceiver = broadcastReceiver.getAllValues().get(0);
154         assertEquals(intentFilter.getAllValues().get(0).getAction(0),
155                 DownloadManager.ACTION_DOWNLOAD_COMPLETE);
156         assertEquals(intentFilter.getAllValues().get(1).getAction(0),
157                 ConnectivityManager.CONNECTIVITY_ACTION);
158         final BroadcastReceiver networkReceiver = broadcastReceiver.getAllValues().get(1);
159 
160         when(mDownloadManager.enqueue(any(DownloadManager.Request.class)))
161                 .thenReturn(TEST_DOWNLOAD_ID);
162         setNetworkConnected(true);
163 
164         networkReceiver.onReceive(mContext,
165                 new Intent(ConnectivityManager.CONNECTIVITY_ACTION));
166 
167         final Cursor cursor = createCursor(DownloadManager.STATUS_SUCCESSFUL, mDownloadPath);
168         when(mDownloadManager.query(any(DownloadManager.Query.class))).thenReturn(cursor);
169 
170         final Intent downloadCompleteIntent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
171                 .putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, TEST_DOWNLOAD_ID);
172         downloadReceiver.onReceive(mContext, downloadCompleteIntent);
173 
174         verify(mContext).unregisterReceiver(downloadReceiver);
175         verify(mContext).unregisterReceiver(networkReceiver);
176 
177         verify(mResultListener).onFileDownloaded(mDownloadPath);
178         verifyNoMoreInteractions(mResultListener);
179 
180         verify(mProgressDialog).dismiss();
181     }
182 
183     @Test
testDownloadVideo_downloadFailed()184     public void testDownloadVideo_downloadFailed() throws Exception {
185         final DownloadVideoTask task = new DownloadVideoTask(mContext,
186                 mDownloadPath, mPreloadedVideo, mResultListener, new TestInjector(mContext));
187         when(mDownloadManager.enqueue(any(DownloadManager.Request.class)))
188                 .thenReturn(TEST_DOWNLOAD_ID);
189 
190         task.run();
191 
192         final ArgumentCaptor<BroadcastReceiver> downloadReceiver =
193                 verifyIfDownloadCompleteReceiverRegistered();
194 
195         verify(mProgressDialog, times(1)).show();
196 
197         final Cursor cursor = createCursor(DownloadManager.STATUS_FAILED, mDownloadPath);
198         when(mDownloadManager.query(any(DownloadManager.Query.class))).thenReturn(cursor);
199 
200         final Intent downloadCompleteIntent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
201                 .putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, TEST_DOWNLOAD_ID);
202         downloadReceiver.getValue().onReceive(mContext, downloadCompleteIntent);
203 
204         verify(mContext).unregisterReceiver(downloadReceiver.getValue());
205 
206         verify(mResultListener, times(1)).onError();
207         verifyNoMoreInteractions(mResultListener);
208 
209         verify(mProgressDialog, times(1)).dismiss();
210     }
211 
212     @Test
testDownloadUpdatedVideo()213     public void testDownloadUpdatedVideo() throws Exception {
214         new File(mDownloadPath).createNewFile();
215 
216         final TestInjector injector = new TestInjector(mContext);
217         final DownloadVideoTask task = new DownloadVideoTask(mContext,
218                 mDownloadPath, mPreloadedVideo, mResultListener, injector);
219         final Handler handler = injector.getHandler(task);
220 
221         when(mConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_OK);
222         handler.handleMessage(handler.obtainMessage(DownloadVideoTask.MSG_CHECK_FOR_UPDATE));
223 
224         verify(mConnection).setIfModifiedSince(anyLong());
225         verify(mDownloadManager).enqueue(any(DownloadManager.Request.class));
226     }
227 
228     @Test
testDownloadUpdatedVideo_notModified()229     public void testDownloadUpdatedVideo_notModified() throws Exception {
230         new File(mDownloadPath).createNewFile();
231 
232         final TestInjector injector = new TestInjector(mContext);
233         final DownloadVideoTask task = new DownloadVideoTask(mContext,
234                 mDownloadPath, mPreloadedVideo, mResultListener, injector);
235         final Handler handler = injector.getHandler(task);
236 
237         when(mConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_NOT_MODIFIED);
238         handler.handleMessage(handler.obtainMessage(DownloadVideoTask.MSG_CHECK_FOR_UPDATE));
239 
240         verify(mConnection).setIfModifiedSince(anyLong());
241         verifyZeroInteractions(mDownloadManager);
242     }
243 
verifyIfDownloadCompleteReceiverRegistered()244     private ArgumentCaptor<BroadcastReceiver> verifyIfDownloadCompleteReceiverRegistered() {
245         final ArgumentCaptor<BroadcastReceiver> broadcastReceiver =
246                 ArgumentCaptor.forClass(BroadcastReceiver.class);
247         final ArgumentCaptor<IntentFilter> intentFilter =
248                 ArgumentCaptor.forClass(IntentFilter.class);
249         verify(mContext).registerReceiver(
250                 broadcastReceiver.capture(), intentFilter.capture());
251         assertEquals(intentFilter.getValue().getAction(0),
252                 DownloadManager.ACTION_DOWNLOAD_COMPLETE);
253         return broadcastReceiver;
254     }
255 
createCursor(int status, String filePath)256     private Cursor createCursor(int status, String filePath) {
257         final MatrixCursor cursor = new MatrixCursor(new String[] {
258                 DownloadManager.COLUMN_STATUS,
259                 DownloadManager.COLUMN_LOCAL_URI
260         });
261         cursor.addRow(new Object[] {
262                 status,
263                 Uri.fromFile(new File(filePath))
264         });
265         return cursor;
266     }
267 
setNetworkConnected(boolean connected)268     private void setNetworkConnected(boolean connected) {
269         NetworkInfo networkInfo = Mockito.mock(NetworkInfo.class);
270         when(networkInfo.isConnected()).thenReturn(connected);
271         when(mConnectivityManager.getActiveNetworkInfo()).thenReturn(networkInfo);
272     }
273 
274     private class TestInjector extends DownloadVideoTask.Injector {
TestInjector(Context context)275         TestInjector(Context context) {
276             super(context);
277         }
278 
279         @Override
getDownloadManager()280         DownloadManager getDownloadManager() {
281             return mDownloadManager;
282         }
283 
284         @Override
getDownloadUrl()285         String getDownloadUrl() {
286             return TEST_URL;
287         }
288 
289         @Override
getConnectivityManager()290         ConnectivityManager getConnectivityManager() {
291             return mConnectivityManager;
292         }
293 
294         @Override
getHandler(DownloadVideoTask task)295         Handler getHandler(DownloadVideoTask task) {
296             return task.new ThreadHandler(Looper.getMainLooper());
297         }
298 
299         @Override
getProgressDialog()300         ProgressDialog getProgressDialog() {
301             return mProgressDialog;
302         }
303 
304         @Override
openConnection(String downloadUri)305         HttpURLConnection openConnection(String downloadUri) {
306             return mConnection;
307         }
308     }
309 }