package com.kickstarter.viewmodels;
import android.support.annotation.NonNull;
import android.util.Pair;
import com.kickstarter.KSRobolectricTestCase;
import com.kickstarter.factories.ActivityEnvelopeFactory;
import com.kickstarter.factories.ActivityFactory;
import com.kickstarter.factories.CategoryFactory;
import com.kickstarter.factories.ProjectFactory;
import com.kickstarter.factories.UserFactory;
import com.kickstarter.libs.CurrentUserType;
import com.kickstarter.libs.Environment;
import com.kickstarter.libs.KoalaEvent;
import com.kickstarter.libs.MockCurrentUser;
import com.kickstarter.libs.RefTag;
import com.kickstarter.libs.preferences.MockIntPreference;
import com.kickstarter.libs.utils.ListUtils;
import com.kickstarter.models.Activity;
import com.kickstarter.models.Project;
import com.kickstarter.services.ApiClientType;
import com.kickstarter.services.DiscoveryParams;
import com.kickstarter.services.MockApiClient;
import com.kickstarter.services.apiresponses.ActivityEnvelope;
import org.junit.Test;
import java.util.Collections;
import java.util.List;
import rx.Observable;
import rx.observers.TestSubscriber;
public class DiscoveryFragmentViewModelTest extends KSRobolectricTestCase {
@Test
public void testProjectsEmitWithNewCategoryParams() {
final DiscoveryFragmentViewModel vm = new DiscoveryFragmentViewModel(environment());
final TestSubscriber<Boolean> hasProjects = new TestSubscriber<>();
vm.outputs.projects().map(ListUtils::nonEmpty).subscribe(hasProjects);
// Load initial params and root categories from activity.
vm.inputs.paramsFromActivity(DiscoveryParams.builder().sort(DiscoveryParams.Sort.HOME).build());
vm.inputs.rootCategories(CategoryFactory.rootCategories());
// Should emit current fragment's projects.
hasProjects.assertValues(true);
koalaTest.assertValues("Discover List View");
// Select a new category.
vm.inputs.paramsFromActivity(
DiscoveryParams.builder()
.category(CategoryFactory.artCategory())
.sort(DiscoveryParams.Sort.HOME)
.build()
);
// Projects are cleared, new projects load.
hasProjects.assertValues(true, false, true);
koalaTest.assertValues("Discover List View", "Discover List View");
vm.inputs.clearPage();
hasProjects.assertValues(true, false, true, false);
}
@Test
public void testProjectsEmitWithNewSort() {
final DiscoveryFragmentViewModel vm = new DiscoveryFragmentViewModel(environment());
final TestSubscriber<List<Project>> projects = new TestSubscriber<>();
vm.outputs.projects().filter(ListUtils::nonEmpty).subscribe(projects);
// Initial load.
vm.inputs.paramsFromActivity(DiscoveryParams.builder().sort(DiscoveryParams.Sort.HOME).build());
vm.inputs.rootCategories(CategoryFactory.rootCategories());
projects.assertValueCount(1);
koalaTest.assertValues("Discover List View");
// Popular tab clicked.
vm.inputs.paramsFromActivity(DiscoveryParams.builder().sort(DiscoveryParams.Sort.POPULAR).build());
projects.assertValueCount(2);
koalaTest.assertValues("Discover List View", "Discover List View");
}
@Test
public void testProjectsRefreshAfterLogin() {
final CurrentUserType currentUser = new MockCurrentUser();
final Environment environment = environment().toBuilder()
.currentUser(currentUser)
.build();
final DiscoveryFragmentViewModel vm = new DiscoveryFragmentViewModel(environment);
final TestSubscriber<List<Project>> projects = new TestSubscriber<>();
vm.outputs.projects().filter(ListUtils::nonEmpty).subscribe(projects);
// Initial load.
vm.inputs.rootCategories(CategoryFactory.rootCategories());
vm.inputs.paramsFromActivity(DiscoveryParams.builder().sort(DiscoveryParams.Sort.HOME).build());
// Projects should emit.
projects.assertValueCount(1);
// Log in.
currentUser.refresh(UserFactory.user());
// Projects should emit again.
projects.assertValueCount(2);
}
@Test
public void testShowHeaderViews() {
final CurrentUserType currentUser = new MockCurrentUser();
final Activity activity = ActivityFactory.activity();
final ApiClientType apiClient = new MockApiClient() {
@Override
public @NonNull Observable<ActivityEnvelope> fetchActivities() {
return Observable.just(
ActivityEnvelopeFactory.activityEnvelope(Collections.singletonList(activity))
);
}
};
final MockIntPreference activitySamplePreference = new MockIntPreference(987654321);
final Environment environment = environment().toBuilder()
.activitySamplePreference(activitySamplePreference)
.apiClient(apiClient)
.currentUser(currentUser)
.build();
final DiscoveryFragmentViewModel vm = new DiscoveryFragmentViewModel(environment);
final TestSubscriber<Activity> activityTest = new TestSubscriber<>();
vm.outputs.activity().subscribe(activityTest);
final TestSubscriber<Boolean> shouldShowOnboardingViewTest = new TestSubscriber<>();
vm.outputs.shouldShowOnboardingView().subscribe(shouldShowOnboardingViewTest);
// Initial home all projects params.
vm.inputs.paramsFromActivity(DiscoveryParams.builder().sort(DiscoveryParams.Sort.HOME).build());
vm.inputs.rootCategories(CategoryFactory.rootCategories());
// Should show onboarding view.
shouldShowOnboardingViewTest.assertValues(true);
activityTest.assertValue(null);
// Change params. Onboarding view should not be shown.
vm.inputs.paramsFromActivity(DiscoveryParams.builder().build());
shouldShowOnboardingViewTest.assertValues(true, false);
activityTest.assertValues(null, null);
// Login.
currentUser.refresh(UserFactory.user());
// Activity sampler should be shown rather than onboarding view.
shouldShowOnboardingViewTest.assertValues(true, false, false);
activityTest.assertValues(null, null, activity);
// Change params. Activity sampler should not be shown.
vm.inputs.paramsFromActivity(DiscoveryParams.builder().build());
activityTest.assertValues(null, null, activity, null);
}
@Test
public void testClickingInterfaceElements() {
final DiscoveryFragmentViewModel vm = new DiscoveryFragmentViewModel(environment());
final TestSubscriber<Boolean> showActivityFeed = new TestSubscriber<>();
vm.outputs.showActivityFeed().subscribe(showActivityFeed);
final TestSubscriber<Activity> showActivityUpdate = new TestSubscriber<>();
vm.outputs.showActivityUpdate().subscribe(showActivityUpdate);
final TestSubscriber<Boolean> showLoginTout = new TestSubscriber<>();
vm.outputs.showLoginTout().subscribe(showLoginTout);
final TestSubscriber<Pair<Project, RefTag>> showProject = new TestSubscriber<>();
vm.outputs.showProject().subscribe(showProject);
// Clicking see activity feed button on sampler should show activity feed.
showActivityFeed.assertNoValues();
vm.inputs.activitySampleFriendBackingViewHolderSeeActivityClicked(null);
showActivityFeed.assertValues(true);
vm.inputs.activitySampleFriendFollowViewHolderSeeActivityClicked(null);
showActivityFeed.assertValues(true, true);
vm.inputs.activitySampleProjectViewHolderSeeActivityClicked(null);
showActivityFeed.assertValues(true, true, true);
// Clicking activity update on sampler should show activity update.
showActivityUpdate.assertNoValues();
vm.inputs.activitySampleProjectViewHolderUpdateClicked(null, ActivityFactory.updateActivity());
showActivityUpdate.assertValueCount(1);
koalaTest.assertValues(KoalaEvent.VIEWED_UPDATE);
// Clicking login on onboarding view should show login tout.
showLoginTout.assertNoValues();
vm.inputs.discoveryOnboardingViewHolderLoginToutClick(null);
showLoginTout.assertValue(true);
// Pass in params and sort to fetch projects.
vm.inputs.paramsFromActivity(DiscoveryParams.builder().build());
// Clicking on a project card should show project activity.
showProject.assertNoValues();
vm.inputs.projectCardViewHolderClick(null, ProjectFactory.project());
showProject.assertValueCount(1);
}
}