package com.kickstarter.viewmodels;
import android.content.Intent;
import android.support.annotation.NonNull;
import com.kickstarter.KSRobolectricTestCase;
import com.kickstarter.factories.ProjectFactory;
import com.kickstarter.factories.UpdateFactory;
import com.kickstarter.libs.Environment;
import com.kickstarter.libs.KoalaEvent;
import com.kickstarter.libs.utils.NumberUtils;
import com.kickstarter.models.Project;
import com.kickstarter.models.Update;
import com.kickstarter.services.ApiClientType;
import com.kickstarter.services.MockApiClient;
import com.kickstarter.ui.IntentKey;
import org.junit.Test;
import okhttp3.Request;
import rx.Observable;
import rx.observers.TestSubscriber;
public final class UpdateViewModelTest extends KSRobolectricTestCase {
private final Intent defaultIntent = new Intent()
.putExtra(IntentKey.PROJECT, ProjectFactory.project())
.putExtra(IntentKey.UPDATE, UpdateFactory.update());
@Test
public void testUpdateViewModel_ExternalLinkActivated() {
final UpdateViewModel.ViewModel vm = new UpdateViewModel.ViewModel(environment());
// Start the intent with a project and update.
vm.intent(defaultIntent);
vm.inputs.externalLinkActivated();
koalaTest.assertValues(KoalaEvent.OPENED_EXTERNAL_LINK);
}
@Test
public void testUpdateViewModel_LoadsWebViewUrl() {
final UpdateViewModel.ViewModel vm = new UpdateViewModel.ViewModel(environment());
final Update update = UpdateFactory.update();
final String anotherUpdateUrl = "https://kck.str/projects/param/param/posts/next-id";
final Request anotherUpdateRequest = new Request.Builder()
.url(anotherUpdateUrl)
.build();
final TestSubscriber<String> webViewUrl = new TestSubscriber<>();
vm.outputs.webViewUrl().subscribe(webViewUrl);
// Start the intent with a project and update.
vm.intent(defaultIntent);
// Initial update's url emits.
webViewUrl.assertValues(update.urls().web().update());
// Make a request for another update.
vm.inputs.goToUpdateRequest(anotherUpdateRequest);
// New update url emits.
webViewUrl.assertValues(update.urls().web().update(), anotherUpdateUrl);
}
@Test
public void testUpdateViewModel_StartCommentsActivity() {
final UpdateViewModel.ViewModel vm = new UpdateViewModel.ViewModel(environment());
final Update update = UpdateFactory.update();
final Request commentsRequest = new Request.Builder()
.url("https://kck.str/projects/param/param/posts/id/comments")
.build();
final TestSubscriber<Update> startCommentsActivity = new TestSubscriber<>();
vm.outputs.startCommentsActivity().subscribe(startCommentsActivity);
// Start the intent with a project and update.
vm.intent(new Intent()
.putExtra(IntentKey.PROJECT, ProjectFactory.project())
.putExtra(IntentKey.UPDATE, update)
);
vm.inputs.goToCommentsRequest(commentsRequest);
startCommentsActivity.assertValues(update);
}
@Test
public void testUpdateViewModel_StartProjectActivity() {
final Update update = UpdateFactory.update()
.toBuilder()
.projectId(1234)
.build();
final Project project = ProjectFactory.project()
.toBuilder()
.id(update.projectId())
.build();
final Request projectRequest = new Request.Builder()
.url("https://kck.str/projects/param/param")
.build();
final ApiClientType apiClient = new MockApiClient() {
@Override
public @NonNull Observable<Project> fetchProject(final @NonNull String param) {
return Observable.just(project);
}
};
final Environment environment = environment().toBuilder().apiClient(apiClient).build();
final UpdateViewModel.ViewModel vm = new UpdateViewModel.ViewModel(environment);
final TestSubscriber<Project> startProjectActivity = new TestSubscriber<>();
vm.outputs.startProjectActivity().map(pr -> pr.first).subscribe(startProjectActivity);
// Start the intent with a project and update.
vm.intent(new Intent()
.putExtra(IntentKey.PROJECT, project)
.putExtra(IntentKey.UPDATE, update)
);
vm.inputs.goToProjectRequest(projectRequest);
startProjectActivity.assertValues(project);
}
@Test
public void testUpdateViewModel_StartShareIntent() {
final UpdateViewModel.ViewModel vm = new UpdateViewModel.ViewModel(environment());
final Update update = UpdateFactory.update();
final TestSubscriber<Update> startShareIntent = new TestSubscriber<>();
vm.outputs.startShareIntent().subscribe(startShareIntent);
// Start the intent with a project and update.
vm.intent(new Intent()
.putExtra(IntentKey.PROJECT, ProjectFactory.project())
.putExtra(IntentKey.UPDATE, update)
);
vm.inputs.shareIconButtonClicked();
startShareIntent.assertValues(update);
}
@Test
public void testUpdateViewModel_UpdateSequence() {
final Update initialUpdate = UpdateFactory.update().toBuilder().sequence(1).build();
final Update anotherUpdate = UpdateFactory.update().toBuilder().sequence(2).build();
final Request anotherUpdateRequest = new Request.Builder()
.url("https://kck.str/projects/param/param/posts/id")
.build();
final ApiClientType apiClient = new MockApiClient() {
@Override
public @NonNull Observable<Update> fetchUpdate(final @NonNull String projectParam, final @NonNull String updateParam) {
return Observable.just(anotherUpdate);
}
};
final Environment environment = environment().toBuilder().apiClient(apiClient).build();
final UpdateViewModel.ViewModel vm = new UpdateViewModel.ViewModel(environment);
final TestSubscriber<String> updateSequence = new TestSubscriber<>();
vm.outputs.updateSequence().subscribe(updateSequence);
// Start the intent with a project and update.
vm.intent(new Intent()
.putExtra(IntentKey.PROJECT, ProjectFactory.project())
.putExtra(IntentKey.UPDATE, initialUpdate)
);
// Initial update's sequence number emits.
updateSequence.assertValues(NumberUtils.format(initialUpdate.sequence()));
vm.inputs.goToUpdateRequest(anotherUpdateRequest);
// New sequence should emit for new update page.
updateSequence.assertValues(NumberUtils.format(initialUpdate.sequence()), NumberUtils.format(anotherUpdate.sequence()));
}
@Test
public void testUpdateViewModel_WebViewUrl() {
final UpdateViewModel.ViewModel vm = new UpdateViewModel.ViewModel(environment());
final Update update = UpdateFactory.update();
final TestSubscriber<String> webViewUrl = new TestSubscriber<>();
vm.outputs.webViewUrl().subscribe(webViewUrl);
// Start the intent with a project and update.
vm.intent(new Intent()
.putExtra(IntentKey.PROJECT, ProjectFactory.project())
.putExtra(IntentKey.UPDATE, update)
);
// Initial update index url emits.
webViewUrl.assertValues(update.urls().web().update());
}
}