From b64a353acbff561fb731479ffbec024b6b0d0034 Mon Sep 17 00:00:00 2001 From: Fernando Cejas Date: Mon, 26 Dec 2016 14:03:46 -0300 Subject: [PATCH 1/2] Generify UseCase --- .../domain/interactor/GetUserDetails.java | 7 +++---- .../sample/domain/interactor/GetUserList.java | 7 +++---- .../sample/domain/interactor/UseCase.java | 9 ++++----- .../sample/domain/interactor/UseCaseTest.java | 2 +- .../internal/di/modules/UserModule.java | 20 ------------------- .../presenter/UserDetailsPresenter.java | 6 ++---- .../presenter/UserListPresenter.java | 6 ++---- 7 files changed, 15 insertions(+), 42 deletions(-) diff --git a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java index d45edcd..c43fc09 100644 --- a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java +++ b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java @@ -28,9 +28,8 @@ import javax.inject.Inject; * This class is an implementation of {@link UseCase} that represents a use case for * retrieving data related to an specific {@link User}. */ -public class GetUserDetails extends UseCase { +public class GetUserDetails extends UseCase { - public static final String NAME = "userDetails"; public static final String PARAM_USER_ID_KEY = "userId"; @VisibleForTesting @@ -39,13 +38,13 @@ public class GetUserDetails extends UseCase { private final UserRepository userRepository; @Inject - public GetUserDetails(UserRepository userRepository, ThreadExecutor threadExecutor, + GetUserDetails(UserRepository userRepository, ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { super(threadExecutor, postExecutionThread); this.userRepository = userRepository; } - @Override protected Observable buildUseCaseObservable(Optional params) { + @Override protected Observable buildUseCaseObservable(Optional params) { if (params.isPresent()) { final int userId = params.get().getInt(PARAM_USER_ID_KEY, PARAM_USER_ID_DEFAULT_VALUE); return this.userRepository.user(userId); diff --git a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java index f1988f6..a092b04 100644 --- a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java +++ b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java @@ -21,15 +21,14 @@ import com.fernandocejas.android10.sample.domain.executor.ThreadExecutor; import com.fernandocejas.android10.sample.domain.repository.UserRepository; import com.fernandocejas.arrow.optional.Optional; import io.reactivex.Observable; +import java.util.List; import javax.inject.Inject; /** * This class is an implementation of {@link UseCase} that represents a use case for * retrieving a collection of all {@link User}. */ -public class GetUserList extends UseCase { - - public static final String NAME = "userList"; +public class GetUserList extends UseCase> { private final UserRepository userRepository; @@ -40,7 +39,7 @@ public class GetUserList extends UseCase { this.userRepository = userRepository; } - @Override public Observable buildUseCaseObservable(Optional params) { + @Override public Observable> buildUseCaseObservable(Optional params) { return this.userRepository.users(); } } diff --git a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java index f656656..3f801d7 100644 --- a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java +++ b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java @@ -33,7 +33,7 @@ import io.reactivex.schedulers.Schedulers; * By convention each UseCase implementation will return the result using a {@link DisposableObserver} * that will execute its job in a background thread and will post the result in the UI thread. */ -public abstract class UseCase { +public abstract class UseCase { private final ThreadExecutor threadExecutor; private final PostExecutionThread postExecutionThread; @@ -48,7 +48,7 @@ public abstract class UseCase { /** * Builds an {@link Observable} which will be used when executing the current {@link UseCase}. */ - protected abstract Observable buildUseCaseObservable(Optional params); + abstract Observable buildUseCaseObservable(Optional params); /** * Executes the current use case. @@ -57,9 +57,8 @@ public abstract class UseCase { * by {@link #buildUseCaseObservable(Optional)} ()} method. * @param params Parameters used to build execute this use case. */ - @SuppressWarnings("unchecked") - public void execute(DisposableObserver observer, Params params) { - final Observable observable = this.buildUseCaseObservable(Optional.of(params)) + public void execute(DisposableObserver observer, Params params) { + final Observable observable = this.buildUseCaseObservable(Optional.of(params)) .subscribeOn(Schedulers.from(threadExecutor)) .observeOn(postExecutionThread.getScheduler()); addDisposable(observable.subscribeWith(observer)); diff --git a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java index 482a8d4..a2fa2c0 100644 --- a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java +++ b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java @@ -63,7 +63,7 @@ public class UseCaseTest { assertThat(testObserver.isDisposed()).isTrue(); } - private static class UseCaseTestClass extends UseCase { + private static class UseCaseTestClass extends UseCase { UseCaseTestClass(ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { super(threadExecutor, postExecutionThread); diff --git a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/internal/di/modules/UserModule.java b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/internal/di/modules/UserModule.java index 94cbebd..be255a0 100644 --- a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/internal/di/modules/UserModule.java +++ b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/internal/di/modules/UserModule.java @@ -15,16 +15,7 @@ */ package com.fernandocejas.android10.sample.presentation.internal.di.modules; -import com.fernandocejas.android10.sample.domain.executor.PostExecutionThread; -import com.fernandocejas.android10.sample.domain.executor.ThreadExecutor; -import com.fernandocejas.android10.sample.domain.interactor.GetUserDetails; -import com.fernandocejas.android10.sample.domain.interactor.GetUserList; -import com.fernandocejas.android10.sample.domain.interactor.UseCase; -import com.fernandocejas.android10.sample.domain.repository.UserRepository; -import com.fernandocejas.android10.sample.presentation.internal.di.PerActivity; import dagger.Module; -import dagger.Provides; -import javax.inject.Named; /** * Dagger module that provides user related collaborators. @@ -33,15 +24,4 @@ import javax.inject.Named; public class UserModule { public UserModule() {} - - @Provides @PerActivity @Named(GetUserList.NAME) UseCase provideGetUserListUseCase( - GetUserList getUserList) { - return getUserList; - } - - @Provides @PerActivity @Named(GetUserDetails.NAME) UseCase provideGetUserDetailsUseCase( - UserRepository userRepository, ThreadExecutor threadExecutor, - PostExecutionThread postExecutionThread) { - return new GetUserDetails(userRepository, threadExecutor, postExecutionThread); - } } diff --git a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java index 78827fe..96218f6 100644 --- a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java +++ b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java @@ -21,7 +21,6 @@ import com.fernandocejas.android10.sample.domain.exception.DefaultErrorBundle; import com.fernandocejas.android10.sample.domain.exception.ErrorBundle; import com.fernandocejas.android10.sample.domain.interactor.DefaultObserver; import com.fernandocejas.android10.sample.domain.interactor.GetUserDetails; -import com.fernandocejas.android10.sample.domain.interactor.UseCase; import com.fernandocejas.android10.sample.domain.interactor.Params; import com.fernandocejas.android10.sample.presentation.exception.ErrorMessageFactory; import com.fernandocejas.android10.sample.presentation.internal.di.PerActivity; @@ -29,7 +28,6 @@ import com.fernandocejas.android10.sample.presentation.mapper.UserModelDataMappe import com.fernandocejas.android10.sample.presentation.model.UserModel; import com.fernandocejas.android10.sample.presentation.view.UserDetailsView; import javax.inject.Inject; -import javax.inject.Named; /** * {@link Presenter} that controls communication between views and models of the presentation @@ -40,11 +38,11 @@ public class UserDetailsPresenter implements Presenter { private UserDetailsView viewDetailsView; - private final UseCase getUserDetailsUseCase; + private final GetUserDetails getUserDetailsUseCase; private final UserModelDataMapper userModelDataMapper; @Inject - public UserDetailsPresenter(@Named(GetUserDetails.NAME) UseCase getUserDetailsUseCase, + public UserDetailsPresenter(GetUserDetails getUserDetailsUseCase, UserModelDataMapper userModelDataMapper) { this.getUserDetailsUseCase = getUserDetailsUseCase; this.userModelDataMapper = userModelDataMapper; diff --git a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java index 4d67717..2208a44 100644 --- a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java +++ b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java @@ -21,7 +21,6 @@ import com.fernandocejas.android10.sample.domain.exception.DefaultErrorBundle; import com.fernandocejas.android10.sample.domain.exception.ErrorBundle; import com.fernandocejas.android10.sample.domain.interactor.DefaultObserver; import com.fernandocejas.android10.sample.domain.interactor.GetUserList; -import com.fernandocejas.android10.sample.domain.interactor.UseCase; import com.fernandocejas.android10.sample.domain.interactor.Params; import com.fernandocejas.android10.sample.presentation.exception.ErrorMessageFactory; import com.fernandocejas.android10.sample.presentation.internal.di.PerActivity; @@ -31,7 +30,6 @@ import com.fernandocejas.android10.sample.presentation.view.UserListView; import java.util.Collection; import java.util.List; import javax.inject.Inject; -import javax.inject.Named; /** * {@link Presenter} that controls communication between views and models of the presentation @@ -42,11 +40,11 @@ public class UserListPresenter implements Presenter { private UserListView viewListView; - private final UseCase getUserListUseCase; + private final GetUserList getUserListUseCase; private final UserModelDataMapper userModelDataMapper; @Inject - public UserListPresenter(@Named(GetUserList.NAME) UseCase getUserListUserCase, + public UserListPresenter(GetUserList getUserListUserCase, UserModelDataMapper userModelDataMapper) { this.getUserListUseCase = getUserListUserCase; this.userModelDataMapper = userModelDataMapper; From 8c78f8f148ace6874b9c5c12adca1fced0f89b4f Mon Sep 17 00:00:00 2001 From: Fernando Cejas Date: Mon, 26 Dec 2016 16:21:57 -0300 Subject: [PATCH 2/2] Fix tests and generify use case parameters. --- .../repository/UserDataRepositoryTest.java | 9 +--- .../domain/interactor/GetUserDetails.java | 31 ++++++------ .../sample/domain/interactor/GetUserList.java | 5 +- .../sample/domain/interactor/Params.java | 50 ------------------- .../sample/domain/interactor/UseCase.java | 12 ++--- .../domain/interactor/GetUserDetailsTest.java | 33 ++++-------- .../domain/interactor/GetUserListTest.java | 15 +----- .../sample/domain/interactor/ParamsTest.java | 49 ------------------ .../sample/domain/interactor/UseCaseTest.java | 28 ++++++++--- .../presenter/UserDetailsPresenterTest.java | 3 +- .../test/presenter/UserListPresenterTest.java | 4 +- .../presenter/UserDetailsPresenter.java | 6 +-- .../presenter/UserListPresenter.java | 3 +- 13 files changed, 64 insertions(+), 184 deletions(-) delete mode 100644 domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/Params.java delete mode 100644 domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/ParamsTest.java diff --git a/data/src/test/java/com/fernandocejas/android10/sample/data/repository/UserDataRepositoryTest.java b/data/src/test/java/com/fernandocejas/android10/sample/data/repository/UserDataRepositoryTest.java index ef596f6..1eac1d0 100644 --- a/data/src/test/java/com/fernandocejas/android10/sample/data/repository/UserDataRepositoryTest.java +++ b/data/src/test/java/com/fernandocejas/android10/sample/data/repository/UserDataRepositoryTest.java @@ -24,9 +24,7 @@ import io.reactivex.Observable; import java.util.ArrayList; import java.util.List; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; -import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @@ -48,14 +46,9 @@ public class UserDataRepositoryTest { @Mock private UserEntity mockUserEntity; @Mock private User mockUser; - @Rule - public ExpectedException expectedException = ExpectedException.none(); - @Before public void setUp() { - userDataRepository = new UserDataRepository(mockUserDataStoreFactory, - mockUserEntityDataMapper); - + userDataRepository = new UserDataRepository(mockUserDataStoreFactory, mockUserEntityDataMapper); given(mockUserDataStoreFactory.create(anyInt())).willReturn(mockUserDataStore); given(mockUserDataStoreFactory.createCloudDataStore()).willReturn(mockUserDataStore); } diff --git a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java index c43fc09..377d0c1 100644 --- a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java +++ b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java @@ -19,8 +19,7 @@ import com.fernandocejas.android10.sample.domain.User; import com.fernandocejas.android10.sample.domain.executor.PostExecutionThread; import com.fernandocejas.android10.sample.domain.executor.ThreadExecutor; import com.fernandocejas.android10.sample.domain.repository.UserRepository; -import com.fernandocejas.arrow.annotations.VisibleForTesting; -import com.fernandocejas.arrow.optional.Optional; +import com.fernandocejas.arrow.checks.Preconditions; import io.reactivex.Observable; import javax.inject.Inject; @@ -28,12 +27,7 @@ import javax.inject.Inject; * This class is an implementation of {@link UseCase} that represents a use case for * retrieving data related to an specific {@link User}. */ -public class GetUserDetails extends UseCase { - - public static final String PARAM_USER_ID_KEY = "userId"; - - @VisibleForTesting - static final int PARAM_USER_ID_DEFAULT_VALUE = -1; +public class GetUserDetails extends UseCase { private final UserRepository userRepository; @@ -44,12 +38,21 @@ public class GetUserDetails extends UseCase { this.userRepository = userRepository; } - @Override protected Observable buildUseCaseObservable(Optional params) { - if (params.isPresent()) { - final int userId = params.get().getInt(PARAM_USER_ID_KEY, PARAM_USER_ID_DEFAULT_VALUE); - return this.userRepository.user(userId); - } else { - return Observable.empty(); + @Override Observable buildUseCaseObservable(Params params) { + Preconditions.checkNotNull(params); + return this.userRepository.user(params.userId); + } + + public static final class Params { + + private final int userId; + + private Params(int userId) { + this.userId = userId; + } + + public static Params forUser(int userId) { + return new Params(userId); } } } diff --git a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java index a092b04..e43ce75 100644 --- a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java +++ b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java @@ -19,7 +19,6 @@ import com.fernandocejas.android10.sample.domain.User; import com.fernandocejas.android10.sample.domain.executor.PostExecutionThread; import com.fernandocejas.android10.sample.domain.executor.ThreadExecutor; import com.fernandocejas.android10.sample.domain.repository.UserRepository; -import com.fernandocejas.arrow.optional.Optional; import io.reactivex.Observable; import java.util.List; import javax.inject.Inject; @@ -28,7 +27,7 @@ import javax.inject.Inject; * This class is an implementation of {@link UseCase} that represents a use case for * retrieving a collection of all {@link User}. */ -public class GetUserList extends UseCase> { +public class GetUserList extends UseCase, Void> { private final UserRepository userRepository; @@ -39,7 +38,7 @@ public class GetUserList extends UseCase> { this.userRepository = userRepository; } - @Override public Observable> buildUseCaseObservable(Optional params) { + @Override Observable> buildUseCaseObservable(Void unused) { return this.userRepository.users(); } } diff --git a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/Params.java b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/Params.java deleted file mode 100644 index b2113e0..0000000 --- a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/Params.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (C) 2016 Fernando Cejas Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.fernandocejas.android10.sample.domain.interactor; - -import java.util.HashMap; -import java.util.Map; - -/** - * Class backed by a Map, used to pass parameters to {@link UseCase} instances. - */ -public final class Params { - public static final Params EMPTY = Params.create(); - - private final Map parameters = new HashMap<>(); - - private Params() {} - - public static Params create() { - return new Params(); - } - - public void putInt(String key, int value) { - parameters.put(key, value); - } - - int getInt(String key, int defaultValue) { - final Object object = parameters.get(key); - if (object == null) { - return defaultValue; - } - try { - return (int) object; - } catch (ClassCastException e) { - return defaultValue; - } - } -} diff --git a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java index 3f801d7..e71f914 100644 --- a/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java +++ b/domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java @@ -18,7 +18,6 @@ package com.fernandocejas.android10.sample.domain.interactor; import com.fernandocejas.android10.sample.domain.executor.PostExecutionThread; import com.fernandocejas.android10.sample.domain.executor.ThreadExecutor; import com.fernandocejas.arrow.checks.Preconditions; -import com.fernandocejas.arrow.optional.Optional; import io.reactivex.Observable; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; @@ -33,7 +32,7 @@ import io.reactivex.schedulers.Schedulers; * By convention each UseCase implementation will return the result using a {@link DisposableObserver} * that will execute its job in a background thread and will post the result in the UI thread. */ -public abstract class UseCase { +public abstract class UseCase { private final ThreadExecutor threadExecutor; private final PostExecutionThread postExecutionThread; @@ -48,17 +47,18 @@ public abstract class UseCase { /** * Builds an {@link Observable} which will be used when executing the current {@link UseCase}. */ - abstract Observable buildUseCaseObservable(Optional params); + abstract Observable buildUseCaseObservable(Params params); /** * Executes the current use case. * * @param observer {@link DisposableObserver} which will be listening to the observable build - * by {@link #buildUseCaseObservable(Optional)} ()} method. - * @param params Parameters used to build execute this use case. + * by {@link #buildUseCaseObservable(Params)} ()} method. + * @param params Parameters (Optional) used to build/execute this use case. */ public void execute(DisposableObserver observer, Params params) { - final Observable observable = this.buildUseCaseObservable(Optional.of(params)) + Preconditions.checkNotNull(observer); + final Observable observable = this.buildUseCaseObservable(params) .subscribeOn(Schedulers.from(threadExecutor)) .observeOn(postExecutionThread.getScheduler()); addDisposable(observable.subscribeWith(observer)); diff --git a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetailsTest.java b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetailsTest.java index 2379205..01baab9 100644 --- a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetailsTest.java +++ b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetailsTest.java @@ -17,16 +17,16 @@ package com.fernandocejas.android10.sample.domain.interactor; import com.fernandocejas.android10.sample.domain.executor.PostExecutionThread; import com.fernandocejas.android10.sample.domain.executor.ThreadExecutor; +import com.fernandocejas.android10.sample.domain.interactor.GetUserDetails.Params; import com.fernandocejas.android10.sample.domain.repository.UserRepository; -import com.fernandocejas.arrow.optional.Optional; -import io.reactivex.Observable; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; @@ -42,6 +42,8 @@ public class GetUserDetailsTest { @Mock private ThreadExecutor mockThreadExecutor; @Mock private PostExecutionThread mockPostExecutionThread; + @Rule public ExpectedException expectedException = ExpectedException.none(); + @Before public void setUp() { getUserDetails = new GetUserDetails(mockUserRepository, mockThreadExecutor, @@ -50,10 +52,7 @@ public class GetUserDetailsTest { @Test public void testGetUserDetailsUseCaseObservableHappyCase() { - final Params params = Params.create(); - params.putInt(GetUserDetails.PARAM_USER_ID_KEY, USER_ID); - - getUserDetails.buildUseCaseObservable(Optional.of(params)); + getUserDetails.buildUseCaseObservable(Params.forUser(USER_ID)); verify(mockUserRepository).user(USER_ID); verifyNoMoreInteractions(mockUserRepository); @@ -62,22 +61,8 @@ public class GetUserDetailsTest { } @Test - public void testShouldReturnEmptyObservableWhenNoParameters() { - final Observable observable = getUserDetails.buildUseCaseObservable(Optional.absent()); - - assertThat(observable).isEqualTo(Observable.empty()); - verifyZeroInteractions(mockUserRepository); - verifyZeroInteractions(mockPostExecutionThread); - verifyZeroInteractions(mockThreadExecutor); - } - - @Test - public void testShouldUseDefaultUserIdValueWhenNoUserIdParameter() { - getUserDetails.buildUseCaseObservable(Optional.of(Params.create())); - - verify(mockUserRepository).user(GetUserDetails.PARAM_USER_ID_DEFAULT_VALUE); - verifyNoMoreInteractions(mockUserRepository); - verifyZeroInteractions(mockPostExecutionThread); - verifyZeroInteractions(mockThreadExecutor); + public void testShouldFailWhenNoOrEmptyParameters() { + expectedException.expect(NullPointerException.class); + getUserDetails.buildUseCaseObservable(null); } } diff --git a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserListTest.java b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserListTest.java index 73cf0e1..1369406 100644 --- a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserListTest.java +++ b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserListTest.java @@ -18,14 +18,12 @@ package com.fernandocejas.android10.sample.domain.interactor; import com.fernandocejas.android10.sample.domain.executor.PostExecutionThread; import com.fernandocejas.android10.sample.domain.executor.ThreadExecutor; import com.fernandocejas.android10.sample.domain.repository.UserRepository; -import com.fernandocejas.arrow.optional.Optional; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; @@ -47,22 +45,11 @@ public class GetUserListTest { @Test public void testGetUserListUseCaseObservableHappyCase() { - getUserList.buildUseCaseObservable(Optional.of(Params.EMPTY)); + getUserList.buildUseCaseObservable(null); verify(mockUserRepository).users(); verifyNoMoreInteractions(mockUserRepository); verifyZeroInteractions(mockThreadExecutor); verifyZeroInteractions(mockPostExecutionThread); } - - @Test - @SuppressWarnings("unchecked") - public void testThereShouldNotBeAnyInteractionWithParams() { - Optional params = mock(Optional.class); - - getUserList.buildUseCaseObservable(params); - - verify(mockUserRepository).users(); - verifyZeroInteractions(params); - } } diff --git a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/ParamsTest.java b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/ParamsTest.java deleted file mode 100644 index 4d95afc..0000000 --- a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/ParamsTest.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Copyright (C) 2016 Fernando Cejas Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.fernandocejas.android10.sample.domain.interactor; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.runners.MockitoJUnitRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -@RunWith(MockitoJUnitRunner.class) -public class ParamsTest { - - private Params params; - - @Before - public void setUp() { - params = Params.create(); - } - - @Test - public void testShouldReturnIntValue() { - params.putInt("key01", 3); - - assertThat(params.getInt("key01", 5)).isEqualTo(3); - } - - @Test - public void testShouldReturnIntDefaultValue() { - params.putInt("key01", 3); - params.putInt("key02", 4); - - assertThat(params.getInt("key03", 5)).isEqualTo(5); - } -} diff --git a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java index a2fa2c0..b888200 100644 --- a/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java +++ b/domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java @@ -17,12 +17,13 @@ package com.fernandocejas.android10.sample.domain.interactor; import com.fernandocejas.android10.sample.domain.executor.PostExecutionThread; import com.fernandocejas.android10.sample.domain.executor.ThreadExecutor; -import com.fernandocejas.arrow.optional.Optional; import io.reactivex.Observable; import io.reactivex.observers.DisposableObserver; import io.reactivex.schedulers.TestScheduler; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; @@ -35,11 +36,13 @@ public class UseCaseTest { private UseCaseTestClass useCase; - private TestDisposableObserver testObserver; + private TestDisposableObserver testObserver; @Mock private ThreadExecutor mockThreadExecutor; @Mock private PostExecutionThread mockPostExecutionThread; + @Rule public ExpectedException expectedException = ExpectedException.none(); + @Before public void setUp() { this.useCase = new UseCaseTestClass(mockThreadExecutor, mockPostExecutionThread); @@ -48,7 +51,6 @@ public class UseCaseTest { } @Test - @SuppressWarnings("unchecked") public void testBuildUseCaseObservableReturnCorrectResult() { useCase.execute(testObserver, Params.EMPTY); @@ -63,18 +65,25 @@ public class UseCaseTest { assertThat(testObserver.isDisposed()).isTrue(); } - private static class UseCaseTestClass extends UseCase { + @Test + public void testShouldFailWhenExecuteWithNullObserver() { + expectedException.expect(NullPointerException.class); + useCase.execute(null, Params.EMPTY); + } + + private static class UseCaseTestClass extends UseCase { UseCaseTestClass(ThreadExecutor threadExecutor, PostExecutionThread postExecutionThread) { super(threadExecutor, postExecutionThread); } - @Override protected Observable buildUseCaseObservable(Optional params) { + @Override Observable buildUseCaseObservable(Params params) { return Observable.empty(); } - @Override public void execute(DisposableObserver observer, Params params) { - super.execute(observer, Params.EMPTY); + @Override + public void execute(DisposableObserver observer, Params params) { + super.execute(observer, params); } } @@ -93,4 +102,9 @@ public class UseCaseTest { // no-op by default. } } + + private static class Params { + private static Params EMPTY = new Params(); + private Params() {} + } } diff --git a/presentation/src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserDetailsPresenterTest.java b/presentation/src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserDetailsPresenterTest.java index 74673b7..e836065 100644 --- a/presentation/src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserDetailsPresenterTest.java +++ b/presentation/src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserDetailsPresenterTest.java @@ -17,6 +17,7 @@ package com.fernandocejas.android10.sample.test.presenter; import android.content.Context; import com.fernandocejas.android10.sample.domain.interactor.GetUserDetails; +import com.fernandocejas.android10.sample.domain.interactor.GetUserDetails.Params; import com.fernandocejas.android10.sample.presentation.mapper.UserModelDataMapper; import com.fernandocejas.android10.sample.presentation.presenter.UserDetailsPresenter; import com.fernandocejas.android10.sample.presentation.view.UserDetailsView; @@ -27,7 +28,6 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import com.fernandocejas.android10.sample.domain.interactor.Params; import static org.mockito.BDDMockito.given; import static org.mockito.Matchers.any; import static org.mockito.Mockito.verify; @@ -51,6 +51,7 @@ public class UserDetailsPresenterTest { } @Test + @SuppressWarnings("unchecked") public void testUserDetailsPresenterInitialize() { given(mockUserDetailsView.context()).willReturn(mockContext); diff --git a/presentation/src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserListPresenterTest.java b/presentation/src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserListPresenterTest.java index 2d3637f..35c9985 100644 --- a/presentation/src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserListPresenterTest.java +++ b/presentation/src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserListPresenterTest.java @@ -17,7 +17,6 @@ package com.fernandocejas.android10.sample.test.presenter; import android.content.Context; import com.fernandocejas.android10.sample.domain.interactor.GetUserList; -import com.fernandocejas.android10.sample.domain.interactor.Params; import com.fernandocejas.android10.sample.presentation.mapper.UserModelDataMapper; import com.fernandocejas.android10.sample.presentation.presenter.UserListPresenter; import com.fernandocejas.android10.sample.presentation.view.UserListView; @@ -49,6 +48,7 @@ public class UserListPresenterTest { } @Test + @SuppressWarnings("unchecked") public void testUserListPresenterInitialize() { given(mockUserListView.context()).willReturn(mockContext); @@ -56,6 +56,6 @@ public class UserListPresenterTest { verify(mockUserListView).hideRetry(); verify(mockUserListView).showLoading(); - verify(mockGetUserList).execute(any(DisposableObserver.class), any(Params.class)); + verify(mockGetUserList).execute(any(DisposableObserver.class), any(Void.class)); } } diff --git a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java index 96218f6..4e3c3bf 100644 --- a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java +++ b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java @@ -21,7 +21,7 @@ import com.fernandocejas.android10.sample.domain.exception.DefaultErrorBundle; import com.fernandocejas.android10.sample.domain.exception.ErrorBundle; import com.fernandocejas.android10.sample.domain.interactor.DefaultObserver; import com.fernandocejas.android10.sample.domain.interactor.GetUserDetails; -import com.fernandocejas.android10.sample.domain.interactor.Params; +import com.fernandocejas.android10.sample.domain.interactor.GetUserDetails.Params; import com.fernandocejas.android10.sample.presentation.exception.ErrorMessageFactory; import com.fernandocejas.android10.sample.presentation.internal.di.PerActivity; import com.fernandocejas.android10.sample.presentation.mapper.UserModelDataMapper; @@ -72,9 +72,7 @@ public class UserDetailsPresenter implements Presenter { } private void getUserDetails(int userId) { - final Params params = Params.create(); - params.putInt(GetUserDetails.PARAM_USER_ID_KEY, userId); - this.getUserDetailsUseCase.execute(new UserDetailsObserver(), params); + this.getUserDetailsUseCase.execute(new UserDetailsObserver(), Params.forUser(userId)); } private void showViewLoading() { diff --git a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java index 2208a44..f17a460 100644 --- a/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java +++ b/presentation/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java @@ -21,7 +21,6 @@ import com.fernandocejas.android10.sample.domain.exception.DefaultErrorBundle; import com.fernandocejas.android10.sample.domain.exception.ErrorBundle; import com.fernandocejas.android10.sample.domain.interactor.DefaultObserver; import com.fernandocejas.android10.sample.domain.interactor.GetUserList; -import com.fernandocejas.android10.sample.domain.interactor.Params; import com.fernandocejas.android10.sample.presentation.exception.ErrorMessageFactory; import com.fernandocejas.android10.sample.presentation.internal.di.PerActivity; import com.fernandocejas.android10.sample.presentation.mapper.UserModelDataMapper; @@ -112,7 +111,7 @@ public class UserListPresenter implements Presenter { } private void getUserList() { - this.getUserListUseCase.execute(new UserListObserver(), Params.EMPTY); + this.getUserListUseCase.execute(new UserListObserver(), null); } private final class UserListObserver extends DefaultObserver> {