/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.gtasks;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerFuture;
import android.content.Intent;
import android.os.Bundle;
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
import com.google.api.services.tasks.model.Tasks;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.ContextManager;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gtasks.api.GtasksApiUtilities;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.gtasks.auth.GtasksTokenValidator;
import com.todoroo.astrid.gtasks.sync.GtasksSyncService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.test.DatabaseTestCase;
public class GtasksSyncOnSaveTest extends DatabaseTestCase {
@Autowired TaskService taskService;
@Autowired GtasksSyncService gtasksSyncService;
@Autowired GtasksMetadataService gtasksMetadataService;
@Autowired GtasksPreferenceService gtasksPreferenceService;
private static GtasksInvoker gtasksService;
private boolean initialized = false;
private boolean bypassTests = false;
private static final String TEST_ACCOUNT = "sync_tester2@astrid.com";
private static String DEFAULT_LIST = "@default";
//Have to wait a long time because sync on save happens in another thread--currently no way to know when finished
private static final long TIME_TO_WAIT = 8000L;
public void testSyncOnCreate() throws IOException {
if(bypassTests) return;
performBasicCreation("");
}
private Task performBasicCreation(String appendToTitle) throws IOException {
String title = "Created task" + appendToTitle;
Task localTask = setupLocalTaskModel(title);
taskService.save(localTask);
AndroidUtilities.sleepDeep(TIME_TO_WAIT);
com.google.api.services.tasks.model.Task remoteTask = getRemoteTaskForLocalId(localTask.getId());
assertEquals(title, remoteTask.getTitle());
return localTask;
}
private Task setupLocalTaskModel(String title) {
Task localTask = new Task();
localTask.setValue(Task.TITLE, title);
return localTask;
}
private com.google.api.services.tasks.model.Task getRemoteTaskForLocalId(long localId) throws IOException {
Metadata gtasksMetadata = gtasksMetadataService.getTaskMetadata(localId);
assertNotNull(gtasksMetadata);
com.google.api.services.tasks.model.Task remoteTask = gtasksService.getGtask(DEFAULT_LIST, gtasksMetadata.getValue(GtasksMetadata.ID));
assertNotNull(remoteTask);
return remoteTask;
}
public void testSyncOnTitleUpdate() throws IOException {
if(bypassTests) return;
Task localTask = performBasicCreation("-title will change");
String newTitle = "Title has changed!";
localTask.setValue(Task.TITLE, newTitle);
taskService.save(localTask);
AndroidUtilities.sleepDeep(TIME_TO_WAIT);
com.google.api.services.tasks.model.Task remoteTask = getRemoteTaskForLocalId(localTask.getId());
assertEquals(newTitle, remoteTask.getTitle());
}
public void testSyncOnDueDateUpdate() throws IOException {
if(bypassTests) return;
Task localTask = performBasicCreation("-due date will change");
long dueDate = new Date(115, 2, 14).getTime();
localTask.setValue(Task.DUE_DATE, dueDate);
taskService.save(localTask);
AndroidUtilities.sleepDeep(TIME_TO_WAIT);
com.google.api.services.tasks.model.Task remoteTask = getRemoteTaskForLocalId(localTask.getId());
assertEquals(dueDate, GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0));
}
public void testSyncOnNotesUpdate() throws IOException {
if(bypassTests) return;
Task localTask = performBasicCreation("-notes will change");
String notes = "Noted!";
localTask.setValue(Task.NOTES, notes);
taskService.save(localTask);
AndroidUtilities.sleepDeep(TIME_TO_WAIT);
com.google.api.services.tasks.model.Task remoteTask = getRemoteTaskForLocalId(localTask.getId());
assertEquals(notes, remoteTask.getNotes());
}
public void testSyncOnCompleted() throws IOException {
if(bypassTests) return;
Task localTask = performBasicCreation("-will be completed");
long completionDate = (DateUtilities.now() / 1000L) * 1000L;
localTask.setValue(Task.COMPLETION_DATE, completionDate);
taskService.save(localTask);
AndroidUtilities.sleepDeep(TIME_TO_WAIT);
com.google.api.services.tasks.model.Task remoteTask = getRemoteTaskForLocalId(localTask.getId());
assertEquals("completed", remoteTask.getStatus());
assertEquals(completionDate, GtasksApiUtilities.gtasksCompletedTimeToUnixTime(remoteTask.getCompleted(), 0));
}
public void testSyncOnDeleted() throws IOException {
if(bypassTests) return;
Task localTask = performBasicCreation("-will be deleted");
long deletionDate = DateUtilities.now();
localTask.setValue(Task.DELETION_DATE, deletionDate);
taskService.save(localTask);
AndroidUtilities.sleepDeep(TIME_TO_WAIT);
com.google.api.services.tasks.model.Task remoteTask = getRemoteTaskForLocalId(localTask.getId());
assertTrue(remoteTask.getDeleted());
assertFalse(taskWithTitleExists(localTask.getValue(Task.TITLE)));
}
private boolean taskWithTitleExists(String title) throws IOException {
Tasks allTasks = gtasksService.getAllGtasksFromListId(DEFAULT_LIST, false, false, 0);
List<com.google.api.services.tasks.model.Task> items = allTasks.getItems();
if (items != null) {
for (com.google.api.services.tasks.model.Task t : items) {
if (t.getTitle().equals(title))
return true;
}
}
return false;
}
@Override
protected void setUp() throws Exception {
super.setUp();
if (!initialized) {
initializeTestService();
gtasksSyncService.initialize();
initialized = true;
}
setupTestList();
}
private void initializeTestService() throws Exception {
GoogleAccountManager manager = new GoogleAccountManager(ContextManager.getContext());
Account[] accounts = manager.getAccounts();
Account toUse = null;
for (Account a : accounts) {
if (a.name.equals(TEST_ACCOUNT)) {
toUse = a;
break;
}
}
if (toUse == null) {
if(accounts.length == 0) {
bypassTests = true;
return;
}
toUse = accounts[0];
}
Preferences.setString(GtasksPreferenceService.PREF_USER_NAME, toUse.name);
AccountManagerFuture<Bundle> accountManagerFuture = manager.manager.getAuthToken(toUse, "oauth2:https://www.googleapis.com/auth/tasks", true, null, null);
Bundle authTokenBundle = accountManagerFuture.getResult();
if (authTokenBundle.containsKey(AccountManager.KEY_INTENT)) {
Intent i = (Intent) authTokenBundle.get(AccountManager.KEY_INTENT);
ContextManager.getContext().startActivity(i);
return;
}
String authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN);
authToken = GtasksTokenValidator.validateAuthToken(getContext(), authToken);
gtasksPreferenceService.setToken(authToken);
gtasksService = new GtasksInvoker(authToken);
initialized = true;
}
private void setupTestList() throws Exception {
Tasks defaultListTasks = gtasksService.getAllGtasksFromListId(DEFAULT_LIST, false, false, 0);
List<com.google.api.services.tasks.model.Task> items = defaultListTasks.getItems();
if (items != null) {
for (com.google.api.services.tasks.model.Task t : items) {
gtasksService.deleteGtask(DEFAULT_LIST, t.getId());
}
}
}
}