package com.khmelenko.lab.varis.presenter; import com.khmelenko.lab.varis.BuildConfig; import com.khmelenko.lab.varis.dagger.DaggerTestComponent; import com.khmelenko.lab.varis.dagger.TestComponent; import com.khmelenko.lab.varis.network.response.Build; import com.khmelenko.lab.varis.network.response.BuildDetails; import com.khmelenko.lab.varis.network.response.Commit; import com.khmelenko.lab.varis.network.response.Job; import com.khmelenko.lab.varis.network.retrofit.raw.RawClient; import com.khmelenko.lab.varis.network.retrofit.travis.TravisRestClient; import com.khmelenko.lab.varis.storage.AppSettings; import com.khmelenko.lab.varis.storage.CacheStorage; import com.khmelenko.lab.varis.task.TaskError; import com.khmelenko.lab.varis.task.TaskException; import com.khmelenko.lab.varis.task.TaskManager; import com.khmelenko.lab.varis.view.BuildDetailsView; import com.squareup.okhttp.Protocol; import com.squareup.okhttp.Request; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.annotation.Config; import java.util.ArrayList; import java.util.Collections; import java.util.List; import javax.inject.Inject; import de.greenrobot.event.EventBus; import retrofit.client.Header; import retrofit.client.Response; import retrofit.mime.TypedOutput; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; /** * Testing {@link BuildsDetailsPresenter} * * @author Dmytro Khmelenko (d.khmelenko@gmail.com) */ @RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class TestBuildDetailsPresenter { @Inject TaskManager mTaskManager; @Inject EventBus mEventBus; @Inject CacheStorage mCacheStorage; @Inject RawClient mRawClient; @Inject TravisRestClient mTravisRestClient; private BuildsDetailsPresenter mBuildsDetailsPresenter; private BuildDetailsView mBuildDetailsView; @Before public void setup() { TestComponent component = DaggerTestComponent.builder().build(); component.inject(this); mBuildsDetailsPresenter = spy(new BuildsDetailsPresenter(mEventBus, mTaskManager, mCacheStorage)); mBuildDetailsView = mock(BuildDetailsView.class); mBuildsDetailsPresenter.attach(mBuildDetailsView); } @Test public void testStartLoadingLogNoToken() { final long jobId = 1L; final String expectedUrl = "https://sample.org"; Response response = new Response(expectedUrl, 200, "", Collections.<Header>emptyList(), null); when(mRawClient.getApiService().getLog(String.valueOf(jobId))).thenReturn(response); mBuildsDetailsPresenter.startLoadingLog(jobId); verify(mTaskManager).getLogUrl(jobId); verify(mBuildDetailsView).setLogUrl(expectedUrl); } @Test public void testStartLoadingLogWithToken() { final long jobId = 1L; final String expectedUrl = "https://sample.org"; Response response = new Response(expectedUrl, 200, "", Collections.<Header>emptyList(), null); final String accessToken = "test"; final String authToken = "token " + accessToken; when(mRawClient.getApiService().getLog(authToken, String.valueOf(jobId))).thenReturn(response); AppSettings.putAccessToken(accessToken); mBuildsDetailsPresenter.startLoadingLog(jobId); verify(mTaskManager).getLogUrl(authToken, jobId); verify(mBuildDetailsView).setLogUrl(expectedUrl); } @Test public void testStartLoadingLogFailed() { final long jobId = 1L; final int errorCode = 401; final String errorMsg = "error"; TaskError error = spy(new TaskError(errorCode, errorMsg)); Response response = new Response("url", 200, "", Collections.<Header>emptyList(), null); error.setResponse(response); TaskException exception = spy(new TaskException(error)); when(mRawClient.getApiService().getLog(String.valueOf(jobId))).thenThrow(exception); mBuildsDetailsPresenter.startLoadingLog(jobId); int loadLogInvocations = BuildsDetailsPresenter.LOAD_LOG_MAX_ATTEMPT + 1; verify(mTaskManager, times(loadLogInvocations)).getLogUrl(jobId); verify(mBuildDetailsView).showLoadingError(error.getMessage()); verify(mBuildDetailsView).showLogError(); } @Test public void testStartLoadingDataSingleJob() { final long buildId = 1L; final String slug = "test"; final Build build = new Build(); final Commit commit = new Commit(); final List<Job> jobs = new ArrayList<>(); final Job job = new Job(); jobs.add(job); BuildDetails buildDetails = new BuildDetails(); buildDetails.setBuild(build); buildDetails.setCommit(commit); buildDetails.setJobs(jobs); final String expectedUrl = "https://sample.org"; Response response = new Response(expectedUrl, 200, "", Collections.<Header>emptyList(), null); final String accessToken = "test"; final String authToken = "token " + accessToken; AppSettings.putAccessToken("test"); when(mRawClient.getApiService().getLog(authToken, String.valueOf(job.getId()))).thenReturn(response); when(mTravisRestClient.getApiService().getBuild(slug, buildId)).thenReturn(buildDetails); mBuildsDetailsPresenter.startLoadingData(null, slug, buildId); verify(mTaskManager).getBuildDetails(slug, buildId); verify(mBuildDetailsView).showProgress(); verify(mBuildDetailsView).hideProgress(); verify(mBuildDetailsView).updateBuildDetails(buildDetails); verify(mBuildDetailsView).showBuildLogs(); verify(mBuildDetailsView).showAdditionalActionsForBuild(buildDetails); } @Test public void testStartLoadingDataManyJobs() { final long buildId = 1L; final String slug = "test"; final Build build = new Build(); final Commit commit = new Commit(); final List<Job> jobs = new ArrayList<>(); final Job job1 = new Job(); jobs.add(job1); final Job job2 = new Job(); jobs.add(job2); BuildDetails buildDetails = new BuildDetails(); buildDetails.setBuild(build); buildDetails.setCommit(commit); buildDetails.setJobs(jobs); when(mTravisRestClient.getApiService().getBuild(slug, buildId)).thenReturn(buildDetails); mBuildsDetailsPresenter.startLoadingData(null, slug, buildId); verify(mTaskManager).getBuildDetails(slug, buildId); verify(mBuildDetailsView).showProgress(); verify(mBuildDetailsView).hideProgress(); verify(mBuildDetailsView).updateBuildDetails(buildDetails); verify(mBuildDetailsView).showBuildJobs(jobs); } @Test public void testStartLoadingDataIntentUrl() throws Exception { final long buildId = 188971232L; final String slug = "dkhmelenko/Varis-Android"; final String intentUrl = "https://travis-ci.org/dkhmelenko/Varis-Android/builds/188971232"; when(mRawClient.singleRequest(intentUrl)).thenReturn(intentResponse()); mBuildsDetailsPresenter.startLoadingData(intentUrl, slug, buildId); verify(mTaskManager).intentUrl(intentUrl); verify(mTaskManager).getBuildDetails(slug, buildId); } @Test public void testStartLoadingDataFailed() { final long buildId = 1L; final String slug = "test"; final int errorCode = 401; final String errorMsg = "error"; TaskError error = spy(new TaskError(errorCode, errorMsg)); Response response = new Response("url", 200, "", Collections.<Header>emptyList(), null); error.setResponse(response); TaskException exception = spy(new TaskException(error)); when(mTravisRestClient.getApiService().getBuild(slug, buildId)).thenThrow(exception); mBuildsDetailsPresenter.startLoadingData(null, slug, buildId); verify(mTaskManager).getBuildDetails(slug, buildId); verify(mBuildDetailsView).showProgress(); verify(mBuildDetailsView).hideProgress(); verify(mBuildDetailsView).updateBuildDetails(null); verify(mBuildDetailsView).showLoadingError(error.getMessage()); } @Test public void testStartLoadingDataIntentUrlFailed() throws Exception { final long buildId = 0L; final String slug = "dkhmelenko/Varis-Android"; final String intentUrl = "https://travis-ci.org/dkhmelenko/Varis-Android/builds"; final String expectedUrl = "https://sample.org"; Request request = new Request.Builder() .url(expectedUrl) .build(); com.squareup.okhttp.Response response = new com.squareup.okhttp.Response.Builder() .request(request) .protocol(Protocol.HTTP_1_1) .code(200) .build(); final int errorCode = TaskError.NETWORK_ERROR; final String errorMsg = ""; TaskError error = spy(new TaskError(errorCode, errorMsg)); when(mRawClient.singleRequest(intentUrl)).thenReturn(response); mBuildsDetailsPresenter.startLoadingData(intentUrl, slug, buildId); verify(mTaskManager).intentUrl(intentUrl); verify(mBuildDetailsView).hideProgress(); verify(mBuildDetailsView).updateBuildDetails(null); verify(mBuildDetailsView).showLoadingError(error.getMessage()); } @Test public void testRestartBuild() { when(mTravisRestClient.getApiService().restartBuild(any(Long.class), any(TypedOutput.class))) .thenReturn(null); mBuildsDetailsPresenter.restartBuild(); verify(mTaskManager).getBuildDetails(any(String.class), any(Long.class)); } @Test public void testRestartBuildFailed() { final int errorCode = 401; final String errorMsg = "error"; TaskError error = spy(new TaskError(errorCode, errorMsg)); TaskException exception = spy(new TaskException(error)); when(mTravisRestClient.getApiService().restartBuild(any(Long.class), any(TypedOutput.class))) .thenThrow(exception); mBuildsDetailsPresenter.restartBuild(); verify(mTaskManager).getBuildDetails(any(String.class), any(Long.class)); verify(mBuildDetailsView, times(2)).showLoadingError(error.getMessage()); } @Test public void testCancelBuild() { when(mTravisRestClient.getApiService().cancelBuild(any(Long.class), any(TypedOutput.class))) .thenReturn(null); mBuildsDetailsPresenter.cancelBuild(); verify(mTaskManager).getBuildDetails(any(String.class), any(Long.class)); } @Test public void testCancelBuildFailed() { final int errorCode = 401; final String errorMsg = "error"; TaskError error = spy(new TaskError(errorCode, errorMsg)); TaskException exception = spy(new TaskException(error)); when(mTravisRestClient.getApiService().cancelBuild(any(Long.class), any(TypedOutput.class))) .thenThrow(exception); mBuildsDetailsPresenter.cancelBuild(); verify(mTaskManager).getBuildDetails(any(String.class), any(Long.class)); verify(mBuildDetailsView, times(2)).showLoadingError(error.getMessage()); } @Test public void testCanUserContributeToRepoTrue() throws Exception { final long buildId = 188971232L; final String slug = "dkhmelenko/Varis-Android"; final String intentUrl = "https://travis-ci.org/dkhmelenko/Varis-Android/builds/188971232"; when(mRawClient.singleRequest(intentUrl)).thenReturn(intentResponse()); String[] repos = {"Repo1", "Repo2", "Repo3", slug, "Repo4"}; when(mCacheStorage.restoreRepos()).thenReturn(repos); mBuildsDetailsPresenter.startLoadingData(intentUrl, slug, buildId); boolean actual = mBuildsDetailsPresenter.canUserContributeToRepo(); assertEquals(true, actual); } @Test public void testCanUserContributeToRepoFalse() throws Exception { final long buildId = 188971232L; final String slug = "dkhmelenko/Varis-Android"; final String intentUrl = "https://travis-ci.org/dkhmelenko/Varis-Android/builds/188971232"; when(mRawClient.singleRequest(intentUrl)).thenReturn(intentResponse()); String[] repos = {"Repo1", "Repo2", "Repo3"}; when(mCacheStorage.restoreRepos()).thenReturn(repos); mBuildsDetailsPresenter.startLoadingData(intentUrl, slug, buildId); boolean actual = mBuildsDetailsPresenter.canUserContributeToRepo(); assertEquals(false, actual); } private com.squareup.okhttp.Response intentResponse() { final String expectedUrl = "https://sample.org"; Request request = new Request.Builder() .url(expectedUrl) .build(); return new com.squareup.okhttp.Response.Builder() .request(request) .protocol(Protocol.HTTP_1_1) .code(200) .build(); } }