Skip to content

Commit

Permalink
Refactored our UseCases so we can test them
Browse files Browse the repository at this point in the history
  • Loading branch information
AllanHasegawa committed Jul 30, 2017
1 parent e7c6d4a commit 0a6c8b1
Show file tree
Hide file tree
Showing 13 changed files with 443 additions and 150 deletions.
12 changes: 9 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,11 @@ dependencies {
leonids : '1.3.1',

junit : '4.12',
mockito : '2.+',

espresso : '2.2.2',
]

androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile "com.android.support:appcompat-v7:$versions.supportLib"
compile "com.android.support:design:$versions.supportLib"
compile "com.squareup.picasso:picasso:$versions.picasso"
Expand All @@ -48,5 +48,11 @@ dependencies {
exclude group: 'stax', module: 'stax'
exclude group: 'xpp3', module: 'xpp3'
})

testCompile "junit:junit:$versions.junit"
testCompile "org.mockito:mockito-core:$versions.mockito"

androidTestCompile("com.android.support.test.espresso:espresso-core:$versions.espresso", {
exclude group: 'com.android.support', module: 'support-annotations'
})
}
5 changes: 4 additions & 1 deletion app/src/main/java/io/catter2/FavoritesActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@

import java.util.List;

import io.catter2.favorites.FavoritesRepository;
import io.catter2.favorites.GetFavoritesUseCase;
import io.catter2.favorites.SharedPrefFavoritesRepository;

public class FavoritesActivity extends AppCompatActivity {

Expand Down Expand Up @@ -62,7 +64,8 @@ public void onClick(View view) {
}
Log.d(TAG, "UserToken: " + userToken);

getFavoritesUseCase = new GetFavoritesUseCase(this, userToken);
FavoritesRepository favoritesRepository = new SharedPrefFavoritesRepository(this, userToken);
getFavoritesUseCase = new GetFavoritesUseCase(favoritesRepository);
getFavoritesUseCase.getFavorites(new GetFavoritesUseCase.Callback() {
@Override
public void favoriteUrlsUpdated(List<String> favoriteUrls) {
Expand Down
10 changes: 8 additions & 2 deletions app/src/main/java/io/catter2/ListActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
import java.util.List;

import io.catter2.cat_api.FetchCatImagesUseCase;
import io.catter2.cat_api.RetrofitTheCatAPI;
import io.catter2.cat_api.TheCatAPI;
import io.catter2.favorites.AddFavoriteUseCase;
import io.catter2.favorites.FavoritesRepository;
import io.catter2.favorites.SharedPrefFavoritesRepository;

public class ListActivity extends AppCompatActivity {
private static String TAG = "List";
Expand Down Expand Up @@ -60,8 +64,10 @@ public void imageClicked(ImageView view, String url) {
recyclerView.setAdapter(adapter);


addFavoriteUseCase = new AddFavoriteUseCase(this, userToken);
fetchCatImagesUseCase = new FetchCatImagesUseCase();
FavoritesRepository favoritesRepository = new SharedPrefFavoritesRepository(this, userToken);
addFavoriteUseCase = new AddFavoriteUseCase(favoritesRepository);
TheCatAPI catAPI = new RetrofitTheCatAPI();
fetchCatImagesUseCase = new FetchCatImagesUseCase(catAPI);

fetchCatImagesUseCase.getImagesUrls(new FetchCatImagesUseCase.Callback() {
@Override
Expand Down
32 changes: 9 additions & 23 deletions app/src/main/java/io/catter2/cat_api/FetchCatImagesUseCase.java
Original file line number Diff line number Diff line change
@@ -1,45 +1,31 @@
package io.catter2.cat_api;

import android.util.Log;

import java.util.ArrayList;
import java.util.List;

import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;

public class FetchCatImagesUseCase {
public interface Callback {
void imagesUrls(List<String> urls);
}

private static String TAG = "FetchCatImagesUseCase";
private TheCatAPI catAPI;

public FetchCatImagesUseCase(TheCatAPI catAPI) {
this.catAPI = catAPI;
}

public void getImagesUrls(final Callback callback) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://thecatapi.com/api/")
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
RetrofitTheCatAPI retrofitTheCatApi = retrofit.create(RetrofitTheCatAPI.class);
retrofitTheCatApi.listCatsWithHat().enqueue(new retrofit2.Callback<CatImagesModel>() {
catAPI.getCatsWithHats(new TheCatAPI.Callback() {
@Override
public void onResponse(Call<CatImagesModel> call, Response<CatImagesModel> response) {
public void response(CatImagesModel response) {
ArrayList<String> imageUrls = new ArrayList<>();
if (response.body().catImages != null) {
for (CatImageModel img : response.body().catImages) {
Log.d(TAG, "Found: " + img.url);
if (response != null) {
for (CatImageModel img : response.catImages) {
imageUrls.add(img.url);
}
}
callback.imagesUrls(imageUrls);
}

@Override
public void onFailure(Call<CatImagesModel> call, Throwable t) {
Log.e(TAG, "Error fetching cat images", t);
}
});
}
}
36 changes: 33 additions & 3 deletions app/src/main/java/io/catter2/cat_api/RetrofitTheCatAPI.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,39 @@
package io.catter2.cat_api;

import android.util.Log;

import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;
import retrofit2.http.GET;

public interface RetrofitTheCatAPI {
@GET("images/get?format=xml&results_per_page=20&category=hats")
Call<CatImagesModel> listCatsWithHat();
import static android.content.ContentValues.TAG;

public class RetrofitTheCatAPI implements TheCatAPI {
interface RetrofitCatService {
@GET("images/get?format=xml&results_per_page=20&category=hats")
Call<CatImagesModel> listCatsWithHat();
}

@Override
public void getCatsWithHats(final Callback callback) {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://thecatapi.com/api/")
.addConverterFactory(SimpleXmlConverterFactory.create())
.build();
RetrofitCatService retrofitCatService = retrofit.create(RetrofitCatService.class);
retrofitCatService.listCatsWithHat().enqueue(new retrofit2.Callback<CatImagesModel>() {
@Override
public void onResponse(Call<CatImagesModel> call, Response<CatImagesModel> response) {
callback.response(response.body());
}

@Override
public void onFailure(Call<CatImagesModel> call, Throwable t) {
Log.e(TAG, "Error fetching cat images", t);
callback.response(null);
}
});
}
}
9 changes: 9 additions & 0 deletions app/src/main/java/io/catter2/cat_api/TheCatAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.catter2.cat_api;

public interface TheCatAPI {
interface Callback {
void response(CatImagesModel response);
}

void getCatsWithHats(Callback callback);
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package io.catter2.favorites;

import android.content.Context;

import java.util.List;

public class AddFavoriteUseCase {
private FavoritesRepository repo;

public AddFavoriteUseCase(Context context, String userToken) {
repo = new FavoritesRepository(context, userToken);
public AddFavoriteUseCase(FavoritesRepository favoritesRepository) {
this.repo = favoritesRepository;
}

/**
Expand Down
116 changes: 6 additions & 110 deletions app/src/main/java/io/catter2/favorites/FavoritesRepository.java
Original file line number Diff line number Diff line change
@@ -1,128 +1,24 @@
package io.catter2.favorites;

import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import io.catter2.R;

public class FavoritesRepository {
public interface ChangeListener {
public interface FavoritesRepository {
interface ChangeListener {
void onFavoritesChanged(List<FavoriteModel> favorites);
}

private static String SP_USER_FAVORITES_KEY = "user-favorites-urls-%s";
private static String TAG = "FavoritesRepository";

private Context context;
private String userToken;
private ChangeListener changeListener;
private SharedPreferences.OnSharedPreferenceChangeListener sharedPrefListener;

public FavoritesRepository(Context context, String userToken) {
this.context = context;
this.userToken = userToken;
}

/**
* @return A list of favorites sorted by the time it was added.
*/
public List<FavoriteModel> getFavorites() {
SharedPreferences pref = getPref();
String prefKey = getFavoritesKey();
Set<String> entriesSet = pref.getStringSet(prefKey, new HashSet<String>());

ArrayList<FavoriteModel> favorites = new ArrayList<>(entriesSet.size());
for (String entry : entriesSet) {
String[] decoded = entry.split(";");
favorites.add(new FavoriteModel(Long.valueOf(decoded[1]), decoded[0]));
}

Collections.sort(favorites, new Comparator<FavoriteModel>() {
@Override
public int compare(FavoriteModel o1, FavoriteModel o2) {
return (int) (o2.getTimeAdded() - o1.getTimeAdded());
}
});

return favorites;
}
List<FavoriteModel> getFavorites();

/**
* @param model
* @return A list of favorites sorted by the time it was added, with the newly added favorite.
*/
public List<FavoriteModel> addFavorite(FavoriteModel model) {
List<FavoriteModel> oldModels = getFavorites();
List<FavoriteModel> addFavorite(FavoriteModel model);

boolean hasUrl = false;
for (FavoriteModel entry : oldModels) {
if (entry.getUrl().equals(model.getUrl())) {
hasUrl = true;
break;
}
}
void registerChangeListener(final ChangeListener listener);

if (hasUrl) {
return oldModels;
}

ArrayList<FavoriteModel> newList = new ArrayList<>(oldModels);
newList.add(model);
saveFavorites(newList);

return newList;
}

public void registerChangeListener(final ChangeListener listener) {
if (this.changeListener != null) {
throw new RuntimeException("Listener already registered.");
}
this.changeListener = listener;
this.sharedPrefListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d(TAG, "Key changed: " + key);
String prefKey = String.format(SP_USER_FAVORITES_KEY, userToken);
if (key.equals(prefKey)) {
changeListener.onFavoritesChanged(getFavorites());
}
}
};
getPref().registerOnSharedPreferenceChangeListener(this.sharedPrefListener);
}

public void clearChangeListener() {
this.changeListener = null;
if (this.sharedPrefListener != null) {
getPref().unregisterOnSharedPreferenceChangeListener(this.sharedPrefListener);
this.sharedPrefListener = null;
}
}

private SharedPreferences getPref() {
String prefName = context.getString(R.string.pref_key_user_data);
return context.getSharedPreferences(prefName, Context.MODE_PRIVATE);
}

private String getFavoritesKey() {
return String.format(SP_USER_FAVORITES_KEY, userToken);
}

private void saveFavorites(ArrayList<FavoriteModel> newList) {
HashSet<String> newEntries = new HashSet<>(newList.size());

for (FavoriteModel entry : newList) {
newEntries.add(entry.getUrl() + ";" + entry.getTimeAdded());
}

getPref().edit().putStringSet(getFavoritesKey(), newEntries).apply();
}
void clearChangeListener();
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package io.catter2.favorites;

import android.content.Context;

import java.util.ArrayList;
import java.util.List;

Expand All @@ -12,8 +10,8 @@ public interface Callback {

private FavoritesRepository repo;

public GetFavoritesUseCase(Context context, String userToken) {
this.repo = new FavoritesRepository(context, userToken);
public GetFavoritesUseCase(FavoritesRepository favoritesRepository) {
this.repo = favoritesRepository;
}

/**
Expand Down
Loading

0 comments on commit 0a6c8b1

Please sign in to comment.