package io.github.hidroh.materialistic;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;
import android.widget.PopupMenu;
import android.widget.TextView;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.MockitoAnnotations;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Config;
import org.robolectric.fakes.RoboMenuItem;
import org.robolectric.internal.ShadowExtractor;
import org.robolectric.shadows.ShadowContentObserver;
import org.robolectric.shadows.ShadowPopupMenu;
import org.robolectric.shadows.ShadowToast;
import org.robolectric.util.ActivityController;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Named;
import io.github.hidroh.materialistic.accounts.UserServices;
import io.github.hidroh.materialistic.data.FavoriteManager;
import io.github.hidroh.materialistic.data.HackerNewsClient;
import io.github.hidroh.materialistic.data.Item;
import io.github.hidroh.materialistic.data.ItemManager;
import io.github.hidroh.materialistic.data.MaterialisticProvider;
import io.github.hidroh.materialistic.data.ResponseListener;
import io.github.hidroh.materialistic.data.SessionManager;
import io.github.hidroh.materialistic.data.TestHnItem;
import io.github.hidroh.materialistic.data.WebItem;
import io.github.hidroh.materialistic.test.ListActivity;
import io.github.hidroh.materialistic.test.TestLayoutManager;
import io.github.hidroh.materialistic.test.TestRunner;
import io.github.hidroh.materialistic.test.shadow.ShadowAnimation;
import io.github.hidroh.materialistic.test.shadow.ShadowItemTouchHelper;
import io.github.hidroh.materialistic.test.shadow.ShadowRecyclerView;
import io.github.hidroh.materialistic.test.shadow.ShadowRecyclerViewAdapter;
import io.github.hidroh.materialistic.test.shadow.ShadowSnackbar;
import io.github.hidroh.materialistic.test.shadow.ShadowSwipeRefreshLayout;
import io.github.hidroh.materialistic.test.suite.SlowTest;
import static io.github.hidroh.materialistic.test.shadow.CustomShadows.customShadowOf;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.assertj.android.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.robolectric.Shadows.shadowOf;
@SuppressWarnings("ConstantConditions")
@Category(SlowTest.class)
@Config(shadows = {ShadowSwipeRefreshLayout.class,
ShadowRecyclerViewAdapter.class,
ShadowRecyclerView.class,
ShadowItemTouchHelper.class,
ShadowAnimation.class,
ShadowSnackbar.class})
@RunWith(TestRunner.class)
public class ListFragmentViewHolderTest {
private ActivityController<ListActivity> controller;
private ShadowRecyclerViewAdapter adapter;
private ListActivity activity;
private TestHnItem item;
@Inject SessionManager sessionManager;
@Inject @Named(ActivityModule.HN) ItemManager itemManager;
@Inject FavoriteManager favoriteManager;
@Inject UserServices userServices;
@Captor ArgumentCaptor<ResponseListener<Item[]>> storiesListener;
@Captor ArgumentCaptor<ResponseListener<Item>> itemListener;
@Captor ArgumentCaptor<UserServices.Callback> voteCallback;
private RecyclerView recyclerView;
private ItemTouchHelper.SimpleCallback swipeCallback;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
TestApplication.applicationGraph.inject(this);
reset(sessionManager);
reset(favoriteManager);
reset(itemManager);
reset(userServices);
item = new TestHnItem(1) {
@Override
public int getRank() {
return 46;
}
@Override
public String getBy() {
return "author";
}
};
controller = Robolectric.buildActivity(ListActivity.class)
.create().start().resume().visible();
activity = controller.get();
Bundle args = new Bundle();
args.putString(ListFragment.EXTRA_ITEM_MANAGER, HackerNewsClient.class.getName());
args.putString(ListFragment.EXTRA_FILTER, ItemManager.TOP_FETCH_MODE);
activity.getSupportFragmentManager()
.beginTransaction()
.add(android.R.id.content,
Fragment.instantiate(activity, ListFragment.class.getName(), args))
.commit();
verify(itemManager).getStories(any(),
eq(ItemManager.MODE_DEFAULT),
storiesListener.capture());
storiesListener.getValue().onResponse(new Item[]{item});
recyclerView = (RecyclerView) activity.findViewById(R.id.recycler_view);
swipeCallback = (ItemTouchHelper.SimpleCallback) customShadowOf(recyclerView).getItemTouchHelperCallback();
adapter = customShadowOf(recyclerView.getAdapter());
item.populate(new PopulatedStory(1));
}
@Test
public void testStory() {
item.setIsViewed(true);
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat(holder.itemView.findViewById(R.id.bookmarked)).isNotVisible();
assertThat((TextView) holder.itemView.findViewById(R.id.rank)).hasTextString("46");
assertThat((TextView) holder.itemView.findViewById(R.id.title)).hasTextString("title");
assertThat((TextView) holder.itemView.findViewById(R.id.comment))
.isVisible()
.isEmpty();
assertViewed();
}
@Test
public void testNewStory() {
reset(itemManager);
ShadowSwipeRefreshLayout shadowSwipeRefreshLayout = (ShadowSwipeRefreshLayout)
ShadowExtractor.extract(activity.findViewById(R.id.swipe_layout));
shadowSwipeRefreshLayout.getOnRefreshListener().onRefresh();
verify(itemManager).getStories(any(),
eq(ItemManager.MODE_NETWORK),
storiesListener.capture());
storiesListener.getValue().onResponse(new Item[]{new TestHnItem(2) {
@Override
public int getRank() {
return 46;
}
}});
ShadowSnackbar.getLatestView().findViewById(R.id.snackbar_action).performClick();
verify(itemManager, atLeastOnce()).getItem(any(),
eq(ItemManager.MODE_NETWORK),
itemListener.capture());
itemListener.getValue().onResponse(new PopulatedStory(2));
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.rank)).hasTextString("46*");
}
@Test
public void testPromoted() {
reset(itemManager);
ShadowSwipeRefreshLayout shadowSwipeRefreshLayout = (ShadowSwipeRefreshLayout)
ShadowExtractor.extract(activity.findViewById(R.id.swipe_layout));
shadowSwipeRefreshLayout.getOnRefreshListener().onRefresh();
verify(itemManager).getStories(any(),
eq(ItemManager.MODE_NETWORK),
storiesListener.capture());
storiesListener.getValue().onResponse(new Item[]{new TestHnItem(1) {
@Override
public int getRank() {
return 45;
}
}});
verify(itemManager).getItem(any(), eq(ItemManager.MODE_NETWORK), itemListener.capture());
itemListener.getValue().onResponse(new PopulatedStory(1));
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.rank)).containsText("+1");
}
@Test
public void testNewComments() {
reset(itemManager);
ShadowSwipeRefreshLayout shadowSwipeRefreshLayout = (ShadowSwipeRefreshLayout)
ShadowExtractor.extract(activity.findViewById(R.id.swipe_layout));
shadowSwipeRefreshLayout.getOnRefreshListener().onRefresh();
verify(itemManager).getStories(any(),
eq(ItemManager.MODE_NETWORK),
storiesListener.capture());
storiesListener.getValue().onResponse(new Item[]{new TestHnItem(1)});
verify(itemManager).getItem(any(), eq(ItemManager.MODE_NETWORK), itemListener.capture());
itemListener.getValue().onResponse(new PopulatedStory(1) {
@Override
public int getDescendants() {
return 2;
}
@Override
public long[] getKids() {
return new long[]{2, 3};
}
});
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.comment)).hasTextString("2*");
}
@Test
public void testPreferenceChange() {
reset(itemManager);
ShadowSwipeRefreshLayout shadowSwipeRefreshLayout = (ShadowSwipeRefreshLayout)
ShadowExtractor.extract(activity.findViewById(R.id.swipe_layout));
shadowSwipeRefreshLayout.getOnRefreshListener().onRefresh();
verify(itemManager).getStories(any(),
eq(ItemManager.MODE_NETWORK),
storiesListener.capture());
storiesListener.getValue().onResponse(new Item[]{new TestHnItem(2) {
@Override
public int getRank() {
return 46;
}
}});
verify(itemManager).getItem(any(), eq(ItemManager.MODE_NETWORK), itemListener.capture());
itemListener.getValue().onResponse(new PopulatedStory(2));
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.rank)).hasTextString("46*");
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putBoolean(activity.getString(R.string.pref_highlight_updated), false)
.apply();
holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.rank)).hasTextString("46");
}
@Test
public void testComment() {
item.populate(new PopulatedStory(1) {
@Override
public int getDescendants() {
return 1;
}
@Override
public long[] getKids() {
return new long[]{2};
}
});
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
View commentButton = holder.itemView.findViewById(R.id.comment);
assertThat(commentButton).isVisible();
reset(activity.multiPaneListener);
commentButton.performClick();
verify(activity.multiPaneListener, never()).onItemSelected(any(WebItem.class)
);
Intent actual = shadowOf(activity).getNextStartedActivity();
assertEquals(ItemActivity.class.getName(), actual.getComponent().getClassName());
assertThat(actual).hasExtra(ItemActivity.EXTRA_OPEN_COMMENTS, true);
}
@Test
public void testJob() {
item.populate(new PopulatedStory(1) {
@Override
public String getRawType() {
return JOB_TYPE;
}
});
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.source)).isEmpty();
}
@Test
public void testPoll() {
item.populate(new PopulatedStory(1) {
@Override
public String getRawType() {
return POLL_TYPE;
}
});
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.source)).isEmpty();
}
@Test
public void testItemClick() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
adapter.getViewHolder(0).itemView.performClick();
verify(activity.multiPaneListener).onItemSelected(any(WebItem.class));
}
@Test
public void testViewedObserver() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
assertNotViewed();
controller.pause();
ShadowContentObserver observer = shadowOf(shadowOf(activity
.getContentResolver())
.getContentObservers(MaterialisticProvider.URI_VIEWED)
.iterator()
.next());
observer.dispatchChange(false, MaterialisticProvider.URI_VIEWED
.buildUpon().appendPath("2").build()); // not in view
observer.dispatchChange(false, MaterialisticProvider.URI_VIEWED
.buildUpon().appendPath("1").build()); // in view
controller.resume();
assertViewed();
}
@Test
public void testFavoriteObserver() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
item.setFavorite(true);
itemListener.getValue().onResponse(item);
assertTrue(item.isFavorite());
controller.pause();
ShadowContentObserver observer = shadowOf(shadowOf(activity
.getContentResolver())
.getContentObservers(MaterialisticProvider.URI_FAVORITE)
.iterator()
.next());
// observed clear
observer.dispatchChange(false, MaterialisticProvider.URI_FAVORITE
.buildUpon()
.appendPath("clear")
.build());
RecyclerView.ViewHolder viewHolder = adapter.getViewHolder(0);
assertFalse(item.isFavorite());
assertThat(viewHolder.itemView.findViewById(R.id.bookmarked)).isNotVisible();
// observed add
observer.dispatchChange(false, MaterialisticProvider.URI_FAVORITE
.buildUpon()
.appendPath("add")
.appendPath("1")
.build());
assertTrue(item.isFavorite());
// observed remove
observer.dispatchChange(false, MaterialisticProvider.URI_FAVORITE
.buildUpon()
.appendPath("remove")
.appendPath("1")
.build());
assertFalse(item.isFavorite());
controller.resume();
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testSaveItem() {
ShadowContentObserver observer = shadowOf(shadowOf(activity
.getContentResolver())
.getContentObservers(MaterialisticProvider.URI_FAVORITE)
.iterator()
.next());
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
adapter.getViewHolder(0).itemView.performLongClick();
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
assertNotNull(popupMenu);
assertThat(popupMenu.getMenu().findItem(R.id.menu_contextual_save).isVisible()).isFalse();
shadowOf(popupMenu).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_save));
verify(favoriteManager).add(any(Context.class), eq(item));
observer.dispatchChange(false, MaterialisticProvider.URI_FAVORITE
.buildUpon()
.appendPath("add")
.appendPath("1")
.build());
assertTrue(item.isFavorite());
View snackbarView = ShadowSnackbar.getLatestView();
assertThat((TextView) snackbarView.findViewById(R.id.snackbar_text))
.isNotNull()
.containsText(R.string.toast_saved);
snackbarView.findViewById(R.id.snackbar_action).performClick();
verify(favoriteManager).remove(any(Context.class), eq("1"));
observer.dispatchChange(false, MaterialisticProvider.URI_FAVORITE
.buildUpon()
.appendPath("remove")
.appendPath("1")
.build());
assertFalse(item.isFavorite());
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testSwipeToSaveItem() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat(swipeCallback.onMove(recyclerView, holder, holder)).isFalse();
assertThat(swipeCallback.getSwipeThreshold(holder)).isGreaterThan(0f);
assertThat(swipeCallback.getSwipeDirs(recyclerView, holder))
.isEqualTo(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
Canvas canvas = mock(Canvas.class);
swipeCallback.onChildDraw(canvas, recyclerView, holder, -1f, 0f,
ItemTouchHelper.ACTION_STATE_SWIPE, true);
verify(canvas).drawText(eq(activity.getString(R.string.save).toUpperCase()),
anyFloat(), anyFloat(), any(Paint.class));
swipeCallback.onSwiped(holder, ItemTouchHelper.LEFT);
verify(favoriteManager).add(any(Context.class), eq(item));
item.setFavorite(true);
assertThat(swipeCallback.getSwipeDirs(recyclerView, holder))
.isEqualTo(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
}
@Test
public void testDisableSwipe() {
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putString(activity.getString(R.string.pref_list_swipe_left),
Preferences.SwipeAction.None.name())
.putString(activity.getString(R.string.pref_list_swipe_right),
Preferences.SwipeAction.None.name())
.apply();
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat(swipeCallback.getSwipeDirs(recyclerView, holder)).isEqualTo(0);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testViewUser() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
adapter.getViewHolder(0).itemView.performLongClick();
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_profile));
assertThat(shadowOf(activity).getNextStartedActivity())
.hasComponent(activity, UserActivity.class)
.hasExtra(UserActivity.EXTRA_USERNAME, "author");
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testVoteItem() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
adapter.getViewHolder(0).itemView.performLongClick();
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
assertNotNull(popupMenu);
assertThat(popupMenu.getMenu().findItem(R.id.menu_contextual_vote).isVisible()).isFalse();
shadowOf(popupMenu).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote));
verify(userServices).voteUp(any(Context.class), eq(item.getId()), voteCallback.capture());
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testSwipeToVoteItem() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat(swipeCallback.getSwipeDirs(recyclerView, holder))
.isEqualTo(ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
Canvas canvas = mock(Canvas.class);
swipeCallback.onChildDraw(canvas, recyclerView, holder, 1f, 0f,
ItemTouchHelper.ACTION_STATE_SWIPE, true);
verify(canvas).drawText(eq(activity.getString(R.string.vote_up).toUpperCase()),
anyFloat(), anyFloat(), any(Paint.class));
swipeCallback.onSwiped(holder, ItemTouchHelper.RIGHT);
verify(userServices).voteUp(any(Context.class), eq(item.getId()), voteCallback.capture());
item.incrementScore();
assertThat(swipeCallback.getSwipeDirs(recyclerView, holder))
.isEqualTo(ItemTouchHelper.LEFT);
item.clearPendingVoted();
assertThat(swipeCallback.getSwipeDirs(recyclerView, holder))
.isEqualTo(ItemTouchHelper.LEFT);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testVoteItemPromptToLogin() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
adapter.getViewHolder(0).itemView.findViewById(R.id.button_more).performClick();
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote));
verify(userServices).voteUp(any(Context.class), eq(item.getId()), voteCallback.capture());
voteCallback.getValue().onDone(false);
assertThat(shadowOf(activity).getNextStartedActivity())
.hasComponent(activity, LoginActivity.class);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testVoteItemFailed() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
adapter.getViewHolder(0).itemView.performLongClick();
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_vote));
verify(userServices).voteUp(any(Context.class), eq(item.getId()), voteCallback.capture());
voteCallback.getValue().onError(new IOException());
assertEquals(activity.getString(R.string.vote_failed), ShadowToast.getTextOfLatestToast());
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testReply() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
adapter.getViewHolder(0).itemView.performLongClick();
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_comment));
assertThat(shadowOf(activity).getNextStartedActivity())
.hasComponent(activity, ComposeActivity.class)
.hasExtra(ComposeActivity.EXTRA_PARENT_ID, "1");
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testRefresh() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
reset(itemManager);
adapter.getViewHolder(0).itemView.performLongClick();
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_refresh));
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), any());
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testSwipeToRefresh() {
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
reset(itemManager);
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putString(activity.getString(R.string.pref_list_swipe_left),
Preferences.SwipeAction.None.name())
.putString(activity.getString(R.string.pref_list_swipe_right),
Preferences.SwipeAction.Refresh.name())
.apply();
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat(swipeCallback.getSwipeDirs(recyclerView, holder))
.isEqualTo(ItemTouchHelper.RIGHT);
Canvas canvas = mock(Canvas.class);
swipeCallback.onChildDraw(canvas, recyclerView, holder, 1f, 0f,
ItemTouchHelper.ACTION_STATE_SWIPE, true);
verify(canvas).drawText(eq(activity.getString(R.string.refresh).toUpperCase()),
anyFloat(), anyFloat(), any(Paint.class));
swipeCallback.onSwiped(holder, ItemTouchHelper.RIGHT);
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), any());
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Test
public void testShare() {
TestApplication.addResolver(new Intent(Intent.ACTION_SEND));
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
adapter.getViewHolder(0).itemView.performLongClick();
PopupMenu popupMenu = ShadowPopupMenu.getLatestPopupMenu();
assertNotNull(popupMenu);
shadowOf(popupMenu).getOnMenuItemClickListener()
.onMenuItemClick(new RoboMenuItem(R.id.menu_contextual_share));
assertThat(shadowOf(activity).getNextStartedActivity())
.hasAction(Intent.ACTION_SEND);
}
@Test
public void testAutoMarkAsViewed() {
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putBoolean(activity.getString(R.string.pref_auto_viewed), true)
.apply();
ShadowRecyclerView shadowRecyclerView = customShadowOf(recyclerView);
TestLayoutManager testLayout = new TestLayoutManager(activity);
recyclerView.setLayoutManager(testLayout);
testLayout.firstVisiblePosition = 0;
shadowRecyclerView.getScrollListener().onScrolled(recyclerView, 0, 1);
verify(sessionManager, never()).view(any(Context.class), any());
verify(itemManager).getItem(any(), eq(ItemManager.MODE_DEFAULT), itemListener.capture());
itemListener.getValue().onResponse(item);
testLayout.firstVisiblePosition = 0;
shadowRecyclerView.getScrollListener().onScrolled(recyclerView, 0, 1);
verify(sessionManager, never()).view(any(Context.class), any());
testLayout.firstVisiblePosition = 1;
shadowRecyclerView.getScrollListener().onScrolled(recyclerView, 0, 1);
verify(sessionManager).view(any(Context.class), any());
item.setIsViewed(true);
testLayout.firstVisiblePosition = 1;
shadowRecyclerView.getScrollListener().onScrolled(recyclerView, 0, 1);
verify(sessionManager).view(any(Context.class), any()); // should not trigger again
PreferenceManager.getDefaultSharedPreferences(activity)
.edit()
.putBoolean(activity.getString(R.string.pref_auto_viewed), false)
.apply();
assertNull(shadowRecyclerView.getScrollListener());
}
@After
public void tearDown() {
controller.pause().stop().destroy();
}
private void assertViewed() {
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.title))
.hasCurrentTextColor(ContextCompat.getColor(activity, AppUtils.getThemedResId(activity, android.R.attr.textColorSecondary)));
}
private void assertNotViewed() {
RecyclerView.ViewHolder holder = adapter.getViewHolder(0);
assertThat((TextView) holder.itemView.findViewById(R.id.title))
.hasCurrentTextColor(ContextCompat.getColor(activity, R.color.blackT87));
}
@SuppressLint("ParcelCreator")
private static class PopulatedStory extends TestHnItem {
public PopulatedStory(long id) {
super(id);
}
@Override
public String getTitle() {
return "title";
}
@Override
public String getRawType() {
return STORY_TYPE;
}
@Override
public long[] getKids() {
return new long[0];
}
@Override
public int getDescendants() {
return 0;
}
}
}