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

Unified Diff: chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java

Issue 2860463002: [Suggestions] Remove TreeNode.getSuggestionAt() in favor of a visitor. (Closed)
Patch Set: review Created 3 years, 7 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/ntp/cards/NewTabPageAdapterTest.java
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
index 9c9a2d0d086480726f561bed0cc0b79207a53432..4f488c0184ae6cd9b52a41ac3378d32756a53a89 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ntp/cards/NewTabPageAdapterTest.java
@@ -7,26 +7,25 @@ package org.chromium.chrome.browser.ntp.cards;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import static org.chromium.base.test.util.Matchers.greaterThanOrEqualTo;
import static org.chromium.chrome.browser.ntp.cards.ContentSuggestionsUnitTestUtils.bindViewHolders;
import static org.chromium.chrome.browser.ntp.cards.ContentSuggestionsUnitTestUtils.makeUiConfig;
import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.createDummySuggestions;
-import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.explainFailedExpectation;
import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.registerCategory;
-import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.viewTypeToString;
+import static org.chromium.chrome.test.util.browser.suggestions.ContentSuggestionsTestUtils.stringify;
import android.content.res.Resources;
import android.support.v7.widget.RecyclerView;
@@ -39,8 +38,13 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import org.mockito.exceptions.base.MockitoAssertionError;
+import org.mockito.internal.verification.Times;
+import org.mockito.internal.verification.api.VerificationDataInOrder;
+import org.mockito.verification.VerificationMode;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
@@ -57,6 +61,7 @@ import org.chromium.chrome.browser.ntp.ContextMenuManager;
import org.chromium.chrome.browser.ntp.cards.SignInPromo.SigninObserver;
import org.chromium.chrome.browser.ntp.snippets.CategoryInt;
import org.chromium.chrome.browser.ntp.snippets.CategoryStatus;
+import org.chromium.chrome.browser.ntp.snippets.KnownCategories;
import org.chromium.chrome.browser.ntp.snippets.SnippetArticle;
import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
import org.chromium.chrome.browser.preferences.ChromePreferenceManager;
@@ -108,89 +113,119 @@ public class NewTabPageAdapterTest {
* Stores information about a section that should be present in the adapter.
*/
private static class SectionDescriptor {
- public final int mNumSuggestions;
+ public boolean mHeader = true;
+ public final List<SnippetArticle> mSuggestions;
public final boolean mStatusCard;
- public boolean mActionButton;
+ public boolean mViewAllButton;
+ public boolean mFetchButton;
public boolean mProgressItem;
- public SnippetArticle mFirstItem;
- public SectionDescriptor(int numSuggestions) {
- mNumSuggestions = numSuggestions;
- mStatusCard = numSuggestions == 0;
+ public SectionDescriptor(List<SnippetArticle> suggestions) {
+ mSuggestions = suggestions;
+ mStatusCard = suggestions.isEmpty();
}
- public SectionDescriptor withActionButton() {
- mActionButton = true;
+ public SectionDescriptor withoutHeader() {
+ mHeader = false;
return this;
}
- public SectionDescriptor withProgress() {
- mProgressItem = true;
+ public SectionDescriptor withViewAllButton() {
+ mViewAllButton = true;
+ return this;
+ }
+
+ public SectionDescriptor withFetchButton() {
+ mFetchButton = true;
return this;
}
- public SectionDescriptor withFirstItem(SnippetArticle firstItem) {
- mFirstItem = firstItem;
+ public SectionDescriptor withProgress() {
+ mProgressItem = true;
return this;
}
}
/**
* Checks the list of items from the adapter against a sequence of expectation, which is
- * expressed as a sequence of calls to the {@link #expect} methods.
+ * expressed as a sequence of calls to the {@code expect...()} methods.
*/
private static class ItemsMatcher { // TODO(pke): Find better name.
- private final TreeNode mTreeNode;
- private int mCurrentIndex;
+ private final TreeNode mRoot;
+ private final NodeVisitor mVisitor = mock(NodeVisitor.class);
+ private final InOrder mInOrder = inOrder(mVisitor);
+
+ /**
+ * The {@link org.mockito.internal.verification.Description} verification mode doesn't
+ * support in-order verification, so we use a custom verification mode that derives from the
+ * default one.
+ */
+ private final VerificationMode mVerification = new Times(1) {
+ @Override
+ public void verifyInOrder(VerificationDataInOrder data) {
+ try {
+ super.verifyInOrder(data);
+ } catch (MockitoAssertionError e) {
+ throw new MockitoAssertionError(e, stringify(mRoot));
+ }
+ }
+ };
public ItemsMatcher(TreeNode root) {
- mTreeNode = root;
+ mRoot = root;
+ root.visitItems(mVisitor);
}
- public void expect(@ItemViewType int expectedItemType) {
- if (mCurrentIndex >= mTreeNode.getItemCount()) {
- fail("Expected item of type " + viewTypeToString(expectedItemType)
- + " but encountered end of list\n"
- + explainFailedExpectation(mTreeNode, mCurrentIndex, expectedItemType));
- }
- if (mTreeNode.getItemViewType(mCurrentIndex) != expectedItemType) {
- fail("Type mismatch at position " + mCurrentIndex + "\n"
- + explainFailedExpectation(mTreeNode, mCurrentIndex, expectedItemType));
+ public void expectSection(SectionDescriptor descriptor) {
+ if (descriptor.mHeader) {
+ mInOrder.verify(mVisitor, mVerification).visitHeader();
}
- mCurrentIndex++;
- }
-
- public void expect(SectionDescriptor descriptor) {
- expect(ItemViewType.HEADER);
- if (descriptor.mFirstItem != null) {
- if (mTreeNode.getSuggestionAt(mCurrentIndex) != descriptor.mFirstItem) {
- fail("Wrong item at position " + mCurrentIndex + "\n"
- + explainFailedExpectation(
- mTreeNode, mCurrentIndex, ItemViewType.SNIPPET));
- }
+ for (SnippetArticle suggestion : descriptor.mSuggestions) {
+ mInOrder.verify(mVisitor, mVerification).visitSuggestion(eq(suggestion));
}
- for (int i = 1; i <= descriptor.mNumSuggestions; i++) {
- expect(ItemViewType.SNIPPET);
+ if (descriptor.mStatusCard) {
+ mInOrder.verify(mVisitor, mVerification).visitNoSuggestionsItem();
}
- if (descriptor.mStatusCard) {
- expect(ItemViewType.STATUS);
+ if (descriptor.mViewAllButton) {
+ mInOrder.verify(mVisitor, mVerification)
+ .visitActionItem(ContentSuggestionsAdditionalAction.VIEW_ALL);
}
- if (descriptor.mActionButton) {
- // TODO(bauerb): Verify the action.
- expect(ItemViewType.ACTION);
+ if (descriptor.mFetchButton) {
+ mInOrder.verify(mVisitor, mVerification)
+ .visitActionItem(ContentSuggestionsAdditionalAction.FETCH);
}
if (descriptor.mProgressItem) {
- expect(ItemViewType.PROGRESS);
+ mInOrder.verify(mVisitor, mVerification).visitProgressItem();
}
}
+ public void expectAboveTheFoldItem() {
+ mInOrder.verify(mVisitor, mVerification).visitAboveTheFoldItem();
+ }
+
+ public void expectAllDismissedItem() {
+ mInOrder.verify(mVisitor, mVerification).visitAllDismissedItem();
+ }
+
+ public void expectFooter() {
+ mInOrder.verify(mVisitor, mVerification).visitFooter();
+ }
+
+ public void expectSpacingItem() {
+ mInOrder.verify(mVisitor, mVerification).visitSpacingItem();
+ }
+
public void expectEnd() {
- assertEquals(mTreeNode.getItemCount(), mCurrentIndex);
+ try {
+ verifyNoMoreInteractions(mVisitor);
+ } catch (MockitoAssertionError e) {
+ throw new MockitoAssertionError(e, stringify(mRoot));
+ }
}
}
@@ -242,7 +277,7 @@ public class NewTabPageAdapterTest {
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(numSuggestions));
+ assertItemsFor(section(suggestions));
}
/**
@@ -262,7 +297,7 @@ public class NewTabPageAdapterTest {
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(numSuggestions));
+ assertItemsFor(section(suggestions));
}
/**
@@ -274,12 +309,12 @@ public class NewTabPageAdapterTest {
List<SnippetArticle> suggestions = createDummySuggestions(4, TEST_CATEGORY);
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(4));
+ assertItemsFor(section(suggestions));
// If we get told that the category is enabled, we just leave the current suggestions do not
// clear them.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
- assertItemsFor(section(4));
+ assertItemsFor(section(suggestions));
// When the category is disabled, the section should go away completely.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.CATEGORY_EXPLICITLY_DISABLED);
@@ -293,7 +328,7 @@ public class NewTabPageAdapterTest {
// After a full refresh, the adapter should accept suggestions again.
mSource.fireFullRefreshRequired();
- assertItemsFor(section(6));
+ assertItemsFor(section(suggestions));
}
/**
@@ -307,17 +342,17 @@ public class NewTabPageAdapterTest {
// By default, status is INITIALIZING, so we can load suggestions.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(3));
+ assertItemsFor(section(suggestions));
// Add another suggestion.
- suggestions.add(new SnippetArticle(TEST_CATEGORY, "https://site.com/url1", "title1", "pub1",
- "txt1", "https://site.com/url1", 0, 0, 0));
+ suggestions.add(new SnippetArticle(TEST_CATEGORY, "https://site.com/url3", "title3", "pub3",
+ "txt3", "https://site.com/url3", 0, 0, 0));
// When the provider is removed, we should not be able to load suggestions. The UI should
// stay the same though.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.NOT_PROVIDED);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(3));
+ assertItemsFor(section(suggestions.subList(0, 3)));
// INITIALIZING lets us load suggestions still.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.INITIALIZING);
@@ -327,7 +362,7 @@ public class NewTabPageAdapterTest {
// The adapter should now be waiting for new suggestions and the fourth one should appear.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(4));
+ assertItemsFor(section(suggestions));
// When the category gets disabled, the section should go away and not load any suggestions.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.CATEGORY_EXPLICITLY_DISABLED);
@@ -370,7 +405,7 @@ public class NewTabPageAdapterTest {
List<SnippetArticle> suggestions = createDummySuggestions(5, TEST_CATEGORY);
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(5));
+ assertItemsFor(section(suggestions));
// When the category goes away with a hard error, the section is cleared from the UI.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.LOADING_ERROR);
@@ -384,7 +419,7 @@ public class NewTabPageAdapterTest {
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
reloadNtp();
- assertItemsFor(section(5));
+ assertItemsFor(section(suggestions));
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.CATEGORY_EXPLICITLY_DISABLED);
assertItemsFor();
@@ -401,12 +436,12 @@ public class NewTabPageAdapterTest {
List<SnippetArticle> suggestions = createDummySuggestions(4, TEST_CATEGORY);
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(4));
+ assertItemsFor(section(suggestions));
// When the category switches to NOT_PROVIDED, UI stays the same.
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.NOT_PROVIDED);
mSource.silentlyRemoveCategory(TEST_CATEGORY);
- assertItemsFor(section(4));
+ assertItemsFor(section(suggestions));
reloadNtp();
assertItemsFor();
@@ -431,17 +466,17 @@ public class NewTabPageAdapterTest {
mSource.setSuggestionsForCategory(otherCategory, otherSuggestions);
reloadNtp();
- assertItemsFor(section(4), section(2));
+ assertItemsFor(section(suggestions), section(otherSuggestions));
// Bind the whole section - indicate that it is being viewed.
bindViewHolders(mAdapter.getSectionListForTesting().getSectionForTesting(otherCategory));
List<SnippetArticle> newSuggestions = createDummySuggestions(3, TEST_CATEGORY, "new");
mSource.setSuggestionsForCategory(TEST_CATEGORY, newSuggestions);
- assertItemsFor(section(3), section(2));
+ assertItemsFor(section(newSuggestions), section(otherSuggestions));
reloadNtp();
- assertItemsFor(section(3), section(2));
+ assertItemsFor(section(newSuggestions), section(otherSuggestions));
}
/** Tests whether a section stays visible if empty, if required. */
@@ -464,12 +499,12 @@ public class NewTabPageAdapterTest {
Collections.unmodifiableList(createDummySuggestions(3, TEST_CATEGORY));
suggestionsSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
suggestionsSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(3));
+ assertItemsFor(section(suggestions));
// 1.3 - When all suggestions are dismissed
SuggestionsSection section =
mAdapter.getSectionListForTesting().getSectionForTesting(TEST_CATEGORY);
- assertSectionMatches(section(3), section);
+ assertSectionMatches(section(suggestions), section);
section.removeSuggestionById(suggestions.get(0).mIdWithinCategory);
section.removeSuggestionById(suggestions.get(1).mIdWithinCategory);
section.removeSuggestionById(suggestions.get(2).mIdWithinCategory);
@@ -499,7 +534,7 @@ public class NewTabPageAdapterTest {
*/
@Test
@Feature({"Ntp"})
- public void testMoreButton() {
+ public void testViewAllButton() {
// Part 1: With "View All" action
FakeSuggestionsSource suggestionsSource = new FakeSuggestionsSource();
suggestionsSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.INITIALIZING);
@@ -512,23 +547,23 @@ public class NewTabPageAdapterTest {
// 1.1 - Initial state.
when(mUiDelegate.getSuggestionsSource()).thenReturn(suggestionsSource);
reloadNtp();
- assertItemsFor(sectionWithStatusCard().withActionButton().withProgress());
+ assertItemsFor(sectionWithStatusCard().withViewAllButton().withProgress());
// 1.2 - With suggestions.
List<SnippetArticle> suggestions =
Collections.unmodifiableList(createDummySuggestions(3, TEST_CATEGORY));
suggestionsSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
suggestionsSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(3).withActionButton());
+ assertItemsFor(section(suggestions).withViewAllButton());
// 1.3 - When all suggestions are dismissed.
SuggestionsSection section =
mAdapter.getSectionListForTesting().getSectionForTesting(TEST_CATEGORY);
- assertSectionMatches(section(3).withActionButton(), section);
+ assertSectionMatches(section(suggestions).withViewAllButton(), section);
section.removeSuggestionById(suggestions.get(0).mIdWithinCategory);
section.removeSuggestionById(suggestions.get(1).mIdWithinCategory);
section.removeSuggestionById(suggestions.get(2).mIdWithinCategory);
- assertItemsFor(sectionWithStatusCard().withActionButton());
+ assertItemsFor(sectionWithStatusCard().withViewAllButton());
// Part 1: Without "View All" action
suggestionsSource = new FakeSuggestionsSource();
@@ -544,11 +579,11 @@ public class NewTabPageAdapterTest {
// 2.2 - With suggestions.
suggestionsSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
suggestionsSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(3));
+ assertItemsFor(section(suggestions));
// 2.3 - When all suggestions are dismissed.
section = mAdapter.getSectionListForTesting().getSectionForTesting(TEST_CATEGORY);
- assertSectionMatches(section(3), section);
+ assertSectionMatches(section(suggestions), section);
section.removeSuggestionById(suggestions.get(0).mIdWithinCategory);
section.removeSuggestionById(suggestions.get(1).mIdWithinCategory);
section.removeSuggestionById(suggestions.get(2).mIdWithinCategory);
@@ -556,6 +591,70 @@ public class NewTabPageAdapterTest {
}
/**
+ * Tests that the more button is shown for sections that declare it.
+ */
+ @Test
+ @Feature({"Ntp"})
+ public void testFetchButton() {
+ @CategoryInt
+ final int category = TEST_CATEGORY;
+
+ // Part 1: With "Fetch more" action
+ FakeSuggestionsSource suggestionsSource = new FakeSuggestionsSource();
+ suggestionsSource.setStatusForCategory(category, CategoryStatus.INITIALIZING);
+ suggestionsSource.setInfoForCategory(category,
+ new CategoryInfoBuilder(category)
+ .withAction(ContentSuggestionsAdditionalAction.FETCH)
+ .showIfEmpty()
+ .build());
+
+ // 1.1 - Initial state.
+ when(mUiDelegate.getSuggestionsSource()).thenReturn(suggestionsSource);
+ reloadNtp();
+ assertItemsFor(sectionWithStatusCard().withFetchButton().withProgress());
+
+ // 1.2 - With suggestions.
+ List<SnippetArticle> articles =
+ Collections.unmodifiableList(createDummySuggestions(3, category));
+ suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABLE);
+ suggestionsSource.setSuggestionsForCategory(category, articles);
+ assertItemsFor(section(articles).withFetchButton());
+
+ // 1.3 - When all suggestions are dismissed.
+ SuggestionsSection section =
+ mAdapter.getSectionListForTesting().getSectionForTesting(category);
+ assertSectionMatches(section(articles).withFetchButton(), section);
+ section.removeSuggestionById(articles.get(0).mIdWithinCategory);
+ section.removeSuggestionById(articles.get(1).mIdWithinCategory);
+ section.removeSuggestionById(articles.get(2).mIdWithinCategory);
+ assertItemsFor(sectionWithStatusCard().withFetchButton());
+
+ // Part 1: Without "Fetch more" action
+ suggestionsSource = new FakeSuggestionsSource();
+ suggestionsSource.setStatusForCategory(category, CategoryStatus.INITIALIZING);
+ suggestionsSource.setInfoForCategory(
+ category, new CategoryInfoBuilder(category).showIfEmpty().build());
+
+ // 2.1 - Initial state.
+ when(mUiDelegate.getSuggestionsSource()).thenReturn(suggestionsSource);
+ reloadNtp();
+ assertItemsFor(sectionWithStatusCard().withProgress());
+
+ // 2.2 - With suggestions.
+ suggestionsSource.setStatusForCategory(category, CategoryStatus.AVAILABLE);
+ suggestionsSource.setSuggestionsForCategory(category, articles);
+ assertItemsFor(section(articles));
+
+ // 2.3 - When all suggestions are dismissed.
+ section = mAdapter.getSectionListForTesting().getSectionForTesting(category);
+ assertSectionMatches(section(articles), section);
+ section.removeSuggestionById(articles.get(0).mIdWithinCategory);
+ section.removeSuggestionById(articles.get(1).mIdWithinCategory);
+ section.removeSuggestionById(articles.get(2).mIdWithinCategory);
+ assertItemsFor(sectionWithStatusCard());
+ }
+
+ /**
* Tests that invalidated suggestions are immediately removed.
*/
@Test
@@ -564,12 +663,11 @@ public class NewTabPageAdapterTest {
List<SnippetArticle> suggestions = createDummySuggestions(3, TEST_CATEGORY);
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(3));
- assertArticlesEqual(suggestions, 2, 5);
+ assertItemsFor(section(suggestions));
SnippetArticle removed = suggestions.remove(1);
mSource.fireSuggestionInvalidated(TEST_CATEGORY, removed.mIdWithinCategory);
- assertArticlesEqual(suggestions, 2, 4);
+ assertItemsFor(section(suggestions));
}
/**
@@ -581,7 +679,7 @@ public class NewTabPageAdapterTest {
List<SnippetArticle> suggestions = createDummySuggestions(3, TEST_CATEGORY);
mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
- assertItemsFor(section(3));
+ assertItemsFor(section(suggestions));
int dynamicCategory1 = 1010;
List<SnippetArticle> dynamics1 = createDummySuggestions(5, dynamicCategory1);
@@ -593,7 +691,7 @@ public class NewTabPageAdapterTest {
mSource.setSuggestionsForCategory(dynamicCategory1, dynamics1);
reloadNtp();
- assertItemsFor(section(3), section(5).withActionButton());
+ assertItemsFor(section(suggestions), section(dynamics1).withViewAllButton());
int dynamicCategory2 = 1011;
List<SnippetArticle> dynamics2 = createDummySuggestions(11, dynamicCategory2);
@@ -602,7 +700,33 @@ public class NewTabPageAdapterTest {
mSource.setStatusForCategory(dynamicCategory2, CategoryStatus.AVAILABLE);
mSource.setSuggestionsForCategory(dynamicCategory2, dynamics2);
reloadNtp();
- assertItemsFor(section(3), section(5).withActionButton(), section(11));
+ assertItemsFor(
+ section(suggestions), section(dynamics1).withViewAllButton(), section(dynamics2));
+ }
+
+ @Test
+ @Feature({"Ntp"})
+ public void testArticlesForYouSection() {
+ // Show one section of suggestions from the test category, and one section with Articles for
+ // You.
+ List<SnippetArticle> suggestions = createDummySuggestions(3, TEST_CATEGORY);
+ mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.AVAILABLE);
+ mSource.setSuggestionsForCategory(TEST_CATEGORY, suggestions);
+
+ mSource.setInfoForCategory(KnownCategories.ARTICLES,
+ new CategoryInfoBuilder(KnownCategories.ARTICLES).build());
+ mSource.setStatusForCategory(KnownCategories.ARTICLES, CategoryStatus.AVAILABLE);
+ List<SnippetArticle> articles = createDummySuggestions(3, KnownCategories.ARTICLES);
+ mSource.setSuggestionsForCategory(KnownCategories.ARTICLES, articles);
+
+ reloadNtp();
+ assertItemsFor(section(suggestions), section(articles));
+
+ // Remove the test category section. The remaining lone Articles for You section should not
+ // have a header.
+ mSource.setStatusForCategory(TEST_CATEGORY, CategoryStatus.NOT_PROVIDED);
+ reloadNtp();
+ assertItemsFor(section(articles).withoutHeader());
}
/**
@@ -962,7 +1086,7 @@ public class NewTabPageAdapterTest {
*/
private void assertSectionMatches(SectionDescriptor descriptor, SuggestionsSection section) {
ItemsMatcher matcher = new ItemsMatcher(section);
- matcher.expect(descriptor);
+ matcher.expectSection(descriptor);
matcher.expectEnd();
}
@@ -975,28 +1099,28 @@ public class NewTabPageAdapterTest {
*/
private void assertItemsFor(SectionDescriptor... descriptors) {
ItemsMatcher matcher = new ItemsMatcher(mAdapter.getRootForTesting());
- matcher.expect(ItemViewType.ABOVE_THE_FOLD);
- for (SectionDescriptor descriptor : descriptors) matcher.expect(descriptor);
+ matcher.expectAboveTheFoldItem();
+ for (SectionDescriptor descriptor : descriptors) matcher.expectSection(descriptor);
if (descriptors.length == 0) {
- matcher.expect(ItemViewType.ALL_DISMISSED);
+ matcher.expectAllDismissedItem();
} else {
- matcher.expect(ItemViewType.FOOTER);
+ matcher.expectFooter();
}
- matcher.expect(ItemViewType.SPACING);
+ matcher.expectSpacingItem();
matcher.expectEnd();
}
/**
* To be used with {@link #assertItemsFor(SectionDescriptor...)}, for a section with
* {@code numSuggestions} cards in it.
- * @param numSuggestions The number of suggestions in the section. If there are zero, use either
+ * @param suggestions The list of suggestions in the section. If the list is empty, use either
* no section at all (if it is not displayed) or
* {@link #sectionWithStatusCard()}.
* @return A descriptor for the section.
*/
- private SectionDescriptor section(int numSuggestions) {
- assert numSuggestions > 0;
- return new SectionDescriptor(numSuggestions);
+ private SectionDescriptor section(List<SnippetArticle> suggestions) {
+ assert !suggestions.isEmpty();
+ return new SectionDescriptor(suggestions);
}
/**
@@ -1005,7 +1129,7 @@ public class NewTabPageAdapterTest {
* @return A descriptor for the section.
*/
private SectionDescriptor sectionWithStatusCard() {
- return new SectionDescriptor(0);
+ return new SectionDescriptor(Collections.<SnippetArticle>emptyList());
}
private void reloadNtp() {
@@ -1015,13 +1139,6 @@ public class NewTabPageAdapterTest {
mAdapter.refreshSuggestions();
}
- private void assertArticlesEqual(List<SnippetArticle> articles, int start, int end) {
- assertThat(mAdapter.getItemCount(), greaterThanOrEqualTo(end));
- for (int i = start; i < end; i++) {
- assertEquals(articles.get(i - start), mAdapter.getSuggestionAt(i));
- }
- }
-
private boolean isSignInPromoVisible() {
return mAdapter.getFirstPositionForType(ItemViewType.PROMO) != RecyclerView.NO_POSITION;
}

Powered by Google App Engine
This is Rietveld 408576698