Skip to content

Commit 605e8a2

Browse files
committed
* Suggestion of fix for parse-community#827
* Improved test for parse-community#827 : - Generalize to any server error that is different to CONNECTION_FAILED (not only INVALID_SESSION_TOKEN) - Added isDirty() checks - fixed test tearDown
1 parent 6dea925 commit 605e8a2

File tree

3 files changed

+55
-29
lines changed

3 files changed

+55
-29
lines changed

Parse/src/main/java/com/parse/Parse.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ public Void then(Task<Void> task) throws Exception {
319319
}
320320

321321
static void destroy() {
322+
ParseObject.unregisterParseSubclasses();
323+
322324
ParseEventuallyQueue queue;
323325
synchronized (MUTEX) {
324326
queue = eventuallyQueue;
@@ -330,6 +332,8 @@ static void destroy() {
330332

331333
ParseCorePlugins.getInstance().reset();
332334
ParsePlugins.reset();
335+
336+
setLocalDatastore(null);
333337
}
334338

335339
/**

Parse/src/main/java/com/parse/ParseObject.java

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,20 @@ private ParseRESTObjectCommand currentSaveEventuallyCommand(
14201420
final ParseObject.State result, final ParseOperationSet operationsBeforeSave) {
14211421
Task<Void> task = Task.forResult(null);
14221422

1423+
/*
1424+
* If this object is in the offline store, then we need to make sure that we pull in any dirty
1425+
* changes it may have before merging the server data into it.
1426+
*/
1427+
final OfflineStore store = Parse.getLocalDatastore();
1428+
if (store != null) {
1429+
task = task.onSuccessTask(new Continuation<Void, Task<Void>>() {
1430+
@Override
1431+
public Task<Void> then(Task<Void> task) throws Exception {
1432+
return store.fetchLocallyAsync(ParseObject.this).makeVoid();
1433+
}
1434+
});
1435+
}
1436+
14231437
final boolean success = result != null;
14241438
synchronized (mutex) {
14251439
// Find operationsBeforeSave in the queue so that we can remove it and move to the next
@@ -1433,24 +1447,18 @@ private ParseRESTObjectCommand currentSaveEventuallyCommand(
14331447
// Merge the data from the failed save into the next save.
14341448
ParseOperationSet nextOperation = opIterator.next();
14351449
nextOperation.mergeFrom(operationsBeforeSave);
1450+
if (store != null) {
1451+
task = task.onSuccessTask(new Continuation<Void, Task<Void>>() {
1452+
@Override
1453+
public Task<Void> then(Task<Void> task) throws Exception {
1454+
return store.updateDataForObjectAsync(ParseObject.this);
1455+
}
1456+
});
1457+
}
14361458
return task;
14371459
}
14381460
}
14391461

1440-
/*
1441-
* If this object is in the offline store, then we need to make sure that we pull in any dirty
1442-
* changes it may have before merging the server data into it.
1443-
*/
1444-
final OfflineStore store = Parse.getLocalDatastore();
1445-
if (store != null) {
1446-
task = task.onSuccessTask(new Continuation<Void, Task<Void>>() {
1447-
@Override
1448-
public Task<Void> then(Task<Void> task) throws Exception {
1449-
return store.fetchLocallyAsync(ParseObject.this).makeVoid();
1450-
}
1451-
});
1452-
}
1453-
14541462
// fetchLocallyAsync will return an error if this object isn't in the LDS yet and that's ok
14551463
task = task.continueWith(new Continuation<Void, Void>() {
14561464
@Override

Parse/src/test/java/com/parse/ParseUserTest.java

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@
2424
import org.robolectric.RuntimeEnvironment;
2525
import org.robolectric.Shadows;
2626
import org.robolectric.annotation.Config;
27-
import org.robolectric.shadows.ShadowApplication;
2827

29-
import java.net.URL;
3028
import java.util.Collections;
3129
import java.util.Date;
3230
import java.util.HashMap;
@@ -77,9 +75,19 @@ public void setUp() throws Exception {
7775
@After
7876
public void tearDown() throws Exception {
7977
super.tearDown();
80-
ParseObject.unregisterSubclass(ParseUser.class);
81-
ParseObject.unregisterSubclass(ParseSession.class);
82-
Parse.disableLocalDatastore();
78+
if (ParsePlugins.get() != null) {
79+
ParseCurrentInstallationController installationController =
80+
ParseCorePlugins.getInstance().getCurrentInstallationController();
81+
if (installationController != null) {
82+
installationController.clearFromDisk();
83+
}
84+
ParseCurrentUserController userController =
85+
ParseCorePlugins.getInstance().getCurrentUserController();
86+
if (userController != null) {
87+
userController.clearFromDisk();
88+
}
89+
}
90+
Parse.destroy();
8391
}
8492

8593
@Test
@@ -1551,10 +1559,10 @@ private static void setLazy(ParseUser user) {
15511559
user.putAuthData(ParseAnonymousUtils.AUTH_TYPE, anonymousAuthData);
15521560
}
15531561

1554-
//region testSaveEventuallyWhenSessionIsInvalid
1562+
//region testSaveEventuallyWhenServerError
15551563

15561564
@Test
1557-
public void testSaveEventuallyWhenSessionIsInvalid() throws Exception {
1565+
public void testSaveEventuallyWhenServerError() throws Exception {
15581566
Shadows.shadowOf(RuntimeEnvironment.application)
15591567
.grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE);
15601568
Parse.Configuration configuration =
@@ -1578,7 +1586,10 @@ public void testSaveEventuallyWhenSessionIsInvalid() throws Exception {
15781586
Parse.initialize(configuration, plugins);
15791587

15801588
ParseUser user = ParseUser.logIn("username", "password");
1589+
assertFalse(user.isDirty());
1590+
15811591
user.put("field", "data");
1592+
assertTrue(user.isDirty());
15821593

15831594
mockResponse = new JSONObject();
15841595
mockResponse.put("updatedAt", ParseDateFormat.getInstance().format(new Date(3000)));
@@ -1597,12 +1608,14 @@ public Void then(Task<Void> task) throws Exception {
15971608
});
15981609
assertTrue(saveCountDown1.await(5, TimeUnit.SECONDS));
15991610
assertNull(exceptionCapture.get());
1611+
assertFalse(user.isDirty());
16001612

16011613
user.put("field", "other data");
1614+
assertTrue(user.isDirty());
16021615

16031616
mockResponse = new JSONObject();
1604-
mockResponse.put("error", "invalid session token");
1605-
mockResponse.put("code", 209);
1617+
mockResponse.put("error", "Save is not allowed");
1618+
mockResponse.put("code", 141);
16061619
ParseTestUtils.updateMockParseHttpClientWithResponse(
16071620
restClient, mockResponse, 400, "Bad Request");
16081621

@@ -1617,14 +1630,17 @@ public Void then(Task<Void> task) throws Exception {
16171630
});
16181631
assertTrue(saveEventuallyCountDown.await(5, TimeUnit.SECONDS));
16191632
assertTrue(exceptionCapture.get() instanceof ParseException);
1620-
assertEquals(ParseException.INVALID_SESSION_TOKEN, ((ParseException)exceptionCapture.get()).getCode());
1621-
assertEquals("invalid session token", exceptionCapture.get().getMessage());
1633+
assertEquals(ParseException.SCRIPT_ERROR, ((ParseException)exceptionCapture.get()).getCode());
1634+
assertEquals("Save is not allowed", exceptionCapture.get().getMessage());
1635+
assertTrue(user.isDirty());
16221636

16231637
// Simulate reboot
16241638
Parse.destroy();
16251639
Parse.initialize(configuration, plugins);
16261640

16271641
user = ParseUser.getCurrentUser();
1642+
assertTrue(user.isDirty());
1643+
16281644
assertEquals("other data", user.get("field"));
16291645
user.put("field", "another data");
16301646

@@ -1642,12 +1658,10 @@ public Void then(Task<Void> task) throws Exception {
16421658
return null;
16431659
}
16441660
});
1661+
16451662
assertTrue(saveCountDown2.await(5, TimeUnit.SECONDS));
16461663
assertNull(exceptionCapture.get());
1647-
1648-
ParseCorePlugins.getInstance().getCurrentUserController().clearFromDisk();
1649-
ParseCorePlugins.getInstance().getCurrentInstallationController().clearFromDisk();
1650-
Parse.destroy();
1664+
assertFalse(user.isDirty());
16511665
}
16521666

16531667
//endregion

0 commit comments

Comments
 (0)