|
8 | 8 | */
|
9 | 9 | package com.parse;
|
10 | 10 |
|
| 11 | +import android.Manifest; |
11 | 12 | import android.os.Parcel;
|
12 | 13 |
|
13 | 14 | import org.json.JSONObject;
|
|
20 | 21 | import org.mockito.ArgumentCaptor;
|
21 | 22 | import org.mockito.Matchers;
|
22 | 23 | import org.robolectric.RobolectricTestRunner;
|
| 24 | +import org.robolectric.RuntimeEnvironment; |
| 25 | +import org.robolectric.Shadows; |
23 | 26 | import org.robolectric.annotation.Config;
|
24 | 27 |
|
25 | 28 | import java.util.Collections;
|
| 29 | +import java.util.Date; |
26 | 30 | import java.util.HashMap;
|
27 | 31 | import java.util.Map;
|
| 32 | +import java.util.concurrent.CountDownLatch; |
28 | 33 | import java.util.concurrent.Semaphore;
|
29 | 34 | import java.util.concurrent.TimeUnit;
|
30 | 35 |
|
| 36 | +import bolts.Capture; |
| 37 | +import bolts.Continuation; |
31 | 38 | import bolts.Task;
|
32 | 39 |
|
33 | 40 | import static org.junit.Assert.assertEquals;
|
@@ -68,9 +75,19 @@ public void setUp() throws Exception {
|
68 | 75 | @After
|
69 | 76 | public void tearDown() throws Exception {
|
70 | 77 | super.tearDown();
|
71 |
| - ParseObject.unregisterSubclass(ParseUser.class); |
72 |
| - ParseObject.unregisterSubclass(ParseSession.class); |
73 |
| - 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(); |
74 | 91 | }
|
75 | 92 |
|
76 | 93 | @Test
|
@@ -1541,4 +1558,111 @@ private static void setLazy(ParseUser user) {
|
1541 | 1558 | anonymousAuthData.put("anonymousToken", "anonymousTest");
|
1542 | 1559 | user.putAuthData(ParseAnonymousUtils.AUTH_TYPE, anonymousAuthData);
|
1543 | 1560 | }
|
| 1561 | + |
| 1562 | + //region testSaveEventuallyWhenServerError |
| 1563 | + |
| 1564 | + @Test |
| 1565 | + public void testSaveEventuallyWhenServerError() throws Exception { |
| 1566 | + Shadows.shadowOf(RuntimeEnvironment.application) |
| 1567 | + .grantPermissions(Manifest.permission.ACCESS_NETWORK_STATE); |
| 1568 | + Parse.Configuration configuration = |
| 1569 | + new Parse.Configuration.Builder(RuntimeEnvironment.application) |
| 1570 | + .applicationId(BuildConfig.APPLICATION_ID) |
| 1571 | + .server("https://api.parse.com/1") |
| 1572 | + .enableLocalDataStore() |
| 1573 | + .build(); |
| 1574 | + ParsePlugins plugins = ParseTestUtils.mockParsePlugins(configuration); |
| 1575 | + JSONObject mockResponse = new JSONObject(); |
| 1576 | + mockResponse.put("objectId", "objectId"); |
| 1577 | + mockResponse. put( "email", "[email protected]"); |
| 1578 | + mockResponse.put("username", "username"); |
| 1579 | + mockResponse.put("sessionToken", "r:sessionToken"); |
| 1580 | + mockResponse.put("createdAt", ParseDateFormat.getInstance().format(new Date(1000))); |
| 1581 | + mockResponse.put("updatedAt", ParseDateFormat.getInstance().format(new Date(2000))); |
| 1582 | + ParseHttpClient restClient = ParseTestUtils.mockParseHttpClientWithResponse( |
| 1583 | + mockResponse,200, "OK"); |
| 1584 | + when(plugins.restClient()) |
| 1585 | + .thenReturn(restClient); |
| 1586 | + Parse.initialize(configuration, plugins); |
| 1587 | + |
| 1588 | + ParseUser user = ParseUser.logIn("username", "password"); |
| 1589 | + assertFalse(user.isDirty()); |
| 1590 | + |
| 1591 | + user.put("field", "data"); |
| 1592 | + assertTrue(user.isDirty()); |
| 1593 | + |
| 1594 | + mockResponse = new JSONObject(); |
| 1595 | + mockResponse.put("updatedAt", ParseDateFormat.getInstance().format(new Date(3000))); |
| 1596 | + ParseTestUtils.updateMockParseHttpClientWithResponse( |
| 1597 | + restClient, mockResponse, 200, "OK"); |
| 1598 | + |
| 1599 | + final CountDownLatch saveCountDown1 = new CountDownLatch(1); |
| 1600 | + final Capture<Exception> exceptionCapture = new Capture<>(); |
| 1601 | + user.saveInBackground().continueWith(new Continuation<Void, Void>() { |
| 1602 | + @Override |
| 1603 | + public Void then(Task<Void> task) throws Exception { |
| 1604 | + exceptionCapture.set(task.getError()); |
| 1605 | + saveCountDown1.countDown(); |
| 1606 | + return null; |
| 1607 | + } |
| 1608 | + }); |
| 1609 | + assertTrue(saveCountDown1.await(5, TimeUnit.SECONDS)); |
| 1610 | + assertNull(exceptionCapture.get()); |
| 1611 | + assertFalse(user.isDirty()); |
| 1612 | + |
| 1613 | + user.put("field", "other data"); |
| 1614 | + assertTrue(user.isDirty()); |
| 1615 | + |
| 1616 | + mockResponse = new JSONObject(); |
| 1617 | + mockResponse.put("error", "Save is not allowed"); |
| 1618 | + mockResponse.put("code", 141); |
| 1619 | + ParseTestUtils.updateMockParseHttpClientWithResponse( |
| 1620 | + restClient, mockResponse, 400, "Bad Request"); |
| 1621 | + |
| 1622 | + final CountDownLatch saveEventuallyCountDown = new CountDownLatch(1); |
| 1623 | + user.saveEventually().continueWith(new Continuation<Void, Void>() { |
| 1624 | + @Override |
| 1625 | + public Void then(Task<Void> task) throws Exception { |
| 1626 | + exceptionCapture.set(task.getError()); |
| 1627 | + saveEventuallyCountDown.countDown(); |
| 1628 | + return null; |
| 1629 | + } |
| 1630 | + }); |
| 1631 | + assertTrue(saveEventuallyCountDown.await(5, TimeUnit.SECONDS)); |
| 1632 | + assertTrue(exceptionCapture.get() instanceof ParseException); |
| 1633 | + assertEquals(ParseException.SCRIPT_ERROR, ((ParseException)exceptionCapture.get()).getCode()); |
| 1634 | + assertEquals("Save is not allowed", exceptionCapture.get().getMessage()); |
| 1635 | + assertTrue(user.isDirty()); |
| 1636 | + |
| 1637 | + // Simulate reboot |
| 1638 | + Parse.destroy(); |
| 1639 | + Parse.initialize(configuration, plugins); |
| 1640 | + |
| 1641 | + user = ParseUser.getCurrentUser(); |
| 1642 | + assertTrue(user.isDirty()); |
| 1643 | + |
| 1644 | + assertEquals("other data", user.get("field")); |
| 1645 | + user.put("field", "another data"); |
| 1646 | + |
| 1647 | + mockResponse = new JSONObject(); |
| 1648 | + mockResponse.put("updatedAt", ParseDateFormat.getInstance().format(new Date(4000))); |
| 1649 | + ParseTestUtils.updateMockParseHttpClientWithResponse( |
| 1650 | + restClient, mockResponse, 200, "OK"); |
| 1651 | + |
| 1652 | + final CountDownLatch saveCountDown2 = new CountDownLatch(1); |
| 1653 | + user.saveInBackground().continueWith(new Continuation<Void, Void>() { |
| 1654 | + @Override |
| 1655 | + public Void then(Task<Void> task) throws Exception { |
| 1656 | + exceptionCapture.set(task.getError()); |
| 1657 | + saveCountDown2.countDown(); |
| 1658 | + return null; |
| 1659 | + } |
| 1660 | + }); |
| 1661 | + |
| 1662 | + assertTrue(saveCountDown2.await(5, TimeUnit.SECONDS)); |
| 1663 | + assertNull(exceptionCapture.get()); |
| 1664 | + assertFalse(user.isDirty()); |
| 1665 | + } |
| 1666 | + |
| 1667 | + //endregion |
1544 | 1668 | }
|
0 commit comments