Fixed bugs and improved sync unit tests

pull/14/head
Sam Bosley 14 years ago
parent fac40b89e2
commit aba9f2f154

@ -1,5 +1,6 @@
package com.todoroo.astrid.gtasks;
import java.util.HashSet;
import java.util.List;
import com.google.api.services.tasks.model.TaskList;
@ -27,8 +28,9 @@ public class GtasksListService {
}
private void readLists() {
if(lists != null)
if(lists != null) {
return;
}
TodorooCursor<StoreObject> cursor = storeObjectDao.query(Query.select(StoreObject.PROPERTIES).
where(StoreObjectCriteria.byType(GtasksList.TYPE)));
@ -85,10 +87,12 @@ public class GtasksListService {
public synchronized void updateLists(TaskLists remoteLists) {
readLists();
HashSet<Long> previousLists = new HashSet<Long>(lists.length);
for(StoreObject list : lists)
list.setValue(StoreObject.TYPE, "");
previousLists.add(list.getId());
List<TaskList> items = remoteLists.getItems();
StoreObject[] newLists = new StoreObject[items.size()];
for(int i = 0; i < items.size(); i++) {
com.google.api.services.tasks.model.TaskList remote = items.get(i);
@ -109,14 +113,15 @@ public class GtasksListService {
local.setValue(GtasksList.NAME, remote.getTitle());
local.setValue(GtasksList.ORDER, i);
storeObjectDao.persist(local);
previousLists.remove(local.getId());
newLists[i] = local;
}
lists = newLists;
// check for lists that aren't on remote server
for(StoreObject list : lists)
if(list.getValue(StoreObject.TYPE).equals(""))
storeObjectDao.delete(list.getId());
clearListCache();
for(Long listId : previousLists) {
storeObjectDao.delete(listId);
}
}
public StoreObject addNewList(com.google.api.services.tasks.model.TaskList newList) {

@ -28,6 +28,7 @@ import com.todoroo.astrid.gtasks.api.GtasksApiUtilities;
import com.todoroo.astrid.gtasks.api.GtasksInvoker;
import com.todoroo.astrid.gtasks.api.MoveRequest;
import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.TaskService;
public final class GtasksSyncService {
@ -98,7 +99,7 @@ public final class GtasksSyncService {
public void onModelUpdated(final Task model) {
if(model.checkAndClearTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC))
return;
if (gtasksPreferenceService.isOngoing()) //Don't try and sync changes that occur during a normal sync
if (gtasksPreferenceService.isOngoing() && !model.checkTransitory(TaskService.TRANS_REPEAT_COMPLETE)) //Don't try and sync changes that occur during a normal sync
return;
final ContentValues setValues = model.getSetValues();
if(setValues == null || !checkForToken())

@ -119,6 +119,10 @@ public class GtasksSyncV2Provider extends SyncV2Provider {
}
StoreObject[] lists = gtasksListService.getLists();
if (lists.length == 0) {
finishSync(callback);
return;
}
callback.incrementMax(25 * lists.length);
final AtomicInteger finisher = new AtomicInteger(lists.length);

@ -2,6 +2,7 @@ package com.todoroo.astrid.gtasks;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Semaphore;
import android.accounts.Account;
import android.accounts.AccountManager;
@ -133,11 +134,13 @@ public class GtasksNewSyncTest extends DatabaseTestCase {
localTask = refetchLocalTask(localTask);
assertTrue(String.format("Expected %s, was %s", new Date(startDate), new Date(localTask.getValue(Task.DUE_DATE))),
Math.abs(startDate - localTask.getValue(Task.DUE_DATE)) < 5000);
assertEquals(startDate, GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0));
long dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0);
long createdDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate);
assertEquals(startDate, createdDate);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new due date on local task
long newDueDate = new Date(116, 1, 8).getTime();
long newDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(116, 1, 8).getTime());
localTask.setValue(Task.DUE_DATE, newDueDate);
taskService.save(localTask);
@ -147,7 +150,9 @@ public class GtasksNewSyncTest extends DatabaseTestCase {
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newDueDate, localTask.getValue(Task.DUE_DATE).longValue());
assertEquals(newDueDate, GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0));
dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0);
createdDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate);
assertEquals(newDueDate, createdDate);
}
public void testDateChangedRemotely() throws Exception {
@ -161,12 +166,15 @@ public class GtasksNewSyncTest extends DatabaseTestCase {
localTask = refetchLocalTask(localTask);
assertTrue(String.format("Expected %s, was %s", new Date(startDate), new Date(localTask.getValue(Task.DUE_DATE))),
Math.abs(startDate - localTask.getValue(Task.DUE_DATE)) < 5000);
assertEquals(startDate, GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0));
long dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0);
long createdDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate);
assertEquals(startDate, createdDate);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new due date on remote task
long newDueDate = new Date(116, 1, 8).getTime();
remoteTask.setDue(GtasksApiUtilities.unixTimeToGtasksDueDate(newDueDate));
newDueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, newDueDate);
gtasksService.updateGtask(DEFAULT_LIST, remoteTask);
whenInvokeSync();
@ -175,7 +183,9 @@ public class GtasksNewSyncTest extends DatabaseTestCase {
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newDueDate, localTask.getValue(Task.DUE_DATE).longValue());
assertEquals(newDueDate, GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0));
dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0);
createdDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate);
assertEquals(newDueDate, createdDate);
}
@ -190,11 +200,13 @@ public class GtasksNewSyncTest extends DatabaseTestCase {
localTask = refetchLocalTask(localTask);
assertTrue(String.format("Expected %s, was %s", new Date(startDate), new Date(localTask.getValue(Task.DUE_DATE))),
Math.abs(startDate - localTask.getValue(Task.DUE_DATE)) < 5000);
assertEquals(startDate, GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0));
long dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0);
long createdDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate);
assertEquals(startDate, createdDate);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new due date on remote task first
long newLocalDate = new Date(128, 5, 11).getTime();
long newLocalDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, new Date(128, 5, 11).getTime());
long newRemoteDate = new Date(121, 5, 25).getTime();
remoteTask.setDue(GtasksApiUtilities.unixTimeToGtasksDueDate(newRemoteDate));
@ -211,7 +223,9 @@ public class GtasksNewSyncTest extends DatabaseTestCase {
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newLocalDate, localTask.getValue(Task.DUE_DATE).longValue());
assertEquals(newLocalDate, GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0));
dueDate = GtasksApiUtilities.gtasksDueTimeToUnixTime(remoteTask.getDue(), 0);
createdDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY, dueDate);
assertEquals(newLocalDate, createdDate);
}
public void DISABLED_testDateChangedBoth_ChooseRemote() throws Exception {
@ -255,7 +269,11 @@ public class GtasksNewSyncTest extends DatabaseTestCase {
*/
private Task createLocalTaskForDateTests(String addToTitle) {
Task localTask = createNewLocalTask("Due date will change" + addToTitle);
long dueDate = new Date(115, 2, 14).getTime();
Date date = new Date(115, 2, 14);
date.setHours(12);
date.setMinutes(0);
date.setSeconds(0);
long dueDate = date.getTime();
localTask.setValue(Task.DUE_DATE, dueDate);
taskService.save(localTask);
@ -473,18 +491,15 @@ public class GtasksNewSyncTest extends DatabaseTestCase {
//Perform a synchronization
private void whenInvokeSync() {
final Semaphore sema = new Semaphore(0);
GtasksSyncV2Provider.getInstance().synchronizeActiveTasks(true, new SyncResultCallbackAdapter() {
@Override
public void finished() {
synchronized(GtasksNewSyncTest.this) {
GtasksNewSyncTest.this.notify();
}
sema.release();
}
});
try {
synchronized(this) {
wait();
}
sema.acquire();
} catch (InterruptedException e) {
fail("Interrupted while waiting for sync to finish");
}

@ -1,857 +0,0 @@
package com.todoroo.astrid.producteev;
import java.util.Date;
import org.json.JSONArray;
import org.json.JSONObject;
import com.timsu.astrid.R;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
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.producteev.api.ApiUtilities;
import com.todoroo.astrid.producteev.api.ProducteevInvoker;
import com.todoroo.astrid.producteev.sync.ProducteevDataService;
import com.todoroo.astrid.producteev.sync.ProducteevSyncProvider;
import com.todoroo.astrid.producteev.sync.ProducteevTask;
import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.test.DatabaseTestCase;
@SuppressWarnings("nls")
public class ProducteevSyncTest extends DatabaseTestCase {
private static final String TEST_USER = "sync_tester@astrid.com";
private static final String TEST_PASSWORD = "wonky1234";
private static final String TEST_USER_2 = "sync_tester2@astrid.com";
private static ProducteevSyncProvider syncProvider;
private static ProducteevInvoker invoker;
private static final long TIME_BETWEEN_SYNCS = 3000l;
private boolean initialized = false;
private int dashboardId;
@Autowired TaskService taskService;
@Autowired MetadataService metadataService;
@Autowired TagService tagService;
private ProducteevDataService producteevDataService;
/*
* Basic creation tests
*/
public void testTaskCreatedLocally() {
String title = "Astrid task 1";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
assertTaskExistsRemotely(localTask, title);
}
public void testTaskCreatedRemotely() {
JSONObject remoteTask = createNewRemoteTask("Producteev task 1");
whenInvokeSync();
assertTaskExistsLocally(remoteTask);
}
/*
* Title editing tests
*/
public void testNameChangedLocally() {
String title = "Astrid task 2";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new title on local task
String newTitle = "Astrid task 2 edited";
localTask.setValue(Task.TITLE, newTitle);
taskService.save(localTask);
whenInvokeSync();
//Refetch remote task and assert that both local and remote titles match expected
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newTitle, localTask.getValue(Task.TITLE));
assertEquals(newTitle, getRemoteTitle(remoteTask));
}
public void testNameChangedRemotely() throws Exception {
String title = "Astrid task 3";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new title on remote task
String newRemoteTitle = "Task 3 edited on producteev";
invoker.tasksSetTitle(getRemoteId(remoteTask), newRemoteTitle);
whenInvokeSync();
//Refetch local/remote tasks, assert that both titles match expected
remoteTask = refetchRemoteTask(remoteTask);
localTask = refetchLocalTask(localTask);
assertEquals(newRemoteTitle, getRemoteTitle(remoteTask));
assertEquals(newRemoteTitle, localTask.getValue(Task.TITLE));
}
/*
* Tests for note creation
*/
public void testNoteChangedLocally() {
String title = "Astrid task 4";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new note on local task
String newNote1 = "This is a new note";
localTask.setValue(Task.NOTES, newNote1);
taskService.save(localTask);
whenInvokeSync();
//Refetch and assert that the note has been pushed to producteev
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newNote1, getFirstNote(remoteTask));
assertEquals(newNote1, localTask.getValue(Task.NOTES));
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Create a new note locally
String newNote2 = "This is a second note";
localTask.setValue(Task.NOTES, newNote2);
taskService.save(localTask);
whenInvokeSync();
//Refetch and assert that new note has been pushed and old note is still there
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newNote2, getFirstNote(remoteTask));
assertEquals(newNote1, getSecondNote(remoteTask));
assertEquals(newNote2, localTask.getValue(Task.NOTES));
}
public void testNoteChangedRemotely() throws Exception {
String title = "Astrid task 5";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Create a new remote note
String newNote1 = "Note added in producteev";
invoker.tasksNoteCreate(getRemoteId(remoteTask), "Note added in producteev");
whenInvokeSync();
//Refetch both and assert new note exists, local note does not (?)
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newNote1, getFirstNote(remoteTask));
assertEquals("", localTask.getValue(Task.NOTES));
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Create a second note remotely
String newNote2 = "Second producteev note";
invoker.tasksNoteCreate(getRemoteId(remoteTask), newNote2);
whenInvokeSync();
//Refetch both and assert two remote notes exist, local note does not (?)
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newNote2, getFirstNote(remoteTask));
assertEquals(newNote1,getSecondNote(remoteTask));
assertEquals("", localTask.getValue(Task.NOTES));
}
/*
* Helper methods for notes
*/
private String getFirstNote(JSONObject remoteTask) {
return getNoteAtIndex(remoteTask, 0);
}
private String getSecondNote(JSONObject remoteTask) {
return getNoteAtIndex(remoteTask, 1);
}
private String getNoteAtIndex(JSONObject remoteTask, int index) {
String result = null;
try {
result = getRemoteNotesArray(remoteTask).getJSONObject(index).getJSONObject("note").getString("message");
} catch (Exception e) {
fail("Failed to extract note from notes array");
}
return result;
}
/*
* Due date editing tests
*/
public void testDateChangedLocally() {
Task localTask = createLocalTaskForDateTests(" locally");
String title = localTask.getValue(Task.TITLE);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
//Assert the originally set due date matches between local/remote tasks
assertEquals(localTask.getValue(Task.DUE_DATE).longValue(), getRemoteDueDate(remoteTask));
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new due date on local task
long newDueDate = new Date(116, 1, 8).getTime();
localTask.setValue(Task.DUE_DATE, newDueDate);
taskService.save(localTask);
whenInvokeSync();
//Refetch remote task and assert that both tasks match expected due date
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newDueDate, localTask.getValue(Task.DUE_DATE).longValue());
assertEquals(newDueDate, getRemoteDueDate(remoteTask));
}
public void testDateChangedRemotely() throws Exception {
Task localTask = createLocalTaskForDateTests(" remotely");
String title = localTask.getValue(Task.TITLE);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
//Assert the originally set due date matches between local/remote tasks
assertEquals(localTask.getValue(Task.DUE_DATE).longValue(), getRemoteDueDate(remoteTask));
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new due date on remote task
long newDueDate = new Date(116, 1, 8).getTime();
invoker.tasksSetDeadline(getRemoteId(remoteTask), ApiUtilities.unixTimeToProducteev(newDueDate), 0);
whenInvokeSync();
//Refetch remote/local tasks and assert that due dates match expected due date
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newDueDate, getRemoteDueDate(remoteTask));
assertEquals(newDueDate, localTask.getValue(Task.DUE_DATE).longValue());
}
public void testDateChangedBoth_ChooseLocal() throws Exception{
Task localTask = createLocalTaskForDateTests(" in both");
String title = localTask.getValue(Task.TITLE);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
assertEquals(localTask.getValue(Task.DUE_DATE).longValue(), getRemoteDueDate(remoteTask));
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new due date on remote task first
long newLocalDate = new Date(128, 5, 11).getTime();
long newRemoteDate = new Date(121, 5, 25).getTime();
invoker.tasksSetDeadline(getRemoteId(remoteTask), ApiUtilities.unixTimeToProducteev(newRemoteDate), 0);
//Sleep between updates to tasks to establish which should be dominant in sync
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new local date second
localTask.setValue(Task.DUE_DATE, newLocalDate);
taskService.save(localTask);
whenInvokeSync();
//Refetch both and assert that due dates match the one we set to local (more recent)
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newLocalDate, localTask.getValue(Task.DUE_DATE).longValue());
assertEquals(newLocalDate, getRemoteDueDate(remoteTask));
}
public void DISABLED_testDateChangedBoth_ChooseRemote() throws Exception { //This test currently fails--known bug/expected behavior?
Task localTask = createLocalTaskForDateTests(" in both");
String title = localTask.getValue(Task.TITLE);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
assertEquals(localTask.getValue(Task.DUE_DATE).longValue(), getRemoteDueDate(remoteTask));
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new local date first
long newLocalDate = new Date(128, 5, 11).getTime();
long newRemoteDate = new Date(121, 5, 25).getTime();
localTask.setValue(Task.DUE_DATE, newLocalDate);
taskService.save(localTask);
//Sleep between updates to tasks to establish which should be dominant in sync
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new remote date second
invoker.tasksSetDeadline(getRemoteId(remoteTask), ApiUtilities.unixDateToProducteev(newRemoteDate), 0);
whenInvokeSync();
//Refetch both and assert that dates match the one we set to remote (more recent)
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newRemoteDate, localTask.getValue(Task.DUE_DATE).longValue());
assertEquals(newRemoteDate, getRemoteDueDate(remoteTask));
}
/*
* Helper method for due date methods
*/
private Task createLocalTaskForDateTests(String addToTitle) {
Task localTask = createNewLocalTask("Due date will change" + addToTitle);
long dueDate = new Date(115, 2, 14).getTime();
localTask.setValue(Task.DUE_DATE, dueDate);
taskService.save(localTask);
return localTask;
}
/*
* Priority editing tests
*/
public void testPriorityChangedLocally() {
String title = "Priority will change locally";
Task localTask = createNewLocalTask(title);
localTask.setValue(Task.IMPORTANCE, Task.IMPORTANCE_MOST);
taskService.save(localTask);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
assertEquals(expectedNumStars(Task.IMPORTANCE_MOST), getStars(remoteTask));
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new local importance
int newImportance = Task.IMPORTANCE_LEAST;
localTask.setValue(Task.IMPORTANCE, newImportance);
taskService.save(localTask);
whenInvokeSync();
//Refetch and assert both match expected priority/# of stars
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(newImportance, localTask.getValue(Task.IMPORTANCE).intValue());
assertEquals(expectedNumStars(newImportance), getStars(remoteTask));
}
public void testPriorityChangedRemotely() throws Exception {
String title = "Priority will change remotely";
Task localTask = createNewLocalTask(title);
localTask.setValue(Task.IMPORTANCE, Task.IMPORTANCE_MUST_DO);
taskService.save(localTask);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
assertEquals(expectedNumStars(Task.IMPORTANCE_MUST_DO), getStars(remoteTask));
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new remote # of stars
int numStars = 0;
invoker.tasksSetStar(getRemoteId(remoteTask), numStars);
whenInvokeSync();
//Refetch and assert both match expected priority/# of stars
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(numStars, getStars(remoteTask));
assertEquals(expectedPriority(numStars), localTask.getValue(Task.IMPORTANCE).intValue());
}
/*
* Helper methods for priority tests
*/
private int getStars(JSONObject remoteTask) {
int numStars = -1;
try {
numStars = remoteTask.getInt("star");
} catch (Exception e){
fail("Failed to extract stars count from remote object");
}
return numStars;
}
private int expectedNumStars(int importance) {
return 5 - importance;
}
private int expectedPriority(int numStars) {
return 5 - numStars;
}
/*
* Tests for label creation
*/
public void testLabelCreatedLocally() throws Exception {
String title = "This task will get a tag";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set a new local tag on the task
Metadata newTagData = new Metadata();
newTagData.setValue(Metadata.TASK, localTask.getId());
newTagData.setValue(Metadata.KEY, TagService.KEY);
String newTag = "This is a new tag";
newTagData.setValue(TagService.TAG, newTag);
metadataService.save(newTagData);
assertLocalTaskHasTag(localTask, newTag);
localTask.setValue(Task.MODIFICATION_DATE, DateUtilities.now());
taskService.save(localTask);
whenInvokeSync();
//Refetch remote; assert the label exists remotely both in general and on the remote task
remoteTask = refetchRemoteTask(remoteTask);
assertLocalTaskHasTag(localTask, newTag);
assertRemoteTaskHasLabel(remoteTask, newTag);
assertRemoteLabelListHasLabel(newTag);
}
public void testLabelCreatedRemotely() throws Exception {
String title = "This task will get a tag";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Remotely create a new label and set it to the remote task
String newTag = "Remote label";
JSONObject newLabel = invoker.labelsCreate(dashboardId, newTag).getJSONObject("label");
long labelId = newLabel.getLong("id_label");
invoker.tasksChangeLabel(getRemoteId(remoteTask), labelId);
whenInvokeSync();
//Refetch and assert that the remote task still has the label and that the local task does too
localTask = refetchLocalTask(localTask);
remoteTask = refetchRemoteTask(remoteTask);
assertRemoteLabelListHasLabel(newTag);
assertRemoteTaskHasLabel(remoteTask, newTag);
invoker.labelsDelete(labelId); //Cleanup the test account by deleting the new remote label
assertLocalTaskHasTag(localTask, newTag);
}
/*
* Helper methods for tag/label tests
*/
private void assertLocalTaskHasTag(Task localTask, String tag) {
TodorooCursor<Metadata> tags = tagService.getTags(localTask.getId());
boolean foundTag = false;
try {
assertTrue(tags.getCount() > 0);
int length = tags.getCount();
Metadata m = new Metadata();
for (int i = 0; i < length; i++) {
tags.moveToNext();
m.readFromCursor(tags);
if(tag.equals(m.getValue(TagService.TAG))) {
foundTag = true;
break;
}
}
if (!foundTag) throw new Exception();
} catch (Exception e) {
fail("Local task does not have tag " + tag);
} finally {
tags.close();
}
}
private void assertRemoteTaskHasLabel(JSONObject remoteTask, String label) {
boolean foundLabel = false;
try {
JSONArray labels = invoker.tasksLabels(getRemoteId(remoteTask));
foundLabel = searchForLabel(labels, label);
} catch (Exception e){
fail("Couldn't extract labels from task");
}
if (!foundLabel) fail("Remote task did not have label " + label);
}
private void assertRemoteLabelListHasLabel(String label) {
boolean foundLabel = false;
try {
JSONArray labels = invoker.labelsShowList(dashboardId, null);
System.err.println(labels);
foundLabel = searchForLabel(labels, label);
} catch (Exception e) {
fail("Couldn't parse label list");
}
if (!foundLabel) fail("Remote list did not have label " + label);
}
private boolean searchForLabel(JSONArray labels, String toFind) throws Exception {
for (int i = 0; i < labels.length(); i++) {
String currLabel = labels.getJSONObject(i).getJSONObject("label").getString("title");
if (currLabel.equals(toFind)) {
return true;
}
}
return false;
}
/*
* Assignment editing tests
*/
public void testAssignmentChangedLocally() throws Exception {
String title = "This will get assigned to sync_tester2 locally";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set the colleague id locally to be sync_tester2
Metadata producteevData = producteevDataService.getTaskMetadata(localTask.getId());
producteevData.setValue(Metadata.TASK, localTask.getId());
producteevData.setValue(Metadata.KEY, ProducteevTask.METADATA_KEY);
long colleagueId = getColleagueId();
producteevData.setValue(ProducteevTask.RESPONSIBLE_ID, colleagueId);
metadataService.save(producteevData);
localTask.setValue(Task.MODIFICATION_DATE, DateUtilities.now());
taskService.save(localTask);
assertEquals(colleagueId, producteevData.getValue(ProducteevTask.RESPONSIBLE_ID).longValue());
whenInvokeSync();
//Get local metadata for the task and assert that the responsible id matches the expected colleague id
Metadata localMetadata = producteevDataService.getTaskMetadata(localTask.getId());
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(colleagueId, localMetadata.getValue(ProducteevTask.RESPONSIBLE_ID).longValue());
assertEquals(colleagueId, getRemoteResponsible(remoteTask));
//Assert that the email of that person is in fact sync_tester2
assertEquals(TEST_USER_2, getColleagueEmail(colleagueId));
}
public void testAssignmentChangedRemotely() throws Exception {
String title = "This will get assigned to sync_tester2 remotely";
Task localTask = createNewLocalTask(title);
whenInvokeSync();
JSONObject remoteTask = assertTaskExistsRemotely(localTask, title);
AndroidUtilities.sleepDeep(TIME_BETWEEN_SYNCS);
//Set new responsible id (the id for sync_tester)
long colleagueId = getColleagueId();
invoker.tasksSetResponsible(getRemoteId(remoteTask), getColleagueId());
whenInvokeSync();
//Get local metadata for the task and assert that the responsible id matches the expected colleague id
Metadata localMetadata = producteevDataService.getTaskMetadata(localTask.getId());
remoteTask = refetchRemoteTask(remoteTask);
assertEquals(colleagueId, localMetadata.getValue(ProducteevTask.RESPONSIBLE_ID).longValue());
assertEquals(colleagueId, getRemoteResponsible(remoteTask));
//Assert that the email of that person is in fact sync_tester2
assertEquals(TEST_USER_2, getColleagueEmail(colleagueId));
}
/*
* Helper methods for assignment tests
*/
private long getColleagueId() {
long id = -1;
try {
JSONArray colleagues = invoker.usersColleagues().getJSONArray("colleagues");
JSONObject colleagueObj = colleagues.getJSONObject(0).getJSONObject("user");
id = colleagueObj.getLong("id_user");
} catch (Exception e) {
fail("Unable to extract colleague id");
}
return id;
}
private long getRemoteResponsible(JSONObject remoteTask) {
long responsibleId = -1;
try {
responsibleId = remoteTask.getLong("id_responsible");
} catch (Exception e) {
fail("Unable to extract responsible id field");
}
return responsibleId;
}
private String getColleagueEmail(long colleagueId) {
String email = null;
try {
JSONObject user = invoker.usersView(colleagueId).getJSONObject("user");
email = user.getString("email");
} catch (Exception e) {
fail("Failed to extract colleague email");
}
return email;
}
/*
* Helper method that looks for a local task's remote counterpart, asserts the titles
* are both what is expected, and returns the remote JSON object
*/
private JSONObject assertTaskExistsRemotely(Task task, String expectedTitle) {
long remoteId = remoteIdForTask(task);
JSONObject remoteTask = remoteTaskWithId(remoteId);
assertNotNull(remoteTask);
assertEquals(expectedTitle, task.getValue(Task.TITLE));
assertEquals(expectedTitle, getRemoteTitle(remoteTask));
return remoteTask;
}
/*
* Extracts the remote id from a remote task JSON object
*/
private long getRemoteId(JSONObject remoteTask) {
long remoteId = 0;
try {
remoteId = remoteTask.getLong("id_task");
} catch (Exception e) {
fail("Remote task object did not contain id_task field");
}
return remoteId;
}
/*
* Extracts the remote due date from a remote task JSON object
*/
private long getRemoteDueDate(JSONObject remoteTask) {
long remoteDueDate = 0;
try {
remoteDueDate = ApiUtilities.producteevToUnixTime(remoteTask.getString("deadline"), 0);
} catch (Exception e) {
fail("Couldn't fetch time from remote task");
}
return remoteDueDate;
}
/*
* Extracts the remote title from a remote task JSON object
*/
private String getRemoteTitle(JSONObject remoteTask) {
String result = null;
try {
result = ApiUtilities.decode(remoteTask.getString("title"));
} catch (Exception e) {
fail("Remote task object did not contain title field");
}
return result;
}
/*
* Extract the remote notes array from a remote task JSON object
*/
private JSONArray getRemoteNotesArray(JSONObject remoteTask) {
JSONArray result = null;
try {
result = remoteTask.getJSONArray("notes");
} catch (Exception e) {
fail("Remote task object did not contain notes field");
}
return result;
}
/*
* Looks up and returns a remote task JSON object with the given remote id
*/
private JSONObject remoteTaskWithId(long remoteId) {
JSONObject remoteTask = null;
try {
remoteTask = invoker.tasksView(remoteId).getJSONObject("task");
assertNotNull(remoteTask);
} catch (Exception e) {
fail("Failed to find remote task " + remoteId);
}
return remoteTask;
}
/*
* Look up a remote tasks's corresponding local task and return the local task object
*/
private Task assertTaskExistsLocally(JSONObject remoteTask) {
long localId = localIdForTask(remoteTask);
//Fetch the local task from the database
Task localTask = taskService.fetchById(localId, Task.PROPERTIES);
assertNotNull(localTask);
assertEquals(getRemoteTitle(remoteTask), localTask.getValue(Task.TITLE));
return localTask;
}
/*
* Maps a local task to the corresponding remote task's id
*/
private long remoteIdForTask(Task t) {
return producteevDataService.getTaskMetadata(t.getId()).getValue(ProducteevTask.ID);
}
/*
* Maps a remote task to the corresponding local task's id
*/
private long localIdForTask(JSONObject remoteTask) {
Long remoteId = 0l;
try {
remoteId = remoteTask.getLong("id_task");
} catch (Exception e) {
fail("Couldn't extract id from remote task object");
}
TodorooCursor<Metadata> cursor = metadataService.query(Query.select(Metadata.TASK).
where(Criterion.and(Metadata.KEY.eq(ProducteevTask.METADATA_KEY), ProducteevTask.ID.eq(remoteId))));
try {
assertEquals(1, cursor.getCount());
cursor.moveToFirst();
return cursor.get(Metadata.TASK);
} finally {
cursor.close();
}
}
/*
* Start synchronizing with Producteev
*/
private void whenInvokeSync() {
syncProvider.synchronize(getContext());
}
/*
* Create and save a new local task with the given title
*/
private Task createNewLocalTask(String title) {
Task task = new Task();
task.setValue(Task.TITLE, title);
taskService.save(task);
return task;
}
/*
* Create a new remote task with the given title
*/
private JSONObject createNewRemoteTask(String title) {
JSONObject toReturn = null;
try {
toReturn = invoker.tasksCreate(title, null,
null, null, null, null, null).getJSONObject("task");
System.err.println(toReturn);
} catch (Exception e) {
e.printStackTrace();
fail("Failed to create remote task");
}
return toReturn;
}
/*
* Refetch and return local task object from the database
*/
private Task refetchLocalTask(Task localTask) {
return taskService.fetchById(localTask.getId(), Task.PROPERTIES);
}
/*
* Refetch and return a remote task with the same id
*/
private JSONObject refetchRemoteTask(JSONObject remoteTask) {
return remoteTaskWithId(getRemoteId(remoteTask));
}
@Override
protected void setUp() throws Exception {
super.setUp();
Preferences.setString(ProducteevUtilities.PREF_SERVER_LAST_SYNC, null);
if (!initialized) {
initializeTestService();
}
clearAllRemoteTasks();
}
private void initializeTestService() throws Exception {
//Set the username and password for the service
Preferences.setString(R.string.producteev_PPr_email, TEST_USER);
Preferences.setString(R.string.producteev_PPr_password, TEST_PASSWORD);
invoker = ProducteevSyncProvider.getInvoker();
producteevDataService = ProducteevDataService.getInstance();
//clear dashboard cache since database was empty
producteevDataService.updateDashboards(new JSONArray());
invoker.authenticate(TEST_USER, TEST_PASSWORD);
//Get the id for the default dashboard (needed for some tests)
dashboardId = invoker.dashboardsShowList(null).getJSONObject(0).getJSONObject("dashboard").getInt("id_dashboard");
syncProvider = new ProducteevSyncProvider();
initialized = true;
}
/*
* Deletes all the remote tasks on the default dashboard to ensure
* clean tests.
*/
private void clearAllRemoteTasks() {
try {
JSONArray remoteTasks = invoker.tasksShowList(null, null);
for (int i = 0; i < remoteTasks.length(); i++) {
JSONObject task = remoteTasks.getJSONObject(i).getJSONObject("task");
invoker.tasksDelete(getRemoteId(task));
}
} catch (Exception e) {
fail("Failed to clear remote tasks before tests");
}
}
}

@ -120,7 +120,7 @@ abstract public class AbstractSyncRepeatTests<REMOTE_MODEL> extends DatabaseTest
Task t = new Task();
t.setValue(Task.TITLE, title);
long dueDate = DateUtilities.now() + DateUtilities.ONE_DAY * 3;
dueDate = (dueDate / 1000L) * 1000L; // Strip milliseconds
dueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, (dueDate / 1000L) * 1000L); // Strip milliseconds
if (fromCompletion)
t.setFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION, true);
@ -150,16 +150,10 @@ abstract public class AbstractSyncRepeatTests<REMOTE_MODEL> extends DatabaseTest
Task task = new Task(cursor);
System.err.println("Task: " + task.getValue(Task.TITLE) + ", due: " + task.getValue(Task.DUE_DATE));
}
assertEquals(2, cursor.getCount());
assertEquals(1, cursor.getCount());
cursor.moveToFirst();
t.readFromCursor(cursor);
assertEquals(title, t.getValue(Task.TITLE));
assertEquals(dueDate, (long)t.getValue(Task.DUE_DATE));
assertTrue(t.isCompleted());
cursor.moveToNext();
t.readFromCursor(cursor);
assertEquals(title, t.getValue(Task.TITLE));
assertFalse(t.isCompleted());
long newDueDate = t.getValue(Task.DUE_DATE);
@ -191,7 +185,7 @@ abstract public class AbstractSyncRepeatTests<REMOTE_MODEL> extends DatabaseTest
}
Weekday[] allWeekdays = Weekday.values();
result -= DateUtilities.ONE_DAY;
// result -= DateUtilities.ONE_DAY;
Date date = new Date(result);
Weekday start = allWeekdays[date.getDay()];
int i;
@ -259,7 +253,8 @@ abstract public class AbstractSyncRepeatTests<REMOTE_MODEL> extends DatabaseTest
originalCompleteDate.setYear(originalCompleteDate.getYear() + interval);
expectedTime = originalCompleteDate.getTime();
}
return expectedTime;
return Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, expectedTime);
}
private void testFromDueDate(boolean completeBefore, Frequency frequency, String title) {
@ -372,7 +367,7 @@ abstract public class AbstractSyncRepeatTests<REMOTE_MODEL> extends DatabaseTest
testFromCompletionDate(false, Frequency.YEARLY, "yearly-after");
}
private void testAdvancedWeeklyFromCompleteDate(boolean completeBefore, String title) {
private void testAdvancedWeekly(boolean fromCompletion, boolean completeBefore, String title) {
RRule rrule = new RRule();
rrule.setFreq(Frequency.WEEKLY);
@ -382,25 +377,25 @@ abstract public class AbstractSyncRepeatTests<REMOTE_MODEL> extends DatabaseTest
weekdays.add(new WeekdayNum(0, Weekday.MO));
weekdays.add(new WeekdayNum(0, Weekday.WE));
rrule.setByDay(weekdays);
testRepeating(completeBefore, true, rrule, Frequency.WEEKLY, title);
testRepeating(completeBefore, fromCompletion, rrule, Frequency.WEEKLY, title);
}
// disabled until test can be fixed
public void testAdvancedRepeatWeeklyFromDueDateCompleteBefore() {
// testAdvancedWeeklyFromDueDate(true, "advanced-weekly-before");
testAdvancedWeekly(false, true, "advanced-weekly-before");
}
public void testAdvancedRepeatWeeklyFromDueDateCompleteAfter() {
// testAdvancedWeeklyFromDueDate(false, "advanced-weekly-after");
testAdvancedWeekly(false, false, "advanced-weekly-after");
}
public void testAdvancedRepeatWeeklyFromCompleteDateCompleteBefore() {
testAdvancedWeeklyFromCompleteDate(true, "advanced-weekly-before");
testAdvancedWeekly(true, true, "advanced-weekly-before");
}
public void testAdvancedRepeatWeeklyFromCompleteDateCompleteAfter() {
testAdvancedWeeklyFromCompleteDate(false, "advanced-weekly-after");
testAdvancedWeekly(true, false, "advanced-weekly-after");
}
}

@ -2,6 +2,7 @@ package com.todoroo.astrid.sync.repeats;
import java.io.IOException;
import java.util.ArrayList;
import java.util.concurrent.Semaphore;
import org.json.JSONArray;
import org.json.JSONObject;
@ -95,18 +96,15 @@ public class RepeatTestsActFmSync extends AbstractSyncRepeatTests<Task> {
@Override
protected void waitAndSync() {
AndroidUtilities.sleepDeep(3000L);
final Semaphore sema = new Semaphore(0);
new ActFmSyncV2Provider().synchronizeActiveTasks(true, new SyncResultCallbackAdapter() {
@Override
public void finished() {
synchronized(RepeatTestsActFmSync.this) {
RepeatTestsActFmSync.this.notify();
}
sema.release();
}
});
try {
synchronized(this) {
wait();
}
sema.acquire();
} catch (InterruptedException e) {
fail("Interrupted while waiting for sync to finish");
}
@ -136,7 +134,7 @@ public class RepeatTestsActFmSync extends AbstractSyncRepeatTests<Task> {
Task t = new Task();
t.setValue(Task.TITLE, title);
long dueDate = DateUtilities.now() + DateUtilities.ONE_DAY * 3;
dueDate = (dueDate / 1000L) * 1000L; // Strip milliseconds
dueDate = Task.createDueDate(Task.URGENCY_SPECIFIC_DAY_TIME, (dueDate / 1000L) * 1000L); // Strip milliseconds
if (fromCompletion)
t.setFlag(Task.FLAGS, Task.FLAG_REPEAT_AFTER_COMPLETION, true);

@ -3,6 +3,7 @@ package com.todoroo.astrid.sync.repeats;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Semaphore;
import android.accounts.Account;
import android.accounts.AccountManager;
@ -25,6 +26,7 @@ import com.todoroo.astrid.gtasks.GtasksPreferenceService;
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.gtasks.sync.GtasksSyncV2Provider;
import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.sync.SyncResultCallbackAdapter;
@ -34,6 +36,7 @@ public class RepeatTestsGtasksSync extends AbstractSyncRepeatTests<com.google.ap
@Autowired MetadataService metadataService;
@Autowired GtasksMetadataService gtasksMetadataService;
@Autowired GtasksPreferenceService gtasksPreferenceService;
@Autowired GtasksSyncService gtasksSyncService;
private static final String TEST_ACCOUNT = "sync_tester2@astrid.com";
public static final String DEFAULT_LIST = "@default";
@ -49,6 +52,7 @@ public class RepeatTestsGtasksSync extends AbstractSyncRepeatTests<com.google.ap
if (!initialized) {
initializeTestService();
}
gtasksSyncService.initialize();
setupTestList();
}
@ -56,22 +60,20 @@ public class RepeatTestsGtasksSync extends AbstractSyncRepeatTests<com.google.ap
@Override
protected void waitAndSync() {
AndroidUtilities.sleepDeep(3000L);
final Semaphore sema = new Semaphore(0);
GtasksSyncV2Provider.getInstance().synchronizeActiveTasks(true, new SyncResultCallbackAdapter() {
@Override
public void finished() {
synchronized(RepeatTestsGtasksSync.this) {
RepeatTestsGtasksSync.this.notify();
}
sema.release();
}
});
try {
synchronized(this) {
wait();
}
sema.acquire();
} catch (InterruptedException e) {
fail("Interrupted while waiting for sync to finish");
}
AndroidUtilities.sleepDeep(3000L);
gtasksSyncService.waitUntilEmpty();
}
@Override
@ -96,7 +98,7 @@ public class RepeatTestsGtasksSync extends AbstractSyncRepeatTests<com.google.ap
expected.setSeconds(0);
long gtasksTime = GtasksApiUtilities.gtasksDueTimeToUnixTime(remote.getDue(), 0);
assertEquals(expected.getTime(), gtasksTime);
assertTimesMatch(expected.getTime(), gtasksTime);
return remote;
}
@ -116,8 +118,6 @@ public class RepeatTestsGtasksSync extends AbstractSyncRepeatTests<com.google.ap
assertNotNull(remote);
assertEquals(t.getValue(Task.TITLE), remote.getTitle());
assertEquals("completed", remote.getStatus());
}
private void initializeTestService() throws Exception {

@ -31,19 +31,4 @@ public class RepeatTestsGtasksSyncRemote extends RepeatTestsGtasksSync {
}
return completionDate;
}
@Override
protected long computeNextDueDateFromDate(long fromDate, RRule rrule, boolean fromCompletion) {
long expectedDate = super.computeNextDueDateFromDate(fromDate, rrule, fromCompletion);
Frequency freq = rrule.getFreq();
if (fromCompletion && (freq == Frequency.HOURLY || freq == Frequency.MINUTELY)) {
long millis = (freq == Frequency.HOURLY ? DateUtilities.ONE_HOUR : DateUtilities.ONE_MINUTE);
Date rounded = new Date(expectedDate);
rounded.setHours(0);
rounded.setMinutes(0);
rounded.setSeconds(0);
return rounded.getTime() + rrule.getInterval() * millis;
} else {
return expectedDate;
}
}
}

@ -1,128 +0,0 @@
package com.todoroo.astrid.sync.repeats;
import org.json.JSONArray;
import org.json.JSONObject;
import com.timsu.astrid.R;
import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.utility.AndroidUtilities;
import com.todoroo.andlib.utility.Preferences;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.producteev.ProducteevUtilities;
import com.todoroo.astrid.producteev.api.ApiUtilities;
import com.todoroo.astrid.producteev.api.ProducteevInvoker;
import com.todoroo.astrid.producteev.sync.ProducteevDataService;
import com.todoroo.astrid.producteev.sync.ProducteevSyncProvider;
import com.todoroo.astrid.producteev.sync.ProducteevTask;
import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.tags.TagService;
public class RepeatTestsProducteevSync extends AbstractSyncRepeatTests<JSONObject> {
private static boolean initialized = false;
protected static ProducteevInvoker invoker;
@Autowired TaskService taskService;
@Autowired MetadataService metadataService;
@Autowired TagService tagService;
protected ProducteevDataService producteevDataService;
private static final String TEST_USER = "sync_tester2@astrid.com";
private static final String TEST_PASSWORD = "wonkwonkjj";
@Override
protected void setUp() throws Exception {
super.setUp();
Preferences.setString(ProducteevUtilities.PREF_SERVER_LAST_SYNC, null);
if (!initialized) {
initializeTestService();
}
producteevDataService = ProducteevDataService.getInstance();
producteevDataService.updateDashboards(new JSONArray());
clearAllRemoteTasks();
}
private void initializeTestService() throws Exception {
//Set the username and password for the service
Preferences.setString(R.string.producteev_PPr_email, TEST_USER);
Preferences.setString(R.string.producteev_PPr_password, TEST_PASSWORD);
invoker = ProducteevSyncProvider.getInvoker();
invoker.authenticate(TEST_USER, TEST_PASSWORD);
initialized = true;
}
/*
* Deletes all the remote tasks on the default dashboard to ensure
* clean tests.
*/
private void clearAllRemoteTasks() {
try {
JSONArray remoteTasks = invoker.tasksShowList(null, null);
for (int i = 0; i < remoteTasks.length(); i++) {
JSONObject task = remoteTasks.getJSONObject(i).getJSONObject("task");
System.err.println(invoker.tasksDelete(getRemoteId(task)));
}
} catch (Exception e) {
fail("Failed to clear remote tasks before tests");
}
}
protected long getRemoteId(JSONObject remoteTask) {
long remoteId = 0;
try {
remoteId = remoteTask.getLong("id_task");
} catch (Exception e) {
fail("Remote task object did not contain id_task field");
}
return remoteId;
}
@Override
protected void waitAndSync() {
AndroidUtilities.sleepDeep(3000L);
new ProducteevSyncProvider().synchronize(null);
AndroidUtilities.sleepDeep(3000L);
}
/**
* @param t
* @param expectedDueDate
*/
@Override
protected JSONObject assertTaskExistsRemotely(Task t, long expectedDueDate) {
long remoteId = producteevDataService.getTaskMetadata(t.getId()).getValue(ProducteevTask.ID);
JSONObject remoteTask = null;
try {
remoteTask = invoker.tasksView(remoteId).getJSONObject("task");
assertNotNull(remoteTask);
long remoteDueDate = ApiUtilities.producteevToUnixTime(remoteTask.getString("deadline"), 0);
assertTimesMatch(expectedDueDate, remoteDueDate);
} catch (Exception e) {
e.printStackTrace();
fail("Error in producteev invoker");
}
return remoteTask;
}
@Override
protected void assertTaskCompletedRemotely(Task t) {
long remoteId = producteevDataService.getTaskMetadata(t.getId()).getValue(ProducteevTask.ID);
JSONObject remoteTask = null;
try {
remoteTask = invoker.tasksView(remoteId).getJSONObject("task");
assertNotNull(remoteTask);
System.err.println(remoteTask);
assertEquals(2, remoteTask.getInt("status"));
} catch (Exception e) {
e.printStackTrace();
fail("Error in producteev invoker");
}
}
}

@ -1,44 +0,0 @@
package com.todoroo.astrid.sync.repeats;
import java.util.Date;
import org.json.JSONObject;
import com.google.ical.values.RRule;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.data.Task;
public class RepeatTestsProducteevSyncRemote extends RepeatTestsProducteevSync {
@Override
protected long setCompletionDate(boolean completeBefore, Task t,
JSONObject remoteModel, long dueDate) {
long completionDate;
if (completeBefore)
completionDate = dueDate - DateUtilities.ONE_DAY;
else
completionDate = dueDate + DateUtilities.ONE_DAY;
try {
invoker.tasksSetStatus(getRemoteId(remoteModel), 2);
} catch (Exception e) {
e.printStackTrace();
fail("Error in producteev invoker");
}
return completionDate;
}
@Override
protected long computeNextDueDateFromDate(long fromDate, RRule rrule, boolean fromCompletion) {
if (fromCompletion) {
fromDate = DateUtilities.now() - 5000L;
}
return super.computeNextDueDateFromDate(fromDate, rrule, fromCompletion);
}
@Override
protected void assertTimesMatch(long expectedTime, long newDueDate) {
assertTrue(String.format("Expected %s, was %s", new Date(expectedTime), new Date(newDueDate)),
Math.abs(expectedTime - newDueDate) < 60000); // More lenient with producteev since we use now() in setting completion during sync
}
}
Loading…
Cancel
Save