| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 package org.chromium.chrome.browser.ntp.cards; | 5 package org.chromium.chrome.browser.ntp.cards; |
| 6 | 6 |
| 7 import static org.junit.Assert.assertEquals; | 7 import static org.junit.Assert.assertEquals; |
| 8 import static org.junit.Assert.assertFalse; | 8 import static org.junit.Assert.assertFalse; |
| 9 import static org.junit.Assert.assertNotEquals; | 9 import static org.junit.Assert.assertNotEquals; |
| 10 import static org.junit.Assert.assertThat; | 10 import static org.junit.Assert.assertThat; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 import org.chromium.chrome.browser.ntp.snippets.CategoryInt; | 60 import org.chromium.chrome.browser.ntp.snippets.CategoryInt; |
| 61 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus; | 61 import org.chromium.chrome.browser.ntp.snippets.CategoryStatus; |
| 62 import org.chromium.chrome.browser.ntp.snippets.FakeSuggestionsSource; | 62 import org.chromium.chrome.browser.ntp.snippets.FakeSuggestionsSource; |
| 63 import org.chromium.chrome.browser.ntp.snippets.KnownCategories; | 63 import org.chromium.chrome.browser.ntp.snippets.KnownCategories; |
| 64 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; | 64 import org.chromium.chrome.browser.ntp.snippets.SnippetArticle; |
| 65 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; | 65 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge; |
| 66 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; | 66 import org.chromium.chrome.browser.preferences.ChromePreferenceManager; |
| 67 import org.chromium.chrome.browser.signin.SigninManager; | 67 import org.chromium.chrome.browser.signin.SigninManager; |
| 68 import org.chromium.chrome.browser.signin.SigninManager.SignInAllowedObserver; | 68 import org.chromium.chrome.browser.signin.SigninManager.SignInAllowedObserver; |
| 69 import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; | 69 import org.chromium.chrome.browser.signin.SigninManager.SignInStateObserver; |
| 70 import org.chromium.chrome.browser.suggestions.SuggestionsMetricsReporter; |
| 70 import org.chromium.testing.local.LocalRobolectricTestRunner; | 71 import org.chromium.testing.local.LocalRobolectricTestRunner; |
| 71 | 72 |
| 72 import java.util.ArrayList; | 73 import java.util.ArrayList; |
| 73 import java.util.Collections; | 74 import java.util.Collections; |
| 74 import java.util.HashMap; | 75 import java.util.HashMap; |
| 75 import java.util.List; | 76 import java.util.List; |
| 76 import java.util.Locale; | 77 import java.util.Locale; |
| 77 | 78 |
| 78 /** | 79 /** |
| 79 * Unit tests for {@link NewTabPageAdapter}. | 80 * Unit tests for {@link NewTabPageAdapter}. |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 RecordUserAction.disableForTests(); | 204 RecordUserAction.disableForTests(); |
| 204 | 205 |
| 205 @CategoryInt | 206 @CategoryInt |
| 206 final int category = KnownCategories.ARTICLES; | 207 final int category = KnownCategories.ARTICLES; |
| 207 mSource = new FakeSuggestionsSource(); | 208 mSource = new FakeSuggestionsSource(); |
| 208 mSource.setStatusForCategory(category, CategoryStatus.INITIALIZING); | 209 mSource.setStatusForCategory(category, CategoryStatus.INITIALIZING); |
| 209 mSource.setInfoForCategory(category, | 210 mSource.setInfoForCategory(category, |
| 210 new CategoryInfoBuilder(category).showIfEmpty().build()); | 211 new CategoryInfoBuilder(category).showIfEmpty().build()); |
| 211 | 212 |
| 212 when(mNewTabPageManager.getSuggestionsSource()).thenReturn(mSource); | 213 when(mNewTabPageManager.getSuggestionsSource()).thenReturn(mSource); |
| 214 when(mNewTabPageManager.getSuggestionsMetricsReporter()) |
| 215 .thenReturn(mock(SuggestionsMetricsReporter.class)); |
| 213 when(mNewTabPageManager.isCurrentPage()).thenReturn(true); | 216 when(mNewTabPageManager.isCurrentPage()).thenReturn(true); |
| 214 | 217 |
| 215 reloadNtp(); | 218 reloadNtp(); |
| 216 } | 219 } |
| 217 | 220 |
| 218 @After | 221 @After |
| 219 public void tearDown() { | 222 public void tearDown() { |
| 220 SigninManager.setInstanceForTesting(null); | 223 SigninManager.setInstanceForTesting(null); |
| 221 ChromePreferenceManager.getInstance(RuntimeEnvironment.application) | 224 ChromePreferenceManager.getInstance(RuntimeEnvironment.application) |
| 222 .setNewTabPageSigninPromoDismissed(false); | 225 .setNewTabPageSigninPromoDismissed(false); |
| 223 } | 226 } |
| 224 | 227 |
| 225 /** | 228 /** |
| 226 * Tests the content of the adapter under standard conditions: on start and
after a suggestions | 229 * Tests the content of the adapter under standard conditions: on start and
after a suggestions |
| 227 * fetch. | 230 * fetch. |
| 228 */ | 231 */ |
| 229 @Test | 232 @Test |
| 230 @Feature({"Ntp"}) | 233 @Feature({"Ntp"}) |
| 231 public void testSuggestionLoading() { | 234 public void testSuggestionLoading() { |
| 232 assertItemsFor(sectionWithStatusCard().withProgress()); | 235 assertItemsFor(sectionWithStatusCard().withProgress()); |
| 233 | 236 |
| 234 final int numSuggestions = 3; | 237 final int numSuggestions = 3; |
| 235 List<SnippetArticle> suggestions = createDummySuggestions(numSuggestions
); | 238 List<SnippetArticle> suggestions = |
| 239 createDummySuggestions(numSuggestions, KnownCategories.ARTICLES)
; |
| 236 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 240 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 237 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; | 241 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; |
| 238 | 242 |
| 239 assertItemsFor(section(numSuggestions)); | 243 assertItemsFor(section(numSuggestions)); |
| 240 } | 244 } |
| 241 | 245 |
| 242 /** | 246 /** |
| 243 * Tests that the adapter keeps listening for suggestion updates. | 247 * Tests that the adapter keeps listening for suggestion updates. |
| 244 */ | 248 */ |
| 245 @Test | 249 @Test |
| 246 @Feature({"Ntp"}) | 250 @Feature({"Ntp"}) |
| 247 public void testSuggestionLoadingInitiallyEmpty() { | 251 public void testSuggestionLoadingInitiallyEmpty() { |
| 252 final int category = KnownCategories.ARTICLES; |
| 253 |
| 248 // If we don't get anything, we should be in the same situation as the i
nitial one. | 254 // If we don't get anything, we should be in the same situation as the i
nitial one. |
| 249 mSource.setSuggestionsForCategory( | 255 mSource.setSuggestionsForCategory(category, new ArrayList<SnippetArticle
>()); |
| 250 KnownCategories.ARTICLES, new ArrayList<SnippetArticle>()); | |
| 251 assertItemsFor(sectionWithStatusCard().withProgress()); | 256 assertItemsFor(sectionWithStatusCard().withProgress()); |
| 252 | 257 |
| 253 // We should load new suggestions when we get notified about them. | 258 // We should load new suggestions when we get notified about them. |
| 254 final int numSuggestions = 5; | 259 final int numSuggestions = 5; |
| 255 List<SnippetArticle> suggestions = createDummySuggestions(numSuggestions
); | 260 |
| 256 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 261 List<SnippetArticle> suggestions = createDummySuggestions(numSuggestions
, category); |
| 257 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; | 262 mSource.setStatusForCategory(category, CategoryStatus.AVAILABLE); |
| 263 mSource.setSuggestionsForCategory(category, suggestions); |
| 258 | 264 |
| 259 assertItemsFor(section(numSuggestions)); | 265 assertItemsFor(section(numSuggestions)); |
| 260 } | 266 } |
| 261 | 267 |
| 262 /** | 268 /** |
| 263 * Tests that the adapter clears the suggestions when asked to. | 269 * Tests that the adapter clears the suggestions when asked to. |
| 264 */ | 270 */ |
| 265 @Test | 271 @Test |
| 266 @Feature({"Ntp"}) | 272 @Feature({"Ntp"}) |
| 267 public void testSuggestionClearing() { | 273 public void testSuggestionClearing() { |
| 268 List<SnippetArticle> suggestions = createDummySuggestions(4); | 274 List<SnippetArticle> suggestions = createDummySuggestions(4, KnownCatego
ries.ARTICLES); |
| 269 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 275 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 270 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; | 276 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; |
| 271 assertItemsFor(section(4)); | 277 assertItemsFor(section(4)); |
| 272 | 278 |
| 273 // If we get told that the category is enabled, we just leave the curren
t suggestions do not | 279 // If we get told that the category is enabled, we just leave the curren
t suggestions do not |
| 274 // clear them. | 280 // clear them. |
| 275 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 281 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 276 assertItemsFor(section(4)); | 282 assertItemsFor(section(4)); |
| 277 | 283 |
| 278 // When the category is disabled, the suggestions are cleared and we sho
uld go back to | 284 // When the category is disabled, the suggestions are cleared and we sho
uld go back to |
| 279 // the situation with the status card. | 285 // the situation with the status card. |
| 280 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.SI
GNED_OUT); | 286 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.SI
GNED_OUT); |
| 281 assertItemsFor(sectionWithStatusCard()); | 287 assertItemsFor(sectionWithStatusCard()); |
| 282 | 288 |
| 283 // The adapter should now be waiting for new suggestions. | 289 // The adapter should now be waiting for new suggestions. |
| 284 suggestions = createDummySuggestions(6); | 290 suggestions = createDummySuggestions(6, KnownCategories.ARTICLES); |
| 285 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 291 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 286 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; | 292 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; |
| 287 assertItemsFor(section(6)); | 293 assertItemsFor(section(6)); |
| 288 } | 294 } |
| 289 | 295 |
| 290 /** | 296 /** |
| 291 * Tests that the adapter loads suggestions only when the status is favorabl
e. | 297 * Tests that the adapter loads suggestions only when the status is favorabl
e. |
| 292 */ | 298 */ |
| 293 @Test | 299 @Test |
| 294 @Feature({"Ntp"}) | 300 @Feature({"Ntp"}) |
| 295 public void testSuggestionLoadingBlock() { | 301 public void testSuggestionLoadingBlock() { |
| 296 List<SnippetArticle> suggestions = createDummySuggestions(3); | 302 List<SnippetArticle> suggestions = createDummySuggestions(3, KnownCatego
ries.ARTICLES); |
| 297 | 303 |
| 298 // By default, status is INITIALIZING, so we can load suggestions. | 304 // By default, status is INITIALIZING, so we can load suggestions. |
| 299 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 305 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 300 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; | 306 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; |
| 301 assertItemsFor(section(3)); | 307 assertItemsFor(section(3)); |
| 302 | 308 |
| 303 // Add another snippet. | 309 // Add another snippet. |
| 304 suggestions.add(new SnippetArticle(0, "https://site.com/url1", "title1",
"pub1", "txt1", | 310 suggestions.add(new SnippetArticle(KnownCategories.ARTICLES, "https://si
te.com/url1", |
| 305 "https://site.com/url1", 0, 0, 0)); | 311 "title1", "pub1", "txt1", "https://site.com/url1", 0, 0)); |
| 306 | 312 |
| 307 // When snippets are disabled, we should not be able to load them. | 313 // When snippets are disabled, we should not be able to load them. |
| 308 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.SI
GNED_OUT); | 314 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.SI
GNED_OUT); |
| 309 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; | 315 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; |
| 310 assertItemsFor(sectionWithStatusCard()); | 316 assertItemsFor(sectionWithStatusCard()); |
| 311 | 317 |
| 312 // INITIALIZING lets us load snippets still. | 318 // INITIALIZING lets us load snippets still. |
| 313 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.IN
ITIALIZING); | 319 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.IN
ITIALIZING); |
| 314 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; | 320 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, suggestions)
; |
| 315 assertItemsFor(sectionWithStatusCard().withProgress()); | 321 assertItemsFor(sectionWithStatusCard().withProgress()); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 343 assertFalse(progress.isVisible()); | 349 assertFalse(progress.isVisible()); |
| 344 } | 350 } |
| 345 | 351 |
| 346 /** | 352 /** |
| 347 * Tests that the entire section disappears if its status switches to LOADIN
G_ERROR or | 353 * Tests that the entire section disappears if its status switches to LOADIN
G_ERROR or |
| 348 * CATEGORY_EXPLICITLY_DISABLED. Also tests that they are not shown when the
NTP reloads. | 354 * CATEGORY_EXPLICITLY_DISABLED. Also tests that they are not shown when the
NTP reloads. |
| 349 */ | 355 */ |
| 350 @Test | 356 @Test |
| 351 @Feature({"Ntp"}) | 357 @Feature({"Ntp"}) |
| 352 public void testSectionClearingWhenUnavailable() { | 358 public void testSectionClearingWhenUnavailable() { |
| 353 List<SnippetArticle> snippets = createDummySuggestions(5); | 359 List<SnippetArticle> snippets = createDummySuggestions(5, KnownCategorie
s.ARTICLES); |
| 354 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 360 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 355 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); | 361 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); |
| 356 assertItemsFor(section(5)); | 362 assertItemsFor(section(5)); |
| 357 | 363 |
| 358 // When the category goes away with a hard error, the section is cleared
from the UI. | 364 // When the category goes away with a hard error, the section is cleared
from the UI. |
| 359 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.LO
ADING_ERROR); | 365 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.LO
ADING_ERROR); |
| 360 assertItemsFor(); | 366 assertItemsFor(); |
| 361 | 367 |
| 362 // Same when loading a new NTP. | 368 // Same when loading a new NTP. |
| 363 reloadNtp(); | 369 reloadNtp(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 375 reloadNtp(); | 381 reloadNtp(); |
| 376 assertItemsFor(); | 382 assertItemsFor(); |
| 377 } | 383 } |
| 378 | 384 |
| 379 /** | 385 /** |
| 380 * Tests that the UI remains untouched if a category switches to NOT_PROVIDE
D. | 386 * Tests that the UI remains untouched if a category switches to NOT_PROVIDE
D. |
| 381 */ | 387 */ |
| 382 @Test | 388 @Test |
| 383 @Feature({"Ntp"}) | 389 @Feature({"Ntp"}) |
| 384 public void testUIUntouchedWhenNotProvided() { | 390 public void testUIUntouchedWhenNotProvided() { |
| 385 List<SnippetArticle> snippets = createDummySuggestions(4); | 391 List<SnippetArticle> snippets = createDummySuggestions(4, KnownCategorie
s.ARTICLES); |
| 386 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 392 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 387 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); | 393 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); |
| 388 assertItemsFor(section(4)); | 394 assertItemsFor(section(4)); |
| 389 | 395 |
| 390 // When the category switches to NOT_PROVIDED, UI stays the same. | 396 // When the category switches to NOT_PROVIDED, UI stays the same. |
| 391 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.NO
T_PROVIDED); | 397 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.NO
T_PROVIDED); |
| 392 mSource.silentlyRemoveCategory(KnownCategories.ARTICLES); | 398 mSource.silentlyRemoveCategory(KnownCategories.ARTICLES); |
| 393 assertItemsFor(section(4)); | 399 assertItemsFor(section(4)); |
| 394 | 400 |
| 395 reloadNtp(); | 401 reloadNtp(); |
| 396 assertItemsFor(); | 402 assertItemsFor(); |
| 397 } | 403 } |
| 398 | 404 |
| 399 /** | 405 /** |
| 400 * Tests that the UI updates on updated suggestions. | 406 * Tests that the UI updates on updated suggestions. |
| 401 */ | 407 */ |
| 402 @Test | 408 @Test |
| 403 @Feature({"Ntp"}) | 409 @Feature({"Ntp"}) |
| 404 public void testUIUpdatesOnNewSuggestionsWhenOtherSectionSeen() { | 410 public void testUIUpdatesOnNewSuggestionsWhenOtherSectionSeen() { |
| 405 List<SnippetArticle> snippets = createDummySuggestions(4); | 411 List<SnippetArticle> snippets = createDummySuggestions(4, KnownCategorie
s.ARTICLES); |
| 406 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 412 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 407 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); | 413 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); |
| 408 | 414 |
| 409 List<SnippetArticle> bookmarks = createDummySuggestions(2); | 415 List<SnippetArticle> bookmarks = createDummySuggestions(2, KnownCategori
es.BOOKMARKS); |
| 410 mSource.setStatusForCategory(KnownCategories.BOOKMARKS, CategoryStatus.A
VAILABLE); | 416 mSource.setStatusForCategory(KnownCategories.BOOKMARKS, CategoryStatus.A
VAILABLE); |
| 411 mSource.setInfoForCategory(KnownCategories.BOOKMARKS, | 417 mSource.setInfoForCategory(KnownCategories.BOOKMARKS, |
| 412 new CategoryInfoBuilder(KnownCategories.BOOKMARKS).showIfEmpty()
.build()); | 418 new CategoryInfoBuilder(KnownCategories.BOOKMARKS).showIfEmpty()
.build()); |
| 413 mSource.setSuggestionsForCategory(KnownCategories.BOOKMARKS, bookmarks); | 419 mSource.setSuggestionsForCategory(KnownCategories.BOOKMARKS, bookmarks); |
| 414 | 420 |
| 415 reloadNtp(); | 421 reloadNtp(); |
| 416 assertItemsFor(section(4), section(2)); | 422 assertItemsFor(section(4), section(2)); |
| 417 | 423 |
| 418 mAdapter.getSectionListForTesting() | 424 mAdapter.getSectionListForTesting() |
| 419 .getSectionForTesting(KnownCategories.BOOKMARKS) | 425 .getSectionForTesting(KnownCategories.BOOKMARKS) |
| 420 .childSeen(2); | 426 .childSeen(2); |
| 421 | 427 |
| 422 List<SnippetArticle> newSnippets = createDummySuggestions(3); | 428 List<SnippetArticle> newSnippets = createDummySuggestions(3, KnownCatego
ries.ARTICLES); |
| 423 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, newSnippets)
; | 429 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, newSnippets)
; |
| 424 assertItemsFor(section(3), section(2)); | 430 assertItemsFor(section(3), section(2)); |
| 425 | 431 |
| 426 reloadNtp(); | 432 reloadNtp(); |
| 427 assertItemsFor(section(3), section(2)); | 433 assertItemsFor(section(3), section(2)); |
| 428 } | 434 } |
| 429 | 435 |
| 430 /** | 436 /** |
| 431 * Tests that the UI updates the first item of the section if the first item
of some other | 437 * Tests that the UI updates the first item of the section if the first item
of some other |
| 432 * section has been viewed. | 438 * section has been viewed. |
| 433 */ | 439 */ |
| 434 @Test | 440 @Test |
| 435 @Feature({"Ntp"}) | 441 @Feature({"Ntp"}) |
| 436 public void testUIUpdatesOnNewSuggestionsWhenFirstOfOtherSectionIsSeen() { | 442 public void testUIUpdatesOnNewSuggestionsWhenFirstOfOtherSectionIsSeen() { |
| 437 List<SnippetArticle> snippets = createDummySuggestions(4); | 443 List<SnippetArticle> snippets = createDummySuggestions(4, KnownCategorie
s.ARTICLES); |
| 438 SnippetArticle earlier = snippets.get(0); | |
| 439 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 444 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 440 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); | 445 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, snippets); |
| 441 | 446 |
| 442 List<SnippetArticle> bookmarks = createDummySuggestions(1); | 447 List<SnippetArticle> bookmarks = createDummySuggestions(1, KnownCategori
es.BOOKMARKS); |
| 443 mSource.setStatusForCategory(KnownCategories.BOOKMARKS, CategoryStatus.A
VAILABLE); | 448 mSource.setStatusForCategory(KnownCategories.BOOKMARKS, CategoryStatus.A
VAILABLE); |
| 444 mSource.setInfoForCategory(KnownCategories.BOOKMARKS, | 449 mSource.setInfoForCategory(KnownCategories.BOOKMARKS, |
| 445 new CategoryInfoBuilder(KnownCategories.BOOKMARKS).showIfEmpty()
.build()); | 450 new CategoryInfoBuilder(KnownCategories.BOOKMARKS).showIfEmpty()
.build()); |
| 446 mSource.setSuggestionsForCategory(KnownCategories.BOOKMARKS, bookmarks); | 451 mSource.setSuggestionsForCategory(KnownCategories.BOOKMARKS, bookmarks); |
| 447 | 452 |
| 448 reloadNtp(); | 453 reloadNtp(); |
| 449 assertItemsFor(section(4), section(1)); | 454 assertItemsFor(section(4), section(1)); |
| 450 | 455 |
| 451 mAdapter.getSectionListForTesting() | 456 mAdapter.getSectionListForTesting() |
| 452 .getSectionForTesting(KnownCategories.BOOKMARKS) | 457 .getSectionForTesting(KnownCategories.BOOKMARKS) |
| 453 .childSeen(1); | 458 .childSeen(1); |
| 454 | 459 |
| 455 List<SnippetArticle> newSnippets = createDummySuggestions(3); | 460 List<SnippetArticle> newSnippets = createDummySuggestions(3, KnownCatego
ries.ARTICLES); |
| 456 SnippetArticle newer = newSnippets.get(0); | 461 SnippetArticle newer = newSnippets.get(0); |
| 457 | 462 |
| 458 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, newSnippets)
; | 463 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, newSnippets)
; |
| 459 assertItemsFor(section(3).withFirstItem(newer), section(1)); | 464 assertItemsFor(section(3).withFirstItem(newer), section(1)); |
| 460 | 465 |
| 461 reloadNtp(); | 466 reloadNtp(); |
| 462 assertItemsFor(section(3).withFirstItem(newer), section(1)); | 467 assertItemsFor(section(3).withFirstItem(newer), section(1)); |
| 463 } | 468 } |
| 464 | 469 |
| 465 /** Tests whether a section stays visible if empty, if required. */ | 470 /** Tests whether a section stays visible if empty, if required. */ |
| 466 @Test | 471 @Test |
| 467 @Feature({"Ntp"}) | 472 @Feature({"Ntp"}) |
| 468 public void testSectionVisibleIfEmpty() { | 473 public void testSectionVisibleIfEmpty() { |
| 469 @CategoryInt | 474 @CategoryInt |
| 470 final int category = 42; | 475 final int category = 42; |
| 471 | 476 |
| 472 // Part 1: VisibleIfEmpty = true | 477 // Part 1: VisibleIfEmpty = true |
| 473 FakeSuggestionsSource suggestionsSource = new FakeSuggestionsSource(); | 478 FakeSuggestionsSource suggestionsSource = new FakeSuggestionsSource(); |
| 474 suggestionsSource.setStatusForCategory(category, CategoryStatus.INITIALI
ZING); | 479 suggestionsSource.setStatusForCategory(category, CategoryStatus.INITIALI
ZING); |
| 475 suggestionsSource.setInfoForCategory(category, | 480 suggestionsSource.setInfoForCategory(category, |
| 476 new CategoryInfoBuilder(category).showIfEmpty().build()); | 481 new CategoryInfoBuilder(category).showIfEmpty().build()); |
| 477 | 482 |
| 478 // 1.1 - Initial state | 483 // 1.1 - Initial state |
| 479 when(mNewTabPageManager.getSuggestionsSource()).thenReturn(suggestionsSo
urce); | 484 when(mNewTabPageManager.getSuggestionsSource()).thenReturn(suggestionsSo
urce); |
| 480 reloadNtp(); | 485 reloadNtp(); |
| 481 assertItemsFor(sectionWithStatusCard().withProgress()); | 486 assertItemsFor(sectionWithStatusCard().withProgress()); |
| 482 | 487 |
| 483 // 1.2 - With suggestions | 488 // 1.2 - With suggestions |
| 484 List<SnippetArticle> articles = Collections.unmodifiableList(createDummy
Suggestions(3)); | 489 List<SnippetArticle> articles = |
| 490 Collections.unmodifiableList(createDummySuggestions(3, category)
); |
| 485 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL
E); | 491 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL
E); |
| 486 suggestionsSource.setSuggestionsForCategory(category, articles); | 492 suggestionsSource.setSuggestionsForCategory(category, articles); |
| 487 assertItemsFor(section(3)); | 493 assertItemsFor(section(3)); |
| 488 | 494 |
| 489 // 1.3 - When all suggestions are dismissed | 495 // 1.3 - When all suggestions are dismissed |
| 490 SuggestionsSection section42 = | 496 SuggestionsSection section42 = |
| 491 mAdapter.getSectionListForTesting().getSectionForTesting(categor
y); | 497 mAdapter.getSectionListForTesting().getSectionForTesting(categor
y); |
| 492 assertSectionMatches(section(3), section42); | 498 assertSectionMatches(section(3), section42); |
| 493 section42.removeSuggestionById(articles.get(0).mIdWithinCategory); | 499 section42.removeSuggestionById(articles.get(0).mIdWithinCategory); |
| 494 section42.removeSuggestionById(articles.get(1).mIdWithinCategory); | 500 section42.removeSuggestionById(articles.get(1).mIdWithinCategory); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 .withViewAllActio
n() | 535 .withViewAllActio
n() |
| 530 .showIfEmpty() | 536 .showIfEmpty() |
| 531 .build()); | 537 .build()); |
| 532 | 538 |
| 533 // 1.1 - Initial state. | 539 // 1.1 - Initial state. |
| 534 when(mNewTabPageManager.getSuggestionsSource()).thenReturn(suggestionsSo
urce); | 540 when(mNewTabPageManager.getSuggestionsSource()).thenReturn(suggestionsSo
urce); |
| 535 reloadNtp(); | 541 reloadNtp(); |
| 536 assertItemsFor(sectionWithStatusCard().withActionButton().withProgress()
); | 542 assertItemsFor(sectionWithStatusCard().withActionButton().withProgress()
); |
| 537 | 543 |
| 538 // 1.2 - With suggestions. | 544 // 1.2 - With suggestions. |
| 539 List<SnippetArticle> articles = Collections.unmodifiableList(createDummy
Suggestions(3)); | 545 List<SnippetArticle> articles = |
| 546 Collections.unmodifiableList(createDummySuggestions(3, category)
); |
| 540 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL
E); | 547 suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABL
E); |
| 541 suggestionsSource.setSuggestionsForCategory(category, articles); | 548 suggestionsSource.setSuggestionsForCategory(category, articles); |
| 542 assertItemsFor(section(3).withActionButton()); | 549 assertItemsFor(section(3).withActionButton()); |
| 543 | 550 |
| 544 // 1.3 - When all suggestions are dismissed. | 551 // 1.3 - When all suggestions are dismissed. |
| 545 SuggestionsSection section42 = | 552 SuggestionsSection section42 = |
| 546 mAdapter.getSectionListForTesting().getSectionForTesting(categor
y); | 553 mAdapter.getSectionListForTesting().getSectionForTesting(categor
y); |
| 547 assertSectionMatches(section(3).withActionButton(), section42); | 554 assertSectionMatches(section(3).withActionButton(), section42); |
| 548 section42.removeSuggestionById(articles.get(0).mIdWithinCategory); | 555 section42.removeSuggestionById(articles.get(0).mIdWithinCategory); |
| 549 section42.removeSuggestionById(articles.get(1).mIdWithinCategory); | 556 section42.removeSuggestionById(articles.get(1).mIdWithinCategory); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 574 section42.removeSuggestionById(articles.get(2).mIdWithinCategory); | 581 section42.removeSuggestionById(articles.get(2).mIdWithinCategory); |
| 575 assertItemsFor(sectionWithStatusCard()); | 582 assertItemsFor(sectionWithStatusCard()); |
| 576 } | 583 } |
| 577 | 584 |
| 578 /** | 585 /** |
| 579 * Tests that invalidated suggestions are immediately removed. | 586 * Tests that invalidated suggestions are immediately removed. |
| 580 */ | 587 */ |
| 581 @Test | 588 @Test |
| 582 @Feature({"Ntp"}) | 589 @Feature({"Ntp"}) |
| 583 public void testSuggestionInvalidated() { | 590 public void testSuggestionInvalidated() { |
| 584 List<SnippetArticle> articles = createDummySuggestions(3); | 591 List<SnippetArticle> articles = createDummySuggestions(3, KnownCategorie
s.ARTICLES); |
| 585 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 592 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 586 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, articles); | 593 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, articles); |
| 587 assertItemsFor(section(3)); | 594 assertItemsFor(section(3)); |
| 588 assertArticlesEqual(articles, 2, 5); | 595 assertArticlesEqual(articles, 2, 5); |
| 589 | 596 |
| 590 SnippetArticle removed = articles.remove(1); | 597 SnippetArticle removed = articles.remove(1); |
| 591 mSource.fireSuggestionInvalidated(KnownCategories.ARTICLES, removed.mIdW
ithinCategory); | 598 mSource.fireSuggestionInvalidated(KnownCategories.ARTICLES, removed.mIdW
ithinCategory); |
| 592 assertArticlesEqual(articles, 2, 4); | 599 assertArticlesEqual(articles, 2, 4); |
| 593 } | 600 } |
| 594 | 601 |
| 595 /** | 602 /** |
| 596 * Tests that the UI handles dynamically added (server-side) categories corr
ectly. | 603 * Tests that the UI handles dynamically added (server-side) categories corr
ectly. |
| 597 */ | 604 */ |
| 598 @Test | 605 @Test |
| 599 @Feature({"Ntp"}) | 606 @Feature({"Ntp"}) |
| 600 public void testDynamicCategories() { | 607 public void testDynamicCategories() { |
| 601 List<SnippetArticle> articles = createDummySuggestions(3); | 608 List<SnippetArticle> articles = createDummySuggestions(3, KnownCategorie
s.ARTICLES); |
| 602 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 609 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 603 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, articles); | 610 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, articles); |
| 604 assertItemsFor(section(3)); | 611 assertItemsFor(section(3)); |
| 605 | 612 |
| 606 int dynamicCategory1 = 1010; | 613 int dynamicCategory1 = 1010; |
| 607 List<SnippetArticle> dynamics1 = createDummySuggestions(5); | 614 List<SnippetArticle> dynamics1 = createDummySuggestions(5, KnownCategori
es.ARTICLES); |
| 608 mSource.setInfoForCategory(dynamicCategory1, new CategoryInfoBuilder(dyn
amicCategory1) | 615 mSource.setInfoForCategory(dynamicCategory1, new CategoryInfoBuilder(dyn
amicCategory1) |
| 609 .withViewAllAction(
) | 616 .withViewAllAction(
) |
| 610 .build()); | 617 .build()); |
| 611 mSource.setStatusForCategory(dynamicCategory1, CategoryStatus.AVAILABLE)
; | 618 mSource.setStatusForCategory(dynamicCategory1, CategoryStatus.AVAILABLE)
; |
| 612 mSource.setSuggestionsForCategory(dynamicCategory1, dynamics1); | 619 mSource.setSuggestionsForCategory(dynamicCategory1, dynamics1); |
| 613 reloadNtp(); | 620 reloadNtp(); |
| 614 | 621 |
| 615 assertItemsFor(section(3), section(5).withActionButton()); | 622 assertItemsFor(section(3), section(5).withActionButton()); |
| 616 | 623 |
| 617 int dynamicCategory2 = 1011; | 624 int dynamicCategory2 = 1011; |
| 618 List<SnippetArticle> dynamics2 = createDummySuggestions(11); | 625 List<SnippetArticle> dynamics2 = createDummySuggestions(11, KnownCategor
ies.ARTICLES); |
| 619 mSource.setInfoForCategory(dynamicCategory2, | 626 mSource.setInfoForCategory(dynamicCategory2, |
| 620 new CategoryInfoBuilder(dynamicCategory1).build()); | 627 new CategoryInfoBuilder(dynamicCategory1).build()); |
| 621 mSource.setStatusForCategory(dynamicCategory2, CategoryStatus.AVAILABLE)
; | 628 mSource.setStatusForCategory(dynamicCategory2, CategoryStatus.AVAILABLE)
; |
| 622 mSource.setSuggestionsForCategory(dynamicCategory2, dynamics2); | 629 mSource.setSuggestionsForCategory(dynamicCategory2, dynamics2); |
| 623 reloadNtp(); | 630 reloadNtp(); |
| 624 assertItemsFor(section(3), section(5).withActionButton(), section(11)); | 631 assertItemsFor(section(3), section(5).withActionButton(), section(11)); |
| 625 } | 632 } |
| 626 | 633 |
| 627 /** | 634 /** |
| 628 * Tests that the order of the categories is kept. | 635 * Tests that the order of the categories is kept. |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 745 // 0 | Above-the-fold | 752 // 0 | Above-the-fold |
| 746 // 1 | Header | 753 // 1 | Header |
| 747 // 2 | Status | 754 // 2 | Status |
| 748 // 3 | Action | 755 // 3 | Action |
| 749 // 4 | Progress Indicator | 756 // 4 | Progress Indicator |
| 750 // 5 | Footer | 757 // 5 | Footer |
| 751 // 6 | Spacer | 758 // 6 | Spacer |
| 752 | 759 |
| 753 final int newSuggestionCount = 7; | 760 final int newSuggestionCount = 7; |
| 754 reset(dataObserver); | 761 reset(dataObserver); |
| 755 suggestionsSource.setSuggestionsForCategory( | 762 suggestionsSource.setSuggestionsForCategory(KnownCategories.ARTICLES, |
| 756 KnownCategories.ARTICLES, createDummySuggestions(newSuggestionCo
unt)); | 763 createDummySuggestions(newSuggestionCount, KnownCategories.ARTIC
LES)); |
| 757 verify(dataObserver).onItemRangeInserted(2, newSuggestionCount); | 764 verify(dataObserver).onItemRangeInserted(2, newSuggestionCount); |
| 758 verify(dataObserver).onItemRangeChanged(5 + newSuggestionCount, 1, null)
; // Spacer refresh | 765 verify(dataObserver).onItemRangeChanged(5 + newSuggestionCount, 1, null)
; // Spacer refresh |
| 759 verify(dataObserver, times(2)).onItemRangeRemoved(2 + newSuggestionCount
, 1); | 766 verify(dataObserver, times(2)).onItemRangeRemoved(2 + newSuggestionCount
, 1); |
| 760 verify(dataObserver).onItemRangeChanged(4 + newSuggestionCount, 1, null)
; // Spacer refresh | 767 verify(dataObserver).onItemRangeChanged(4 + newSuggestionCount, 1, null)
; // Spacer refresh |
| 761 verify(dataObserver).onItemRangeChanged(3 + newSuggestionCount, 1, null)
; // Spacer refresh | 768 verify(dataObserver).onItemRangeChanged(3 + newSuggestionCount, 1, null)
; // Spacer refresh |
| 762 | 769 |
| 763 // Adapter content: | 770 // Adapter content: |
| 764 // Idx | Item | 771 // Idx | Item |
| 765 // ----|---------------- | 772 // ----|---------------- |
| 766 // 0 | Above-the-fold | 773 // 0 | Above-the-fold |
| 767 // 1 | Header | 774 // 1 | Header |
| 768 // 2-8 | Sugg*7 | 775 // 2-8 | Sugg*7 |
| 769 // 9 | Footer | 776 // 9 | Footer |
| 770 // 10 | Spacer | 777 // 10 | Spacer |
| 771 | 778 |
| 772 verifyNoMoreInteractions(dataObserver); | 779 verifyNoMoreInteractions(dataObserver); |
| 773 reset(dataObserver); | 780 reset(dataObserver); |
| 774 suggestionsSource.setSuggestionsForCategory( | 781 suggestionsSource.setSuggestionsForCategory( |
| 775 KnownCategories.ARTICLES, createDummySuggestions(0)); | 782 KnownCategories.ARTICLES, createDummySuggestions(0, KnownCategor
ies.ARTICLES)); |
| 776 mAdapter.getSectionListForTesting().onCategoryStatusChanged( | 783 mAdapter.getSectionListForTesting().onCategoryStatusChanged( |
| 777 KnownCategories.ARTICLES, CategoryStatus.SIGNED_OUT); | 784 KnownCategories.ARTICLES, CategoryStatus.SIGNED_OUT); |
| 778 verify(dataObserver).onItemRangeRemoved(2, newSuggestionCount); | 785 verify(dataObserver).onItemRangeRemoved(2, newSuggestionCount); |
| 779 verify(dataObserver).onItemRangeChanged(3, 1, null); // Spacer refresh | 786 verify(dataObserver).onItemRangeChanged(3, 1, null); // Spacer refresh |
| 780 verify(dataObserver).onItemRangeInserted(2, 1); // Status card added | 787 verify(dataObserver).onItemRangeInserted(2, 1); // Status card added |
| 781 verify(dataObserver).onItemRangeChanged(4, 1, null); // Spacer refresh | 788 verify(dataObserver).onItemRangeChanged(4, 1, null); // Spacer refresh |
| 782 verify(dataObserver).onItemRangeInserted(3, 1); // Action item added | 789 verify(dataObserver).onItemRangeInserted(3, 1); // Action item added |
| 783 verify(dataObserver).onItemRangeChanged(5, 1, null); // Spacer refresh | 790 verify(dataObserver).onItemRangeChanged(5, 1, null); // Spacer refresh |
| 784 verifyNoMoreInteractions(dataObserver); | 791 verifyNoMoreInteractions(dataObserver); |
| 785 } | 792 } |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 939 // 1 | Sign In Promo | 946 // 1 | Sign In Promo |
| 940 // 2 | Footer | 947 // 2 | Footer |
| 941 // 3 | Spacer | 948 // 3 | Spacer |
| 942 assertEquals(ItemViewType.FOOTER, mAdapter.getItemViewType(2)); | 949 assertEquals(ItemViewType.FOOTER, mAdapter.getItemViewType(2)); |
| 943 assertEquals(RecyclerView.NO_POSITION, | 950 assertEquals(RecyclerView.NO_POSITION, |
| 944 mAdapter.getFirstPositionForType(ItemViewType.ALL_DISMISSED)); | 951 mAdapter.getFirstPositionForType(ItemViewType.ALL_DISMISSED)); |
| 945 | 952 |
| 946 // Prepare some suggestions. They should not load because the category i
s dismissed on | 953 // Prepare some suggestions. They should not load because the category i
s dismissed on |
| 947 // the current NTP. | 954 // the current NTP. |
| 948 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); | 955 mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AV
AILABLE); |
| 949 mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, createDummyS
uggestions(1)); | 956 mSource.setSuggestionsForCategory( |
| 957 KnownCategories.ARTICLES, createDummySuggestions(1, KnownCategor
ies.ARTICLES)); |
| 950 mSource.setInfoForCategory(KnownCategories.ARTICLES, | 958 mSource.setInfoForCategory(KnownCategories.ARTICLES, |
| 951 new CategoryInfoBuilder(KnownCategories.ARTICLES).build()); | 959 new CategoryInfoBuilder(KnownCategories.ARTICLES).build()); |
| 952 assertEquals(4, mAdapter.getItemCount()); // TODO(dgn): rewrite with sec
tion descriptors. | 960 assertEquals(4, mAdapter.getItemCount()); // TODO(dgn): rewrite with sec
tion descriptors. |
| 953 | 961 |
| 954 // On Sign in, we should reset the sections, bring back suggestions inst
ead of the All | 962 // On Sign in, we should reset the sections, bring back suggestions inst
ead of the All |
| 955 // Dismissed item. | 963 // Dismissed item. |
| 956 mAdapter.getSectionListForTesting().onFullRefreshRequired(); | 964 mAdapter.getSectionListForTesting().onFullRefreshRequired(); |
| 957 when(mMockSigninManager.isSignInAllowed()).thenReturn(true); | 965 when(mMockSigninManager.isSignInAllowed()).thenReturn(true); |
| 958 signinObserver.onSignedIn(); | 966 signinObserver.onSignedIn(); |
| 959 // Adapter content: | 967 // Adapter content: |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1076 viewTypeToString(expectedType)); | 1084 viewTypeToString(expectedType)); |
| 1077 } | 1085 } |
| 1078 addLine(stringBuilder, "explainFailedExpectation -- END --"); | 1086 addLine(stringBuilder, "explainFailedExpectation -- END --"); |
| 1079 return stringBuilder.toString(); | 1087 return stringBuilder.toString(); |
| 1080 } | 1088 } |
| 1081 | 1089 |
| 1082 private static void addLine(StringBuilder stringBuilder, String template, Ob
ject... args) { | 1090 private static void addLine(StringBuilder stringBuilder, String template, Ob
ject... args) { |
| 1083 stringBuilder.append(String.format(Locale.US, template + "\n", args)); | 1091 stringBuilder.append(String.format(Locale.US, template + "\n", args)); |
| 1084 } | 1092 } |
| 1085 } | 1093 } |
| OLD | NEW |