Skip to content

Commit c1cd197

Browse files
committed
Fix signUp and linkWith with an anonymous user
Fixes integration test failures caused by #52 We strip anonymity in `signUp` and `linkWith` before calling into `saveAsync` where there's a fork in logic for `isLazy()`. Since we now determine `isLazy()` based off `objectId != null && ParseAnonymousUtils.isLinked(this)`, `isLazy()` returns the incorrect value for these logic paths. The solution is to get the value of `isLazy()` before stripping anonymity and passing it through to `saveAsync()`.
1 parent 8499cf5 commit c1cd197

File tree

2 files changed

+38
-40
lines changed

2 files changed

+38
-40
lines changed

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

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -475,26 +475,28 @@ private void restoreAnonymity(Map<String, String> anonymousData) {
475475

476476
@Override
477477
/* package */ Task<Void> saveAsync(String sessionToken, Task<Void> toAwait) {
478-
synchronized (mutex) {
479-
Task<Void> task;
480-
if (isLazy()) {
481-
task = resolveLazinessAsync(toAwait);
482-
} else {
483-
task = super.saveAsync(sessionToken, toAwait);
484-
}
478+
return saveAsync(sessionToken, isLazy(), toAwait);
479+
}
485480

486-
return task.onSuccessTask(new Continuation<Void, Task<Void>>() {
487-
@Override
488-
public Task<Void> then(Task<Void> task) throws Exception {
489-
// If the user is the currently logged in user, we persist all data to disk
490-
if (isCurrentUser()) {
491-
cleanUpAuthData();
492-
return saveCurrentUserAsync(ParseUser.this);
493-
}
494-
return Task.forResult(null);
495-
}
496-
});
481+
/* package for tests */ Task<Void> saveAsync(String sessionToken, boolean isLazy, Task<Void> toAwait) {
482+
Task<Void> task;
483+
if (isLazy) {
484+
task = resolveLazinessAsync(toAwait);
485+
} else {
486+
task = super.saveAsync(sessionToken, toAwait);
497487
}
488+
489+
return task.onSuccessTask(new Continuation<Void, Task<Void>>() {
490+
@Override
491+
public Task<Void> then(Task<Void> task) throws Exception {
492+
// If the user is the currently logged in user, we persist all data to disk
493+
if (isCurrentUser()) {
494+
cleanUpAuthData();
495+
return saveCurrentUserAsync(ParseUser.this);
496+
}
497+
return Task.forResult(null);
498+
}
499+
});
498500
}
499501

500502
@Override
@@ -622,6 +624,7 @@ public Task<Void> then(Task<Void> task) throws Exception {
622624
checkForChangesToMutableContainers();
623625
user.checkForChangesToMutableContainers();
624626

627+
boolean isLazy = user.isLazy();
625628
final String oldUsername = user.getUsername();
626629
final String oldPassword = user.getPassword();
627630
final Map<String, String> anonymousData = user.getAuthData(ParseAnonymousUtils.AUTH_TYPE);
@@ -631,7 +634,7 @@ public Task<Void> then(Task<Void> task) throws Exception {
631634
user.setPassword(getPassword());
632635
revert();
633636

634-
return user.saveAsync(sessionToken, toAwait).continueWithTask(new Continuation<Void, Task<Void>>() {
637+
return user.saveAsync(sessionToken, isLazy, toAwait).continueWithTask(new Continuation<Void, Task<Void>>() {
635638
@Override
636639
public Task<Void> then(Task<Void> task) throws Exception {
637640
if (task.isCancelled() || task.isFaulted()) { // Error
@@ -1229,20 +1232,14 @@ private Task<Void> linkWithAsync(
12291232
final Map<String, String> authData,
12301233
final Task<Void> toAwait,
12311234
final String sessionToken) {
1232-
final Map<String, String> oldAnonymousData = getAuthData(ParseAnonymousUtils.AUTH_TYPE);
12331235
synchronized (mutex) {
1236+
final boolean isLazy = isLazy();
1237+
final Map<String, String> oldAnonymousData = getAuthData(ParseAnonymousUtils.AUTH_TYPE);
1238+
12341239
stripAnonymity();
12351240
putAuthData(authType, authData);
12361241

1237-
// TODO(grantland): Should we really be getting the current user's sessionToken?
1238-
// What if we're not the current user?
1239-
// TODO(mengyan): Delete getCurrentSessionTokenAsync or delete the inject sessionToken
1240-
return ParseUser.getCurrentSessionTokenAsync().onSuccessTask(new Continuation<String, Task<Void>>() {
1241-
@Override
1242-
public Task<Void> then(Task<String> task) throws Exception {
1243-
return saveAsync(sessionToken, toAwait);
1244-
}
1245-
}).continueWithTask(new Continuation<Void, Task<Void>>() {
1242+
return saveAsync(sessionToken, isLazy, toAwait).continueWithTask(new Continuation<Void, Task<Void>>() {
12461243
@Override
12471244
public Task<Void> then(Task<Void> task) throws Exception {
12481245
synchronized (mutex) {
@@ -1292,9 +1289,6 @@ private void logOutWith(String authType) {
12921289
*/
12931290
/* package for tests */ Task<Void> resolveLazinessAsync(Task<Void> toAwait) {
12941291
synchronized (mutex) {
1295-
if (!isLazy()) {
1296-
return Task.forResult(null);
1297-
}
12981292
if (getAuthData().size() == 0) { // TODO(grantland): Could we just check isDirty(KEY_AUTH_DATA)?
12991293
// If there are no linked services, treat this as a SignUp.
13001294
return signUpAsync(toAwait);

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

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUser() throws Exception {
221221
when(currentUser.isLinked(ParseAnonymousUtils.AUTH_TYPE)).thenReturn(true);
222222
when(currentUser.getSessionToken()).thenReturn("oldSessionToken");
223223
when(currentUser.getAuthData()).thenReturn(new HashMap<String, Map<String, String>>());
224-
when(currentUser.saveAsync(anyString(), Matchers.<Task<Void>>any()))
224+
when(currentUser.saveAsync(anyString(), eq(false), Matchers.<Task<Void>>any()))
225225
.thenReturn(Task.<Void>forResult(null));
226226
ParseUser.State state = new ParseUser.State.Builder()
227227
.put("oldKey", "oldValue")
@@ -249,7 +249,8 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUser() throws Exception {
249249
verify(currentUser, times(1)).setUsername("userName");
250250
verify(currentUser, times(1)).setPassword("password");
251251
// Make sure we save currentUser
252-
verify(currentUser, times(1)).saveAsync(eq("oldSessionToken"), Matchers.<Task<Void>>any());
252+
verify(currentUser, times(1))
253+
.saveAsync(eq("oldSessionToken"), eq(false), Matchers.<Task<Void>>any());
253254
// Make sure we merge currentUser with user after save
254255
assertEquals("oldValue", user.get("oldKey"));
255256
// Make sure set currentUser
@@ -264,13 +265,14 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUserSaveFailure() throws Exce
264265
oldAnonymousAuthData.put("oldKey", "oldToken");
265266
currentUser.putAuthData(ParseAnonymousUtils.AUTH_TYPE, oldAnonymousAuthData);
266267
ParseUser partialMockCurrentUser = spy(currentUser);
268+
when(partialMockCurrentUser.getObjectId()).thenReturn("oldObjectId");
267269
when(partialMockCurrentUser.getUsername()).thenReturn("oldUserName");
268270
when(partialMockCurrentUser.getPassword()).thenReturn("oldPassword");
269271
when(partialMockCurrentUser.getSessionToken()).thenReturn("oldSessionToken");
270272
ParseException saveException = new ParseException(ParseException.OTHER_CAUSE, "");
271273
doReturn(Task.<Void>forError(saveException))
272274
.when(partialMockCurrentUser)
273-
.saveAsync(anyString(), Matchers.<Task<Void>>any());
275+
.saveAsync(anyString(), eq(false), Matchers.<Task<Void>>any());
274276
ParseCurrentUserController currentUserController = mock(ParseCurrentUserController.class);
275277
when(currentUserController.getAsync(anyBoolean()))
276278
.thenReturn(Task.forResult(partialMockCurrentUser));
@@ -295,7 +297,7 @@ public void testSignUpAsyncWithMergeInDiskAnonymousUserSaveFailure() throws Exce
295297
verify(partialMockCurrentUser, times(1)).copyChangesFrom(eq(user));
296298
// Make sure we save currentUser
297299
verify(partialMockCurrentUser, times(1))
298-
.saveAsync(eq("oldSessionToken"), Matchers.<Task<Void>>any());
300+
.saveAsync(eq("oldSessionToken"), eq(false), Matchers.<Task<Void>>any());
299301
// Make sure we restore old username and password after save fails
300302
verify(partialMockCurrentUser, times(1)).setUsername("oldUserName");
301303
verify(partialMockCurrentUser, times(1)).setPassword("oldPassword");
@@ -575,7 +577,7 @@ public void testLinkWithAsyncWithSaveAsyncSuccess() throws Exception {
575577
ParseUser partialMockUser = spy(user);
576578
doReturn(Task.<Void>forResult(null))
577579
.when(partialMockUser)
578-
.saveAsync(anyString(), Matchers.<Task<Void>>any());
580+
.saveAsync(anyString(), eq(false), Matchers.<Task<Void>>any());
579581
String authType = "facebook";
580582
Map<String, String> authData = new HashMap<>();
581583
authData.put("token", "test");
@@ -587,7 +589,8 @@ public void testLinkWithAsyncWithSaveAsyncSuccess() throws Exception {
587589
// Make sure new authData is added
588590
assertSame(authData, partialMockUser.getAuthData().get("facebook"));
589591
// Make sure we save the user
590-
verify(partialMockUser, times(1)).saveAsync(eq("sessionTokenAgain"), Matchers.<Task<Void>>any());
592+
verify(partialMockUser, times(1))
593+
.saveAsync(eq("sessionTokenAgain"), eq(false), Matchers.<Task<Void>>any());
591594
// Make sure synchronizeAuthData() is called
592595
verify(provider, times(1)).restoreAuthentication(authData);
593596
}
@@ -610,7 +613,7 @@ public void testLinkWithAsyncWithSaveAsyncFailure() throws Exception {
610613
Exception saveException = new Exception();
611614
doReturn(Task.<Void>forError(saveException))
612615
.when(partialMockUser)
613-
.saveAsync(anyString(), Matchers.<Task<Void>>any());
616+
.saveAsync(anyString(), eq(false), Matchers.<Task<Void>>any());
614617
String facebookAuthType = "facebook";
615618
Map<String, String> facebookAuthData = new HashMap<>();
616619
facebookAuthData.put("facebookToken", "facebookTest");
@@ -622,7 +625,8 @@ public void testLinkWithAsyncWithSaveAsyncFailure() throws Exception {
622625
// Make sure new authData is added
623626
assertSame(facebookAuthData, partialMockUser.getAuthData().get("facebook"));
624627
// Make sure we save the user
625-
verify(partialMockUser, times(1)).saveAsync(eq("sessionTokenAgain"), Matchers.<Task<Void>>any());
628+
verify(partialMockUser, times(1))
629+
.saveAsync(eq("sessionTokenAgain"), eq(false), Matchers.<Task<Void>>any());
626630
// Make sure old authData is restored
627631
assertSame(anonymousAuthData, partialMockUser.getAuthData().get(ParseAnonymousUtils.AUTH_TYPE));
628632
// Verify exception

0 commit comments

Comments
 (0)