Permalink
Browse files

Merge pull request #202 from android10/generic-use-cases

Generic use cases
  • Loading branch information...
android10 committed Dec 27, 2016
2 parents 70eeacf + 8c78f8f commit aaa21c1b7cb4dc7b80a4da7f0552036bcb7ff40e
Showing with 71 additions and 218 deletions.
  1. +1 −8 data/src/test/java/com/fernandocejas/android10/sample/data/repository/UserDataRepositoryTest.java
  2. +18 −16 domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetails.java
  3. +3 −5 domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/GetUserList.java
  4. +0 −50 domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/Params.java
  5. +7 −8 domain/src/main/java/com/fernandocejas/android10/sample/domain/interactor/UseCase.java
  6. +9 −24 domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserDetailsTest.java
  7. +1 −14 domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/GetUserListTest.java
  8. +0 −49 domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/ParamsTest.java
  9. +21 −7 domain/src/test/java/com/fernandocejas/android10/sample/domain/interactor/UseCaseTest.java
  10. +2 −1 .../androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserDetailsPresenterTest.java
  11. +2 −2 ...src/androidTest/java/com/fernandocejas/android10/sample/test/presenter/UserListPresenterTest.java
  12. +0 −20 ...src/main/java/com/fernandocejas/android10/sample/presentation/internal/di/modules/UserModule.java
  13. +4 −8 ...src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserDetailsPresenter.java
  14. +3 −6 ...on/src/main/java/com/fernandocejas/android10/sample/presentation/presenter/UserListPresenter.java
@@ -24,9 +24,7 @@
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 @@
@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);
}
@@ -19,38 +19,40 @@
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;
/**
* 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 NAME = "userDetails";
public static final String PARAM_USER_ID_KEY = "userId";
@VisibleForTesting
static final int PARAM_USER_ID_DEFAULT_VALUE = -1;
public class GetUserDetails extends UseCase<User, GetUserDetails.Params> {
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> 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<User> 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);
}
}
}
@@ -19,17 +19,15 @@
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;
/**
* 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<List<User>, Void> {
private final UserRepository userRepository;
@@ -40,7 +38,7 @@
this.userRepository = userRepository;
}
@Override public Observable buildUseCaseObservable(Optional<Params> params) {
@Override Observable<List<User>> buildUseCaseObservable(Void unused) {
return this.userRepository.users();
}
}

This file was deleted.

Oops, something went wrong.
@@ -18,7 +18,6 @@
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 @@
* 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<T, Params> {
private final ThreadExecutor threadExecutor;
private final PostExecutionThread postExecutionThread;
@@ -48,18 +47,18 @@
/**
* Builds an {@link Observable} which will be used when executing the current {@link UseCase}.
*/
protected abstract Observable buildUseCaseObservable(Optional<Params> params);
abstract Observable<T> 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.
*/
@SuppressWarnings("unchecked")
public void execute(DisposableObserver observer, Params params) {
final Observable<?> observable = this.buildUseCaseObservable(Optional.of(params))
public void execute(DisposableObserver<T> observer, Params params) {
Preconditions.checkNotNull(observer);
final Observable<T> observable = this.buildUseCaseObservable(params)
.subscribeOn(Schedulers.from(threadExecutor))
.observeOn(postExecutionThread.getScheduler());
addDisposable(observable.subscribeWith(observer));
@@ -17,16 +17,16 @@
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 @@
@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 void setUp() {
@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 void testGetUserDetailsUseCaseObservableHappyCase() {
}
@Test
public void testShouldReturnEmptyObservableWhenNoParameters() {
final Observable observable = getUserDetails.buildUseCaseObservable(Optional.<Params>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);
}
}
@@ -18,14 +18,12 @@
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 void setUp() {
@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);
}
}

This file was deleted.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit aaa21c1

Please sign in to comment.