Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 package org.chromium.chrome.browser.download.items; | |
| 6 | |
| 7 import static org.mockito.Mockito.inOrder; | |
| 8 import static org.mockito.Mockito.never; | |
| 9 import static org.mockito.Mockito.times; | |
| 10 import static org.mockito.Mockito.verify; | |
| 11 | |
| 12 import android.graphics.Bitmap; | |
| 13 | |
| 14 import org.chromium.chrome.browser.download.DownloadInfo; | |
| 15 import org.chromium.chrome.browser.download.DownloadNotifier; | |
| 16 import org.chromium.components.offline_items_collection.ContentId; | |
| 17 import org.chromium.components.offline_items_collection.OfflineContentProvider; | |
| 18 import org.chromium.components.offline_items_collection.OfflineItem; | |
| 19 import org.chromium.components.offline_items_collection.OfflineItemState; | |
| 20 import org.chromium.components.offline_items_collection.OfflineItemVisuals; | |
| 21 import org.chromium.testing.local.LocalRobolectricTestRunner; | |
| 22 import org.junit.Assert; | |
| 23 import org.junit.Rule; | |
| 24 import org.junit.Test; | |
| 25 import org.junit.runner.RunWith; | |
| 26 import org.mockito.ArgumentCaptor; | |
| 27 import org.mockito.ArgumentMatchers; | |
| 28 import org.mockito.InOrder; | |
| 29 import org.mockito.Mock; | |
| 30 import org.mockito.junit.MockitoJUnit; | |
| 31 import org.mockito.junit.MockitoRule; | |
| 32 import org.robolectric.annotation.Config; | |
| 33 | |
| 34 import java.util.ArrayList; | |
| 35 import java.util.List; | |
| 36 | |
| 37 /** | |
| 38 * Unit tests for {@link OfflineContentAggregatorNotifierBridgeUi}. Validate th at it interacts with | |
| 39 * both the {@link DownloadNotifier} and the {@link OfflineContentProvider} in e xpected ways. | |
| 40 */ | |
| 41 @RunWith(LocalRobolectricTestRunner.class) | |
| 42 @Config(manifest = Config.NONE) | |
| 43 public class OfflineContentAggregatorNotifierBridgeUiTest { | |
| 44 @Mock | |
| 45 private OfflineContentProvider mProvider; | |
| 46 | |
| 47 @Mock | |
| 48 private DownloadNotifier mNotifier; | |
| 49 | |
| 50 @Rule | |
| 51 public MockitoRule mMockitoRule = MockitoJUnit.rule(); | |
| 52 | |
| 53 private static OfflineItem buildOfflineItem(ContentId id, @OfflineItemState int state) { | |
| 54 OfflineItem item = new OfflineItem(); | |
| 55 item.id = id; | |
| 56 item.state = state; | |
| 57 return item; | |
| 58 } | |
| 59 | |
| 60 @Test | |
| 61 public void testOnlyInterestingNewItemsGetSentToTheUi() { | |
| 62 OfflineContentAggregatorNotificationBridgeUi bridge = | |
|
nyquist
2017/04/13 05:08:24
Should this and the verify-line below be part of a
| |
| 63 new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNot ifier); | |
| 64 verify(mProvider, times(1)).addObserver(bridge); | |
| 65 | |
| 66 ArrayList<OfflineItem> items = new ArrayList<OfflineItem>() { | |
| 67 { | |
| 68 add(buildOfflineItem(new ContentId("1", "A"), OfflineItemState.I N_PROGRESS)); | |
| 69 add(buildOfflineItem(new ContentId("2", "B"), OfflineItemState.P ENDING)); | |
| 70 add(buildOfflineItem(new ContentId("3", "C"), OfflineItemState.C OMPLETE)); | |
| 71 add(buildOfflineItem(new ContentId("4", "D"), OfflineItemState.C ANCELLED)); | |
| 72 add(buildOfflineItem(new ContentId("5", "E"), OfflineItemState.I NTERRUPTED)); | |
| 73 add(buildOfflineItem(new ContentId("6", "F"), OfflineItemState.F AILED)); | |
| 74 add(buildOfflineItem(new ContentId("7", "G"), OfflineItemState.P AUSED)); | |
| 75 } | |
| 76 }; | |
| 77 | |
| 78 bridge.onItemsAvailable(); | |
| 79 bridge.onItemsAdded(items); | |
| 80 | |
| 81 InOrder order = inOrder(mProvider); | |
| 82 order.verify(mProvider, times(1)) | |
| 83 .getVisualsForItem(items.get(0).id /* OfflineItemState.IN_PROGRE SS */, bridge); | |
| 84 order.verify(mProvider, never()) | |
| 85 .getVisualsForItem(ArgumentMatchers.any(), ArgumentMatchers.any( )); | |
| 86 | |
| 87 bridge.onVisualsAvailable(items.get(0).id, new OfflineItemVisuals()); | |
| 88 | |
| 89 // TODO(dtrainor): Flesh out these validations. | |
|
nyquist
2017/04/13 05:08:24
Was this meant as a TODO-before-submit? Or just a
| |
| 90 verify(mNotifier, times(1)) | |
| 91 .notifyDownloadProgress(ArgumentMatchers.any(), ArgumentMatchers .anyLong(), | |
| 92 ArgumentMatchers.anyBoolean()); | |
| 93 | |
| 94 bridge.destroy(); | |
| 95 verify(mProvider, times(1)).removeObserver(bridge); | |
| 96 } | |
| 97 | |
| 98 @Test | |
| 99 public void testItemUpdatesGetSentToTheUi() { | |
| 100 OfflineContentAggregatorNotificationBridgeUi bridge = | |
| 101 new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNot ifier); | |
| 102 verify(mProvider, times(1)).addObserver(bridge); | |
| 103 | |
| 104 ArrayList<OfflineItem> items = new ArrayList<OfflineItem>() { | |
| 105 { | |
| 106 add(buildOfflineItem(new ContentId("1", "A"), OfflineItemState.I N_PROGRESS)); | |
| 107 add(buildOfflineItem(new ContentId("2", "B"), OfflineItemState.P ENDING)); | |
| 108 add(buildOfflineItem(new ContentId("3", "C"), OfflineItemState.C OMPLETE)); | |
| 109 add(buildOfflineItem(new ContentId("4", "D"), OfflineItemState.C ANCELLED)); | |
| 110 add(buildOfflineItem(new ContentId("5", "E"), OfflineItemState.I NTERRUPTED)); | |
| 111 add(buildOfflineItem(new ContentId("6", "F"), OfflineItemState.F AILED)); | |
| 112 add(buildOfflineItem(new ContentId("7", "G"), OfflineItemState.P AUSED)); | |
| 113 } | |
| 114 }; | |
| 115 | |
| 116 bridge.onItemsAvailable(); | |
| 117 for (int i = 0; i < items.size(); i++) bridge.onItemUpdated(items.get(i) ); | |
| 118 | |
| 119 verify(mProvider, times(1)).getVisualsForItem(items.get(0).id, bridge); | |
| 120 verify(mProvider, times(1)).getVisualsForItem(items.get(1).id, bridge); | |
| 121 verify(mProvider, times(1)).getVisualsForItem(items.get(2).id, bridge); | |
| 122 verify(mProvider, never()).getVisualsForItem(items.get(3).id, bridge); | |
| 123 verify(mProvider, times(1)).getVisualsForItem(items.get(4).id, bridge); | |
| 124 verify(mProvider, times(1)).getVisualsForItem(items.get(5).id, bridge); | |
| 125 verify(mProvider, times(1)).getVisualsForItem(items.get(6).id, bridge); | |
| 126 | |
| 127 for (int i = 0; i < items.size(); i++) { | |
| 128 bridge.onVisualsAvailable(items.get(i).id, new OfflineItemVisuals()) ; | |
| 129 } | |
| 130 | |
| 131 // TODO(dtrainor): Flesh out these validations. | |
| 132 verify(mNotifier, times(1)) | |
| 133 .notifyDownloadProgress(ArgumentMatchers.any(), ArgumentMatchers .anyLong(), | |
| 134 ArgumentMatchers.anyBoolean()); | |
| 135 verify(mNotifier, times(1)) | |
| 136 .notifyDownloadSuccessful(ArgumentMatchers.any(), ArgumentMatche rs.anyLong(), | |
| 137 ArgumentMatchers.anyBoolean(), ArgumentMatchers.anyBoole an()); | |
| 138 verify(mNotifier, times(1)) | |
| 139 .notifyDownloadCanceled(items.get(3).id /* OfflineItemState.CANC ELLED */); | |
| 140 verify(mNotifier, times(1)) | |
| 141 .notifyDownloadInterrupted(ArgumentMatchers.any(), ArgumentMatch ers.anyBoolean()); | |
| 142 verify(mNotifier, times(1)).notifyDownloadFailed(ArgumentMatchers.any()) ; | |
| 143 verify(mNotifier, times(1)).notifyDownloadPaused(ArgumentMatchers.any()) ; | |
| 144 | |
| 145 bridge.destroy(); | |
| 146 verify(mProvider, times(1)).removeObserver(bridge); | |
| 147 } | |
| 148 | |
| 149 @Test | |
| 150 public void testNullVisuals() { | |
| 151 OfflineContentAggregatorNotificationBridgeUi bridge = | |
| 152 new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNot ifier); | |
| 153 verify(mProvider, times(1)).addObserver(bridge); | |
| 154 | |
| 155 OfflineItem item1 = buildOfflineItem(new ContentId("1", "A"), OfflineIte mState.IN_PROGRESS); | |
| 156 OfflineItem item2 = buildOfflineItem(new ContentId("2", "B"), OfflineIte mState.IN_PROGRESS); | |
| 157 | |
| 158 OfflineItemVisuals visuals1 = new OfflineItemVisuals(); | |
| 159 visuals1.icon = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); | |
| 160 | |
| 161 bridge.onItemsAvailable(); | |
| 162 bridge.onItemUpdated(item1); | |
| 163 bridge.onItemUpdated(item2); | |
| 164 | |
| 165 verify(mProvider, times(1)).getVisualsForItem(item1.id, bridge); | |
| 166 verify(mProvider, times(1)).getVisualsForItem(item2.id, bridge); | |
| 167 | |
| 168 ArgumentCaptor<DownloadInfo> captor = ArgumentCaptor.forClass(DownloadIn fo.class); | |
| 169 | |
| 170 bridge.onVisualsAvailable(item1.id, visuals1); | |
| 171 bridge.onVisualsAvailable(item2.id, null); | |
| 172 verify(mNotifier, times(2)) | |
| 173 .notifyDownloadProgress(captor.capture(), ArgumentMatchers.anyLo ng(), | |
| 174 ArgumentMatchers.anyBoolean()); | |
| 175 | |
| 176 List<DownloadInfo> capturedInfo = captor.getAllValues(); | |
| 177 Assert.assertEquals(item1.id, capturedInfo.get(0).getContentId()); | |
| 178 Assert.assertEquals(visuals1.icon, capturedInfo.get(0).getIcon()); | |
| 179 Assert.assertEquals(item2.id, capturedInfo.get(1).getContentId()); | |
| 180 Assert.assertEquals(null, capturedInfo.get(1).getIcon()); | |
| 181 | |
| 182 bridge.destroy(); | |
| 183 verify(mProvider, times(1)).removeObserver(bridge); | |
| 184 } | |
| 185 | |
| 186 @Test | |
| 187 public void testRemovedItemsGetRemovedFromTheUi() { | |
| 188 OfflineContentAggregatorNotificationBridgeUi bridge = | |
| 189 new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNot ifier); | |
| 190 verify(mProvider, times(1)).addObserver(bridge); | |
| 191 | |
| 192 ContentId id = new ContentId("1", "A"); | |
| 193 | |
| 194 bridge.onItemsAvailable(); | |
| 195 bridge.onItemRemoved(id); | |
| 196 verify(mNotifier, times(1)).notifyDownloadCanceled(id); | |
| 197 | |
| 198 bridge.destroy(); | |
| 199 verify(mProvider, times(1)).removeObserver(bridge); | |
| 200 } | |
| 201 | |
| 202 @Test | |
| 203 public void testRemovedItemsIgnoreVisualsCallback() { | |
| 204 OfflineContentAggregatorNotificationBridgeUi bridge = | |
| 205 new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNot ifier); | |
| 206 verify(mProvider, times(1)).addObserver(bridge); | |
| 207 | |
| 208 OfflineItem item = buildOfflineItem(new ContentId("1", "A"), OfflineItem State.IN_PROGRESS); | |
| 209 | |
| 210 bridge.onItemsAvailable(); | |
| 211 bridge.onItemUpdated(item); | |
| 212 verify(mProvider, times(1)).getVisualsForItem(item.id, bridge); | |
| 213 | |
| 214 bridge.onItemRemoved(item.id); | |
| 215 bridge.onVisualsAvailable(item.id, new OfflineItemVisuals()); | |
| 216 InOrder order = inOrder(mNotifier); | |
| 217 order.verify(mNotifier, times(1)).notifyDownloadCanceled(item.id); | |
| 218 order.verifyNoMoreInteractions(); | |
| 219 | |
| 220 bridge.destroy(); | |
| 221 verify(mProvider, times(1)).removeObserver(bridge); | |
| 222 } | |
| 223 | |
| 224 @Test | |
| 225 public void testOnlyRequestsVisualsOnceForMultipleUpdates() { | |
| 226 OfflineContentAggregatorNotificationBridgeUi bridge = | |
| 227 new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNot ifier); | |
| 228 verify(mProvider, times(1)).addObserver(bridge); | |
| 229 | |
| 230 OfflineItem item = buildOfflineItem(new ContentId("1", "A"), OfflineItem State.IN_PROGRESS); | |
| 231 | |
| 232 bridge.onItemsAvailable(); | |
| 233 bridge.onItemUpdated(item); | |
| 234 bridge.onItemUpdated(item); | |
| 235 verify(mProvider, times(1)).getVisualsForItem(item.id, bridge); | |
| 236 | |
| 237 bridge.destroy(); | |
| 238 verify(mProvider, times(1)).removeObserver(bridge); | |
| 239 } | |
| 240 | |
| 241 @Test | |
| 242 public void testVisualsAreCachedForInterestingItems() { | |
| 243 OfflineContentAggregatorNotificationBridgeUi bridge = | |
| 244 new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNot ifier); | |
| 245 verify(mProvider, times(1)).addObserver(bridge); | |
| 246 | |
| 247 ArrayList<OfflineItem> interestingItems = new ArrayList<OfflineItem>() { | |
| 248 { | |
| 249 add(buildOfflineItem(new ContentId("1", "A"), OfflineItemState.I N_PROGRESS)); | |
| 250 add(buildOfflineItem(new ContentId("2", "B"), OfflineItemState.P ENDING)); | |
| 251 add(buildOfflineItem(new ContentId("5", "E"), OfflineItemState.I NTERRUPTED)); | |
| 252 add(buildOfflineItem(new ContentId("7", "G"), OfflineItemState.P AUSED)); | |
| 253 } | |
| 254 }; | |
| 255 | |
| 256 ArrayList<OfflineItem> uninterestingItems = new ArrayList<OfflineItem>() { | |
| 257 { | |
| 258 add(buildOfflineItem(new ContentId("3", "C"), OfflineItemState.C OMPLETE)); | |
| 259 add(buildOfflineItem(new ContentId("6", "F"), OfflineItemState.F AILED)); | |
| 260 } | |
| 261 }; | |
| 262 | |
| 263 bridge.onItemsAvailable(); | |
| 264 | |
| 265 for (int i = 0; i < interestingItems.size(); i++) { | |
| 266 OfflineItem item = interestingItems.get(i); | |
| 267 bridge.onItemUpdated(item); | |
| 268 bridge.onVisualsAvailable(item.id, null); | |
| 269 bridge.onItemUpdated(item); | |
| 270 verify(mProvider, times(1)).getVisualsForItem(item.id, bridge); | |
| 271 verify(mNotifier, times(2)) | |
| 272 .notifyDownloadProgress(ArgumentMatchers.any(), ArgumentMatc hers.anyLong(), | |
| 273 ArgumentMatchers.anyBoolean()); | |
| 274 } | |
| 275 | |
| 276 for (int i = 0; i < uninterestingItems.size(); i++) { | |
| 277 OfflineItem item = uninterestingItems.get(i); | |
| 278 bridge.onItemUpdated(item); | |
| 279 bridge.onVisualsAvailable(item.id, null); | |
| 280 bridge.onItemUpdated(item); | |
| 281 verify(mProvider, times(2)).getVisualsForItem(item.id, bridge); | |
| 282 } | |
| 283 | |
| 284 bridge.destroy(); | |
| 285 verify(mProvider, times(1)).removeObserver(bridge); | |
| 286 } | |
| 287 | |
| 288 @Test | |
| 289 public void testVisualsGetClearedForUninterestingItems() { | |
| 290 OfflineContentAggregatorNotificationBridgeUi bridge = | |
| 291 new OfflineContentAggregatorNotificationBridgeUi(mProvider, mNot ifier); | |
| 292 verify(mProvider, times(1)).addObserver(bridge); | |
| 293 | |
| 294 ContentId id = new ContentId("1", "A"); | |
| 295 OfflineItem item1 = buildOfflineItem(id, OfflineItemState.IN_PROGRESS); | |
| 296 OfflineItem item2 = buildOfflineItem(id, OfflineItemState.FAILED); | |
| 297 OfflineItem item3 = buildOfflineItem(id, OfflineItemState.IN_PROGRESS); | |
| 298 | |
| 299 bridge.onItemsAvailable(); | |
| 300 bridge.onItemUpdated(item1); | |
| 301 bridge.onVisualsAvailable(item1.id, new OfflineItemVisuals()); | |
| 302 bridge.onItemUpdated(item2); | |
| 303 bridge.onItemUpdated(item3); | |
| 304 bridge.onVisualsAvailable(item1.id, new OfflineItemVisuals()); | |
| 305 verify(mProvider, times(2)).getVisualsForItem(id, bridge); | |
| 306 | |
| 307 bridge.destroy(); | |
| 308 verify(mProvider, times(1)).removeObserver(bridge); | |
| 309 } | |
| 310 } | |
| OLD | NEW |