Index: chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java |
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1bda3e2219da5c8c2d466093d6f528f0d3c0f72b |
--- /dev/null |
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/download/DownloadActivityTest.java |
@@ -0,0 +1,318 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.chrome.browser.download; |
+ |
+import android.content.Intent; |
+import android.os.Handler; |
+import android.os.Looper; |
+import android.support.v7.widget.RecyclerView; |
+import android.support.v7.widget.RecyclerView.ViewHolder; |
+import android.test.suitebuilder.annotation.MediumTest; |
+import android.text.TextUtils; |
+import android.view.View; |
+import android.widget.ListView; |
+import android.widget.TextView; |
+ |
+import org.chromium.base.ThreadUtils; |
+import org.chromium.base.test.BaseActivityInstrumentationTestCase; |
+import org.chromium.base.test.util.Restriction; |
+import org.chromium.chrome.R; |
+import org.chromium.chrome.browser.download.ui.DownloadHistoryAdapter; |
+import org.chromium.chrome.browser.download.ui.DownloadHistoryAdapter.ItemViewHolder; |
+import org.chromium.chrome.browser.download.ui.DownloadHistoryItemWrapper; |
+import org.chromium.chrome.browser.download.ui.DownloadItemView; |
+import org.chromium.chrome.browser.download.ui.DownloadManagerUi; |
+import org.chromium.chrome.browser.download.ui.StubbedProvider; |
+import org.chromium.chrome.browser.offlinepages.downloads.OfflinePageDownloadItem; |
+import org.chromium.chrome.browser.widget.selection.SelectionDelegate.SelectionObserver; |
+import org.chromium.chrome.test.util.ChromeRestriction; |
+import org.chromium.content.browser.test.util.CallbackHelper; |
+import org.chromium.content.browser.test.util.Criteria; |
+import org.chromium.content.browser.test.util.CriteriaHelper; |
+ |
+import java.util.List; |
+ |
+/** |
+ * Tests the DownloadActivity and the DownloadManagerUi. |
+ */ |
+@Restriction(ChromeRestriction.RESTRICTION_TYPE_PHONE) |
+public class DownloadActivityTest extends BaseActivityInstrumentationTestCase<DownloadActivity> { |
+ |
+ private static class TestObserver extends RecyclerView.AdapterDataObserver |
+ implements SelectionObserver<DownloadHistoryItemWrapper>, |
+ DownloadManagerUi.DownloadUiObserver { |
+ public final CallbackHelper onChangedCallback = new CallbackHelper(); |
+ public final CallbackHelper onSelectionCallback = new CallbackHelper(); |
+ public final CallbackHelper onFilterCallback = new CallbackHelper(); |
+ |
+ private List<DownloadHistoryItemWrapper> mOnSelectionItems; |
+ private Handler mHandler; |
+ |
+ public TestObserver() { |
+ mHandler = new Handler(Looper.getMainLooper()); |
+ } |
+ |
+ @Override |
+ public void onChanged() { |
+ // To guarantee that all real Observers have had a chance to react to the event, post |
+ // the CallbackHelper.notifyCalled() call. |
+ mHandler.post(new Runnable() { |
+ @Override |
+ public void run() { |
+ onChangedCallback.notifyCalled(); |
+ } |
+ }); |
+ } |
+ |
+ @Override |
+ public void onSelectionStateChange(List<DownloadHistoryItemWrapper> selectedItems) { |
+ mOnSelectionItems = selectedItems; |
+ mHandler.post(new Runnable() { |
+ @Override |
+ public void run() { |
+ onSelectionCallback.notifyCalled(); |
+ } |
+ }); |
+ } |
+ |
+ @Override |
+ public void onFilterChanged(int filter) { |
+ mHandler.post(new Runnable() { |
+ @Override |
+ public void run() { |
+ onFilterCallback.notifyCalled(); |
+ } |
+ }); |
+ } |
+ |
+ @Override |
+ public void onManagerDestroyed() { |
+ } |
+ } |
+ |
+ private StubbedProvider mStubbedProvider; |
+ private TestObserver mAdapterObserver; |
+ private DownloadManagerUi mUi; |
+ private DownloadHistoryAdapter mAdapter; |
+ |
+ private RecyclerView mRecyclerView; |
+ private TextView mSpaceUsedDisplay; |
+ |
+ public DownloadActivityTest() { |
+ super(DownloadActivity.class); |
+ } |
+ |
+ @Override |
+ public void setUp() throws Exception { |
+ super.setUp(); |
+ |
+ mStubbedProvider = new StubbedProvider(); |
+ DownloadManagerUi.setProviderForTests(mStubbedProvider); |
+ |
+ mAdapterObserver = new TestObserver(); |
+ mStubbedProvider.getSelectionDelegate().addObserver(mAdapterObserver); |
+ |
+ startDownloadActivity(); |
+ mUi = getActivity().getDownloadManagerUiForTests(); |
+ mAdapter = mUi.getDownloadHistoryAdapterForTests(); |
+ mAdapter.registerAdapterDataObserver(mAdapterObserver); |
+ |
+ mSpaceUsedDisplay = |
+ (TextView) getActivity().findViewById(R.id.space_used_display); |
+ mRecyclerView = ((RecyclerView) getActivity().findViewById(R.id.recycler_view)); |
+ } |
+ |
+ @MediumTest |
+ public void testSpaceDisplay() throws Exception { |
+ // This first check is a Criteria because initialization of the Adapter is asynchronous. |
+ CriteriaHelper.pollUiThread(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return TextUtils.equals("6.00 GB used", mSpaceUsedDisplay.getText()); |
+ } |
+ }); |
+ |
+ // Add a new item. |
+ int callCount = mAdapterObserver.onChangedCallback.getCallCount(); |
+ final DownloadItem updateItem = StubbedProvider.createDownloadItem(7, "20151021 07:28"); |
+ ThreadUtils.runOnUiThread(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAdapter.onDownloadItemUpdated(updateItem, false); |
+ } |
+ }); |
+ mAdapterObserver.onChangedCallback.waitForCallback(callCount); |
+ assertEquals("6.50 GB used", mSpaceUsedDisplay.getText()); |
+ |
+ // Mark one download as deleted on disk, which should prevent it from being counted. |
+ callCount = mAdapterObserver.onChangedCallback.getCallCount(); |
+ final DownloadItem deletedItem = StubbedProvider.createDownloadItem(6, "20151021 07:28"); |
+ deletedItem.setHasBeenExternallyRemoved(true); |
+ ThreadUtils.runOnUiThread(new Runnable() { |
+ @Override |
+ public void run() { |
+ mAdapter.onDownloadItemUpdated(deletedItem, false); |
+ } |
+ }); |
+ mAdapterObserver.onChangedCallback.waitForCallback(callCount); |
+ assertEquals("5.50 GB used", mSpaceUsedDisplay.getText()); |
+ |
+ // Say that the offline page has been deleted. |
+ callCount = mAdapterObserver.onChangedCallback.getCallCount(); |
+ final OfflinePageDownloadItem deletedPage = |
+ StubbedProvider.createOfflineItem(3, "20151021 07:28"); |
+ ThreadUtils.runOnUiThread(new Runnable() { |
+ @Override |
+ public void run() { |
+ mStubbedProvider.getOfflinePageBridge().observer.onItemDeleted( |
+ deletedPage.getGuid()); |
+ } |
+ }); |
+ mAdapterObserver.onChangedCallback.waitForCallback(callCount); |
+ assertEquals("0.50 GB used", mSpaceUsedDisplay.getText()); |
+ } |
+ |
+ /** Clicking on filters affects various things in the UI. */ |
+ @MediumTest |
+ public void testFilters() throws Exception { |
+ // This first check is a Criteria because initialization of the Adapter is asynchronous. |
+ CriteriaHelper.pollUiThread(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return TextUtils.equals("6.00 GB used", mSpaceUsedDisplay.getText()); |
+ } |
+ }); |
+ |
+ // Change the filter. Only the Offline Page and its date header should stay. |
+ clickOnFilter(mUi, 1); |
+ assertEquals(2, mAdapter.getItemCount()); |
+ |
+ // The title of the toolbar reflects the filter. |
+ assertEquals("Pages", mUi.getDownloadManagerToolbarForTests().getTitle()); |
+ |
+ // Check that the number of items displayed is correct. |
+ // We need to poll because RecyclerView doesn't animate changes immediately. |
+ CriteriaHelper.pollUiThread(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return mRecyclerView.getChildCount() == 2; |
+ } |
+ }); |
+ |
+ // Filtering doesn't affect the total download size. |
+ assertEquals("6.00 GB used", mSpaceUsedDisplay.getText()); |
+ } |
+ |
+ @MediumTest |
+ public void testDeleteFiles() throws Exception { |
+ // This first check is a Criteria because initialization of the Adapter is asynchronous. |
+ CriteriaHelper.pollUiThread(new Criteria() { |
+ @Override |
+ public boolean isSatisfied() { |
+ return TextUtils.equals("6.00 GB used", mSpaceUsedDisplay.getText()); |
+ } |
+ }); |
+ |
+ // Select the first two items. |
+ ViewHolder mostRecentHolder = mRecyclerView.findViewHolderForAdapterPosition(1); |
+ assertTrue(mostRecentHolder instanceof ItemViewHolder); |
+ final DownloadItemView firstItemView = ((ItemViewHolder) mostRecentHolder).mItemView; |
+ |
+ ViewHolder nextMostRecentHolder = mRecyclerView.findViewHolderForAdapterPosition(2); |
+ assertTrue(nextMostRecentHolder instanceof ItemViewHolder); |
+ final DownloadItemView secondItemView = ((ItemViewHolder) nextMostRecentHolder).mItemView; |
+ |
+ assertNull(mAdapterObserver.mOnSelectionItems); |
+ int callCount = mAdapterObserver.onSelectionCallback.getCallCount(); |
+ assertEquals(View.VISIBLE, getActivity().findViewById(R.id.close_menu_id).getVisibility()); |
+ assertEquals(View.GONE, |
+ getActivity().findViewById(R.id.selection_mode_number).getVisibility()); |
+ assertNull(getActivity().findViewById(R.id.selection_mode_share_menu_id)); |
+ assertNull(getActivity().findViewById(R.id.selection_mode_delete_menu_id)); |
+ assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled()); |
+ |
+ ThreadUtils.runOnUiThread(new Runnable() { |
+ @Override |
+ public void run() { |
+ firstItemView.performLongClick(); |
+ secondItemView.performLongClick(); |
+ } |
+ }); |
+ |
+ // The toolbar should flip states to allow doing things with the selected items. |
+ mAdapterObserver.onSelectionCallback.waitForCallback(callCount, 2); |
+ assertNull(getActivity().findViewById(R.id.close_menu_id)); |
+ assertEquals(View.VISIBLE, |
+ getActivity().findViewById(R.id.selection_mode_number).getVisibility()); |
+ assertEquals(View.VISIBLE, |
+ getActivity().findViewById(R.id.selection_mode_share_menu_id).getVisibility()); |
+ assertEquals(View.VISIBLE, |
+ getActivity().findViewById(R.id.selection_mode_delete_menu_id).getVisibility()); |
+ assertTrue(mStubbedProvider.getSelectionDelegate().isSelectionEnabled()); |
+ |
+ // Click the delete button, which should delete the items and reset the toolbar. |
+ assertEquals(11, mAdapter.getItemCount()); |
+ assertEquals(0, |
+ mStubbedProvider.getDownloadDelegate().checkExternalCallback.getCallCount()); |
+ assertEquals(0, |
+ mStubbedProvider.getDownloadDelegate().removeDownloadCallback.getCallCount()); |
+ assertEquals(0, mStubbedProvider.getOfflinePageBridge().deleteItemCallback.getCallCount()); |
+ ThreadUtils.runOnUiThread(new Runnable() { |
+ @Override |
+ public void run() { |
+ assertTrue(mUi.getDownloadManagerToolbarForTests().getMenu() |
+ .performIdentifierAction(R.id.selection_mode_delete_menu_id, 0)); |
+ } |
+ }); |
+ mStubbedProvider.getDownloadDelegate().removeDownloadCallback.waitForCallback(0); |
+ mStubbedProvider.getDownloadDelegate().checkExternalCallback.waitForCallback(0); |
+ mStubbedProvider.getOfflinePageBridge().deleteItemCallback.waitForCallback(0); |
+ assertFalse(mStubbedProvider.getSelectionDelegate().isSelectionEnabled()); |
+ assertEquals(8, mAdapter.getItemCount()); |
+ assertEquals("0.00 GB used", mSpaceUsedDisplay.getText()); |
+ } |
+ |
+ private DownloadActivity startDownloadActivity() throws Exception { |
+ // Load up the downloads lists. |
+ DownloadItem item0 = StubbedProvider.createDownloadItem(0, "19551112 06:38"); |
+ DownloadItem item1 = StubbedProvider.createDownloadItem(1, "19551112 06:38"); |
+ DownloadItem item2 = StubbedProvider.createDownloadItem(2, "19551112 06:38"); |
+ DownloadItem item3 = StubbedProvider.createDownloadItem(3, "19851026 09:00"); |
+ DownloadItem item4 = StubbedProvider.createDownloadItem(4, "19851026 09:00"); |
+ DownloadItem item5 = StubbedProvider.createDownloadItem(5, "19851026 09:00"); |
+ DownloadItem item6 = StubbedProvider.createDownloadItem(6, "20151021 07:28"); |
+ OfflinePageDownloadItem item7 = StubbedProvider.createOfflineItem(3, "20151021 07:28"); |
+ mStubbedProvider.getDownloadDelegate().regularItems.add(item0); |
+ mStubbedProvider.getDownloadDelegate().regularItems.add(item1); |
+ mStubbedProvider.getDownloadDelegate().regularItems.add(item2); |
+ mStubbedProvider.getDownloadDelegate().regularItems.add(item3); |
+ mStubbedProvider.getDownloadDelegate().regularItems.add(item4); |
+ mStubbedProvider.getDownloadDelegate().regularItems.add(item5); |
+ mStubbedProvider.getDownloadDelegate().regularItems.add(item6); |
+ mStubbedProvider.getOfflinePageBridge().items.add(item7); |
+ |
+ // Start the activity up. |
+ Intent intent = new Intent(); |
+ intent.setClass(getInstrumentation().getTargetContext(), DownloadActivity.class); |
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
+ setActivityIntent(intent); |
+ return getActivity(); |
+ } |
+ |
+ private void clickOnFilter(final DownloadManagerUi ui, final int position) throws Exception { |
+ int previousCount = mAdapterObserver.onChangedCallback.getCallCount(); |
+ ThreadUtils.runOnUiThread(new Runnable() { |
+ @Override |
+ public void run() { |
+ ui.openDrawer(); |
+ ListView filterList = (ListView) ui.getView().findViewById(R.id.section_list); |
+ filterList.performItemClick( |
+ filterList.getChildAt(filterList.getHeaderViewsCount() + position), |
+ position, filterList.getAdapter().getItemId(position)); |
+ } |
+ }); |
+ mAdapterObserver.onChangedCallback.waitForCallback(previousCount); |
+ } |
+} |