Repository: auth0/node-auth0
Pull request #224 (2017-12-08 10:20:27)

fixed missing data object error
Fixes issue https://github.com/auth0/node-auth0/issues/223

Following code `delete args[X];` does not change the `length` of the array. This caused an error in the depended `rest-facade` library.

Solution, convert the `array-like` `arguments` object to an array, and remove the item so the `length` property is correct.


Patch:
diff --git a/src/RetryRestClient.js b/src/RetryRestClient.js
index 088def004..78b7cd097 100644
--- a/src/RetryRestClient.js
+++ b/src/RetryRestClient.js
@@ -62,9 +62,10 @@ RetryRestClient.prototype.delete = function ( /* [params], [callback] */ ) {
 
 RetryRestClient.prototype.invoke = function(method, args){
   var cb;
+  args = Array.prototype.slice.call(args); // convert array-like object to array.
   if(args && args[args.length -1] instanceof Function){
     cb = args[args.length -1];
-    delete args[args.length -1];
+    args.pop(); // Remove the callback
   }
 
   var promise = this.handleRetry(method, args);


Test patch:
diff --git a/test/retry-rest-client.tests.js b/test/retry-rest-client.tests.js
index ee73e0ff4..5993b7b44 100644
--- a/test/retry-rest-client.tests.js
+++ b/test/retry-rest-client.tests.js
@@ -59,7 +59,7 @@ describe('RetryRestClient', function () {
     });
   });
 
-  it('should return promise when no callback is provided', function(done){
+  it('should return promise for successful request when no callback is provided', function(done){
     nock(API_URL)
       .get('/')
       .reply(200, { success: true });
@@ -85,7 +85,7 @@ describe('RetryRestClient', function () {
     });
   });
 
-  it('should return promise when no callback is provided', function(done){
+  it('should return promise for failed request when no callback is provided', function(done){
     nock(API_URL)
       .get('/')
       .reply(500);
@@ -294,4 +294,65 @@ describe('RetryRestClient', function () {
         done();
       });
   });
+
+  it('should remove callback from arguments object if data is passed', function (done) {
+    var self = this;
+    var restClientSpy = {
+      create: function(){
+        expect(arguments.length).to.be.equal(1);
+        done();
+        return Promise.resolve();
+      }
+    }
+
+    var client = new RetryRestClient(restClientSpy, { enabled: false });
+    client.create({data: 'foobar'}, function() { });
+  });
+
+  it('should remove callback from arguments object if urlParams and data is passed', function (done) {
+    var self = this;
+    var restClientSpy = {
+      create: function(){
+        expect(arguments.length).to.be.equal(2);
+        done();
+        return Promise.resolve();
+      }
+    }
+
+    var client = new RetryRestClient(restClientSpy, { enabled: false });
+    var urlParams = { id: '123' };
+    var data =  {data: 'foobar'};
+    client.create('/:id', data, function() { });
+  });
+
+  it('should not remove data object when no callback is passed', function (done) {
+    var self = this;
+    var restClientSpy = {
+      create: function(){
+        expect(arguments.length).to.be.equal(1);
+        done();
+        return Promise.resolve();
+      }
+    }
+
+    var client = new RetryRestClient(restClientSpy, { enabled: false });
+    var data =  {data: 'foobar'};
+    client.create(data);
+  });
+
+  it('should not remove data object when urlParams is passed and no callback is passed', function (done) {
+    var self = this;
+    var restClientSpy = {
+      create: function(){
+        expect(arguments.length).to.be.equal(2);
+        done();
+        return Promise.resolve();
+      }
+    }
+
+    var client = new RetryRestClient(restClientSpy, { enabled: false });
+    var urlParams = { id: '123' };
+    var data =  {data: 'foobar'};
+    client.create('/:id', data);
+  });
 });
\ No newline at end of file