Skip to content

Commit

Permalink
Improve JobManager (get errors + parse error message when importing u…
Browse files Browse the repository at this point in the history
…sers) (#407)

* Add support for retrieving errors from import jobs, Add support for parsing error message from the json body of JobsManager.importUsers when present

* Try to improve code coverage
  • Loading branch information
jbauth0 authored and luisrudge committed Aug 8, 2019
1 parent 7605352 commit 0982ca4
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 0 deletions.
59 changes: 59 additions & 0 deletions src/management/JobsManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ var JobsManager = function(options) {
);
this.jobs = new RetryRestClient(auth0RestClient, options.retry);

/**
* Provides an abstraction layer for consuming the
* {@link https://auth0.com/docs/api/v2#!/Jobs/:id/errors Errors endpoint}.
*
* @type {external:RestClient}
*/
var jobErrorsRestClient = new Auth0RestClient(
options.baseUrl + '/jobs/:id/errors',
clientOptions,
options.tokenProvider
);
this.jobErrors = new RetryRestClient(jobErrorsRestClient, options.retry);

/**
* Provides an abstraction layer for consuming the
* {@link https://auth0.com/docs/api/v2#!/Jobs/post_users_exports Create job to export users endpoint}
Expand Down Expand Up @@ -189,6 +202,13 @@ JobsManager.prototype.importUsers = function(data, cb) {
error.status = res.statusCode;
error.method = method;
error.text = res.text;
try {
if (!error.text && res.body) {
error.text = JSON.parse(res.body).message;
}
} catch (ex) {
// Ignore the error.
}
reject(error);
}
resolve(res);
Expand Down Expand Up @@ -264,6 +284,45 @@ JobsManager.prototype.exportUsers = function(data, cb) {
return this.usersExports.create(data);
};

/**
* Given a job ID, retrieve the failed/errored items
*
* @method get
* @memberOf module:management.JobsManager.prototype
*
* @example
* var params = {
* id: '{JOB_ID}'
* };
*
* management.jobs.errors(params, function (err, job) {
* if (err) {
* // Handle error.
* }
*
* // Retrieved job.
* console.log(job);
* });
*
* @param {Object} params Job parameters.
* @param {String} params.id Job ID.
* @param {Function} [cb] Callback function.
*
* @return {Promise|undefined}
*/
JobsManager.prototype.errors = function(params, cb) {
if (!params.id || typeof params.id !== 'string') {
throw new ArgumentError('The id parameter must be a valid job id');
}

if (cb && cb instanceof Function) {
return this.jobErrors.get(params, cb);
}

// Return a promise.
return this.jobErrors.get(params);
};

/**
* Send a verification email to a user.
*
Expand Down
138 changes: 138 additions & 0 deletions test/management/jobs.tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,15 @@ describe('JobsManager', function() {
});
});

it('should throw an ArgumentError if an invalid id is passed', function(done) {
try {
this.jobs.errors({ id: 12345 }, function() {});
} catch (err) {
expect(err).to.exist;
done();
}
});

it('should pass the body of the response to the "then" handler', function(done) {
nock.cleanAll();

Expand Down Expand Up @@ -148,6 +157,110 @@ describe('JobsManager', function() {
});
});

// Error retrieval tests
describe('#errors', function() {
beforeEach(function() {
this.request = nock(API_URL)
.get('/jobs/' + this.id + '/errors')
.reply(200);
});

it('should accept a callback', function(done) {
this.jobs.errors({ id: this.id }, function() {
done();
});
});

it('should return a promise if no callback is given', function(done) {
this.jobs
.errors({ id: this.id })
.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)
.get('/jobs/' + this.id + '/errors')
.reply(500);

this.jobs.errors({ id: this.id }).catch(function(err) {
expect(err).to.exist;
done();
});
});

it('should throw an ArgumentError if an invalid id is passed', function(done) {
try {
this.jobs.errors({ id: null }, function() {});
} catch (err) {
expect(err).to.exist;
done();
}
});

it('should pass the body of the response to the "then" handler', function(done) {
nock.cleanAll();

var data = [{ test: true }];
var request = nock(API_URL)
.get('/jobs/' + this.id + '/errors')
.reply(200, data);

this.jobs.errors({ id: this.id }).then(function(blacklistedTokens) {
expect(blacklistedTokens).to.be.an.instanceOf(Array);

expect(blacklistedTokens.length).to.equal(data.length);

expect(blacklistedTokens[0].test).to.equal(data[0].test);

done();
});
});

it('should perform a GET request to /api/v2/jobs/:id/errors', function(done) {
var request = this.request;

this.jobs.errors({ id: this.id }).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)
.get('/jobs/' + this.id + '/errors')
.matchHeader('Authorization', 'Bearer ' + token)
.reply(200);

this.jobs.errors({ id: this.id }).then(function() {
expect(request.isDone()).to.be.true;
done();
});
});

it('should pass the parameters in the query-string', function(done) {
nock.cleanAll();

var request = nock(API_URL)
.get('/jobs/' + this.id)
.query({
include_fields: true,
fields: 'test'
})
.reply(200);

this.jobs.get({ id: this.id, include_fields: true, fields: 'test' }).then(function() {
expect(request.isDone()).to.be.true;
done();
});
});
});

const usersFilePath = path.join(__dirname, '../data/users.json');

describe('#importUsers', function() {
Expand Down Expand Up @@ -203,6 +316,31 @@ describe('JobsManager', function() {
});
});

it('should pass rest-api json error messages to the promise catch handler', function(done) {
nock.cleanAll();

var request = nock(API_URL)
.post('/jobs/users-imports')
.reply((uri, requestBody) => {
return [
429,
{
statusCode: 429,
error: 'Too Many Requests',
message: 'There are 4 active import users jobs'
}
];
});

this.jobs.importUsers(data).catch(function(err) {
expect(err.message).to.equal(
'cannot POST https://tenant.auth0.com/jobs/users-imports (429)'
);
expect(err.text).to.equal('There are 4 active import users jobs');
done();
});
});

it('should perform a POST request to /api/v2/jobs/users-imports', function(done) {
var request = this.request;

Expand Down

0 comments on commit 0982ca4

Please sign in to comment.