Repository: auth0/node-auth0
Pull request #348 (2019-03-27 19:46:50)

Add method to assign users to a role
### Changes

Please describe both what is changing and why this is important. Include:

- RolesManager and roles.tests.js changed
- Added method assignUsers under RolesManager
- This endoint allows assigning users to a role

### References

### Testing

Add coverage under test/management/roles.tests.js

- [x] This change adds unit test coverage

- [x] This change adds integration test coverage

### Checklist

- [x] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)

- [ ] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)

- [ ] All existing and new tests complete without errors



Patch:
diff --git a/src/management/RolesManager.js b/src/management/RolesManager.js
index 37ef30ce4..826a15cef 100644
--- a/src/management/RolesManager.js
+++ b/src/management/RolesManager.js
@@ -352,4 +352,51 @@ RolesManager.prototype.getUsers = function(params, callback) {
   return this.users.getAll(params, callback);
 };
 
+/**
+ * Assign users to a role
+ *
+ * @method    assignUsers
+ * @memberOf  module:management.RolesManager.prototype
+ *
+ * @example
+ * var params =  { id :'ROLE_ID'};
+ * var data = { "users" : ["userId1","userId2"]};
+ *
+ * management.roles.assignUsers(params, data, function (err, user) {
+ *   if (err) {
+ *     // Handle error.
+ *   }
+ *
+ *   // permissions added.
+ * });
+ *
+ * @param   {String}    params.id                ID of the Role.
+ * @param   {Object}    data                permissions data
+ * @param   {String}    data.permissions    Array of permissions
+ * @param   {String}    data.permissions.permission_name  Name of a permission
+ * @param   {String}    data.permissions.resource_server_identifier  Identifier for a resource
+ * @param   {Function}  [cb]                  Callback function.
+ *
+ * @return  {Promise|undefined}
+ */
+
+RolesManager.prototype.assignUsers = function(params, data, cb) {
+  data = data || {};
+  params = params || {};
+
+  // Require a user ID.
+  if (!params.id) {
+    throw new ArgumentError('The roleId passed in params cannot be null or undefined');
+  }
+  if (typeof params.id !== 'string') {
+    throw new ArgumentError('The role Id has to be a string');
+  }
+
+  if (cb && cb instanceof Function) {
+    return this.permissions.create(params, data, cb);
+  }
+
+  return this.users.create(params, data);
+};
+
 module.exports = RolesManager;


Test patch:
diff --git a/test/management/roles.tests.js b/test/management/roles.tests.js
index d5687af26..fa336e1ae 100644
--- a/test/management/roles.tests.js
+++ b/test/management/roles.tests.js
@@ -26,7 +26,8 @@ describe('RolesManager', function() {
       'getPermissions',
       'addPermissions',
       'removePermissions',
-      'getUsers'
+      'getUsers',
+      'assignUsers'
     ];
 
     methods.forEach(function(method) {
@@ -700,4 +701,97 @@ describe('RolesManager', function() {
       });
     });
   });
+
+  describe('#assignUsers', function() {
+    beforeEach(function() {
+      this.data = {
+        id: 'rol_ID'
+      };
+      this.body = { users: ['userID1'] };
+
+      this.request = nock(API_URL)
+        .post('/roles/' + this.data.id + '/users')
+        .reply(200);
+    });
+
+    it('should validate empty roleId', function() {
+      var _this = this;
+      expect(function() {
+        _this.roles.assignUsers({ id: null }, _this.body, function() {});
+      }).to.throw('The roleId passed in params cannot be null or undefined');
+    });
+
+    it('should validate non-string roleId', function() {
+      var _this = this;
+      expect(function() {
+        _this.roles.assignUsers({ id: 123 }, _this.body, function() {});
+      }).to.throw('The role Id has to be a string');
+    });
+
+    it('should accept a callback', function(done) {
+      this.roles.assignUsers(this.data, {}, function() {
+        done();
+      });
+    });
+
+    it('should return a promise if no callback is given', function(done) {
+      this.roles
+        .assignUsers(this.data, {})
+        .then(done.bind(null, null))
+        .catch(done.bind(null, null));
+    });
+
+    it('should pass any errors to the promise catch handler', function(done) {
+      nock.cleanAll();
+
+      var request = nock(API_URL)
+        .post('/roles/' + this.data.id + '/users')
+        .reply(500);
+
+      this.roles.assignUsers(this.data, {}).catch(function(err) {
+        expect(err).to.exist;
+
+        done();
+      });
+    });
+
+    it('should perform a POST request to /api/v2/roles/rol_ID/users', function(done) {
+      var request = this.request;
+
+      this.roles.assignUsers(this.data, {}).then(function() {
+        expect(request.isDone()).to.be.true;
+
+        done();
+      });
+    });
+
+    it('should pass the data in the body of the request', function(done) {
+      nock.cleanAll();
+
+      var request = nock(API_URL)
+        .post('/roles/' + this.data.id + '/users', this.body)
+        .reply(200);
+
+      this.roles.assignUsers(this.data, this.body).then(function() {
+        expect(request.isDone()).to.be.true;
+
+        done();
+      });
+    });
+
+    it('should include the token in the Authorization header', function(done) {
+      nock.cleanAll();
+
+      var request = nock(API_URL)
+        .post('/roles/' + this.data.id + '/users')
+        .matchHeader('Authorization', 'Bearer ' + this.token)
+        .reply(200);
+
+      this.roles.assignUsers(this.data, {}).then(function() {
+        expect(request.isDone()).to.be.true;
+
+        done();
+      });
+    });
+  });
 });