package com.kickstarter.viewmodels; import android.support.annotation.NonNull; import com.kickstarter.KSRobolectricTestCase; import com.kickstarter.factories.ConfigFactory; import com.kickstarter.factories.DiscoverEnvelopeFactory; import com.kickstarter.factories.ProjectFactory; import com.kickstarter.factories.UserFactory; import com.kickstarter.libs.Config; import com.kickstarter.libs.Environment; import com.kickstarter.libs.FeatureKey; import com.kickstarter.libs.KoalaEvent; import com.kickstarter.libs.MockCurrentConfig; import com.kickstarter.libs.utils.NumberUtils; import com.kickstarter.models.Project; import com.kickstarter.models.User; import com.kickstarter.services.ApiClientType; import com.kickstarter.services.DiscoveryParams; import com.kickstarter.services.MockApiClient; import com.kickstarter.services.apiresponses.DiscoverEnvelope; import org.junit.Test; import java.util.Collections; import java.util.List; import rx.Observable; import rx.observers.TestSubscriber; public class ProfileViewModelTest extends KSRobolectricTestCase { private ProfileViewModel.ViewModel vm; private final TestSubscriber<String> avatarImageViewUrl = new TestSubscriber<>(); private final TestSubscriber<Boolean> backedCountTextViewHidden = new TestSubscriber<>(); private final TestSubscriber<String> backedCountTextViewText = new TestSubscriber<>(); private final TestSubscriber<Boolean> backedTextViewHidden = new TestSubscriber<>(); private final TestSubscriber<Boolean> createdCountTextViewHidden = new TestSubscriber<>(); private final TestSubscriber<String> createdCountTextViewText = new TestSubscriber<>(); private final TestSubscriber<Boolean> createdTextViewHidden = new TestSubscriber<>(); private final TestSubscriber<Boolean> dividerViewHidden = new TestSubscriber<>(); private final TestSubscriber<Boolean> messagesButtonHidden= new TestSubscriber<>(); private final TestSubscriber<List<Project>> projects = new TestSubscriber<>(); private final TestSubscriber<Void> resumeDiscoveryActivity = new TestSubscriber<>(); private final TestSubscriber<Void> startMessageThreadsActivity = new TestSubscriber<>(); private final TestSubscriber<Project> startProjectActivity = new TestSubscriber<>(); private final TestSubscriber<String> userNameTextViewText = new TestSubscriber<>(); private void setUpEnvironment(final @NonNull Environment environment) { this.vm = new ProfileViewModel.ViewModel(environment); this.vm.outputs.avatarImageViewUrl().subscribe(this.avatarImageViewUrl); this.vm.outputs.backedCountTextViewHidden().subscribe(this.backedCountTextViewHidden); this.vm.outputs.backedCountTextViewText().subscribe(this.backedCountTextViewText); this.vm.outputs.backedTextViewHidden().subscribe(this.backedTextViewHidden); this.vm.outputs.createdCountTextViewHidden().subscribe(this.createdCountTextViewHidden); this.vm.outputs.createdCountTextViewText().subscribe(this.createdCountTextViewText); this.vm.outputs.createdTextViewHidden().subscribe(this.createdTextViewHidden); this.vm.outputs.dividerViewHidden().subscribe(this.dividerViewHidden); this.vm.outputs.messagesButtonHidden().subscribe(this.messagesButtonHidden); this.vm.outputs.projects().subscribe(this.projects); this.vm.outputs.resumeDiscoveryActivity().subscribe(this.resumeDiscoveryActivity); this.vm.outputs.startMessageThreadsActivity().subscribe(this.startMessageThreadsActivity); this.vm.outputs.startProjectActivity().subscribe(this.startProjectActivity); this.vm.outputs.userNameTextViewText().subscribe(this.userNameTextViewText); } @Test public void testProfileViewModel_EmitsBackedAndCreatedProjectsData() { final User user = UserFactory.user().toBuilder() .backedProjectsCount(15) .createdProjectsCount(2) .build(); final ApiClientType apiClient = new MockApiClient() { @Override public @NonNull Observable<User> fetchCurrentUser() { return Observable.just(user); } }; setUpEnvironment(environment().toBuilder().apiClient(apiClient).build()); // Backed text views are displayed. this.backedCountTextViewHidden.assertValues(false); this.backedCountTextViewText.assertValues(NumberUtils.format(user.backedProjectsCount())); this.backedTextViewHidden.assertValues(false); // Created text views are displayed. this.createdCountTextViewHidden.assertValues(false); this.createdCountTextViewText.assertValues(NumberUtils.format(user.createdProjectsCount())); this.createdTextViewHidden.assertValues(false); // Divider view is displayed. this.dividerViewHidden.assertValues(false); } @Test public void testProfileViewModel_EmitsBackedProjectsData() { final User user = UserFactory.user().toBuilder() .backedProjectsCount(5) .createdProjectsCount(0) .build(); final ApiClientType apiClient = new MockApiClient() { @Override public @NonNull Observable<User> fetchCurrentUser() { return Observable.just(user); } }; setUpEnvironment(environment().toBuilder().apiClient(apiClient).build()); // Backed text views are displayed. this.backedCountTextViewHidden.assertValues(false); this.backedCountTextViewText.assertValues(NumberUtils.format(user.backedProjectsCount())); this.backedTextViewHidden.assertValues(false); // Created text views are hidden. this.createdCountTextViewHidden.assertValues(true); this.createdCountTextViewText.assertNoValues(); this.createdTextViewHidden.assertValues(true); // Divider view is hidden. this.dividerViewHidden.assertValues(true); } @Test public void testProfileViewModel_EmitsCreatedProjectsData() { final User user = UserFactory.user().toBuilder() .backedProjectsCount(0) .createdProjectsCount(2) .build(); final ApiClientType apiClient = new MockApiClient() { @Override public @NonNull Observable<User> fetchCurrentUser() { return Observable.just(user); } }; setUpEnvironment(environment().toBuilder().apiClient(apiClient).build()); // Backed text views are hidden. this.backedCountTextViewHidden.assertValues(true); this.backedCountTextViewText.assertNoValues(); this.backedTextViewHidden.assertValues(true); // Created text views are displayed. this.createdCountTextViewHidden.assertValues(false); this.createdCountTextViewText.assertValues(NumberUtils.format(user.createdProjectsCount())); this.createdTextViewHidden.assertValues(false); // Divider view is hidden. this.dividerViewHidden.assertValues(true); } @Test public void testProfileViewModel_EmitsProjects() { final ApiClientType apiClient = new MockApiClient() { @Override public @NonNull Observable<DiscoverEnvelope> fetchProjects(final @NonNull DiscoveryParams params) { return Observable.just( DiscoverEnvelopeFactory.discoverEnvelope(Collections.singletonList(ProjectFactory.project())) ); } }; setUpEnvironment(environment().toBuilder().apiClient(apiClient).build()); this.koalaTest.assertValues(KoalaEvent.PROFILE_VIEW_MY, KoalaEvent.VIEWED_PROFILE); this.projects.assertValueCount(1); } @Test public void testProfileViewModel_EmitsUserNameAndAvatar() { final User user = UserFactory.user(); final ApiClientType apiClient = new MockApiClient() { @Override public @NonNull Observable<User> fetchCurrentUser() { return Observable.just(user); } }; setUpEnvironment(environment().toBuilder().apiClient(apiClient).build()); this.avatarImageViewUrl.assertValues(user.avatar().medium()); this.userNameTextViewText.assertValues(user.name()); } @Test public void testProfileViewModel_MessagesButton_EnabledFeature() { final Config config = ConfigFactory.config() .toBuilder() .features(Collections.singletonMap(FeatureKey.ANDROID_MESSAGES, true)) .build(); final MockCurrentConfig currentConfig = new MockCurrentConfig(); currentConfig.config(config); setUpEnvironment(environment().toBuilder().currentConfig(currentConfig).build()); // Messages button shown for config with enabled feature flag. this.messagesButtonHidden.assertValues(false); } @Test public void testProfileViewModel_MessagesButton_NullFeature() { final Config config = ConfigFactory.config() .toBuilder() .features(Collections.emptyMap()) .build(); final MockCurrentConfig currentConfig = new MockCurrentConfig(); currentConfig.config(config); setUpEnvironment(environment().toBuilder().currentConfig(currentConfig).build()); // Messages button hidden for config with missing feature flag. this.messagesButtonHidden.assertValues(true); } @Test public void testProfileViewModel_ResumeDiscoveryActivity() { setUpEnvironment(environment()); this.vm.inputs.exploreProjectsButtonClicked(); this.resumeDiscoveryActivity.assertValueCount(1); } @Test public void testProfileViewModel_StartMessageThreadsActivity() { setUpEnvironment(environment()); this.vm.inputs.messsagesButtonClicked(); this.startMessageThreadsActivity.assertValueCount(1); } @Test public void testProfileViewModel_StartProjectActivity() { setUpEnvironment(environment()); this.vm.inputs.projectCardClicked(ProjectFactory.project()); this.startProjectActivity.assertValueCount(1); } }