mirror of
https://github.com/sudoxnym/habitica-android.git
synced 2026-05-19 20:29:02 +00:00
start testing api call handling
This commit is contained in:
parent
7c89c448a9
commit
e78fea7375
7 changed files with 188 additions and 59 deletions
|
|
@ -1,18 +1,66 @@
|
|||
package com.habitrpg.android.habitica;
|
||||
|
||||
import com.google.gson.ExclusionStrategy;
|
||||
import com.google.gson.FieldAttributes;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import com.amplitude.api.Amplitude;
|
||||
import com.crashlytics.android.Crashlytics;
|
||||
import com.habitrpg.android.habitica.database.CheckListItemExcludeStrategy;
|
||||
import com.magicmicky.habitrpgwrapper.lib.api.ApiService;
|
||||
import com.magicmicky.habitrpgwrapper.lib.api.Server;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.ChatMessage;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.ContentResult;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Customization;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.FAQArticle;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Group;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationRequest;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.PurchaseValidationResult;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Purchases;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.Skill;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.TutorialStep;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.UserAuth;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.UserAuthResponse;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.UserAuthSocial;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.UserAuthSocialTokens;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.inventory.Egg;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.inventory.Food;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.inventory.HatchingPotion;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.inventory.Mount;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.inventory.Pet;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.inventory.QuestContent;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.responses.FeedResponse;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.ChecklistItem;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.ItemData;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.TaskList;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.TaskTag;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.BooleanAsIntAdapter;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.ChatMessageDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.ChecklistItemSerializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.ContentDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.CustomizationDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.DateDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.EggListDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.FAQArticleListDeserilializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.FeedResponseDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.FoodListDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.GroupSerialization;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.HatchingPotionListDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.ItemDataListDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.MountListDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.PetListDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.PurchasedDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.QuestListDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.SkillDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.TaskListDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.TaskSerializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.TaskTagDeserializer;
|
||||
import com.magicmicky.habitrpgwrapper.lib.utils.TutorialStepListDeserializer;
|
||||
import com.raizlabs.android.dbflow.structure.ModelAdapter;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
|
@ -22,10 +70,13 @@ import android.support.v7.app.AlertDialog;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.ConnectException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -133,6 +184,62 @@ public class APIHelper implements Action1<Throwable> {
|
|||
this.apiService = retrofitAdapter.create(ApiService.class);
|
||||
}
|
||||
|
||||
public static GsonConverterFactory createGsonFactory() {
|
||||
Type taskTagClassListType = new TypeToken<List<TaskTag>>() {}.getType();
|
||||
Type skillListType = new TypeToken<List<Skill>>() {}.getType();
|
||||
Type customizationListType = new TypeToken<List<Customization>>() {}.getType();
|
||||
Type tutorialStepListType = new TypeToken<List<TutorialStep>>() {}.getType();
|
||||
Type faqArticleListType = new TypeToken<List<FAQArticle>>() {}.getType();
|
||||
Type itemDataListType = new TypeToken<List<ItemData>>() {}.getType();
|
||||
Type eggListType = new TypeToken<List<Egg>>() {}.getType();
|
||||
Type foodListType = new TypeToken<List<Food>>() {}.getType();
|
||||
Type hatchingPotionListType = new TypeToken<List<HatchingPotion>>() {}.getType();
|
||||
Type questContentListType = new TypeToken<List<QuestContent>>() {}.getType();
|
||||
Type petListType = new TypeToken<HashMap<String, Pet>>() {}.getType();
|
||||
Type mountListType = new TypeToken<HashMap<String, Mount>>() {}.getType();
|
||||
|
||||
//Exclusion strategy needed for DBFlow https://github.com/Raizlabs/DBFlow/issues/121
|
||||
Gson gson = new GsonBuilder()
|
||||
.setExclusionStrategies(new CheckListItemExcludeStrategy())
|
||||
.setExclusionStrategies(new ExclusionStrategy() {
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return f.getDeclaredClass().equals(ModelAdapter.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.registerTypeAdapter(taskTagClassListType, new TaskTagDeserializer())
|
||||
.registerTypeAdapter(Boolean.class, new BooleanAsIntAdapter())
|
||||
.registerTypeAdapter(boolean.class, new BooleanAsIntAdapter())
|
||||
.registerTypeAdapter(skillListType, new SkillDeserializer())
|
||||
.registerTypeAdapter(ChecklistItem.class, new ChecklistItemSerializer())
|
||||
.registerTypeAdapter(TaskList.class, new TaskListDeserializer())
|
||||
.registerTypeAdapter(Purchases.class, new PurchasedDeserializer())
|
||||
.registerTypeAdapter(customizationListType, new CustomizationDeserializer())
|
||||
.registerTypeAdapter(tutorialStepListType, new TutorialStepListDeserializer())
|
||||
.registerTypeAdapter(faqArticleListType, new FAQArticleListDeserilializer())
|
||||
.registerTypeAdapter(Group.class, new GroupSerialization())
|
||||
.registerTypeAdapter(Date.class, new DateDeserializer())
|
||||
.registerTypeAdapter(itemDataListType, new ItemDataListDeserializer())
|
||||
.registerTypeAdapter(eggListType, new EggListDeserializer())
|
||||
.registerTypeAdapter(foodListType, new FoodListDeserializer())
|
||||
.registerTypeAdapter(hatchingPotionListType, new HatchingPotionListDeserializer())
|
||||
.registerTypeAdapter(questContentListType, new QuestListDeserializer())
|
||||
.registerTypeAdapter(petListType, new PetListDeserializer())
|
||||
.registerTypeAdapter(mountListType, new MountListDeserializer())
|
||||
.registerTypeAdapter(ChatMessage.class, new ChatMessageDeserializer())
|
||||
.registerTypeAdapter(Task.class, new TaskSerializer())
|
||||
.registerTypeAdapter(ContentResult.class, new ContentDeserializer())
|
||||
.registerTypeAdapter(FeedResponse.class, new FeedResponseDeserializer())
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||
.create();
|
||||
return GsonConverterFactory.create(gson);
|
||||
}
|
||||
|
||||
public Observable<UserAuthResponse> registerUser(String username, String email, String password, String confirmPassword) {
|
||||
UserAuth auth = new UserAuth();
|
||||
auth.setUsername(username);
|
||||
|
|
@ -218,7 +325,7 @@ public class APIHelper implements Action1<Throwable> {
|
|||
return habitRPGUser;
|
||||
});
|
||||
}
|
||||
return userObservable.compose(configureApiCallObserver());
|
||||
return userObservable;
|
||||
}
|
||||
|
||||
private List<Task> sortTasks(Map<String, Task> taskMap, List<String> taskOrder){
|
||||
|
|
|
|||
|
|
@ -81,59 +81,7 @@ public class ApiModule {
|
|||
|
||||
@Provides
|
||||
public GsonConverterFactory providesGsonConverterFactory() {
|
||||
Type taskTagClassListType = new TypeToken<List<TaskTag>>() {}.getType();
|
||||
Type skillListType = new TypeToken<List<Skill>>() {}.getType();
|
||||
Type customizationListType = new TypeToken<List<Customization>>() {}.getType();
|
||||
Type tutorialStepListType = new TypeToken<List<TutorialStep>>() {}.getType();
|
||||
Type faqArticleListType = new TypeToken<List<FAQArticle>>() {}.getType();
|
||||
Type itemDataListType = new TypeToken<List<ItemData>>() {}.getType();
|
||||
Type eggListType = new TypeToken<List<Egg>>() {}.getType();
|
||||
Type foodListType = new TypeToken<List<Food>>() {}.getType();
|
||||
Type hatchingPotionListType = new TypeToken<List<HatchingPotion>>() {}.getType();
|
||||
Type questContentListType = new TypeToken<List<QuestContent>>() {}.getType();
|
||||
Type petListType = new TypeToken<HashMap<String, Pet>>() {}.getType();
|
||||
Type mountListType = new TypeToken<HashMap<String, Mount>>() {}.getType();
|
||||
|
||||
//Exclusion strategy needed for DBFlow https://github.com/Raizlabs/DBFlow/issues/121
|
||||
Gson gson = new GsonBuilder()
|
||||
.setExclusionStrategies(new CheckListItemExcludeStrategy())
|
||||
.setExclusionStrategies(new ExclusionStrategy() {
|
||||
@Override
|
||||
public boolean shouldSkipField(FieldAttributes f) {
|
||||
return f.getDeclaredClass().equals(ModelAdapter.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldSkipClass(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
.registerTypeAdapter(taskTagClassListType, new TaskTagDeserializer())
|
||||
.registerTypeAdapter(Boolean.class, new BooleanAsIntAdapter())
|
||||
.registerTypeAdapter(boolean.class, new BooleanAsIntAdapter())
|
||||
.registerTypeAdapter(skillListType, new SkillDeserializer())
|
||||
.registerTypeAdapter(ChecklistItem.class, new ChecklistItemSerializer())
|
||||
.registerTypeAdapter(TaskList.class, new TaskListDeserializer())
|
||||
.registerTypeAdapter(Purchases.class, new PurchasedDeserializer())
|
||||
.registerTypeAdapter(customizationListType, new CustomizationDeserializer())
|
||||
.registerTypeAdapter(tutorialStepListType, new TutorialStepListDeserializer())
|
||||
.registerTypeAdapter(faqArticleListType, new FAQArticleListDeserilializer())
|
||||
.registerTypeAdapter(Group.class, new GroupSerialization())
|
||||
.registerTypeAdapter(Date.class, new DateDeserializer())
|
||||
.registerTypeAdapter(itemDataListType, new ItemDataListDeserializer())
|
||||
.registerTypeAdapter(eggListType, new EggListDeserializer())
|
||||
.registerTypeAdapter(foodListType, new FoodListDeserializer())
|
||||
.registerTypeAdapter(hatchingPotionListType, new HatchingPotionListDeserializer())
|
||||
.registerTypeAdapter(questContentListType, new QuestListDeserializer())
|
||||
.registerTypeAdapter(petListType, new PetListDeserializer())
|
||||
.registerTypeAdapter(mountListType, new MountListDeserializer())
|
||||
.registerTypeAdapter(ChatMessage.class, new ChatMessageDeserializer())
|
||||
.registerTypeAdapter(Task.class, new TaskSerializer())
|
||||
.registerTypeAdapter(ContentResult.class, new ContentDeserializer())
|
||||
.registerTypeAdapter(FeedResponse.class, new FeedResponseDeserializer())
|
||||
.setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||
.create();
|
||||
return GsonConverterFactory.create(gson);
|
||||
return APIHelper.createGsonFactory();
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
|
|
|||
|
|
@ -232,6 +232,7 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
if (this.lastSync == null || (new Date().getTime() - this.lastSync.getTime()) > 180000) {
|
||||
if (this.apiHelper != null) {
|
||||
this.apiHelper.retrieveUser(true)
|
||||
.compose(apiHelper.configureApiCallObserver())
|
||||
.subscribe(new HabitRPGUserCallback(this), throwable -> {});
|
||||
this.checkMaintenance();
|
||||
}
|
||||
|
|
@ -672,6 +673,7 @@ public class MainActivity extends BaseActivity implements Action1<Throwable>, Ha
|
|||
if (resultCode == SELECT_CLASS_RESULT) {
|
||||
if (this.apiHelper != null) {
|
||||
this.apiHelper.retrieveUser(true)
|
||||
.compose(apiHelper.configureApiCallObserver())
|
||||
.subscribe(new HabitRPGUserCallback(this), throwable -> {});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -196,6 +196,7 @@ public class TasksFragment extends BaseMainFragment implements OnCheckedChangeLi
|
|||
|
||||
if (apiHelper != null) {
|
||||
apiHelper.retrieveUser(true)
|
||||
.compose(apiHelper.configureApiCallObserver())
|
||||
.subscribe(
|
||||
new HabitRPGUserCallback(activity),
|
||||
throwable -> stopAnimatingRefreshItem()
|
||||
|
|
|
|||
|
|
@ -30,8 +30,13 @@ public class PurchasedDeserializer implements JsonDeserializer<Purchases> {
|
|||
List<Customization> customizations = new ArrayList<Customization>();
|
||||
Purchases purchases = new Purchases();
|
||||
|
||||
List<Customization> existingCustomizations = new Select().from(Customization.class).queryList();
|
||||
|
||||
List<Customization> existingCustomizations;
|
||||
try {
|
||||
existingCustomizations = new Select().from(Customization.class).queryList();
|
||||
} catch (RuntimeException e) {
|
||||
//Tests don't have a database
|
||||
existingCustomizations = new ArrayList<>();
|
||||
}
|
||||
for (Customization customization : existingCustomizations) {
|
||||
if(object.has(customization.getType())) {
|
||||
JsonObject nestedObject = object.get(customization.getType()).getAsJsonObject();
|
||||
|
|
|
|||
|
|
@ -17,9 +17,15 @@ public class TaskTagDeserializer implements JsonDeserializer<List<TaskTag>> {
|
|||
@Override
|
||||
public List<TaskTag> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
|
||||
List<TaskTag> taskTags = new ArrayList<>();
|
||||
List<Tag> allTags = new Select()
|
||||
.from(Tag.class)
|
||||
.queryList();
|
||||
List<Tag> allTags;
|
||||
try {
|
||||
allTags = new Select()
|
||||
.from(Tag.class)
|
||||
.queryList();
|
||||
} catch (RuntimeException e) {
|
||||
//Tests don't have a database
|
||||
allTags = new ArrayList<>();
|
||||
}
|
||||
|
||||
for (JsonElement tagElement : json.getAsJsonArray()) {
|
||||
String tagId = tagElement.getAsString();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package com.habitrpg.android.habitica;
|
||||
|
||||
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.HabitRPGUser;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.Task;
|
||||
import com.magicmicky.habitrpgwrapper.lib.models.tasks.TaskList;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricGradleTestRunner;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import android.os.Build;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import rx.observers.TestSubscriber;
|
||||
|
||||
@Config(constants = BuildConfig.class, sdk = Build.VERSION_CODES.LOLLIPOP)
|
||||
@RunWith(RobolectricGradleTestRunner.class)
|
||||
public class APIHelperTests {
|
||||
|
||||
private APIHelper apiHelper;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
HostConfig hostConfig = new HostConfig(BuildConfig.BASE_URL,
|
||||
BuildConfig.PORT,
|
||||
BuildConfig.TEST_USER_KEY,
|
||||
BuildConfig.TEST_USER_ID);
|
||||
apiHelper = new APIHelper(APIHelper.createGsonFactory(), hostConfig);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLoadUserFromServer() {
|
||||
TestSubscriber<HabitRPGUser> testSubscriber = new TestSubscriber<>();
|
||||
apiHelper.apiService.getUser().subscribe(testSubscriber);
|
||||
testSubscriber.assertNoErrors();
|
||||
testSubscriber.assertCompleted();
|
||||
testSubscriber.assertValueCount(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLoadTasksFromServer() {
|
||||
TestSubscriber<TaskList> testSubscriber = new TestSubscriber<>();
|
||||
apiHelper.apiService.getTasks().subscribe(testSubscriber);
|
||||
testSubscriber.assertNoErrors();
|
||||
testSubscriber.assertCompleted();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldLoadCompleteUserFromServer() {
|
||||
TestSubscriber<HabitRPGUser> testSubscriber = new TestSubscriber<>();
|
||||
apiHelper.retrieveUser(true).subscribe(testSubscriber);
|
||||
testSubscriber.assertNoErrors();
|
||||
testSubscriber.assertCompleted();
|
||||
testSubscriber.assertValueCount(1);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue