| Index: chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotifierUnitTest.java
|
| diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotifierUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotifierUnitTest.java
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a469d8b0978972078cfece66bd4f016b400c56a2
|
| --- /dev/null
|
| +++ b/chrome/android/junit/src/org/chromium/chrome/browser/download/items/OfflineContentAggregatorNotifierUnitTest.java
|
| @@ -0,0 +1,257 @@
|
| +// 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.Mockito.atLeastOnce;
|
| +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 static org.mockito.Mockito.when;
|
| +
|
| +import org.chromium.chrome.browser.download.items.OfflineContentAggregatorNotifier.NotifierUi;
|
| +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.OfflineItemState.OfflineItemStateEnum;
|
| +import org.chromium.testing.local.LocalRobolectricTestRunner;
|
| +import org.junit.Rule;
|
| +import org.junit.Test;
|
| +import org.junit.runner.RunWith;
|
| +import org.mockito.ArgumentCaptor;
|
| +import org.mockito.ArgumentMatchers;
|
| +import org.mockito.Captor;
|
| +import org.mockito.InOrder;
|
| +import org.mockito.Mock;
|
| +import org.mockito.junit.MockitoJUnit;
|
| +import org.mockito.junit.MockitoRule;
|
| +import org.robolectric.annotation.Config;
|
| +
|
| +import java.util.ArrayList;
|
| +
|
| +/** Unit tests for {@link OfflineContentAggregatorNotifier}. */
|
| +@RunWith(LocalRobolectricTestRunner.class)
|
| +@Config(manifest = Config.NONE)
|
| +public class OfflineContentAggregatorNotifierUnitTest {
|
| + @Mock
|
| + private OfflineContentProvider mProvider;
|
| + @Mock
|
| + private NotifierUi mUi;
|
| +
|
| + @Rule
|
| + public MockitoRule mMockitoRule = MockitoJUnit.rule();
|
| +
|
| + @Captor
|
| + ArgumentCaptor<Runnable> mOnUiNeededCaptor;
|
| +
|
| + private static OfflineItem buildOfflineItem(ContentId id, @OfflineItemStateEnum int state) {
|
| + OfflineItem item = new OfflineItem();
|
| + item.id = id;
|
| + item.state = state;
|
| + return item;
|
| + }
|
| +
|
| + @Test
|
| + public void testOnItemsAddedRunningUi() {
|
| + OfflineContentAggregatorNotifier notifier =
|
| + new OfflineContentAggregatorNotifier(mProvider, mUi);
|
| +
|
| + // Initialize NotifierUi expectations.
|
| + when(mUi.onUiNeeded(ArgumentMatchers.any())).thenReturn(true);
|
| +
|
| + // Initialize OfflineContentProvider expectations.
|
| + 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));
|
| + }
|
| + };
|
| +
|
| + notifier.onItemsAvailable();
|
| + notifier.onItemsAdded(items);
|
| + notifier.destroy();
|
| +
|
| + verify(mProvider, times(1)).addObserver(notifier);
|
| + verify(mUi, atLeastOnce()).onUiNeeded(ArgumentMatchers.any());
|
| +
|
| + InOrder order = inOrder(mUi);
|
| +
|
| + order.verify(mUi, times(1)).updateItem(items.get(0) /* OfflineItemState.IN_PROGRESS */);
|
| + order.verify(mUi, times(1)).updateItem(items.get(1) /* OfflineItemState.PENDING */);
|
| + order.verify(mUi, never()).updateItem(ArgumentMatchers.any());
|
| +
|
| + verify(mUi, never()).onUiNotNeeded();
|
| + verify(mProvider, times(1)).removeObserver(notifier);
|
| + }
|
| +
|
| + @Test
|
| + public void testOnItemsRemovedRunningUi() {
|
| + OfflineContentAggregatorNotifier notifier =
|
| + new OfflineContentAggregatorNotifier(mProvider, mUi);
|
| +
|
| + // Initialize NotifierUi expectations.
|
| + when(mUi.onUiNeeded(ArgumentMatchers.any())).thenReturn(true);
|
| +
|
| + // Initialize OfflineContentProvider expectations.
|
| + ContentId id = new ContentId("1", "A");
|
| +
|
| + notifier.onItemsAvailable();
|
| + notifier.onItemRemoved(id);
|
| + notifier.destroy();
|
| +
|
| + verify(mProvider, times(1)).addObserver(notifier);
|
| + verify(mUi, atLeastOnce()).onUiNeeded(ArgumentMatchers.any());
|
| + verify(mUi, times(1)).removeItem(id);
|
| + verify(mUi, atLeastOnce()).onUiNotNeeded();
|
| + verify(mProvider, times(1)).removeObserver(notifier);
|
| + }
|
| +
|
| + @Test
|
| + public void testOnItemUpdatedRunningUi() {
|
| + OfflineContentAggregatorNotifier notifier =
|
| + new OfflineContentAggregatorNotifier(mProvider, mUi);
|
| +
|
| + // Initialize NotifierUi expectations.
|
| + when(mUi.onUiNeeded(ArgumentMatchers.any())).thenReturn(true);
|
| +
|
| + // Initialize OfflineContentProvider expectations.
|
| + OfflineItem item = buildOfflineItem(new ContentId("1", "A"), OfflineItemState.IN_PROGRESS);
|
| +
|
| + notifier.onItemsAvailable();
|
| + notifier.onItemUpdated(item);
|
| + notifier.destroy();
|
| +
|
| + verify(mProvider, times(1)).addObserver(notifier);
|
| + verify(mUi, atLeastOnce()).onUiNeeded(ArgumentMatchers.any());
|
| + verify(mUi, times(1)).updateItem(item);
|
| + verify(mProvider, times(1)).removeObserver(notifier);
|
| + }
|
| +
|
| + @Test
|
| + public void testUiShutdown() {
|
| + OfflineContentAggregatorNotifier notifier =
|
| + new OfflineContentAggregatorNotifier(mProvider, mUi);
|
| +
|
| + // Initialize NotifierUi expectations.
|
| + when(mUi.onUiNeeded(ArgumentMatchers.any())).thenReturn(true);
|
| +
|
| + // Initialize OfflineContentProvider expectations.
|
| + OfflineItem item = buildOfflineItem(new ContentId("1", "A"), OfflineItemState.IN_PROGRESS);
|
| + OfflineItem itemUpdate = buildOfflineItem(new ContentId("1", "A"), OfflineItemState.PAUSED);
|
| +
|
| + notifier.onItemsAvailable();
|
| + notifier.onItemUpdated(item /* OfflineItemState.IN_PROGRESS */);
|
| + notifier.onItemUpdated(itemUpdate /* OfflineItemState.PAUSED */);
|
| + notifier.destroy();
|
| +
|
| + verify(mProvider, times(1)).addObserver(notifier);
|
| + verify(mUi, atLeastOnce()).onUiNeeded(ArgumentMatchers.any());
|
| + verify(mUi, times(1)).onUiNotNeeded();
|
| + verify(mProvider, times(1)).removeObserver(notifier);
|
| + }
|
| +
|
| + @Test
|
| + public void testQueuesActionsWhileWaitingForUi() {
|
| + OfflineContentAggregatorNotifier notifier =
|
| + new OfflineContentAggregatorNotifier(mProvider, mUi);
|
| +
|
| + // Initialize NotifierUi expectations.
|
| + when(mUi.onUiNeeded(mOnUiNeededCaptor.capture())).thenReturn(false);
|
| +
|
| + // Initialize OfflineContentProvider expectations.
|
| + ContentId id1 = new ContentId("1", "A");
|
| + ContentId id2 = new ContentId("2", "B");
|
| + ContentId id3 = new ContentId("3", "C");
|
| +
|
| + OfflineItem item1 = buildOfflineItem(id1, OfflineItemState.IN_PROGRESS);
|
| + OfflineItem item2 = buildOfflineItem(id2, OfflineItemState.PAUSED);
|
| +
|
| + notifier.onItemsAvailable();
|
| + notifier.onItemUpdated(item1);
|
| + notifier.onItemUpdated(item2);
|
| + notifier.onItemRemoved(id3);
|
| +
|
| + // Grab the captured NotifierUi.onUiNeeded Runnable.
|
| + final Runnable capturedOnReadyEvent = mOnUiNeededCaptor.getValue();
|
| +
|
| + verify(mProvider, times(1)).addObserver(notifier);
|
| + verify(mUi, atLeastOnce()).onUiNeeded(capturedOnReadyEvent);
|
| + verify(mUi, never()).updateItem(ArgumentMatchers.any());
|
| + verify(mUi, never()).removeItem(ArgumentMatchers.any());
|
| +
|
| + when(mUi.onUiNeeded(ArgumentMatchers.any())).thenReturn(true);
|
| + capturedOnReadyEvent.run();
|
| + notifier.destroy();
|
| +
|
| + verify(mUi, times(1)).updateItem(item1);
|
| + verify(mUi, times(1)).updateItem(item2);
|
| + verify(mUi, times(1)).removeItem(id3);
|
| + verify(mProvider, times(1)).removeObserver(notifier);
|
| + }
|
| +
|
| + @Test
|
| + public void testQueuesRemoveStaleEntries() {
|
| + OfflineContentAggregatorNotifier notifier =
|
| + new OfflineContentAggregatorNotifier(mProvider, mUi);
|
| +
|
| + // Initialize NotifierUi expectations.
|
| + when(mUi.onUiNeeded(mOnUiNeededCaptor.capture())).thenReturn(false);
|
| +
|
| + // Initialize OfflineContentProvider expectations.
|
| + ContentId id1 = new ContentId("1", "A");
|
| + ContentId id2 = new ContentId("2", "B");
|
| + ContentId id3 = new ContentId("3", "C");
|
| +
|
| + OfflineItem item1 = buildOfflineItem(id1, OfflineItemState.IN_PROGRESS);
|
| + OfflineItem item1Update = buildOfflineItem(id1, OfflineItemState.PAUSED);
|
| + OfflineItem item2 = buildOfflineItem(id2, OfflineItemState.PAUSED);
|
| + OfflineItem item3 = buildOfflineItem(id3, OfflineItemState.PAUSED);
|
| +
|
| + notifier.onItemsAvailable();
|
| + // 1. Overwrite an item1 "update" with item1Update.
|
| + notifier.onItemUpdated(item1);
|
| + notifier.onItemUpdated(item1Update);
|
| +
|
| + // 2. Overwrite an item2 "update" with a "removal."
|
| + notifier.onItemUpdated(item2);
|
| + notifier.onItemRemoved(id2);
|
| +
|
| + // 3. Overwrite an item3 "removal" with an "update."
|
| + notifier.onItemRemoved(id3);
|
| + notifier.onItemUpdated(item3);
|
| +
|
| + // Grab the captured NotifierUi.onUiNeeded Runnable.
|
| + final Runnable capturedOnReadyEvent = mOnUiNeededCaptor.getValue();
|
| +
|
| + verify(mProvider, times(1)).addObserver(notifier);
|
| + verify(mUi, atLeastOnce()).onUiNeeded(capturedOnReadyEvent);
|
| + verify(mUi, never()).updateItem(ArgumentMatchers.any());
|
| + verify(mUi, never()).removeItem(ArgumentMatchers.any());
|
| +
|
| + when(mUi.onUiNeeded(ArgumentMatchers.any())).thenReturn(true);
|
| + capturedOnReadyEvent.run();
|
| + notifier.destroy();
|
| +
|
| + // 1. Verify only the latest update gets called.
|
| + verify(mUi, never()).updateItem(item1);
|
| + verify(mUi, times(1)).updateItem(item1Update);
|
| +
|
| + // 2. Verify only the removal gets called.
|
| + verify(mUi, never()).updateItem(item2);
|
| + verify(mUi, times(1)).removeItem(id2);
|
| +
|
| + // 3. Verify only the update gets called.
|
| + verify(mUi, never()).removeItem(id3);
|
| + verify(mUi, times(1)).updateItem(item3);
|
| +
|
| + verify(mProvider, times(1)).removeObserver(notifier);
|
| + }
|
| +}
|
|
|