Skip to content

Commit 28c739c

Browse files
natario1rogerhu
authored andcommitted
Fix ParseUserCurrentCoder bug (#724)
* Fix ParseUserCurrentCoder bug * Fix tests * Fix TimeZone test
1 parent c0e03a7 commit 28c739c

File tree

4 files changed

+47
-22
lines changed

4 files changed

+47
-22
lines changed

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

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import org.json.JSONException;
1212
import org.json.JSONObject;
1313

14+
import java.util.HashMap;
1415
import java.util.Iterator;
1516
import java.util.Map;
1617
import static com.parse.ParseUser.State;
@@ -54,7 +55,11 @@ public static ParseUserCurrentCoder get() {
5455
@Override
5556
public <T extends ParseObject.State> JSONObject encode(
5657
T state, ParseOperationSet operations, ParseEncoder encoder) {
58+
5759
// FYI we'll be double writing sessionToken and authData for now...
60+
// This is important. super.encode() has no notion of sessionToken and authData, so it treats them
61+
// like objects (simply passed to the encoder). This means that a null sessionToken will become
62+
// JSONObject.NULL. This must be accounted in #decode().
5863
JSONObject objectJSON = super.encode(state, operations, encoder);
5964

6065
String sessionToken = ((State) state).sessionToken();
@@ -90,17 +95,20 @@ public <T extends ParseObject.State> JSONObject encode(
9095
@Override
9196
public <T extends ParseObject.State.Init<?>> T decode(
9297
T builder, JSONObject json, ParseDecoder decoder) {
93-
ParseUser.State.Builder userBuilder = (State.Builder) builder;
98+
ParseUser.State.Builder userBuilder = (State.Builder) super.decode(builder, json, decoder);
99+
100+
// super.decode will read its own values and add them to the builder using put().
101+
// This means the state for session token and auth data might be illegal, returning
102+
// unexpected types. For instance if sessionToken was null, now it's JSONObject.NULL.
103+
// We must overwrite these possibly wrong values.
94104
String newSessionToken = json.optString(KEY_SESSION_TOKEN, null);
95-
if (newSessionToken != null) {
96-
userBuilder.sessionToken(newSessionToken);
97-
json.remove(KEY_SESSION_TOKEN);
98-
}
105+
userBuilder.sessionToken(newSessionToken);
99106

100107
JSONObject newAuthData = json.optJSONObject(KEY_AUTH_DATA);
101-
if (newAuthData != null) {
108+
if (newAuthData == null) {
109+
userBuilder.authData(null);
110+
} else {
102111
try {
103-
// Merge in auth data.
104112
@SuppressWarnings("rawtypes")
105113
Iterator i = newAuthData.keys();
106114
while (i.hasNext()) {
@@ -113,10 +121,8 @@ public <T extends ParseObject.State.Init<?>> T decode(
113121
} catch (JSONException e) {
114122
throw new RuntimeException(e);
115123
}
116-
json.remove(KEY_AUTH_DATA);
117124
}
118125

119-
// FYI we'll be double writing sessionToken and authData for now...
120-
return super.decode(builder, json, decoder);
126+
return (T) userBuilder;
121127
}
122128
}

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,14 @@
4848
// For android.os.Looper
4949
@RunWith(RobolectricTestRunner.class)
5050
@Config(constants = BuildConfig.class, sdk = TestHelper.ROBOLECTRIC_SDK_VERSION)
51-
public class ParseConfigTest {
51+
public class ParseConfigTest extends ResetPluginsParseTest {
5252

5353
@Before
54-
public void setUp() {
54+
public void setUp() throws Exception {
55+
super.setUp();
5556
ParseTestUtils.setTestParseUser();
5657
}
5758

58-
@After
59-
public void tearDown() {
60-
ParseCorePlugins.getInstance().reset();
61-
}
62-
6359
//region testConstructor
6460

6561
@Test

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import bolts.Task;
2828

2929
import static org.junit.Assert.assertEquals;
30+
import static org.junit.Assert.assertFalse;
3031
import static org.junit.Assert.assertNotNull;
3132
import static org.junit.Assert.assertNull;
3233
import static org.junit.Assert.assertTrue;
@@ -253,8 +254,16 @@ public void testUpdateBeforeSave() throws Exception {
253254
installation.updateBeforeSave();
254255

255256
// Make sure we update timezone
256-
String zone = TimeZone.getDefault().getID();
257-
assertEquals(zone, installation.getString(KEY_TIME_ZONE));
257+
String zone = installation.getString(KEY_TIME_ZONE);
258+
String deviceZone = TimeZone.getDefault().getID();
259+
if (zone != null) {
260+
assertEquals(zone, deviceZone);
261+
} else {
262+
// If it's not updated it's because it was not acceptable.
263+
assertFalse(deviceZone.equals("GMT"));
264+
assertFalse(deviceZone.indexOf("/") > 0);
265+
}
266+
258267
// Make sure we update version info
259268
Context context = Parse.getApplicationContext();
260269
String packageName = context.getPackageName();
@@ -265,9 +274,11 @@ public void testUpdateBeforeSave() throws Exception {
265274
assertEquals(packageName, installation.getString(KEY_APP_IDENTIFIER));
266275
assertEquals(appName, installation.getString(KEY_APP_NAME));
267276
assertEquals(appVersion, installation.getString(KEY_APP_VERSION));
277+
268278
// Make sure we update device info
269279
assertEquals("android", installation.getString(KEY_DEVICE_TYPE));
270280
assertEquals("installationId", installation.getString(KEY_INSTALLATION_ID));
281+
271282
// Make sure we update the locale identifier
272283
assertEquals("en-US", installation.getString(KEY_LOCALE_IDENTIFIER));
273284
}

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,6 @@ public void testDecodeSuccessWithSessionTokenAndAuthData() throws Exception {
9292
Map<String, String> twitterAuthData = authData.get("twitter");
9393
assertEquals("twitterId", twitterAuthData.get("id"));
9494
assertEquals("twitterAccessToken", twitterAuthData.get("access_token"));
95-
// Make sure objectJson does not have sessionToken and authData anymore
96-
assertFalse(objectJson.has(KEY_SESSION_TOKEN));
97-
assertFalse(objectJson.has(KEY_AUTH_DATA));
9895
}
9996

10097
@Test
@@ -111,4 +108,19 @@ public void testDecodeSuccessWithoutSessionTokenAndAuthData() throws Exception {
111108
// We always return non-null for authData()
112109
assertEquals(0, state.authData().size());
113110
}
111+
112+
@Test
113+
public void testEncodeDecodeWithNullValues() throws Exception {
114+
ParseUser.State state = new ParseUser.State.Builder()
115+
.sessionToken(null)
116+
.authData(null)
117+
.build();
118+
ParseUserCurrentCoder coder = ParseUserCurrentCoder.get();
119+
JSONObject object = coder.encode(state, null, PointerEncoder.get());
120+
ParseUser.State.Builder builder =
121+
coder.decode(new ParseUser.State.Builder(), object, ParseDecoder.get());
122+
state = builder.build();
123+
assertNull(state.sessionToken());
124+
assertEquals(0, state.authData().size());
125+
}
114126
}

0 commit comments

Comments
 (0)