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.hamcrest.Matchers.is; | 7 import static org.hamcrest.Matchers.is; |
8 import static org.hamcrest.collection.IsIterableContainingInOrder.contains; | 8 import static org.hamcrest.collection.IsIterableContainingInOrder.contains; |
9 import static org.junit.Assert.assertEquals; | 9 import static org.junit.Assert.assertEquals; |
10 import static org.junit.Assert.assertFalse; | 10 import static org.junit.Assert.assertFalse; |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 // Indices in section are off-by-one (index 0 is the header). | 478 // Indices in section are off-by-one (index 0 is the header). |
479 bindViewHolders(section, 1, 2); | 479 bindViewHolders(section, 1, 2); |
480 | 480 |
481 List<SnippetArticle> newSnippets = | 481 List<SnippetArticle> newSnippets = |
482 createDummySuggestions(3, TEST_CATEGORY_ID, "new"); | 482 createDummySuggestions(3, TEST_CATEGORY_ID, "new"); |
483 // Copy the list when passing to the section - it may alter it but we la
ter need it. | 483 // Copy the list when passing to the section - it may alter it but we la
ter need it. |
484 section.updateSuggestions(createSourceFor(new ArrayList<>(newSnippets)))
; | 484 section.updateSuggestions(createSourceFor(new ArrayList<>(newSnippets)))
; |
485 verify(mParent).onItemRangeRemoved(section, 2, 3); | 485 verify(mParent).onItemRangeRemoved(section, 2, 3); |
486 verify(mParent).onItemRangeInserted(section, 2, 2); | 486 verify(mParent).onItemRangeInserted(section, 2, 2); |
487 assertEquals(3, section.getSuggestionsCount()); | 487 assertEquals(3, section.getSuggestionsCount()); |
488 assertEquals(snippets.get(0), section.getSuggestionAt(1)); | 488 List<SnippetArticle> sectionSuggestions = getSuggestions(section); |
489 assertNotEquals(snippets.get(1), section.getSuggestionAt(2)); | 489 assertEquals(snippets.get(0), sectionSuggestions.get(0)); |
490 assertEquals(newSnippets.get(0), section.getSuggestionAt(2)); | 490 assertNotEquals(snippets.get(1), sectionSuggestions.get(1)); |
491 assertNotEquals(snippets.get(2), section.getSuggestionAt(3)); | 491 assertEquals(newSnippets.get(0), sectionSuggestions.get(1)); |
492 assertEquals(newSnippets.get(1), section.getSuggestionAt(3)); | 492 assertNotEquals(snippets.get(2), sectionSuggestions.get(2)); |
| 493 assertEquals(newSnippets.get(1), sectionSuggestions.get(2)); |
493 | 494 |
494 assertTrue(section.isDataStale()); | 495 assertTrue(section.isDataStale()); |
495 } | 496 } |
496 | 497 |
497 /** | 498 /** |
498 * Tests that the UI does not update the first two items of the section if t
hey have been | 499 * Tests that the UI does not update the first two items of the section if t
hey have been |
499 * viewed. | 500 * viewed. |
500 */ | 501 */ |
501 @Test | 502 @Test |
502 @Feature({"Ntp"}) | 503 @Feature({"Ntp"}) |
503 public void testUpdateSectionDoesNotReplaceFirstTwoSuggestionWhenSeen() { | 504 public void testUpdateSectionDoesNotReplaceFirstTwoSuggestionWhenSeen() { |
504 List<SnippetArticle> snippets = createDummySuggestions(4, TEST_CATEGORY_
ID, "old"); | 505 List<SnippetArticle> snippets = createDummySuggestions(4, TEST_CATEGORY_
ID, "old"); |
505 // Copy the list when passing to the section - it may alter it but we la
ter need it. | 506 // Copy the list when passing to the section - it may alter it but we la
ter need it. |
506 SuggestionsSection section = | 507 SuggestionsSection section = |
507 createSectionWithSuggestions(new ArrayList<>(snippets)); | 508 createSectionWithSuggestions(new ArrayList<>(snippets)); |
508 assertEquals(4, section.getSuggestionsCount()); | 509 assertEquals(4, section.getSuggestionsCount()); |
509 | 510 |
510 // Bind the first two suggestions - indicate that they are being viewed. | 511 // Bind the first two suggestions - indicate that they are being viewed. |
511 // Indices in section are off-by-one (index 0 is the header). | 512 // Indices in section are off-by-one (index 0 is the header). |
512 bindViewHolders(section, 1, 3); | 513 bindViewHolders(section, 1, 3); |
513 | 514 |
514 List<SnippetArticle> newSnippets = | 515 List<SnippetArticle> newSnippets = |
515 createDummySuggestions(3, TEST_CATEGORY_ID, "new"); | 516 createDummySuggestions(3, TEST_CATEGORY_ID, "new"); |
516 // Copy the list when passing to the section - it may alter it but we la
ter need it. | 517 // Copy the list when passing to the section - it may alter it but we la
ter need it. |
517 section.updateSuggestions(createSourceFor(new ArrayList<>(newSnippets)))
; | 518 section.updateSuggestions(createSourceFor(new ArrayList<>(newSnippets)))
; |
518 verify(mParent).onItemRangeRemoved(section, 3, 2); | 519 verify(mParent).onItemRangeRemoved(section, 3, 2); |
519 verify(mParent).onItemRangeInserted(section, 3, 1); | 520 verify(mParent).onItemRangeInserted(section, 3, 1); |
520 assertEquals(3, section.getSuggestionsCount()); | 521 assertEquals(3, section.getSuggestionsCount()); |
521 assertEquals(snippets.get(0), section.getSuggestionAt(1)); | 522 List<SnippetArticle> sectionSuggestions = getSuggestions(section); |
522 assertEquals(snippets.get(1), section.getSuggestionAt(2)); | 523 assertEquals(snippets.get(0), sectionSuggestions.get(0)); |
523 assertNotEquals(snippets.get(2), section.getSuggestionAt(3)); | 524 assertEquals(snippets.get(1), sectionSuggestions.get(1)); |
524 assertEquals(newSnippets.get(0), section.getSuggestionAt(3)); | 525 assertNotEquals(snippets.get(2), sectionSuggestions.get(2)); |
| 526 assertEquals(newSnippets.get(0), sectionSuggestions.get(2)); |
525 | 527 |
526 assertTrue(section.isDataStale()); | 528 assertTrue(section.isDataStale()); |
527 } | 529 } |
528 | 530 |
529 /** | 531 /** |
530 * Tests that the UI does not update any items of the section if the new lis
t is shorter than | 532 * Tests that the UI does not update any items of the section if the new lis
t is shorter than |
531 * what has been viewed. | 533 * what has been viewed. |
532 */ | 534 */ |
533 @Test | 535 @Test |
534 @Feature({"Ntp"}) | 536 @Feature({"Ntp"}) |
535 public void testUpdateSectionDoesNothingWhenNewListIsShorterThanItemsSeen()
{ | 537 public void testUpdateSectionDoesNothingWhenNewListIsShorterThanItemsSeen()
{ |
536 List<SnippetArticle> snippets = createDummySuggestions(4, TEST_CATEGORY_
ID, "old"); | 538 List<SnippetArticle> snippets = createDummySuggestions(4, TEST_CATEGORY_
ID, "old"); |
537 // Copy the list when passing to the section - it may alter it but we la
ter need it. | 539 // Copy the list when passing to the section - it may alter it but we la
ter need it. |
538 SuggestionsSection section = | 540 SuggestionsSection section = |
539 createSectionWithSuggestions(new ArrayList<>(snippets)); | 541 createSectionWithSuggestions(new ArrayList<>(snippets)); |
540 assertEquals(4, section.getSuggestionsCount()); | 542 assertEquals(4, section.getSuggestionsCount()); |
541 | 543 |
542 // Bind the first two suggestions - indicate that they are being viewed. | 544 // Bind the first two suggestions - indicate that they are being viewed. |
543 // Indices in section are off-by-one (index 0 is the header). | 545 // Indices in section are off-by-one (index 0 is the header). |
544 bindViewHolders(section, 1, 3); | 546 bindViewHolders(section, 1, 3); |
545 | 547 |
546 section.updateSuggestions(createSourceFor(createDummySuggestions(1, TEST
_CATEGORY_ID))); | 548 section.updateSuggestions(createSourceFor(createDummySuggestions(1, TEST
_CATEGORY_ID))); |
547 // Even though the new list has just one suggestion, we need to keep the
two seen ones | 549 // Even though the new list has just one suggestion, we need to keep the
two seen ones |
548 // around. | 550 // around. |
549 verify(mParent).onItemRangeRemoved(section, 3, 2); | 551 verify(mParent).onItemRangeRemoved(section, 3, 2); |
550 verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt
(), anyInt()); | 552 verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt
(), anyInt()); |
551 assertEquals(2, section.getSuggestionsCount()); | 553 assertEquals(2, section.getSuggestionsCount()); |
552 assertEquals(snippets.get(0), section.getSuggestionAt(1)); | 554 List<SnippetArticle> sectionSuggestions = getSuggestions(section); |
553 assertEquals(snippets.get(1), section.getSuggestionAt(2)); | 555 assertEquals(snippets.get(0), sectionSuggestions.get(0)); |
| 556 assertEquals(snippets.get(1), sectionSuggestions.get(1)); |
554 | 557 |
555 assertTrue(section.isDataStale()); | 558 assertTrue(section.isDataStale()); |
556 } | 559 } |
557 | 560 |
558 /** | 561 /** |
559 * Tests that the UI does not update any items of the section if the current
list is shorter | 562 * Tests that the UI does not update any items of the section if the current
list is shorter |
560 * than what has been viewed. | 563 * than what has been viewed. |
561 */ | 564 */ |
562 @Test | 565 @Test |
563 @Feature({"Ntp"}) | 566 @Feature({"Ntp"}) |
564 public void testUpdateSectionDoesNothingWhenCurrentListIsShorterThanItemsSee
n() { | 567 public void testUpdateSectionDoesNothingWhenCurrentListIsShorterThanItemsSee
n() { |
565 List<SnippetArticle> snippets = createDummySuggestions(3, TEST_CATEGORY_
ID, "old"); | 568 List<SnippetArticle> snippets = createDummySuggestions(3, TEST_CATEGORY_
ID, "old"); |
566 // Copy the list when passing to the section - it may alter it but we la
ter need it. | 569 // Copy the list when passing to the section - it may alter it but we la
ter need it. |
567 SuggestionsSection section = | 570 SuggestionsSection section = |
568 createSectionWithSuggestions(new ArrayList<>(snippets)); | 571 createSectionWithSuggestions(new ArrayList<>(snippets)); |
569 assertEquals(3, section.getSuggestionsCount()); | 572 assertEquals(3, section.getSuggestionsCount()); |
570 | 573 |
571 // Bind the first two suggestions - indicate that they are being viewed. | 574 // Bind the first two suggestions - indicate that they are being viewed. |
572 // Indices in section are off-by-one (index 0 is the header). | 575 // Indices in section are off-by-one (index 0 is the header). |
573 bindViewHolders(section, 1, 3); | 576 bindViewHolders(section, 1, 3); |
574 | 577 |
575 // Remove last two items. | 578 // Remove last two items. |
576 section.removeSuggestionById(section.getSuggestionAt(3).mIdWithinCategor
y); | 579 List<SnippetArticle> sectionSuggestions = getSuggestions(section); |
577 section.removeSuggestionById(section.getSuggestionAt(2).mIdWithinCategor
y); | 580 section.removeSuggestionById(sectionSuggestions.get(2).mIdWithinCategory
); |
| 581 section.removeSuggestionById(sectionSuggestions.get(1).mIdWithinCategory
); |
578 reset(mParent); | 582 reset(mParent); |
579 | 583 |
580 assertEquals(1, section.getSuggestionsCount()); | 584 assertEquals(1, section.getSuggestionsCount()); |
581 | 585 |
582 section.updateSuggestions(createSourceFor(createDummySuggestions(4, TEST
_CATEGORY_ID))); | 586 section.updateSuggestions(createSourceFor(createDummySuggestions(4, TEST
_CATEGORY_ID))); |
583 // We do not touch the current list if all has been seen. | 587 // We do not touch the current list if all has been seen. |
584 verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(
), anyInt()); | 588 verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(
), anyInt()); |
585 verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt
(), anyInt()); | 589 verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt
(), anyInt()); |
586 assertEquals(1, section.getSuggestionsCount()); | 590 assertEquals(1, section.getSuggestionsCount()); |
587 assertEquals(snippets.get(0), section.getSuggestionAt(1)); | 591 assertEquals(snippets.get(0), sectionSuggestions.get(0)); |
588 | 592 |
589 assertTrue(section.isDataStale()); | 593 assertTrue(section.isDataStale()); |
590 } | 594 } |
591 | 595 |
592 /** | 596 /** |
593 * Tests that the UI does not update when the section has been viewed. | 597 * Tests that the UI does not update when the section has been viewed. |
594 */ | 598 */ |
595 @Test | 599 @Test |
596 @Feature({"Ntp"}) | 600 @Feature({"Ntp"}) |
597 public void testUpdateSectionDoesNothingWhenAllSeen() { | 601 public void testUpdateSectionDoesNothingWhenAllSeen() { |
598 List<SnippetArticle> snippets = createDummySuggestions(4, TEST_CATEGORY_
ID, "old"); | 602 List<SnippetArticle> snippets = createDummySuggestions(4, TEST_CATEGORY_
ID, "old"); |
599 SuggestionsSection section = createSectionWithSuggestions(snippets); | 603 SuggestionsSection section = createSectionWithSuggestions(snippets); |
600 assertEquals(4, section.getSuggestionsCount()); | 604 assertEquals(4, section.getSuggestionsCount()); |
601 | 605 |
602 // Bind all the suggestions - indicate that they are being viewed. | 606 // Bind all the suggestions - indicate that they are being viewed. |
603 bindViewHolders(section); | 607 bindViewHolders(section); |
604 | 608 |
605 section.updateSuggestions(createSourceFor(createDummySuggestions(3, TEST
_CATEGORY_ID))); | 609 section.updateSuggestions(createSourceFor(createDummySuggestions(3, TEST
_CATEGORY_ID))); |
606 verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(
), anyInt()); | 610 verify(mParent, never()).onItemRangeRemoved(any(TreeNode.class), anyInt(
), anyInt()); |
607 verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt
(), anyInt()); | 611 verify(mParent, never()).onItemRangeInserted(any(TreeNode.class), anyInt
(), anyInt()); |
608 | 612 |
609 // All old snippets should be in place. | 613 // All old snippets should be in place. |
610 verifySnippets(section, snippets); | 614 assertEquals(snippets, getSuggestions(section)); |
611 | 615 |
612 assertTrue(section.isDataStale()); | 616 assertTrue(section.isDataStale()); |
613 } | 617 } |
614 | 618 |
615 /** | 619 /** |
616 * Tests that the UI does not update when anything has been appended. | 620 * Tests that the UI does not update when anything has been appended. |
617 */ | 621 */ |
618 @Test | 622 @Test |
619 @Feature({"Ntp"}) | 623 @Feature({"Ntp"}) |
620 public void testUpdateSectionDoesNothingWhenUserAppended() { | 624 public void testUpdateSectionDoesNothingWhenUserAppended() { |
621 List<SnippetArticle> snippets = createDummySuggestions(4, TEST_CATEGORY_
ID, "old"); | 625 List<SnippetArticle> snippets = createDummySuggestions(4, TEST_CATEGORY_
ID, "old"); |
622 SuggestionsSection section = createSectionWithSuggestions(snippets); | 626 SuggestionsSection section = createSectionWithSuggestions(snippets); |
623 | 627 |
624 // Append another 3 suggestions. | 628 // Append another 3 suggestions. |
625 List<SnippetArticle> appendedSnippets = | 629 List<SnippetArticle> appendedSnippets = |
626 createDummySuggestions(3, TEST_CATEGORY_ID, "appended"); | 630 createDummySuggestions(3, TEST_CATEGORY_ID, "appended"); |
627 section.appendSuggestions(appendedSnippets, /* userRequested = */ true); | 631 section.appendSuggestions(appendedSnippets, /* userRequested = */ true); |
628 | 632 |
629 // All 7 snippets should be in place. | 633 // All 7 snippets should be in place. |
630 snippets.addAll(appendedSnippets); | 634 snippets.addAll(appendedSnippets); |
631 verifySnippets(section, snippets); | 635 assertEquals(snippets, getSuggestions(section)); |
632 | 636 |
633 // Try to replace them with another list. Should have no effect. | 637 // Try to replace them with another list. Should have no effect. |
634 List<SnippetArticle> newSnippets = | 638 List<SnippetArticle> newSnippets = |
635 createDummySuggestions(5, TEST_CATEGORY_ID, "new"); | 639 createDummySuggestions(5, TEST_CATEGORY_ID, "new"); |
636 section.updateSuggestions(createSourceFor(newSnippets)); | 640 section.updateSuggestions(createSourceFor(newSnippets)); |
637 | 641 |
638 // All previous snippets should be in place. | 642 // All previous snippets should be in place. |
639 verifySnippets(section, snippets); | 643 assertEquals(snippets, getSuggestions(section)); |
640 | 644 |
641 assertTrue(section.isDataStale()); | 645 assertTrue(section.isDataStale()); |
642 } | 646 } |
643 | 647 |
644 @Test | 648 @Test |
645 @Feature({"Ntp"}) | 649 @Feature({"Ntp"}) |
646 public void testCardIsNotifiedWhenBecomingFirst() { | 650 public void testCardIsNotifiedWhenBecomingFirst() { |
647 List<SnippetArticle> suggestions = createDummySuggestions(5, /* category
Id = */ 42); | 651 List<SnippetArticle> suggestions = createDummySuggestions(5, /* category
Id = */ 42); |
648 SuggestionsSection section = createSectionWithFetchAction(false); | 652 SuggestionsSection section = createSectionWithFetchAction(false); |
649 section.appendSuggestions(suggestions, /* userRequested = */ false); | 653 section.appendSuggestions(suggestions, /* userRequested = */ false); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
736 return section; | 740 return section; |
737 } | 741 } |
738 | 742 |
739 @SafeVarargs | 743 @SafeVarargs |
740 private static <T> Set<T> setOf(T... elements) { | 744 private static <T> Set<T> setOf(T... elements) { |
741 Set<T> set = new TreeSet<>(); | 745 Set<T> set = new TreeSet<>(); |
742 set.addAll(Arrays.asList(elements)); | 746 set.addAll(Arrays.asList(elements)); |
743 return set; | 747 return set; |
744 } | 748 } |
745 | 749 |
| 750 private static List<SnippetArticle> getSuggestions(TreeNode root) { |
| 751 final List<SnippetArticle> suggestions = new ArrayList<>(); |
| 752 root.visitItems(new NodeVisitor() { |
| 753 @Override |
| 754 public void visitSuggestion(SnippetArticle suggestion) { |
| 755 suggestions.add(suggestion); |
| 756 } |
| 757 }); |
| 758 return suggestions; |
| 759 } |
| 760 |
746 private SuggestionsSection createSectionWithFetchAction(boolean hasFetchActi
on) { | 761 private SuggestionsSection createSectionWithFetchAction(boolean hasFetchActi
on) { |
747 CategoryInfoBuilder builder = new CategoryInfoBuilder(TEST_CATEGORY_ID).
showIfEmpty(); | 762 CategoryInfoBuilder builder = new CategoryInfoBuilder(TEST_CATEGORY_ID).
showIfEmpty(); |
748 if (hasFetchAction) builder.withAction(ContentSuggestionsAdditionalActio
n.FETCH); | 763 if (hasFetchAction) builder.withAction(ContentSuggestionsAdditionalActio
n.FETCH); |
749 return createSection(builder.build()); | 764 return createSection(builder.build()); |
750 } | 765 } |
751 | 766 |
752 private SuggestionsSection createSection(SuggestionsCategoryInfo info) { | 767 private SuggestionsSection createSection(SuggestionsCategoryInfo info) { |
753 SuggestionsSection section = new SuggestionsSection( | 768 SuggestionsSection section = new SuggestionsSection( |
754 mDelegate, mUiDelegate, mock(SuggestionsRanker.class), mBridge,
info); | 769 mDelegate, mUiDelegate, mock(SuggestionsRanker.class), mBridge,
info); |
755 section.setParent(mParent); | 770 section.setParent(mParent); |
(...skipping 27 matching lines...) Expand all Loading... |
783 section.getActionItemForTesting().performAction(manager); | 798 section.getActionItemForTesting().performAction(manager); |
784 } | 799 } |
785 | 800 |
786 verify(section.getCategoryInfo(), | 801 verify(section.getCategoryInfo(), |
787 (action == ContentSuggestionsAdditionalAction.VIEW_ALL ? times(1
) : never())) | 802 (action == ContentSuggestionsAdditionalAction.VIEW_ALL ? times(1
) : never())) |
788 .performViewAllAction(navDelegate); | 803 .performViewAllAction(navDelegate); |
789 verify(suggestionsSource, | 804 verify(suggestionsSource, |
790 (action == ContentSuggestionsAdditionalAction.FETCH ? times(1) :
never())) | 805 (action == ContentSuggestionsAdditionalAction.FETCH ? times(1) :
never())) |
791 .fetchSuggestions(anyInt(), any(String[].class)); | 806 .fetchSuggestions(anyInt(), any(String[].class)); |
792 } | 807 } |
793 | |
794 private static void verifySnippets(SuggestionsSection section, List<SnippetA
rticle> snippets) { | |
795 assertEquals(snippets.size(), section.getSuggestionsCount()); | |
796 // Indices in section are off-by-one (index 0 is the header). | |
797 int index = 1; | |
798 for (SnippetArticle snippet : snippets) { | |
799 assertEquals(snippet, section.getSuggestionAt(index++)); | |
800 } | |
801 } | |
802 } | 808 } |
OLD | NEW |