diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index 8fccfbb..7b6f2a0 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -205,4 +205,4 @@
-
+
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 3922e41..f31ec33 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -115,7 +115,6 @@ dependencies {
annotationProcessor libraries.daggerCompiler
implementation libraries.rxJava
- releaseImplementation libraries.rxJavaProguardRules
implementation libraries.rxLint
implementation libraries.okHttp
diff --git a/app/src/integrationTests/java/com/artemzin/qualitymatters/integration_tests/api/QualityMattersRestApiIntegrationTest.java b/app/src/integrationTests/java/com/artemzin/qualitymatters/integration_tests/api/QualityMattersRestApiIntegrationTest.java
index 939bff9..b414637 100644
--- a/app/src/integrationTests/java/com/artemzin/qualitymatters/integration_tests/api/QualityMattersRestApiIntegrationTest.java
+++ b/app/src/integrationTests/java/com/artemzin/qualitymatters/integration_tests/api/QualityMattersRestApiIntegrationTest.java
@@ -3,19 +3,17 @@
import com.artemzin.qualitymatters.QualityMattersIntegrationRobolectricTestRunner;
import com.artemzin.qualitymatters.api.QualityMattersRestApi;
import com.artemzin.qualitymatters.api.entities.Item;
-
+import okhttp3.mockwebserver.MockResponse;
+import okhttp3.mockwebserver.MockWebServer;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import retrofit2.HttpException;
import java.io.IOException;
import java.util.List;
-import okhttp3.mockwebserver.MockResponse;
-import okhttp3.mockwebserver.MockWebServer;
-import retrofit2.adapter.rxjava.HttpException;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;
@@ -58,7 +56,7 @@ public void items_shouldHandleCorrectResponse() {
+ "]"));
// Get items from the API
- List- items = qualityMattersRestApi.items().toBlocking().value();
+ List
- items = qualityMattersRestApi.items().blockingGet();
assertThat(items).hasSize(3);
@@ -88,10 +86,9 @@ public void items_shouldThrowExceptionIfWebServerRespondError() {
mockWebServer.enqueue(new MockResponse().setStatus("HTTP/1.1 " + errorCode + " Not today"));
try {
- qualityMattersRestApi.items().toBlocking().value();
+ qualityMattersRestApi.items().blockingGet();
fail("HttpException should be thrown for error code: " + errorCode);
- } catch (RuntimeException expected) {
- HttpException httpException = (HttpException) expected.getCause();
+ } catch (HttpException httpException ) {
assertThat(httpException.code()).isEqualTo(errorCode);
assertThat(httpException.message()).isEqualTo("Not today");
}
diff --git a/app/src/main/java/com/artemzin/qualitymatters/api/ApiModule.java b/app/src/main/java/com/artemzin/qualitymatters/api/ApiModule.java
index f47e0fd..16ec97a 100644
--- a/app/src/main/java/com/artemzin/qualitymatters/api/ApiModule.java
+++ b/app/src/main/java/com/artemzin/qualitymatters/api/ApiModule.java
@@ -1,19 +1,17 @@
package com.artemzin.qualitymatters.api;
import android.support.annotation.NonNull;
-
import com.artemzin.qualitymatters.BuildConfig;
import com.google.gson.Gson;
-
-import javax.inject.Singleton;
-
import dagger.Module;
import dagger.Provides;
import okhttp3.OkHttpClient;
import retrofit2.Retrofit;
-import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
+import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
+import javax.inject.Singleton;
+
@Module
public class ApiModule {
@@ -32,10 +30,10 @@ public ChangeableBaseUrl provideChangeableBaseUrl() {
@Provides @NonNull @Singleton
public QualityMattersRestApi provideQualityMattersApi(@NonNull OkHttpClient okHttpClient, @NonNull Gson gson, @NonNull ChangeableBaseUrl changeableBaseUrl) {
return new Retrofit.Builder()
- .baseUrl(changeableBaseUrl)
+ .baseUrl(changeableBaseUrl.url())
.client(okHttpClient)
.addConverterFactory(GsonConverterFactory.create(gson))
- .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
+ .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.validateEagerly(BuildConfig.DEBUG) // Fail early: check Retrofit configuration at creation time in Debug build.
.build()
.create(QualityMattersRestApi.class);
diff --git a/app/src/main/java/com/artemzin/qualitymatters/api/ChangeableBaseUrl.java b/app/src/main/java/com/artemzin/qualitymatters/api/ChangeableBaseUrl.java
index 891e205..3dd20cd 100644
--- a/app/src/main/java/com/artemzin/qualitymatters/api/ChangeableBaseUrl.java
+++ b/app/src/main/java/com/artemzin/qualitymatters/api/ChangeableBaseUrl.java
@@ -1,16 +1,14 @@
package com.artemzin.qualitymatters.api;
import android.support.annotation.NonNull;
+import okhttp3.HttpUrl;
import java.util.concurrent.atomic.AtomicReference;
-import okhttp3.HttpUrl;
-import retrofit2.BaseUrl;
-
/**
* Such implementation allows us easily change base url in the integration and functional tests!
*/
-public class ChangeableBaseUrl implements BaseUrl {
+public class ChangeableBaseUrl {
@NonNull
private final AtomicReference baseUrl;
@@ -23,7 +21,6 @@ public void setBaseUrl(@NonNull String baseUrl) {
this.baseUrl.set(HttpUrl.parse(baseUrl));
}
- @Override @NonNull
public HttpUrl url() {
return baseUrl.get();
}
diff --git a/app/src/main/java/com/artemzin/qualitymatters/api/QualityMattersRestApi.java b/app/src/main/java/com/artemzin/qualitymatters/api/QualityMattersRestApi.java
index a3fa1f2..451ab64 100644
--- a/app/src/main/java/com/artemzin/qualitymatters/api/QualityMattersRestApi.java
+++ b/app/src/main/java/com/artemzin/qualitymatters/api/QualityMattersRestApi.java
@@ -1,14 +1,12 @@
package com.artemzin.qualitymatters.api;
import android.support.annotation.NonNull;
-
import com.artemzin.qualitymatters.api.entities.Item;
+import io.reactivex.Single;
+import retrofit2.http.GET;
import java.util.List;
-import retrofit2.http.GET;
-import rx.Single;
-
public interface QualityMattersRestApi {
@GET("items") @NonNull
diff --git a/app/src/main/java/com/artemzin/qualitymatters/models/ItemsModel.java b/app/src/main/java/com/artemzin/qualitymatters/models/ItemsModel.java
index 3e00975..382c03d 100644
--- a/app/src/main/java/com/artemzin/qualitymatters/models/ItemsModel.java
+++ b/app/src/main/java/com/artemzin/qualitymatters/models/ItemsModel.java
@@ -1,13 +1,12 @@
package com.artemzin.qualitymatters.models;
import android.support.annotation.NonNull;
-
import com.artemzin.qualitymatters.api.QualityMattersRestApi;
import com.artemzin.qualitymatters.api.entities.Item;
+import io.reactivex.Single;
import java.util.List;
-import rx.Single;
/**
* Model is not an entity. It's a container for business logic code. M(VC), M(VP), M(VVM).
diff --git a/app/src/main/java/com/artemzin/qualitymatters/other/DisposableSubscription.java b/app/src/main/java/com/artemzin/qualitymatters/other/DisposableSubscription.java
deleted file mode 100644
index af3a2aa..0000000
--- a/app/src/main/java/com/artemzin/qualitymatters/other/DisposableSubscription.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package com.artemzin.qualitymatters.other;
-
-import android.support.annotation.NonNull;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import rx.Subscription;
-import rx.functions.Action0;
-
-public class DisposableSubscription implements Subscription {
-
- @NonNull
- private final AtomicBoolean unsubscribed = new AtomicBoolean(false);
-
- @NonNull
- private final Action0 disposeAction;
-
- public DisposableSubscription(@NonNull Action0 disposeAction) {
- this.disposeAction = disposeAction;
- }
-
- @Override
- public boolean isUnsubscribed() {
- return unsubscribed.get();
- }
-
- @Override
- public void unsubscribe() {
- if (unsubscribed.compareAndSet(false, true)) {
- disposeAction.call();
- }
- }
-}
diff --git a/app/src/main/java/com/artemzin/qualitymatters/other/FinishAsyncJobSubscription.java b/app/src/main/java/com/artemzin/qualitymatters/other/FinishAsyncJobSubscription.java
deleted file mode 100644
index f470782..0000000
--- a/app/src/main/java/com/artemzin/qualitymatters/other/FinishAsyncJobSubscription.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.artemzin.qualitymatters.other;
-
-import android.support.annotation.NonNull;
-
-import com.artemzin.qualitymatters.performance.AsyncJob;
-import com.artemzin.qualitymatters.performance.AsyncJobsObserver;
-
-public class FinishAsyncJobSubscription extends DisposableSubscription {
-
- @SuppressWarnings("PMD.EmptyCatchBlock")
- public FinishAsyncJobSubscription(@NonNull AsyncJobsObserver asyncJobsObserver, @NonNull AsyncJob asyncJob) {
- super(() -> {
- try {
- asyncJobsObserver.asyncJobFinished(asyncJob);
- } catch (IllegalArgumentException possible) {
- // Do nothing, async job was probably already finished normally.
- }
- });
- }
-}
diff --git a/app/src/main/java/com/artemzin/qualitymatters/ui/fragments/ItemsFragment.java b/app/src/main/java/com/artemzin/qualitymatters/ui/fragments/ItemsFragment.java
index eac91ba..4ea5508 100644
--- a/app/src/main/java/com/artemzin/qualitymatters/ui/fragments/ItemsFragment.java
+++ b/app/src/main/java/com/artemzin/qualitymatters/ui/fragments/ItemsFragment.java
@@ -8,7 +8,10 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-
+import butterknife.BindView;
+import butterknife.ButterKnife;
+import butterknife.OnClick;
+import butterknife.Unbinder;
import com.artemzin.qualitymatters.QualityMattersApp;
import com.artemzin.qualitymatters.R;
import com.artemzin.qualitymatters.api.entities.Item;
@@ -22,19 +25,13 @@
import com.artemzin.qualitymatters.ui.presenters.ItemsPresenter;
import com.artemzin.qualitymatters.ui.presenters.ItemsPresenterConfiguration;
import com.artemzin.qualitymatters.ui.views.ItemsView;
-
-import java.util.List;
-
-import javax.inject.Inject;
-
-import butterknife.BindView;
-import butterknife.ButterKnife;
-import butterknife.OnClick;
-import butterknife.Unbinder;
import dagger.Module;
import dagger.Provides;
import dagger.Subcomponent;
-import rx.schedulers.Schedulers;
+import io.reactivex.schedulers.Schedulers;
+
+import javax.inject.Inject;
+import java.util.List;
import static android.support.v7.widget.LinearLayoutManager.VERTICAL;
import static android.view.View.GONE;
diff --git a/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenter.java b/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenter.java
index bbebc51..cf3e7e1 100644
--- a/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenter.java
+++ b/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenter.java
@@ -1,15 +1,13 @@
package com.artemzin.qualitymatters.ui.presenters;
import android.support.annotation.NonNull;
-
import com.artemzin.qualitymatters.models.AnalyticsModel;
import com.artemzin.qualitymatters.models.ItemsModel;
-import com.artemzin.qualitymatters.other.FinishAsyncJobSubscription;
import com.artemzin.qualitymatters.performance.AsyncJob;
import com.artemzin.qualitymatters.performance.AsyncJobsObserver;
import com.artemzin.qualitymatters.ui.views.ItemsView;
-
-import rx.Subscription;
+import io.reactivex.disposables.Disposable;
+import io.reactivex.disposables.Disposables;
public class ItemsPresenter extends Presenter {
@@ -47,7 +45,7 @@ public void reloadData() {
final AsyncJob asyncJob = asyncJobsObserver.asyncJobStarted("Reload data in ItemsPresenter");
- final Subscription subscription = itemsModel
+ final Disposable disposable = itemsModel
.getItems()
.subscribeOn(presenterConfiguration.ioScheduler())
.subscribe(
@@ -75,7 +73,11 @@ public void reloadData() {
}
);
+
// Prevent memory leak.
- unsubscribeOnUnbindView(subscription, new FinishAsyncJobSubscription(asyncJobsObserver, asyncJob));
+ Disposable finishAsyncJobDisposable
+ = Disposables.fromAction(() -> asyncJobsObserver.asyncJobFinished(asyncJob));
+
+ unsubscribeOnUnbindView(disposable, finishAsyncJobDisposable);
}
}
diff --git a/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterConfiguration.java b/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterConfiguration.java
index d9601fe..4c4addd 100644
--- a/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterConfiguration.java
+++ b/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterConfiguration.java
@@ -1,10 +1,9 @@
package com.artemzin.qualitymatters.ui.presenters;
import android.support.annotation.NonNull;
-
import com.google.auto.value.AutoValue;
+import io.reactivex.Scheduler;
-import rx.Scheduler;
// Such approach allows us configure presenter in runtime without hardcoded values.
// Also, it allows us easily change some parts of the presenter configuration for tests.
diff --git a/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/Presenter.java b/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/Presenter.java
index 420718b..6479f64 100644
--- a/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/Presenter.java
+++ b/app/src/main/java/com/artemzin/qualitymatters/ui/presenters/Presenter.java
@@ -3,9 +3,8 @@
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-
-import rx.Subscription;
-import rx.subscriptions.CompositeSubscription;
+import io.reactivex.disposables.CompositeDisposable;
+import io.reactivex.disposables.Disposable;
/**
* Base presenter implementation.
@@ -15,7 +14,7 @@
public class Presenter {
@NonNull
- private final CompositeSubscription subscriptionsToUnsubscribeOnUnbindView = new CompositeSubscription();
+ private final CompositeDisposable disposablesToDisposeOnUnbindView = new CompositeDisposable();
@Nullable
private volatile V view;
@@ -36,11 +35,11 @@ protected V view() {
return view;
}
- protected final void unsubscribeOnUnbindView(@NonNull Subscription subscription, @NonNull Subscription... subscriptions) {
- subscriptionsToUnsubscribeOnUnbindView.add(subscription);
+ protected final void unsubscribeOnUnbindView(@NonNull Disposable disposable, @NonNull Disposable... disposables) {
+ disposablesToDisposeOnUnbindView.add(disposable);
- for (Subscription s : subscriptions) {
- subscriptionsToUnsubscribeOnUnbindView.add(s);
+ for (Disposable d : disposables) {
+ disposablesToDisposeOnUnbindView.add(d);
}
}
@@ -56,6 +55,6 @@ public void unbindView(@NonNull V view) {
}
// Unsubscribe all subscriptions that need to be unsubscribed in this lifecycle state.
- subscriptionsToUnsubscribeOnUnbindView.clear();
+ disposablesToDisposeOnUnbindView.clear();
}
}
diff --git a/app/src/unitTests/java/com/artemzin/qualitymatters/models/ItemsModelTest.java b/app/src/unitTests/java/com/artemzin/qualitymatters/models/ItemsModelTest.java
index aa913ad..c977dbf 100644
--- a/app/src/unitTests/java/com/artemzin/qualitymatters/models/ItemsModelTest.java
+++ b/app/src/unitTests/java/com/artemzin/qualitymatters/models/ItemsModelTest.java
@@ -2,14 +2,12 @@
import com.artemzin.qualitymatters.api.QualityMattersRestApi;
import com.artemzin.qualitymatters.api.entities.Item;
-
+import io.reactivex.Single;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
-import rx.Single;
-
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
@@ -31,7 +29,7 @@ public void getItems_shouldReturnItemsFromQualityMattersRestApi() {
List
- items = asList(mock(Item.class), mock(Item.class));
when(qualityMattersRestApi.items()).thenReturn(Single.just(items));
- assertThat(itemsModel.getItems().toBlocking().value()).containsExactlyElementsOf(items);
+ assertThat(itemsModel.getItems().blockingGet()).containsExactlyElementsOf(items);
}
@Test
@@ -40,7 +38,7 @@ public void getItems_shouldReturnErrorFromQualityMattersRestApi() {
when(qualityMattersRestApi.items()).thenReturn(Single.error(error));
try {
- itemsModel.getItems().toBlocking().value();
+ itemsModel.getItems().blockingGet();
failBecauseExceptionWasNotThrown(RuntimeException.class);
} catch (Exception expected) {
assertThat(expected).isSameAs(error);
diff --git a/app/src/unitTests/java/com/artemzin/qualitymatters/other/DisposableSubscriptionTest.java b/app/src/unitTests/java/com/artemzin/qualitymatters/other/DisposableSubscriptionTest.java
deleted file mode 100644
index 6440c4d..0000000
--- a/app/src/unitTests/java/com/artemzin/qualitymatters/other/DisposableSubscriptionTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package com.artemzin.qualitymatters.other;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import rx.functions.Action0;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-public class DisposableSubscriptionTest {
-
- private Action0 disposeAction;
- private DisposableSubscription disposableSubscription;
-
- @Before
- public void beforeEachTest() {
- disposeAction = mock(Action0.class);
- disposableSubscription = new DisposableSubscription(disposeAction);
- }
-
- @Test
- public void unsubscribed_shouldReturnFalseByDefault() {
- assertThat(disposableSubscription.isUnsubscribed()).isFalse();
- verifyZeroInteractions(disposeAction);
- }
-
- @Test
- public void unsubscribe_shouldChangeValueOfIsUsubscribed() {
- disposableSubscription.unsubscribe();
- assertThat(disposableSubscription.isUnsubscribed()).isTrue();
- }
-
- @Test
- public void unsubscribe_shouldCallDisposableAction() {
- disposableSubscription.unsubscribe();
- verify(disposeAction).call();
- }
-
- @Test
- public void unsubscribeTwice_shouldCallDisposableActionOnce() {
- disposableSubscription.unsubscribe();
- disposableSubscription.unsubscribe();
- verify(disposeAction).call();
- }
-}
\ No newline at end of file
diff --git a/app/src/unitTests/java/com/artemzin/qualitymatters/other/FinishAsyncJobSubscriptionTest.java b/app/src/unitTests/java/com/artemzin/qualitymatters/other/FinishAsyncJobSubscriptionTest.java
deleted file mode 100644
index 485838f..0000000
--- a/app/src/unitTests/java/com/artemzin/qualitymatters/other/FinishAsyncJobSubscriptionTest.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package com.artemzin.qualitymatters.other;
-
-import com.artemzin.qualitymatters.performance.AsyncJob;
-import com.artemzin.qualitymatters.performance.AsyncJobsObserver;
-
-import org.junit.Test;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-public class FinishAsyncJobSubscriptionTest {
-
- @Test
- public void constructor_shouldCreateSuchActionThatWillUnregisterAsyncJob() {
- AsyncJobsObserver asyncJobsObserver = mock(AsyncJobsObserver.class);
- AsyncJob asyncJob = mock(AsyncJob.class);
-
- DisposableSubscription disposableSubscription = new FinishAsyncJobSubscription(asyncJobsObserver, asyncJob);
- verifyZeroInteractions(asyncJobsObserver, asyncJob);
-
- disposableSubscription.unsubscribe();
- verify(asyncJobsObserver).asyncJobFinished(asyncJob);
- }
-}
\ No newline at end of file
diff --git a/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterConfigurationTest.java b/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterConfigurationTest.java
index 412dd7b..0b44233 100644
--- a/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterConfigurationTest.java
+++ b/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterConfigurationTest.java
@@ -1,10 +1,9 @@
package com.artemzin.qualitymatters.ui.presenters;
-import org.junit.Test;
-
+import io.reactivex.schedulers.Schedulers;
import nl.jqno.equalsverifier.EqualsVerifier;
import nl.jqno.equalsverifier.Warning;
-import rx.schedulers.Schedulers;
+import org.junit.Test;
public class ItemsPresenterConfigurationTest {
@@ -12,7 +11,7 @@ public class ItemsPresenterConfigurationTest {
public void hashCode_equals_shouldWorkCorrectly() {
EqualsVerifier
.forExamples(
- ItemsPresenterConfiguration.builder().ioScheduler(Schedulers.immediate()).build(),
+ ItemsPresenterConfiguration.builder().ioScheduler(Schedulers.trampoline()).build(),
ItemsPresenterConfiguration.builder().ioScheduler(Schedulers.io()).build())
.suppress(Warning.NULL_FIELDS) // AutoValue checks for nulls, but EqualsVerifier does not expect that by default.
.verify();
diff --git a/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterTest.java b/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterTest.java
index 9d8bc8a..a0da832 100644
--- a/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterTest.java
+++ b/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/ItemsPresenterTest.java
@@ -6,24 +6,18 @@
import com.artemzin.qualitymatters.performance.AsyncJob;
import com.artemzin.qualitymatters.performance.AsyncJobsObserver;
import com.artemzin.qualitymatters.ui.views.ItemsView;
-
+import io.reactivex.Single;
+import io.reactivex.schedulers.Schedulers;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
-import rx.Single;
-import rx.schedulers.Schedulers;
-
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.*;
public class ItemsPresenterTest {
private ItemsModel itemsModel;
@@ -37,7 +31,7 @@ public class ItemsPresenterTest {
public void beforeEachTest() {
itemsModel = mock(ItemsModel.class);
presenterConfiguration = ItemsPresenterConfiguration.builder()
- .ioScheduler(Schedulers.immediate()) // We don't need async behavior in tests.
+ .ioScheduler(Schedulers.trampoline()) // We don't need async behavior in tests.
.build();
asyncJobsObserver = mock(AsyncJobsObserver.class);
@@ -95,4 +89,18 @@ public void reloadData_shouldSendErrorToTheView() {
verify(asyncJobsObserver).asyncJobStarted("Reload data in ItemsPresenter");
verify(asyncJobsObserver).asyncJobFinished(asyncJob);
}
+
+ @Test
+ public void reloadData_shouldFinishJobIfDisposedBeforeSingleEmits() throws Exception {
+ when(itemsModel.getItems()).thenReturn(Single.never());
+
+ itemsPresenter.bindView(itemsView);
+ verifyZeroInteractions(itemsView, asyncJobsObserver);
+
+ itemsPresenter.reloadData();
+ itemsPresenter.unbindView(itemsView);
+ verify(itemsView, never()).showContentUi(anyListOf(Item.class));
+ verify(itemsView, never()).showErrorUi(any(Throwable.class));
+ verify(asyncJobsObserver).asyncJobFinished(asyncJob);
+ }
}
\ No newline at end of file
diff --git a/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/PresenterTest.java b/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/PresenterTest.java
index 2c4bea9..c1641e5 100644
--- a/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/PresenterTest.java
+++ b/app/src/unitTests/java/com/artemzin/qualitymatters/ui/presenters/PresenterTest.java
@@ -1,15 +1,12 @@
package com.artemzin.qualitymatters.ui.presenters;
+import io.reactivex.disposables.Disposable;
import org.junit.Before;
import org.junit.Test;
-import rx.Subscription;
-
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.*;
public class PresenterTest {
private Presenter