Repository: parse-community/Parse-SDK-JS
Pull request #730 (2019-02-08 19:04:49)

Support setting user from JSON (hydrate)

codecov[bot]: # [Codecov](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730?src=pr&el=h1) Report
> Merging [#730](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730?src=pr&el=desc) into [master](https://codecov.io/gh/parse-community/Parse-SDK-JS/commit/a4ba856ae30f1959b1852ac24f9a6904e89dd0c0?src=pr&el=desc) will **increase** coverage by `0.06%`.
> The diff coverage is `100%`.

[![Impacted file tree graph](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730/graphs/tree.svg?width=650&token=8nCENM0QHj&height=150&src=pr)](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master     #730      +/-   ##
==========================================
+ Coverage   88.64%   88.71%   +0.06%     
==========================================
  Files          53       53              
  Lines        4562     4571       +9     
  Branches     1060     1061       +1     
==========================================
+ Hits         4044     4055      +11     
+ Misses        518      516       -2
```


| [Impacted Files](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [src/ParseUser.js](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730/diff?src=pr&el=tree#diff-c3JjL1BhcnNlVXNlci5qcw==) | `69.44% <100%> (+1.22%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730?src=pr&el=footer). Last update [a4ba856...117a3e0](https://codecov.io/gh/parse-community/Parse-SDK-JS/pull/730?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

flovilmart: this gonna end up being a complete mess adding all those undocumented, un discussed and unstable features. Well have fun!

Patch:
diff --git a/src/CoreManager.js b/src/CoreManager.js
index 3dde5d4..494ebde 100644
--- a/src/CoreManager.js
+++ b/src/CoreManager.js
@@ -122,6 +122,7 @@ type UserController = {
   signUp: (user: ParseUser, attrs: AttributeMap, options: RequestOptions) => Promise;
   logIn: (user: ParseUser, options: RequestOptions) => Promise;
   become: (options: RequestOptions) => Promise;
+  hydrate: (userJSON: AttributeMap) => Promise;
   logOut: () => Promise;
   requestPasswordReset: (email: string, options: RequestOptions) => Promise;
   updateUserOnDisk: (user: ParseUser) => Promise;
diff --git a/src/ParseUser.js b/src/ParseUser.js
index cde5c1b..65fe779 100644
--- a/src/ParseUser.js
+++ b/src/ParseUser.js
@@ -638,6 +638,21 @@ class ParseUser extends ParseObject {
     return controller.become(becomeOptions);
   }
 
+  /**
+   * Logs in a user with a session token. On success, this saves the session
+   * to disk, so you can retrieve the currently logged in user using
+   * <code>current</code>. If there is no session token the user will not logged in.
+   *
+   * @param {Object} userJSON The JSON map of the User's data
+   * @static
+   * @return {Promise} A promise that is fulfilled with the user when
+   *     the login completes.
+   */
+  static hydrate(userJSON: AttributeMap) {
+    const controller = CoreManager.getUserController();
+    return controller.hydrate(userJSON);
+  }
+
   static logInWith(provider, options) {
     return ParseUser._logInWith(provider, options);
   }
@@ -954,6 +969,17 @@ const DefaultController = {
     });
   },
 
+  hydrate(userJSON: AttributeMap) {
+    const user = new ParseUser();
+    user._finishFetch(userJSON);
+    user._setExisted(true);
+    if (userJSON.sessionToken && canUseCurrentUser) {
+      return DefaultController.setCurrentUser(user);
+    } else {
+      return Promise.resolve(user);
+    }
+  },
+
   logOut(): Promise {
     return DefaultController.currentUserAsync().then((currentUser) => {
       const path = Storage.generatePath(CURRENT_USER_KEY);


Test patch:
diff --git a/src/__tests__/ParseUser-test.js b/src/__tests__/ParseUser-test.js
index 30886c5..ced1ea1 100644
--- a/src/__tests__/ParseUser-test.js
+++ b/src/__tests__/ParseUser-test.js
@@ -287,6 +287,45 @@ describe('ParseUser', () => {
     });
   });
 
+  it('can hydrate a user with sessionToken in server environment', async () => {
+    ParseUser.enableUnsafeCurrentUser();
+    ParseUser._clearCache();
+    const user = await ParseUser.hydrate({
+      objectId: 'uid3',
+      username: 'username',
+      sessionToken: '123abc',
+    });
+    expect(user.id).toBe('uid3');
+    expect(user.isCurrent()).toBe(true);
+    expect(user.existed()).toBe(true);
+  });
+
+  it('can hydrate a user with sessionToken in non server environment', async () => {
+    ParseUser.disableUnsafeCurrentUser();
+    ParseUser._clearCache();
+    const user = await ParseUser.hydrate({
+      objectId: 'uid3',
+      username: 'username',
+      sessionToken: '123abc',
+    });
+    expect(user.id).toBe('uid3');
+    expect(user.isCurrent()).toBe(false);
+    expect(user.existed()).toBe(true);
+  });
+
+  it('can hydrate a user without sessionToken', async () => {
+    ParseUser.enableUnsafeCurrentUser();
+    ParseUser._clearCache();
+    await ParseUser.logOut();
+    const user = await ParseUser.hydrate({
+      objectId: 'uid3',
+      username: 'username',
+    });
+    expect(user.id).toBe('uid3');
+    expect(user.isCurrent()).toBe(false);
+    expect(user.existed()).toBe(true);
+  });
+
   it('can send a password reset request', () => {
     CoreManager.setRESTController({
       request(method, path, body) {