Repository: auth0/auth0.js
Pull request #307 (2017-01-12 13:20:34)

Do not change casing of the user profile object
Closes https://github.com/auth0/lock/issues/798 (notify)

codecov-io: ## [Current coverage](https://codecov.io/gh/auth0/auth0.js/pull/307?src=pr) is 98.90% (diff: 100%)
> Merging [#307](https://codecov.io/gh/auth0/auth0.js/pull/307?src=pr) into [master](https://codecov.io/gh/auth0/auth0.js/branch/master?src=pr) will increase coverage by **<.01%**

```diff
@@             master       #307   diff @@
==========================================
  Files            30         30          
  Lines           997       1003     +6   
  Methods         172        172          
  Messages          0          0          
  Branches        147        152     +5   
==========================================
+ Hits            986        992     +6   
  Misses           11         11          
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [946ca79...90170ae](https://codecov.io/gh/auth0/auth0.js/compare/946ca795a51d2ca667f0130a1c031cd2039737d9...90170aedccc3354a5b23ef2ca7842e03f98d4d96?src=pr)
codecov-io: ## [Current coverage](https://codecov.io/gh/auth0/auth0.js/pull/307?src=pr) is 98.90% (diff: 100%)
> Merging [#307](https://codecov.io/gh/auth0/auth0.js/pull/307?src=pr) into [master](https://codecov.io/gh/auth0/auth0.js/branch/master?src=pr) will increase coverage by **0.01%**

```diff
@@             master       #307   diff @@
==========================================
  Files            30         30          
  Lines           997       1008    +11   
  Methods         172        172          
  Messages          0          0          
  Branches        147        153     +6   
==========================================
+ Hits            986        997    +11   
  Misses           11         11          
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [946ca79...504a925](https://codecov.io/gh/auth0/auth0.js/compare/946ca795a51d2ca667f0130a1c031cd2039737d9...504a9257b092743e98e7e83a47dbd2faf2de3ecc?src=pr)

Patch:
diff --git a/src/authentication/index.js b/src/authentication/index.js
index 37657cc..4f4b960 100644
--- a/src/authentication/index.js
+++ b/src/authentication/index.js
@@ -334,7 +334,7 @@ Authentication.prototype.userInfo = function (accessToken, cb) {
   return this.request
     .get(url)
     .set('Authorization', 'Bearer ' + accessToken)
-    .end(responseHandler(cb));
+    .end(responseHandler(cb, { ignoreCasing: true }));
 };
 
 /**
diff --git a/src/helper/object.js b/src/helper/object.js
index 758849e..1e3952c 100644
--- a/src/helper/object.js
+++ b/src/helper/object.js
@@ -1,5 +1,6 @@
 /* eslint-disable no-param-reassign */
 
+var assert = require('./assert');
 var objectAssign = require('./object-assign');
 
 function pick(object, keys) {
@@ -75,21 +76,30 @@ function snakeToCamel(str) {
 }
 
 function toSnakeCase(object, exceptions) {
+  if (typeof(object) !== 'object' || assert.isArray(object) || !object === null) {
+    return object;
+  }
+
   exceptions = exceptions || [];
 
   return Object.keys(object).reduce(function (p, key) {
     var newKey = exceptions.indexOf(key) === -1 ? camelToSnake(key) : key;
-    p[newKey] = typeof(object[key]) === 'object' ? toSnakeCase(object[key]) : object[key];
+    p[newKey] = toSnakeCase(object[key]);
     return p;
   }, {});
 }
 
 function toCamelCase(object, exceptions) {
+
+  if (typeof(object) !== 'object' || assert.isArray(object) || !object === null) {
+    return object;
+  }
+
   exceptions = exceptions || [];
 
   return Object.keys(object).reduce(function (p, key) {
     var newKey = exceptions.indexOf(key) === -1 ? snakeToCamel(key) : key;
-    p[newKey] = typeof(object[key]) === 'object' ? toCamelCase(object[key]) : object[key];
+    p[newKey] = toCamelCase(object[key]);
     return p;
   }, {});
 }
diff --git a/src/helper/response-handler.js b/src/helper/response-handler.js
index 20d9940..7862add 100644
--- a/src/helper/response-handler.js
+++ b/src/helper/response-handler.js
@@ -1,7 +1,10 @@
 var error = require('./error');
 var objectHelper = require('./object');
 
-function wrapCallback(cb) {
+function wrapCallback(cb, options) {
+  options = options || {};
+  options.ignoreCasing = options.ignoreCasing ? options.ignoreCasing : false;
+
   return function (err, data) {
     var errObj;
 
@@ -49,7 +52,15 @@ function wrapCallback(cb) {
       return cb(errObj);
     }
 
-    return cb(null, ((data.type && data.type === 'text/html') ? data.text : objectHelper.toCamelCase(data.body || data)));
+    if (data.type && (data.type === 'text/html' || data.type === 'text/plain')) {
+      return cb(null, data.text);
+    }
+
+    if (options.ignoreCasing) {
+      return cb(null, data.body || data);
+    }
+
+    return cb(null, objectHelper.toCamelCase(data.body || data));
   };
 }
 
diff --git a/src/management/index.js b/src/management/index.js
index cb712e1..2674dd6 100644
--- a/src/management/index.js
+++ b/src/management/index.js
@@ -46,7 +46,7 @@ Management.prototype.getUser = function (userId, cb) {
 
   return this.request
     .get(url)
-    .end(responseHandler(cb));
+    .end(responseHandler(cb, { ignoreCasing: true }));
 };
 
 /**
@@ -70,7 +70,7 @@ Management.prototype.patchUserMetadata = function (userId, userMetadata, cb) {
   return this.request
     .patch(url)
     .send({ user_metadata: userMetadata })
-    .end(responseHandler(cb));
+    .end(responseHandler(cb, { ignoreCasing: true }));
 };
 
 /**
@@ -95,7 +95,7 @@ Management.prototype.linkUser = function (userId, secondaryUserToken, cb) {
   return this.request
     .post(url)
     .send({ link_with: secondaryUserToken })
-    .end(responseHandler(cb));
+    .end(responseHandler(cb, { ignoreCasing: true }));
 };
 
 module.exports = Management;


Test patch:
diff --git a/test/authentication/authentication.test.js b/test/authentication/authentication.test.js
index 3a78e7a..2cda228 100644
--- a/test/authentication/authentication.test.js
+++ b/test/authentication/authentication.test.js
@@ -218,7 +218,7 @@ describe('auth0.authentication', function () {
                 user_id: '...',
                 provider: 'auth0',
                 connection: 'Username-Password-Authentication',
-                isSocial: false
+                is_social: false
               }
             });
           }
@@ -228,10 +228,10 @@ describe('auth0.authentication', function () {
       this.auth0.userInfo('abcd1234', function(err, data) {
         expect(err).to.be(null);
         expect(data).to.eql({
-          userId: '...',
+          user_id: '...',
           provider: 'auth0',
           connection: 'Username-Password-Authentication',
-          isSocial: false
+          is_social: false
         });
         done();
       })
diff --git a/test/helper/object.test.js b/test/helper/object.test.js
index be8aeab..e19fc15 100644
--- a/test/helper/object.test.js
+++ b/test/helper/object.test.js
@@ -314,9 +314,11 @@ describe('helpers', function () {
         attrName1: 'attribute_1',
         attrName22: 'attribute_2',
         attrNAME3: 'attribute_3',
+        arrayAtt: [ 'one', 'two' ],
         someObj: {
           objAtt1: 'asd',
-          objAtt2: '123'
+          objAtt2: '123',
+          innerArrayAtt: [ 'one', 'two' ]
         }
       };
 
@@ -326,19 +328,26 @@ describe('helpers', function () {
         attrName1: 'attribute_1',
         attrName22: 'attribute_2',
         attrNAME3: 'attribute_3',
+        arrayAtt: [ 'one', 'two' ],
         someObj: {
           objAtt1: 'asd',
-          objAtt2: '123'
+          objAtt2: '123',
+          innerArrayAtt: [ 'one', 'two' ]
         }
       });
 
+      expect(newObject.array_att).to.be.an('array');
+      expect(newObject.some_obj.inner_array_att).to.be.an('array');
+
       expect(newObject).to.eql({
         attr_name_1: 'attribute_1',
         attr_name_22: 'attribute_2',
         attr_name_3: 'attribute_3',
+        array_att: [ 'one', 'two' ],
         some_obj: {
           obj_att_1: 'asd',
-          obj_att_2: '123'
+          obj_att_2: '123',
+          inner_array_att: [ 'one', 'two' ]
         }
       });
     });
@@ -367,14 +376,17 @@ describe('helpers', function () {
   });
 
   describe('toCamelCase', function () {
+
     it('should change the casing to all the attributes', function () {
       var object = {
         attr_name_1: 'attribute_1',
         attr_name_22: 'attribute_2',
         attr__name_3: 'attribute_3',
+        arr_att: [ "one", "two" ],
         some_obj: {
           obj_att_1: 'asdf',
-          obj_att_2: '1234'
+          obj_att_2: '1234',
+          inner_array_att: [ 'one', 'two' ]
         }
       };
 
@@ -384,23 +396,42 @@ describe('helpers', function () {
         attr_name_1: 'attribute_1',
         attr_name_22: 'attribute_2',
         attr__name_3: 'attribute_3',
+        arr_att: [ "one", "two" ],
         some_obj: {
           obj_att_1: 'asdf',
-          obj_att_2: '1234'
+          obj_att_2: '1234',
+          inner_array_att: [ 'one', 'two' ]
         }
       });
 
+      expect(newObject.arrAtt).to.be.an('array');
+      expect(newObject.someObj.innerArrayAtt).to.be.an('array');
+
       expect(newObject).to.eql({
         attrName1: 'attribute_1',
         attrName22: 'attribute_2',
         attrName3: 'attribute_3',
+        arrAtt: [ "one", "two" ],
         someObj: {
           objAtt1: 'asdf',
-          objAtt2: '1234'
+          objAtt2: '1234',
+          innerArrayAtt: [ 'one', 'two' ]
         }
       });
     });
 
+    it.only('should not breack the string', function () {
+      var object = "some random string";
+
+      var newObject = objectHelper.toCamelCase(object);
+
+      expect(object).to.eql("some random string");
+
+      expect(newObject).to.be.a('string');
+
+      expect(newObject).to.eql("some random string");
+    });
+
     it('should change the casing to all the attributes that are not blacklisted', function () {
       var object = {
         attr_name_1: 'attribute_1',
diff --git a/test/management/management.test.js b/test/management/management.test.js
index 621df7e..9dcff27 100644
--- a/test/management/management.test.js
+++ b/test/management/management.test.js
@@ -99,7 +99,7 @@ describe('auth0.Management', function () {
       this.auth0.getUser('auth0|123', function(err, user) {
         expect(err).to.be(null);
         expect(user).to.eql({
-          'userId': 'auth0|123',
+          'user_id': 'auth0|123',
           'email': 'me@example.com'
         });
         done();
@@ -182,9 +182,9 @@ describe('auth0.Management', function () {
       this.auth0.patchUserMetadata('auth0|123', {role:'admin'}, function(err, user) {
         expect(err).to.be(null);
         expect(user).to.eql({
-          'userId': 'auth0|123',
+          'user_id': 'auth0|123',
           'email': 'me@example.com',
-          'userMetadata': { role: 'admin' }
+          'user_metadata': { role: 'admin' }
         });
         done();
       })
@@ -258,17 +258,17 @@ describe('auth0.Management', function () {
                     'connection': 'twitter',
                     'user_id': '191919191919191',
                     'provider': 'twitter',
-                    'profileData': {
+                    'profile_data': {
                       'email': '',
                       'email_verified': false,
                       'name': '',
                       'username': 'johndoe',
                       'given_name': '',
-                      'phoneNumber': '',
+                      'phone_number': '',
                       'phone_verified': false,
                       'family_name': ''
                     },
-                    'isSocial': false,
+                    'is_social': false,
                     'access_token': ''
                   }
                 ]
@@ -281,20 +281,20 @@ describe('auth0.Management', function () {
         expect(err).to.be(null);
         expect(user).to.eql([{
             'connection': 'twitter',
-            'userId': '191919191919191',
+            'user_id': '191919191919191',
             'provider': 'twitter',
-            'profileData': {
+            'profile_data': {
               'email': '',
-              'emailVerified': false,
+              'email_verified': false,
               'name': '',
               'username': 'johndoe',
-              'givenName': '',
-              'phoneNumber': '',
-              'phoneVerified': false,
-              'familyName': ''
+              'given_name': '',
+              'phone_number': '',
+              'phone_verified': false,
+              'family_name': ''
             },
-            'isSocial': false,
-            'accessToken': ''
+            'is_social': false,
+            'access_token': ''
           }]);
         done();
       })