Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2897)

Unified Diff: chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiTest.java

Issue 2811803006: Add support for pulling icons for OfflineItems (Closed)
Patch Set: More findbugs Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiTest.java
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..2947237bcfa6099043665b961709134b19fb8308
--- /dev/null
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotificationBridgeUiTest.java
@@ -0,0 +1,334 @@
+// Copyright 2017 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.items;
+
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.graphics.Bitmap;
+
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.ArgumentMatchers;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.annotation.Config;
+
+import org.chromium.chrome.browser.download.DownloadInfo;
+import org.chromium.chrome.browser.download.DownloadNotifier;
+import org.chromium.components.offline_items_collection.ContentId;
+import org.chromium.components.offline_items_collection.OfflineContentProvider;
+import org.chromium.components.offline_items_collection.OfflineItem;
+import org.chromium.components.offline_items_collection.OfflineItemState;
+import org.chromium.components.offline_items_collection.OfflineItemVisuals;
+import org.chromium.testing.local.LocalRobolectricTestRunner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Unit tests for {@link OfflineContentAggregatorNotifierBridgeUi}. Validate that it interacts with
+ * both the {@link DownloadNotifier} and the {@link OfflineContentProvider} in expected ways.
+ */
+@RunWith(LocalRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class OfflineContentAggregatorNotificationBridgeUiTest {
+ /** Helper class to validate that a DownloadInfo has the right ContentId. */
+ static class DownloadInfoIdMatcher implements ArgumentMatcher<DownloadInfo> {
+ private final ContentId mExpectedId;
+
+ public DownloadInfoIdMatcher(ContentId expected) {
+ mExpectedId = expected;
+ }
+
+ @Override
+ public boolean matches(DownloadInfo argument) {
+ return ((DownloadInfo) argument).getContentId().equals(mExpectedId);
+ }
+
+ @Override
+ public String toString() {
+ return mExpectedId == null ? null : mExpectedId.toString();
+ }
+ }
+
+ @Mock
+ private OfflineContentProvider mProvider;
+
+ @Mock
+ private DownloadNotifier mNotifier;
+
+ @Rule
+ public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ private static OfflineItem buildOfflineItem(ContentId id, @OfflineItemState int state) {
+ OfflineItem item = new OfflineItem();
+ item.id = id;
+ item.state = state;
+ return item;
+ }
+
+ @Test
+ public void testOnlyInterestingNewItemsGetSentToTheUi() {
+ OfflineContentAggregatorNotificationBridgeUi bridge =
+ new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNotifier);
+ verify(mProvider, times(1)).addObserver(bridge);
+
+ ArrayList<OfflineItem> items = new ArrayList<OfflineItem>() {
+ {
+ add(buildOfflineItem(new ContentId("1", "A"), OfflineItemState.IN_PROGRESS));
+ add(buildOfflineItem(new ContentId("2", "B"), OfflineItemState.PENDING));
+ add(buildOfflineItem(new ContentId("3", "C"), OfflineItemState.COMPLETE));
+ add(buildOfflineItem(new ContentId("4", "D"), OfflineItemState.CANCELLED));
+ add(buildOfflineItem(new ContentId("5", "E"), OfflineItemState.INTERRUPTED));
+ add(buildOfflineItem(new ContentId("6", "F"), OfflineItemState.FAILED));
+ add(buildOfflineItem(new ContentId("7", "G"), OfflineItemState.PAUSED));
+ }
+ };
+
+ bridge.onItemsAvailable();
+ bridge.onItemsAdded(items);
+
+ InOrder order = inOrder(mProvider);
+ order.verify(mProvider, times(1))
+ .getVisualsForItem(items.get(0).id /* OfflineItemState.IN_PROGRESS */, bridge);
+ order.verify(mProvider, never())
+ .getVisualsForItem(ArgumentMatchers.any(), ArgumentMatchers.any());
+
+ bridge.onVisualsAvailable(items.get(0).id, new OfflineItemVisuals());
+
+ verify(mNotifier, times(1))
+ .notifyDownloadProgress(argThat(new DownloadInfoIdMatcher(items.get(0).id)),
+ ArgumentMatchers.anyLong(), ArgumentMatchers.anyBoolean());
+
+ bridge.destroy();
+ verify(mProvider, times(1)).removeObserver(bridge);
+ }
+
+ @Test
+ public void testItemUpdatesGetSentToTheUi() {
+ OfflineContentAggregatorNotificationBridgeUi bridge =
+ new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNotifier);
+ verify(mProvider, times(1)).addObserver(bridge);
+
+ ArrayList<OfflineItem> items = new ArrayList<OfflineItem>() {
+ {
+ add(buildOfflineItem(new ContentId("1", "A"), OfflineItemState.IN_PROGRESS));
+ add(buildOfflineItem(new ContentId("2", "B"), OfflineItemState.PENDING));
+ add(buildOfflineItem(new ContentId("3", "C"), OfflineItemState.COMPLETE));
+ add(buildOfflineItem(new ContentId("4", "D"), OfflineItemState.CANCELLED));
+ add(buildOfflineItem(new ContentId("5", "E"), OfflineItemState.INTERRUPTED));
+ add(buildOfflineItem(new ContentId("6", "F"), OfflineItemState.FAILED));
+ add(buildOfflineItem(new ContentId("7", "G"), OfflineItemState.PAUSED));
+ }
+ };
+
+ bridge.onItemsAvailable();
+ for (int i = 0; i < items.size(); i++) bridge.onItemUpdated(items.get(i));
+
+ verify(mProvider, times(1)).getVisualsForItem(items.get(0).id, bridge);
+ verify(mProvider, times(1)).getVisualsForItem(items.get(1).id, bridge);
+ verify(mProvider, times(1)).getVisualsForItem(items.get(2).id, bridge);
+ verify(mProvider, never()).getVisualsForItem(items.get(3).id, bridge);
+ verify(mProvider, times(1)).getVisualsForItem(items.get(4).id, bridge);
+ verify(mProvider, times(1)).getVisualsForItem(items.get(5).id, bridge);
+ verify(mProvider, times(1)).getVisualsForItem(items.get(6).id, bridge);
+
+ for (int i = 0; i < items.size(); i++) {
+ bridge.onVisualsAvailable(items.get(i).id, new OfflineItemVisuals());
+ }
+
+ verify(mNotifier, times(1))
+ .notifyDownloadProgress(argThat(new DownloadInfoIdMatcher(items.get(0).id)),
+ ArgumentMatchers.anyLong(), ArgumentMatchers.anyBoolean());
+ verify(mNotifier, times(1))
+ .notifyDownloadSuccessful(argThat(new DownloadInfoIdMatcher(items.get(2).id)),
+ ArgumentMatchers.anyLong(), ArgumentMatchers.anyBoolean(),
+ ArgumentMatchers.anyBoolean());
+ verify(mNotifier, times(1))
+ .notifyDownloadCanceled(items.get(3).id /* OfflineItemState.CANCELLED */);
+ verify(mNotifier, times(1))
+ .notifyDownloadInterrupted(argThat(new DownloadInfoIdMatcher(items.get(4).id)),
+ ArgumentMatchers.anyBoolean());
+ verify(mNotifier, times(1))
+ .notifyDownloadFailed(argThat(new DownloadInfoIdMatcher(items.get(5).id)));
+ verify(mNotifier, times(1))
+ .notifyDownloadPaused(argThat(new DownloadInfoIdMatcher(items.get(6).id)));
+
+ bridge.destroy();
+ verify(mProvider, times(1)).removeObserver(bridge);
+ }
+
+ @Test
+ public void testNullVisuals() {
+ OfflineContentAggregatorNotificationBridgeUi bridge =
+ new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNotifier);
+ verify(mProvider, times(1)).addObserver(bridge);
+
+ OfflineItem item1 = buildOfflineItem(new ContentId("1", "A"), OfflineItemState.IN_PROGRESS);
+ OfflineItem item2 = buildOfflineItem(new ContentId("2", "B"), OfflineItemState.IN_PROGRESS);
+
+ OfflineItemVisuals visuals1 = new OfflineItemVisuals();
+ visuals1.icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+
+ bridge.onItemsAvailable();
+ bridge.onItemUpdated(item1);
+ bridge.onItemUpdated(item2);
+
+ verify(mProvider, times(1)).getVisualsForItem(item1.id, bridge);
+ verify(mProvider, times(1)).getVisualsForItem(item2.id, bridge);
+
+ ArgumentCaptor<DownloadInfo> captor = ArgumentCaptor.forClass(DownloadInfo.class);
+
+ bridge.onVisualsAvailable(item1.id, visuals1);
+ bridge.onVisualsAvailable(item2.id, null);
+ verify(mNotifier, times(2))
+ .notifyDownloadProgress(captor.capture(), ArgumentMatchers.anyLong(),
+ ArgumentMatchers.anyBoolean());
+
+ List<DownloadInfo> capturedInfo = captor.getAllValues();
+ Assert.assertEquals(item1.id, capturedInfo.get(0).getContentId());
+ Assert.assertEquals(visuals1.icon, capturedInfo.get(0).getIcon());
+ Assert.assertEquals(item2.id, capturedInfo.get(1).getContentId());
+ Assert.assertEquals(null, capturedInfo.get(1).getIcon());
+
+ bridge.destroy();
+ verify(mProvider, times(1)).removeObserver(bridge);
+ }
+
+ @Test
+ public void testRemovedItemsGetRemovedFromTheUi() {
+ OfflineContentAggregatorNotificationBridgeUi bridge =
+ new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNotifier);
+ verify(mProvider, times(1)).addObserver(bridge);
+
+ ContentId id = new ContentId("1", "A");
+
+ bridge.onItemsAvailable();
+ bridge.onItemRemoved(id);
+ verify(mNotifier, times(1)).notifyDownloadCanceled(id);
+
+ bridge.destroy();
+ verify(mProvider, times(1)).removeObserver(bridge);
+ }
+
+ @Test
+ public void testRemovedItemsIgnoreVisualsCallback() {
+ OfflineContentAggregatorNotificationBridgeUi bridge =
+ new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNotifier);
+ verify(mProvider, times(1)).addObserver(bridge);
+
+ OfflineItem item = buildOfflineItem(new ContentId("1", "A"), OfflineItemState.IN_PROGRESS);
+
+ bridge.onItemsAvailable();
+ bridge.onItemUpdated(item);
+ verify(mProvider, times(1)).getVisualsForItem(item.id, bridge);
+
+ bridge.onItemRemoved(item.id);
+ bridge.onVisualsAvailable(item.id, new OfflineItemVisuals());
+ InOrder order = inOrder(mNotifier);
+ order.verify(mNotifier, times(1)).notifyDownloadCanceled(item.id);
+ order.verifyNoMoreInteractions();
+
+ bridge.destroy();
+ verify(mProvider, times(1)).removeObserver(bridge);
+ }
+
+ @Test
+ public void testOnlyRequestsVisualsOnceForMultipleUpdates() {
+ OfflineContentAggregatorNotificationBridgeUi bridge =
+ new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNotifier);
+ verify(mProvider, times(1)).addObserver(bridge);
+
+ OfflineItem item = buildOfflineItem(new ContentId("1", "A"), OfflineItemState.IN_PROGRESS);
+
+ bridge.onItemsAvailable();
+ bridge.onItemUpdated(item);
+ bridge.onItemUpdated(item);
+ verify(mProvider, times(1)).getVisualsForItem(item.id, bridge);
+
+ bridge.destroy();
+ verify(mProvider, times(1)).removeObserver(bridge);
+ }
+
+ @Test
+ public void testVisualsAreCachedForInterestingItems() {
+ OfflineContentAggregatorNotificationBridgeUi bridge =
+ new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNotifier);
+ verify(mProvider, times(1)).addObserver(bridge);
+
+ ArrayList<OfflineItem> interestingItems = new ArrayList<OfflineItem>() {
+ {
+ add(buildOfflineItem(new ContentId("1", "A"), OfflineItemState.IN_PROGRESS));
+ add(buildOfflineItem(new ContentId("2", "B"), OfflineItemState.PENDING));
+ add(buildOfflineItem(new ContentId("5", "E"), OfflineItemState.INTERRUPTED));
+ add(buildOfflineItem(new ContentId("7", "G"), OfflineItemState.PAUSED));
+ }
+ };
+
+ ArrayList<OfflineItem> uninterestingItems = new ArrayList<OfflineItem>() {
+ {
+ add(buildOfflineItem(new ContentId("3", "C"), OfflineItemState.COMPLETE));
+ add(buildOfflineItem(new ContentId("6", "F"), OfflineItemState.FAILED));
+ }
+ };
+
+ bridge.onItemsAvailable();
+
+ for (int i = 0; i < interestingItems.size(); i++) {
+ OfflineItem item = interestingItems.get(i);
+ bridge.onItemUpdated(item);
+ bridge.onVisualsAvailable(item.id, null);
+ bridge.onItemUpdated(item);
+ verify(mProvider, times(1)).getVisualsForItem(item.id, bridge);
+ verify(mNotifier, times(2))
+ .notifyDownloadProgress(ArgumentMatchers.any(), ArgumentMatchers.anyLong(),
+ ArgumentMatchers.anyBoolean());
+ }
+
+ for (int i = 0; i < uninterestingItems.size(); i++) {
+ OfflineItem item = uninterestingItems.get(i);
+ bridge.onItemUpdated(item);
+ bridge.onVisualsAvailable(item.id, null);
+ bridge.onItemUpdated(item);
+ verify(mProvider, times(2)).getVisualsForItem(item.id, bridge);
+ }
+
+ bridge.destroy();
+ verify(mProvider, times(1)).removeObserver(bridge);
+ }
+
+ @Test
+ public void testVisualsGetClearedForUninterestingItems() {
+ OfflineContentAggregatorNotificationBridgeUi bridge =
+ new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNotifier);
+ verify(mProvider, times(1)).addObserver(bridge);
+
+ ContentId id = new ContentId("1", "A");
+ OfflineItem item1 = buildOfflineItem(id, OfflineItemState.IN_PROGRESS);
+ OfflineItem item2 = buildOfflineItem(id, OfflineItemState.FAILED);
+ OfflineItem item3 = buildOfflineItem(id, OfflineItemState.IN_PROGRESS);
+
+ bridge.onItemsAvailable();
+ bridge.onItemUpdated(item1);
+ bridge.onVisualsAvailable(item1.id, new OfflineItemVisuals());
+ bridge.onItemUpdated(item2);
+ bridge.onItemUpdated(item3);
+ bridge.onVisualsAvailable(item1.id, new OfflineItemVisuals());
+ verify(mProvider, times(2)).getVisualsForItem(id, bridge);
+
+ bridge.destroy();
+ verify(mProvider, times(1)).removeObserver(bridge);
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698