From 576ca9254c98a3f5fd936cc514ce7a544145ce99 Mon Sep 17 00:00:00 2001 From: egli Date: Mon, 7 Jan 2019 13:55:52 +0100 Subject: [PATCH] New Jobs return error message when something wrong with archivable/retrievable bits --- common/models/dataset.js | 80 +++++----- common/models/job.js | 310 ++++++++++++++++++++++++--------------- common/models/policy.js | 9 +- common/models/utils.js | 105 ++----------- test/MessageHistory.js | 52 +++++-- 5 files changed, 296 insertions(+), 260 deletions(-) diff --git a/common/models/dataset.js b/common/models/dataset.js index 05931e1a..4efeecbe 100644 --- a/common/models/dataset.js +++ b/common/models/dataset.js @@ -45,38 +45,34 @@ module.exports = function (Dataset) { ctx.instance.version = p.version; // sourceFolder handling - if(ctx.instance.sourceFolder){ + if (ctx.instance.sourceFolder) { // remove trailing slashes ctx.instance.sourceFolder = ctx.instance.sourceFolder.replace(/\/$/, ""); // autofill datasetName - if (!ctx.instance.datasetName){ - var arr=ctx.instance.sourceFolder.split("/") - if(arr.length == 1){ - ctx.instance.datasetName=arr[0] + if (!ctx.instance.datasetName) { + var arr = ctx.instance.sourceFolder.split("/") + if (arr.length == 1) { + ctx.instance.datasetName = arr[0] } else { - ctx.instance.datasetName=arr[arr.length-2]+"/"+arr[arr.length-1] + ctx.instance.datasetName = arr[arr.length - 2] + "/" + arr[arr.length - 1] } } } - - // auto fill classification if (!ctx.instance.ownerGroup) { - return next("No owner group defined"); + next("No owner group defined"); } + + // auto fill classification and add policy if missing + var Policy = app.models.Policy; - if (!ctx.instance.classification) { - // classification undefined - Policy.findOne({ - where: { - ownerGroup: ctx.instance.ownerGroup - } - }, - function (err, policyInstance) { - if (err) { - var msg = "Error when looking for Policy of pgroup " + ctx.instance.ownerGroup + " " + err; - console.log(msg); - return next(msg); - } else if (policyInstance) { + Policy.findOne(function (err, policyInstance) { + if (err) { + var msg = "Error when looking for Policy of pgroup " + ctx.instance.ownerGroup + " " + err; + console.log(msg); + next(msg); + } else if (policyInstance) { + if (!ctx.instance.classification) { + // Case 1: classification undefined but policy defined:, define classification via policy var classification = ""; switch (policyInstance.tapeRedundancy) { case "low": @@ -92,27 +88,33 @@ module.exports = function (Dataset) { classification = "IN=medium,AV=low,CO=low"; } ctx.instance.classification = classification; - } else { - // neither a policy or a classification exist + } + // case 2: classification defined and policy defined: do nothing + return next() + } else { + let tapeRedundancy = "low" + if (!ctx.instance.classification) { + // case 3: neither a policy nor a classification exist: define default classification and create default policy ctx.instance.classification = "IN=medium,AV=low,CO=low"; - Policy.addDefault(ctx.instance.ownerGroup, ctx.instance.ownerEmail, ""); + } else { + // case 4: classification exists but no policy: create policy from classification + var classification = ctx.instance.classification; + if (classification.includes("AV=low")) { + tapeRedundancy = "low"; + } else if (classification.includes("AV=medium")) { + tapeRedundancy = "medium"; + } else if (classification.includes("AV=high")) { + tapeRedundancy = "high"; + } } - }); - } else { - // create policy from classification - var classification = ctx.instance.classification; - var tapeRedundancy = ""; - if (classification.includes("AV=low")) { - tapeRedundancy = "low"; - } else if (classification.includes("AV=medium")) { - tapeRedundancy = "medium"; - } else if (classification.includes("AV=high")) { - tapeRedundancy = "high"; + Policy.addDefault(ctx.instance.ownerGroup, ctx.instance.ownerEmail, tapeRedundancy, next); + } } - Policy.addDefault(ctx.instance.ownerGroup, ctx.instance.ownerEmail, tapeRedundancy); - } + ); + } else { + // no instance, continue + return next() } - return next(); }); // clean up data connected to a dataset, e.g. if archiving failed diff --git a/common/models/job.js b/common/models/job.js index f38dd5d9..9f283a12 100644 --- a/common/models/job.js +++ b/common/models/job.js @@ -6,6 +6,171 @@ var nodemailer = require('nodemailer'); var config = require('../../server/config.local'); var app = require('../../server/server'); + +function sendMail(to, subjectText, mailText, next) { + if ('smtpSettings' in config && 'smtpMessage' in config) { + let transporter = nodemailer.createTransport(config.smtpSettings); + transporter.verify(function (error, success) { + if (error) { + console.log(error); + next(); + } else { + console.log('Server is ready to send message to ', to); + var message = Object.assign({}, config.smtpMessage); + message['to'] = to; + message['subject'] += subjectText + message['text'] = mailText + transporter.sendMail(message, function (err, info) { + if (err) { + console.log(err); + } else { + console.log('Email sent'); + } + next(); + }); + } + }); + } else { + next() + } +} + +function publishJob(job, ctx, next) { + if ('queue' in config && config.queue === 'rabbitmq') { + job.publishJob(ctx.instance, "jobqueue") + console.log('Saved Job %s#%s and published to message broker', ctx.Model.modelName, ctx.instance.id); + } + + let subjectText = ' ' + ctx.instance.type + ' job submitted successfully'; + let mailText = 'Hello, \n\n You created a job to ' + ctx.instance.type + ' datasets. Your job was received and will be completed as soon as possible. \n\n Many Thanks.\n\n' + JSON.stringify(ctx.instance, null, 4); + let to = ctx.instance.emailJobInitiator + sendMail(to, subjectText, mailText, next) +} + +function MarkDatasetsAsScheduled(job, ctx, idList, next) { + //console.log('Searching for datasetlifecycle with ids:', idList) + let DatasetLifecycle = app.models.DatasetLifecycle; + DatasetLifecycle.updateAll( + { + datasetId: { + inq: idList + } + }, + { + archivable: false, + retrievable: false, + archiveStatusMessage: "scheduledForArchiving" + } + , ctx.options, function (err, p) { + // console.log("============= DatasetLifecycle Result:", JSON.stringify(p)) + if (err) { + var e = new Error(); + e.statusCode = 400; + e.message = 'Can not find all needed DatasetLifecycle entries - no archive job sent:\n' + JSON.stringify(err) + next(e); + } else { + publishJob(job, ctx, next) + } + }); +} +// for archive jobs all datasets must be in state archivable +function TestArchiveJobs(job, ctx, idList, next) { + let Dataset = app.models.Dataset; + Dataset.find({ + where: { + archivable: false, + pid: { + inq: idList + } + } + }, ctx.options, function (err, p) { + //console.log("============= Archive Result:", JSON.stringify(p)) + if (p.length > 0) { + var e = new Error(); + e.statusCode = 400; + e.message = 'The following datasets are not in archivable state - no archive job sent:\n' + JSON.stringify(p) + next(e); + } else { + // mark all Datasets as in state scheduledForArchiving, archivable=false + MarkDatasetsAsScheduled(job, ctx, idList, next) + } + }); + +} + +// for retrieve jobs all datasets must be in state retrievable +// ownerGroup is tested implicitly via Ownable + +function TestRetrieveJobs(job, ctx, idList, next) { + let Dataset = app.models.Dataset; + Dataset.find({ + where: { + retrievable: true, + pid: { + inq: idList + } + } + }, ctx.options, function (err, p) { + // console.log("============= Retrieve Result:",JSON.stringify(p)) + if (err) { + return next(err) + } else if (p.length != idList.length) { + Dataset.find({ + where: { + retrievable: false, + pid: { + inq: idList + } + } + }, ctx.options, function (err2, pmiss) { + if (err2) { + return next(err2) + } else { + var e = new Error(); + e.statusCode = 400; + e.message = 'The following datasets are not in retrievable state - no retrieve job sent:\n' + JSON.stringify(pmiss) + return next(e); + } + }) + } else { + publishJob(job, ctx, next); + } + }); +} + +function TestAllDatasets(job, ctx, idList, next) { + //console.log(" ====== find datasets with id", idList) + let Dataset = app.models.Dataset; + Dataset.find({ + where: { + pid: { + inq: idList + } + } + }, ctx.options, function (err, p) { + let to = ctx.instance.emailJobInitiator + if (err || (p.length != idList.length)) { + var e = new Error(); + e.statusCode = 400; + e.message = 'At least one of the datasets could not be found - no Job sent'; + // TODO should I send an email here ? Only if triggered by autoarchive option ? + // subjectText = + // mailText= + // sendMail(to, subjectText, mailText, next) + return next(e) + } else { + //test if all datasets are in archivable state + if (ctx.instance.type == "archive") { + TestArchiveJobs(job, ctx, idList, next) + } else if (ctx.instance.type == "retrieve") { + TestRetrieveJobs(job, ctx, idList, next) + } else { + publishJob(job, ctx, next) + } + } + }); +} + module.exports = function (Job) { // Attach job submission to Kafka @@ -16,134 +181,49 @@ module.exports = function (Job) { var dataSource = new DataSource('kafka', options); Job.attachTo(dataSource); } + Job.observe('before save', (ctx, next) => { - // replace email with that from userIdentity - var UserIdentity = app.models.UserIdentity; - var userId = ctx.options.accessToken.userId; - //PersistedModel Static Method call - UserIdentity.findOne({ - //json filter - where: { - userId: userId - } - }, function(err, instance) { - if(!!instance) - { - ctx.instance.emailJobInitiator = instance.profile.email; - } - }); if (ctx.instance) { - // auto fill dateOfLastMessage - var now = new Date(); - if (!ctx.instance.dateOfLastMessage) { - ctx.instance.dateOfLastMessage = now.toISOString(); - } - // make some consistency checks: - // - ensure that all wanted datasets exist already - // - TODO: for archive jobs all datasetslifecycle should be in an "archiveable" state - // TODO ensure that job is created by user who has read access to all datasets in case of retrieve JOBS - var Dataset = app.models.Dataset; - // create array of all pids - // console.log("Verifying datasets:",ctx.options) - const idList=ctx.instance.datasetList.map(x => x.pid) - Dataset.find({where: {pid: {inq: idList}}}, ctx.options, function (err, p){ - //console.log("JOBS:lengths",err,p.length,idList.length,p) - if (err || (p.length != idList.length)){ - var e = new Error(); - e.statusCode = 400; - e.message = 'At least one of the datasets could not be found'; - next(e); - } else { - next(); - } - }); - //test for datasets already archived - /*var Lifecycle = app.models.DatasetLifecycle; - Lifecycle.find({ + + // replace email with that from userIdentity + var UserIdentity = app.models.UserIdentity; + var userId = ctx.options.accessToken.userId; + //PersistedModel Static Method call + UserIdentity.findOne({ + //json filter where: { - archivable: false, - datasetId: { - inq: idList - } + userId: userId } - }, ctx.options, function(err, p) { - console.log("LifeCycle: ", p, idList); - if (p.length > 0) { - var e = new Error(); - e.statusCode = 400; - e.message = 'At least one of the datasets is already archived'; - next(e); + }, function (err, u) { + if (!!u) { + ctx.instance.emailJobInitiator = u.profile.email; } - else { - next(); + // auto fill dateOfLastMessage + var now = new Date(); + if (!ctx.instance.dateOfLastMessage) { + ctx.instance.dateOfLastMessage = now.toISOString(); } - });*/ + next() + }) } else { - next(); + next() } }); Job.observe('after save', (ctx, next) => { if (ctx.instance && ctx.isNewInstance) { - - if ('queue' in config && config.queue === 'rabbitmq') { - Job.publishJob(ctx.instance, "jobqueue") - console.log('Saved Job %s#%s and published to message broker', ctx.Model.modelName, ctx.instance.id); - } - if ('smtpSettings' in config && 'smtpMessage' in config) { - let transporter = nodemailer.createTransport(config.smtpSettings); - transporter.verify(function (error, success) { - if (error) { - console.log(error); - next(); - } else { - console.log('Server is ready to take our messages'); - var message = Object.assign({}, config.smtpMessage); - message['to'] = ctx.instance.emailJobInitiator; - message['subject'] += ' ' + ctx.instance.type + ' job submitted successfully'; - let text = 'Hello, \n\n You created a job to ' + ctx.instance.type + ' datasets. Your job was received and will be completed as soon as possible. \n\n Many Thanks.\n\n'+JSON.stringify(ctx.instance, null, 4); - message['text'] = text; - transporter.sendMail(message, function (err, info) { - if (err) { - console.log(err); - } else { - console.log('Email sent'); - } - next(); - }); - } - }); - } else { - next() - } + // first create array of all pids + const idList = ctx.instance.datasetList.map(x => x.pid) + // this is a new job, make some consistency checks concerning the datasets + TestAllDatasets(Job, ctx, idList, next) } else { - if ('smtpSettings' in config && 'smtpMessage' in config) { - if (ctx.instance.jobStatusMessage.startsWith("finish")) { - let transporter = nodemailer.createTransport(config.smtpSettings); - transporter.verify(function(error, success) { - if (error) { - console.log(error); - next(); - } else { - console.log('Server is ready to send message to ', ctx.instance.emailJobInitiator); - var message = Object.assign({}, config.smtpMessage); - message['to'] = ctx.instance.emailJobInitiator; - message['subject'] += ' '+ctx.instance.type + ' job from ' + ctx.instance.creationTime.toISOString().replace(/T/, ' ').replace(/\..+/, '') + ' (UTC) finished with status ' + ctx.instance.jobStatusMessage; - let text = 'Hello, \n\n Your Job from ' + ctx.instance.creationTime + ' is now finished. \n\n The resulting job description is.\n\n' + JSON.stringify(ctx.instance, null, 4); - message['text'] = text; - transporter.sendMail(message, function(err, info) { - if (err) { - console.log(err); - } else { - console.log('Email sent'); - } - next(); - }); - } - }); - } else { - next() - } + // An existing job got some updates - check if you want to send an email + if (ctx.instance.jobStatusMessage.startsWith("finish")) { + // TODO add infos about which Datasets failed if this info is not yet in historyMessages of the Job + let subjectText = ' ' + ctx.instance.type + ' job from ' + ctx.instance.creationTime.toISOString().replace(/T/, ' ').replace(/\..+/, '') + ' (UTC) finished with status ' + ctx.instance.jobStatusMessage; + let mailText = 'Hello, \n\n Your Job from ' + ctx.instance.creationTime + ' is now finished. \n\n The resulting job description is.\n\n' + JSON.stringify(ctx.instance, null, 4); + let to = ctx.instance.emailJobInitiator + sendMail(to, subjectText, mailText, next) } else { next() } diff --git a/common/models/policy.js b/common/models/policy.js index 96f33f18..24a251b7 100644 --- a/common/models/policy.js +++ b/common/models/policy.js @@ -46,8 +46,8 @@ module.exports = function(Policy) { } }); - Policy.addDefault = function(ownerGroup, ownerEmail, tapeRedundancy) { - // TODO: move the deault definition somewhere more sensible + Policy.addDefault = function(ownerGroup, ownerEmail, tapeRedundancy, next) { + // TODO: move the default definition somewhere more sensible var defaultPolicy = Object(); defaultPolicy.ownerGroup = ownerGroup; if (config && !ownerEmail) { @@ -69,11 +69,10 @@ module.exports = function(Policy) { defaultPolicy.archiveEmailsToBeNotified = defaultPolicy.manager; defaultPolicy.retrieveEmailsToBeNotified = defaultPolicy.manager; defaultPolicy.embargoPeriod = 3; - //filter must be an object - var filter = JSON.parse('{"where": {"ownerGroup":"' + ownerGroup + '"}}'); - Policy.findOrCreate(filter, defaultPolicy); + Policy.findOrCreate(defaultPolicy, next); }; + // TODO: understand the following method Policy.updatewhere = async function(where, data) { // where should look like {"or": [{"id":"5c0fe54ed8cc493d4b259989"},{"id": "5c110c90f1e2772bdb1dd868"}]} return Policy.update(where, data); diff --git a/common/models/utils.js b/common/models/utils.js index fd1d3781..8ae4595f 100644 --- a/common/models/utils.js +++ b/common/models/utils.js @@ -12,7 +12,7 @@ var exports = module.exports = {}; // Note: Depending on the request PUT/POST etc either ctx.instance or ctx.currentInstance is set -exports.transferSizeToDataset = function(obj, sizeField, ctx, next) { +exports.transferSizeToDataset = function (obj, sizeField, ctx, next) { var instance = ctx.instance if (!instance) { instance = ctx.currentInstance @@ -31,7 +31,7 @@ exports.transferSizeToDataset = function(obj, sizeField, ctx, next) { } } obj.find(filter, ctx.options).then(instances => { - var total = instances.reduce(function(sum, value) { + var total = instances.reduce(function (sum, value) { return sum + value[sizeField] }, 0); @@ -40,9 +40,9 @@ exports.transferSizeToDataset = function(obj, sizeField, ctx, next) { if (instance) { // important to pass options here, otherwise context gets lost instance.updateAttributes({ - [sizeField]: total - }, ctx.options, - function(err, instance) { + [sizeField]: total + }, ctx.options, + function (err, instance) { if (err) { var error = new Error(); error.statusCode = 403; @@ -73,7 +73,7 @@ exports.transferSizeToDataset = function(obj, sizeField, ctx, next) { } // add ownerGroup field from linked Datasets -exports.addOwnerGroup = function(ctx, next) { +exports.addOwnerGroup = function (ctx, next) { var instance = ctx.instance if (!instance) { instance = ctx.currentInstance @@ -114,8 +114,8 @@ exports.addOwnerGroup = function(ctx, next) { // transform date strings in all fields with key dateKeys to updateTimesToUTC // do nothing if input values are already UTC -exports.updateTimesToUTC = function(dateKeys, instance) { - dateKeys.map(function(dateKey) { +exports.updateTimesToUTC = function (dateKeys, instance) { + dateKeys.map(function (dateKey) { if (instance[dateKey]) { // console.log("Updating old ", dateKey, instance[dateKey]) instance[dateKey] = moment.tz(instance[dateKey], moment.tz.guess()).format(); @@ -124,7 +124,7 @@ exports.updateTimesToUTC = function(dateKeys, instance) { }); } -exports.createNewFacetPipeline = function(name, type, query) { +exports.createNewFacetPipeline = function (name, type, query) { const pipeline = []; if (type.constructor === Array) { @@ -175,10 +175,10 @@ exports.createNewFacetPipeline = function(name, type, query) { // dito but for array of instances -exports.updateAllTimesToUTC = function(dateKeys, instances) { - dateKeys.map(function(dateKey) { +exports.updateAllTimesToUTC = function (dateKeys, instances) { + dateKeys.map(function (dateKey) { // console.log("Updating all time field %s to UTC for %s instances:", dateKey, instances.length) - instances.map(function(instance) { + instances.map(function (instance) { if (instance[dateKey]) { // console.log("Updating old ",dateKey,instance[dateKey]) instance[dateKey] = moment.tz(instance[dateKey], moment.tz.guess()).format() @@ -188,7 +188,7 @@ exports.updateAllTimesToUTC = function(dateKeys, instances) { }); } -exports.handleOwnerGroups = function(ctx, next) { +exports.handleOwnerGroups = function (ctx, next) { if (!ctx.args.fields) ctx.args.fields = {}; let userId = ctx.req.accessToken && ctx.req.accessToken.userId; @@ -203,7 +203,7 @@ exports.handleOwnerGroups = function(ctx, next) { next(e); } - User.findById(userId, function(err, user) { + User.findById(userId, function (err, user) { if (err) { next(err); } else if (user['username'].indexOf('.') === -1) { @@ -215,7 +215,7 @@ exports.handleOwnerGroups = function(ctx, next) { where: { userId: userId } - }, function(err, instance) { + }, function (err, instance) { console.log("UserIdentity Instance:", instance) if (instance && instance.profile) { var foundGroups = instance.profile.accessGroups; @@ -238,78 +238,3 @@ exports.handleOwnerGroups = function(ctx, next) { } }); } - - -exports.createArchiveJob = function(UserIdentity, Policy, Job, ctx) { - var instance = ctx.instance - if (!instance) { - instance = ctx.currentInstance - } - console.log("Instance:", JSON.stringify(instance)) - - const token = ctx.options && ctx.options.accessToken; - const userId = token && token.userId; - - console.log("options, userid:", ctx.options, userId) - //const user = userId ? 'user#' + userId : ''; - UserIdentity.findOne({ - where: { - userId: userId - } - }, function(err, user) { - console.log("UserIdentity Instance:", user) - // TODO: get it from User models - // TODO get proper emails in case of unctional accounts - // TODO remove console.log messages - // TODO add test cases - // TODO add creationTime (should not be needed any more) - var email - var login - if (user && user.profile) { - login = user.profile.login - email = user.profile.email - } else { - login = Object.keys(ctx.options.authorizedRoles)[0] - email = login - } - console.log("Email:", email) // check if a normal user or an internal ROLE - Policy.findOne({ - where: { - ownerGroup: instance.ownerGroup - } - }, function(err2, policyInstance) { - // get policy values for the instance.ownerGroups - if (err2) { - console.log("Error when looking for Policy of pgroup ", instance.ownerGroup, err2) - } else { - var jobParams = {} - jobParams.username = login - if (policyInstance) { - jobParams.autoArchive = (autoArchive in policyInstance) ? policyInstance.autoArchive : false - jobParams.tapeCopies = (tapeCopies in policyInstance) ? policyInstance.tapeCopies : "one" - } else { - console.log("No policy settings found for ownerGroup", instance.ownerGroup) - console.log("Assuming default values") - jobParams.autoArchive = false - jobParams.tapeCopies = "one" - } - var body = { - emailJobInitiator: email, - type: "archive", - jobParams: jobParams, - datasetList: [{ - pid: instance.datasetId, - files: [] - }] - } - console.log("Job body:", body) - if (jobParams.autoArchive) { - Job.create(body, function(err, jobmodel) { - console.log("Created Job:", err, jobmodel) - }) - } - } - - }) - }) -}; diff --git a/test/MessageHistory.js b/test/MessageHistory.js index 5299deb9..3d90e0c3 100644 --- a/test/MessageHistory.js +++ b/test/MessageHistory.js @@ -101,19 +101,21 @@ var testDatasetLifecycle = { "retrieveStatusMessage": "", "isExported": false, "archivable": true, - "retrievable": false, + "retrievable": true, "MessageHistory": [{ "shortMessage": "datasetCreated", - "sender": "stephan.egli@psi.ch", + "sender": "scicatarchivemanager@psi.ch", "payload": { "text": "Nothing special to report" } }] } -var testjob = { +//TODO test to retrieve datasets where you are NOT the owner + +var testArchiveJob = { "emailJobInitiator": "scicatarchivemanger@psi.ch", - "type": "retrieve", + "type": "archive", "jobStatusMessage": "jobForwarded", "datasetList": [{ "pid": "dummy", @@ -124,11 +126,21 @@ var testjob = { } +var testRetrieveJob = { + "emailJobInitiator": "scicatarchivemanger@psi.ch", + "type": "retrieve", + "jobStatusMessage": "jobForwarded", + "datasetList": [{ + "pid": "dummy", + "files": [] + }], + "archiveReturnMessage": "will move to messageList", + "MessageHistory": [] +} -// TODO do I need to pass id explicitly ? var newMessage = { "shortMessage": "JustAnExample", - "sender": "stephan.egli@psi.ch", + "sender": "ingestor", "payload": { "text": "whatever" } @@ -175,7 +187,8 @@ describe('Test MessageHistory in jobs', () => { var pidtest = res.body['pid'] testDatasetLifecycle.id = pidtest testDatasetLifecycle.datasetId = pidtest - testjob.datasetList[0].pid = pidtest + testArchiveJob.datasetList[0].pid = pidtest + testRetrieveJob.datasetList[0].pid = pidtest pid = encodeURIComponent(res.body['pid']); done(); }); @@ -225,10 +238,27 @@ describe('Test MessageHistory in jobs', () => { }); - it('Adds a new job request', function(done) { + it('Adds a new archive job request', function(done) { + request(app) + .post('/api/v2/Jobs?access_token=' + accessTokenIngestor) + .send(testArchiveJob) + .set('Accept', 'application/json') + .expect(200) + .expect('Content-Type', /json/) + .end(function(err, res) { + if (err) + return done(err); + res.body.should.have.property('type').and.be.string; + idJob = res.body['id'] + //console.log("Jobid:", idJob) + done(); + }); + }); + + it('Adds a new retrieve job request', function(done) { request(app) .post('/api/v2/Jobs?access_token=' + accessTokenIngestor) - .send(testjob) + .send(testRetrieveJob) .set('Accept', 'application/json') .expect(200) .expect('Content-Type', /json/) @@ -237,7 +267,7 @@ describe('Test MessageHistory in jobs', () => { return done(err); res.body.should.have.property('type').and.be.string; idJob = res.body['id'] - console.log("Jobid:", idJob) + //console.log("Jobid:", idJob) done(); }); }); @@ -252,7 +282,7 @@ describe('Test MessageHistory in jobs', () => { .end(function(err, res) { if (err) return done(err); - console.log(res.body) + //console.log(res.body) done(); }); });