diff --git a/.jshintrc b/.jshintrc index 4cd07cd..7de9d84 100644 --- a/.jshintrc +++ b/.jshintrc @@ -7,7 +7,7 @@ "curly": false, // Require {} for every new block or scope. "eqeqeq": true, // Require triple equals i.e. `===`. "immed": true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` - "latedef": true, // Prohibit variable use before definition. + "latedef": false, // Prohibit variable use before definition. "newcap": true, // Require capitalization of all constructor functions e.g. `new F()`. "noarg": true, // Prohibit use of `arguments.caller` and `arguments.callee`. "quotmark": "single", // Define quotes to string values. @@ -38,5 +38,6 @@ ], "indent": 4, // Specify indentation spacing "devel": true, // Allow development statements e.g. `console.log();`. - "noempty": true // Prohibit use of empty blocks. -} \ No newline at end of file + "noempty": true, // Prohibit use of empty blocks. + "maxerr": 10000 +} diff --git a/app/controllers/articles.server.controller.js b/app/controllers/articles.server.controller.js index 0a24e81..add57e2 100644 --- a/app/controllers/articles.server.controller.js +++ b/app/controllers/articles.server.controller.js @@ -1,109 +1,86 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Article = mongoose.model('Article'), - _ = require('lodash'); - +var mongoose = require('mongoose'), errorHandler = require('./errors.server.controller'), Article = mongoose.model('Article'), _ = require('lodash'); /** * Create a article */ -exports.create = function(req, res) { - var article = new Article(req.body); - article.user = req.user; - - article.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(article); - } - }); +exports.create = function (req, res) { + var article = new Article(req.body); + article.user = req.user; + article.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.json(article); + } + }); }; - /** * Show the current article */ -exports.read = function(req, res) { - res.json(req.article); +exports.read = function (req, res) { + res.json(req.article); }; - /** * Update a article */ -exports.update = function(req, res) { - var article = req.article; - - article = _.extend(article, req.body); - - article.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(article); - } - }); +exports.update = function (req, res) { + var article = req.article; + article = _.extend(article, req.body); + article.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.json(article); + } + }); }; - /** * Delete an article */ -exports.delete = function(req, res) { - var article = req.article; - - article.remove(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(article); - } - }); +exports.delete = function (req, res) { + var article = req.article; + article.remove(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.json(article); + } + }); }; - /** * List of Articles */ -exports.list = function(req, res) { - Article.find().sort('-created').populate('user', 'displayName').exec(function(err, articles) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.json(articles); - } - }); +exports.list = function (req, res) { + Article.find().sort('-created').populate('user', 'displayName').exec(function (err, articles) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.json(articles); + } + }); }; - /** * Article middleware */ -exports.articleByID = function(req, res, next, id) { - Article.findById(id).populate('user', 'displayName').exec(function(err, article) { - if (err) return next(err); - if (!article) return next(new Error('Failed to load article ' + id)); - req.article = article; - next(); - }); +exports.articleByID = function (req, res, next, id) { + Article.findById(id).populate('user', 'displayName').exec(function (err, article) { + if (err) + return next(err); + if (!article) + return next(new Error('Failed to load article ' + id)); + req.article = article; + next(); + }); }; - /** * Article authorization middleware */ -exports.hasAuthorization = function(req, res, next) { - if (req.article.user.id !== req.user.id) { - return res.status(403).send({ - message: 'User is not authorized' - }); - } - next(); +exports.hasAuthorization = function (req, res, next) { + if (req.article.user.id !== req.user.id) { + return res.status(403).send({ message: 'User is not authorized' }); + } + next(); }; \ No newline at end of file diff --git a/app/controllers/core.server.controller.js b/app/controllers/core.server.controller.js index f2af8e1..60ac9ea 100644 --- a/app/controllers/core.server.controller.js +++ b/app/controllers/core.server.controller.js @@ -1,11 +1,10 @@ 'use strict'; - /** * Module dependencies. */ -exports.index = function(req, res) { - res.render('index', { - user: req.user || null, - request: req - }); +exports.index = function (req, res) { + res.render('index', { + user: req.user || null, + request: req + }); }; \ No newline at end of file diff --git a/app/controllers/dashboards.server.controller.js b/app/controllers/dashboards.server.controller.js index a1e270a..087309f 100644 --- a/app/controllers/dashboards.server.controller.js +++ b/app/controllers/dashboards.server.controller.js @@ -1,191 +1,162 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Dashboard = mongoose.model('Dashboard'), - Product = mongoose.model('Product'), - Metric = mongoose.model('Metric'), - _ = require('lodash'); - - -exports.clone = function(req, res){ - - var dashboardClone = new Dashboard(); - var metricCloneArray = []; - - - _.each(req.dashboard.metrics, function (metric){ - - var metricClone = new Metric(); - metricClone.dashboardId = dashboardClone._id; - metricClone.alias = metric.alias; - metricClone.targets = metric.targets; - metricClone.benchmarkOperator = metric.benchmarkOperator; - metricClone.benchmarkValue = metric.benchmarkValue; - metricClone.requirementValue = metric.requirementValue; - metricClone.requirementOperator = metric.requirementOperator; - metricClone.tags = metric.tags; - metricCloneArray.push(metricClone._id); - - - metricClone.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } - }); - +var mongoose = require('mongoose'), errorHandler = require('./errors.server.controller'), Dashboard = mongoose.model('Dashboard'), Product = mongoose.model('Product'), Metric = mongoose.model('Metric'), _ = require('lodash'); +exports.clone = function (req, res) { + var dashboardClone = new Dashboard(); + var metricCloneArray = []; + _.each(req.dashboard.metrics, function (metric) { + var metricClone = new Metric(); + metricClone.dashboardId = dashboardClone._id; + metricClone.alias = metric.alias; + metricClone.targets = metric.targets; + metricClone.benchmarkOperator = metric.benchmarkOperator; + metricClone.benchmarkValue = metric.benchmarkValue; + metricClone.requirementValue = metric.requirementValue; + metricClone.requirementOperator = metric.requirementOperator; + metricClone.tags = metric.tags; + metricCloneArray.push(metricClone._id); + metricClone.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } }); - - dashboardClone.name = req.dashboard.name + '-CLONE'; - dashboardClone.metricsRegexWily = req.dashboard.metricsRegexWily; - dashboardClone.metrics = metricCloneArray; - dashboardClone.productId = req.dashboard.productId; - dashboardClone.granularity = req.dashboard.granularity; - dashboardClone.metricsRegexWily = req.dashboard.metricsRegexWily; - dashboardClone.hosts = req.dashboard.hosts; - dashboardClone.applications = req.dashboard.applications; - - dashboardClone.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(dashboardClone); - } - }); - + }); + dashboardClone.name = req.dashboard.name + '-CLONE'; + dashboardClone.metricsRegexWily = req.dashboard.metricsRegexWily; + dashboardClone.metrics = metricCloneArray; + dashboardClone.productId = req.dashboard.productId; + dashboardClone.granularity = req.dashboard.granularity; + dashboardClone.metricsRegexWily = req.dashboard.metricsRegexWily; + dashboardClone.hosts = req.dashboard.hosts; + dashboardClone.applications = req.dashboard.applications; + dashboardClone.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(dashboardClone); + } + }); }; - /** * Create a Dashboard */ -exports.create = function(req, res) { - var dashboard = new Dashboard(req.body); - dashboard.user = req.user; - - - dashboard.productId = req.product._id; - - dashboard.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(dashboard); - } - }); - +exports.create = function (req, res) { + var dashboard = new Dashboard(req.body); + dashboard.user = req.user; + dashboard.productId = req.product._id; + dashboard.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(dashboard); + } + }); }; - - /** * Update a Dashboard */ -exports.update = function(req, res) { - var dashboard = req.dashboard ; - - dashboard.name = req.body.name; - dashboard.description = req.body.description; - dashboard.tags = req.body.tags; - dashboard.baseline = req.body.baseline; - dashboard.useInBenchmark = req.body.useInBenchmark; - - dashboard.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(dashboard); - } - }); +exports.update = function (req, res) { + var dashboard = req.dashboard; + dashboard.name = req.body.name; + dashboard.description = req.body.description; + dashboard.tags = req.body.tags; + dashboard.baseline = req.body.baseline; + dashboard.useInBenchmark = req.body.useInBenchmark; + dashboard.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(dashboard); + } + }); }; - /** * Delete an Dashboard */ -exports.delete = function(req, res) { - var dashboard = req.dashboard ; - - dashboard.remove(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(dashboard); - } - }); +exports.delete = function (req, res) { + var dashboard = req.dashboard; + dashboard.remove(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(dashboard); + } + }); }; - /** * List of Dashboards */ -exports.list = function(req, res) { - Dashboard.find().sort('-created').populate('metrics').exec(function(err, dashboards) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(dashboards); - } - }); +exports.list = function (req, res) { + Dashboard.find().sort('-created').populate('metrics').exec(function (err, dashboards) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(dashboards); + } + }); }; - /** * Show the current Dashboard */ -exports.read = function(req, res) { - Dashboard.findOne({productId: req.product._id, name: req.params.dashboardName.toUpperCase()}).populate({path: 'metrics', options: { sort: { tag: 1, alias: 1 } } }).exec(function(err, dashboard){ - if (err) return next(err); - if (! dashboard) return res.status(404).send({ - message: 'No dashboard with name' + req.params.dashboardName + 'has been found' - }); - res.jsonp(dashboard); - }) - +exports.read = function (req, res) { + Dashboard.findOne({ + productId: req.product._id, + name: req.params.dashboardName.toUpperCase() + }).populate({ + path: 'metrics', + options: { + sort: { + tag: 1, + alias: 1 + } + } + }).exec(function (err, dashboard) { + if (err) + return next(err); + if (!dashboard) + return res.status(404).send({ message: 'No dashboard with name' + req.params.dashboardName + 'has been found' }); + res.jsonp(dashboard); + }); }; - /** * Dashboard middleware */ -exports.dashboardByID = function(req, res, next, id) { - Dashboard.findById(id).populate({path: 'metrics', options: { sort: { tag: 1, alias: 1 } } }).exec(function(err, dashboard) { - if (err) return next(err); - if (! dashboard) return next(new Error('Failed to load Dashboard ' + id)); - req.dashboard = dashboard ; - next(); - }); +exports.dashboardByID = function (req, res, next, id) { + Dashboard.findById(id).populate({ + path: 'metrics', + options: { + sort: { + tag: 1, + alias: 1 + } + } + }).exec(function (err, dashboard) { + if (err) + return next(err); + if (!dashboard) + return next(new Error('Failed to load Dashboard ' + id)); + req.dashboard = dashboard; + next(); + }); }; - -exports.dashboardByProductName = function(req, res, next, productName) { - Product.findOne({name: productName.toUpperCase()}).exec(function(err, product) { - if (err) return next(err); - if (! product) return res.status(404).send({ - message: 'No product with name' + productName + 'has been found' - }); - req.product = product ; - next(); - }); +exports.dashboardByProductName = function (req, res, next, productName) { + Product.findOne({ name: productName.toUpperCase() }).exec(function (err, product) { + if (err) + return next(err); + if (!product) + return res.status(404).send({ message: 'No product with name' + productName + 'has been found' }); + req.product = product; + next(); + }); }; - - /** * Dashboard authorization middleware */ -exports.hasAuthorization = function(req, res, next) { - if (req.dashboard.user.id !== req.user.id) { - return res.status(403).send('User is not authorized'); - } - next(); -}; - - +exports.hasAuthorization = function (req, res, next) { + if (req.dashboard.user.id !== req.user.id) { + return res.status(403).send('User is not authorized'); + } + next(); +}; \ No newline at end of file diff --git a/app/controllers/errors.server.controller.js b/app/controllers/errors.server.controller.js index 4e6667e..0ec715b 100644 --- a/app/controllers/errors.server.controller.js +++ b/app/controllers/errors.server.controller.js @@ -1,56 +1,48 @@ 'use strict'; - /** * Get unique error field name */ -var getUniqueErrorMessage = function(err) { - var output; - - try { - var fieldName = err.err.substring(err.err.lastIndexOf('.$') + 2, err.err.lastIndexOf('dup key')-2); - switch(fieldName){ - - case 'name_1': - output = 'Product name already exists!' - break; - case 'name_1_productId_1': - output = 'Dashboard name already exists for this product!' - break; - case 'productName_1_dashboardName_1_testRunId_1_eventDescription_1': - output = 'Combination of testrun ID and description already exists for this dashboard!' - break; - default: - output = 'Unique field already exists'; - } - //output = fieldName.charAt(0).toUpperCase() + fieldName.slice(1) + ' already exists'; - - } catch (ex) { - output = 'Unique field already exists'; - } - - return output; +var getUniqueErrorMessage = function (err) { + var output; + try { + var fieldName = err.err.substring(err.err.lastIndexOf('.$') + 2, err.err.lastIndexOf('dup key') - 2); + switch (fieldName) { + case 'name_1': + output = 'Product name already exists!'; + break; + case 'name_1_productId_1': + output = 'Dashboard name already exists for this product!'; + break; + case 'productName_1_dashboardName_1_testRunId_1_eventDescription_1': + output = 'Combination of testrun ID and description already exists for this dashboard!'; + break; + default: + output = 'Unique field already exists'; + } //output = fieldName.charAt(0).toUpperCase() + fieldName.slice(1) + ' already exists'; + } catch (ex) { + output = 'Unique field already exists'; + } + return output; }; - /** * Get the error message from error object */ -exports.getErrorMessage = function(err) { - var message = ''; - - if (err.code) { - switch (err.code) { - case 11000: - case 11001: - message = getUniqueErrorMessage(err); - break; - default: - message = 'Something went wrong'; - } - } else { - for (var errName in err.errors) { - if (err.errors[errName].message) message = err.errors[errName].message; - } - } - - return message; -}; +exports.getErrorMessage = function (err) { + var message = ''; + if (err.code) { + switch (err.code) { + case 11000: + case 11001: + message = getUniqueErrorMessage(err); + break; + default: + message = 'Something went wrong'; + } + } else { + for (var errName in err.errors) { + if (err.errors[errName].message) + message = err.errors[errName].message; + } + } + return message; +}; \ No newline at end of file diff --git a/app/controllers/events.server.controller.js b/app/controllers/events.server.controller.js index 1361fc4..559e4cc 100644 --- a/app/controllers/events.server.controller.js +++ b/app/controllers/events.server.controller.js @@ -1,205 +1,182 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Event = mongoose.model('Event'), - Testrun = mongoose.model('Testrun'), - Dashboard = mongoose.model('Dashboard'), - Product = mongoose.model('Product'), - testruns = require('./testruns.server.controller.js'), - _ = require('lodash'); - +var mongoose = require('mongoose'), errorHandler = require('./errors.server.controller'), Event = mongoose.model('Event'), Testrun = mongoose.model('Testrun'), Dashboard = mongoose.model('Dashboard'), Product = mongoose.model('Product'), testruns = require('./testruns.server.controller.js'), _ = require('lodash'); /** * Create a Event */ -exports.create = function(req, res) { - var event = new Event(req.body); - event.user = req.user; - - event.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(event); - /* if "end" event, check if corresponding "start" event exist and add to test runs */ - - Product.findOne({name: event.productName}).exec(function(err, product){ - - Dashboard.findOne({$and:[{productId: product._id},{name: event.dashboardName}]}).exec(function(err, dashboard){ - - if (event.eventDescription === "end" && dashboard.useInBenchmark === true){ - - Event.findOne({$and:[{testRunId: event.testRunId}, {eventDescription: "start"}]}).exec(function(err, startEvent) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - var testRun = new Testrun(); - testRun.start = startEvent.eventTimestamp; - testRun.end = event.eventTimestamp; - testRun.productName = event.productName; - testRun.dashboardName = event.dashboardName; - testRun.testRunId = event.testRunId; - testRun.baseline = dashboard.baseline || event.baseline; - testRun.buildResultKey = event.buildResultKey - testRun.eventIds.push(startEvent._id, event._id); - - testruns.benchmarkAndPersistTestRunById(testRun.productName, testRun.dashboardName, testRun, function(storedTestrun){ - - console.log("test run stored"); - }); - - - } - }); - } - }); - }); - } - }); +exports.create = function (req, res) { + var event = new Event(req.body); + event.user = req.user; + event.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(event); + /* if "end" event, check if corresponding "start" event exist and add to test runs */ + Product.findOne({ name: event.productName }).exec(function (err, product) { + Dashboard.findOne({ + $and: [ + { productId: product._id }, + { name: event.dashboardName } + ] + }).exec(function (err, dashboard) { + if (event.eventDescription === 'end' && dashboard.useInBenchmark === true) { + Event.findOne({ + $and: [ + { testRunId: event.testRunId }, + { eventDescription: 'start' } + ] + }).exec(function (err, startEvent) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + var testRun = new Testrun(); + testRun.start = startEvent.eventTimestamp; + testRun.end = event.eventTimestamp; + testRun.productName = event.productName; + testRun.dashboardName = event.dashboardName; + testRun.testRunId = event.testRunId; + testRun.baseline = dashboard.baseline || event.baseline; + testRun.buildResultKey = event.buildResultKey; + testRun.eventIds.push(startEvent._id, event._id); + testruns.benchmarkAndPersistTestRunById(testRun.productName, testRun.dashboardName, testRun, function (storedTestrun) { + console.log('test run stored'); + }); + } + }); + } + }); + }); + } + }); }; - /** * Show the current Event */ -exports.read = function(req, res) { - res.jsonp(req.event); +exports.read = function (req, res) { + res.jsonp(req.event); }; - /** * Update a Event */ -exports.update = function(req, res) { - var event = req.event ; - - event = _.extend(event , req.body); - - event.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(event); - } - }); +exports.update = function (req, res) { + var event = req.event; + event = _.extend(event, req.body); + event.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(event); + } + }); }; - /** * Delete an Event */ -exports.delete = function(req, res) { - var event = req.event ; - - event.remove(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(event); - } - }); +exports.delete = function (req, res) { + var event = req.event; + event.remove(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(event); + } + }); }; - /** * List of Events */ -exports.list = function(req, res) { - Event.find().sort('-created').populate('user', 'displayName').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(events); - } - }); +exports.list = function (req, res) { + Event.find().sort('-created').populate('user', 'displayName').exec(function (err, events) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(events); + } + }); }; - /* * List events for dashboard -*/ -exports.eventsForDashboard = function(req, res) { - Event.find( { $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName } ] } ).sort('-eventTimestamp').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(events); - } - }); + */ +exports.eventsForDashboard = function (req, res) { + Event.find({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName } + ] + }).sort('-eventTimestamp').exec(function (err, events) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(events); + } + }); }; - - /* * Check if event already exists for product-dashboard-testrun combination */ - -exports.checkEvents = function(req, res) { - Event.findOne( { $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName }, { testRunId: req.params.testRunId }, { eventDescription: req.params.eventDescription } ] } ).exec(function(err, event) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - if (! event) { - return res.status(404).send({ - message: 'No event has been found' - }); - }else{ - - res.jsonp(event); - } - - - } - }); +exports.checkEvents = function (req, res) { + Event.findOne({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName }, + { testRunId: req.params.testRunId }, + { eventDescription: req.params.eventDescription } + ] + }).exec(function (err, event) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + if (!event) { + return res.status(404).send({ message: 'No event has been found' }); + } else { + res.jsonp(event); + } + } + }); }; - /* * List events for testrun */ -exports.eventsForTestRun = function(req, res) { - Event.find( { $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName } ], eventTimestamp: {$lte: req.params.until, $gte: req.params.from} } ).sort('-eventTimestamp').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(events); - } - }); +exports.eventsForTestRun = function (req, res) { + Event.find({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName } + ], + eventTimestamp: { + $lte: req.params.until, + $gte: req.params.from + } + }).sort('-eventTimestamp').exec(function (err, events) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(events); + } + }); }; - - - /* * Event middleware */ -exports.eventByID = function(req, res, next, id) { - Event.findById(id).populate('user', 'displayName').exec(function(err, event) { - if (err) return next(err); - if (! event) return next(new Error('Failed to load Event ' + id)); - req.event = event ; - next(); - }); +exports.eventByID = function (req, res, next, id) { + Event.findById(id).populate('user', 'displayName').exec(function (err, event) { + if (err) + return next(err); + if (!event) + return next(new Error('Failed to load Event ' + id)); + req.event = event; + next(); + }); }; - /** * Event authorization middleware */ -exports.hasAuthorization = function(req, res, next) { - if (req.event.user.id !== req.user.id) { - return res.status(403).send('User is not authorized'); - } - next(); -}; +exports.hasAuthorization = function (req, res, next) { + if (req.event.user.id !== req.user.id) { + return res.status(403).send('User is not authorized'); + } + next(); +}; \ No newline at end of file diff --git a/app/controllers/export-db.server.controller.js b/app/controllers/export-db.server.controller.js index 1b610e2..00aba34 100644 --- a/app/controllers/export-db.server.controller.js +++ b/app/controllers/export-db.server.controller.js @@ -1,125 +1,91 @@ //'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - _ = require('lodash'), - fs = require('fs'), - Event = mongoose.model('Event'), - Dashboard = mongoose.model('Dashboard'), - Product = mongoose.model('Product'), - Metric = mongoose.model('Metric'); - - +var mongoose = require('mongoose'), _ = require('lodash'), fs = require('fs'), Event = mongoose.model('Event'), Dashboard = mongoose.model('Dashboard'), Product = mongoose.model('Product'), Metric = mongoose.model('Metric'); var wstream = fs.createWriteStream('myOutput.txt'); - - module.exports.dbExport = function (req, res) { - - var started = false; - - function start(response) { - response.setHeader('Content-disposition', 'attachment; filename=targets-io.dump'); - response.write('var products = [\n') - started = true; + var started = false; + function start(response) { + response.setHeader('Content-disposition', 'attachment; filename=targets-io.dump'); + response.write('var products = [\n'); + started = true; + } + Product.find().lean().stream().on('data', function (product) { + if (!started) { + start(res); } - - Product.find() - .lean() - .stream() - .on('data', function (product) { - if (!started) { - start(res); - } - res.write(JSON.stringify(product) + ',\n'); - }) - .on('close', function () { - res.write('];\n\n') - res.write('var dashboards = [\n') - - Dashboard.find() - .lean() - .stream() - .on('data', function (dashboard) { - if (!started) { - start(res); - } - res.write(JSON.stringify(dashboard) + ',\n'); - }) - .on('close', function () { - res.write('];\n\n') - res.write('var metrics = [\n') - - Metric.find() - .lean() - .stream() - .on('data', function (metric) { - if (!started) { - start(res); - } - res.write(JSON.stringify(metric) + ','); - }) - .on('close', function () { - res.write('];\n\n'); - res.write('var events = [\n'); - - Event.find() - .lean() - .stream() - .on('data', function (event) { - if (!started) { - start(res); - } - res.write(JSON.stringify(event) + ','); - }) - .on('close', function () { - //res.write('];\n\n') - //res.write('var gatlingDetails = [\n') - // - //GatlingDetails.find() - // .lean() - // .stream() - // .on('data', function (gatlingDetails) { - // if (!started) { - // start(res); - // } - // res.write(JSON.stringify(gatlingDetails) + ','); - // }) - // .on('close', function () { - res.write('];'); - res.write('exports.importProducts = products;'); - res.write('exports.importDashboards = dashboards;'); - res.write('exports.importMetrics = metrics;'); - res.write('exports.importEvents = events;'); - res.write('exports.importGatlingDetails = gatlingDetails;'); - res.end(); - }) - .on('error', function (err) { - res.send(500, {err: err, msg: "Failed to get events from db"}); - }); - //}) - //.on('error', function (err) { - // res.send(500, {err: err, msg: "Failed to get gatlingDetails from db"}); - //}); - - - }) - .on('error', function (err) { - res.send(500, {err: err, msg: "Failed to get metrics from db"}); - }); - - }) - .on('error', function (err) { - res.send(500, {err: err, msg: "Failed to get dashboards from db"}); - }); - - }) - .on('error', function (err) { - res.send(500, {err: err, msg: "Failed to get products from db"}); + res.write(JSON.stringify(product) + ',\n'); + }).on('close', function () { + res.write('];\n\n'); + res.write('var dashboards = [\n'); + Dashboard.find().lean().stream().on('data', function (dashboard) { + if (!started) { + start(res); + } + res.write(JSON.stringify(dashboard) + ',\n'); + }).on('close', function () { + res.write('];\n\n'); + res.write('var metrics = [\n'); + Metric.find().lean().stream().on('data', function (metric) { + if (!started) { + start(res); + } + res.write(JSON.stringify(metric) + ','); + }).on('close', function () { + res.write('];\n\n'); + res.write('var events = [\n'); + Event.find().lean().stream().on('data', function (event) { + if (!started) { + start(res); + } + res.write(JSON.stringify(event) + ','); + }).on('close', function () { + //res.write('];\n\n') + //res.write('var gatlingDetails = [\n') + // + //GatlingDetails.find() + // .lean() + // .stream() + // .on('data', function (gatlingDetails) { + // if (!started) { + // start(res); + // } + // res.write(JSON.stringify(gatlingDetails) + ','); + // }) + // .on('close', function () { + res.write('];'); + res.write('exports.importProducts = products;'); + res.write('exports.importDashboards = dashboards;'); + res.write('exports.importMetrics = metrics;'); + res.write('exports.importEvents = events;'); + res.write('exports.importGatlingDetails = gatlingDetails;'); + res.end(); + }).on('error', function (err) { + res.send(500, { + err: err, + msg: 'Failed to get events from db' + }); + }); //}) + //.on('error', function (err) { + // res.send(500, {err: err, msg: "Failed to get gatlingDetails from db"}); + //}); + }).on('error', function (err) { + res.send(500, { + err: err, + msg: 'Failed to get metrics from db' }); - -} - - - + }); + }).on('error', function (err) { + res.send(500, { + err: err, + msg: 'Failed to get dashboards from db' + }); + }); + }).on('error', function (err) { + res.send(500, { + err: err, + msg: 'Failed to get products from db' + }); + }); +}; \ No newline at end of file diff --git a/app/controllers/graphite.server.controller.js b/app/controllers/graphite.server.controller.js index 998400a..a025a14 100644 --- a/app/controllers/graphite.server.controller.js +++ b/app/controllers/graphite.server.controller.js @@ -1,182 +1,116 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - _ = require('lodash'), - errorHandler = require('./errors.server.controller'), - requestjson = require('request-json'), - config = require('../../config/config'), - Memcached = require('memcached'), - md5 = require('MD5'); - - +var mongoose = require('mongoose'), _ = require('lodash'), errorHandler = require('./errors.server.controller'), requestjson = require('request-json'), config = require('../../config/config'), Memcached = require('memcached'), md5 = require('MD5'); /* Memcached config */ - Memcached.config.poolSize = 25; Memcached.config.timeout = 100; Memcached.config.retries = 3; Memcached.config.reconnect = 1000; Memcached.config.maxValue = 10480000; Memcached.config.poolSize = 50; - exports.getGraphiteData = getGraphiteData; exports.flushMemcachedKey = flushMemcachedKey; exports.createMemcachedKey = createMemcachedKey; - - /** * Get Graphite data */ -exports.getData = function(req, res) { - - /* get url params */ - var from = req.query.from; - var until = req.query.until; - var targets = req.query.target; - var maxDataPoints = req.query.maxDataPoints; - - - - getGraphiteData (from, until, targets, maxDataPoints, function(body){ - - res.set('Content-Type', 'application/javascript'); - res.jsonp(body); +exports.getData = function (req, res) { + /* get url params */ + var from = req.query.from; + var until = req.query.until; + var targets = req.query.target; + var maxDataPoints = req.query.maxDataPoints; + getGraphiteData(from, until, targets, maxDataPoints, function (body) { + res.set('Content-Type', 'application/javascript'); + res.jsonp(body); + }); +}; +function getGraphiteData(from, until, targets, maxDataPoints, callback) { + /* memcached stuff*/ + var memcachedKey = createMemcachedKey(from, until, targets); + var memcached = new Memcached(config.memcachedHost); + var graphiteTargetUrl = createUrl(from, until, targets, maxDataPoints); + var client = requestjson.createClient(config.graphiteHost); + /* Don't cache live data! */ + if (until === 'now') { + client.get(graphiteTargetUrl, function (err, response, body) { + if (err) { + // return response.status(400).send({ + // message: errorHandler.getErrorMessage(err) + // }); + callback([]); + } else { + callback(body); + } }); - - -} - -function getGraphiteData(from, until, targets, maxDataPoints, callback){ - - /* memcached stuff*/ - - var memcachedKey = createMemcachedKey (from, until, targets); - var memcached = new Memcached(config.memcachedHost); - - var graphiteTargetUrl = createUrl(from, until, targets, maxDataPoints); - - var client = requestjson.createClient(config.graphiteHost); - - /* Don't cache live data! */ - if(until === 'now'){ - - + } else { + /* first check memcached */ + memcached.get(memcachedKey, function (err, result) { + if (err) + console.error('memcached error: ' + err); + if (result && !err) { + console.dir('cache hit: ' + memcachedKey); + callback(result); + memcached.end(); + } else { + //console.log(graphiteTargetUrl); + /* if no cache hit, go to graphite back end */ client.get(graphiteTargetUrl, function (err, response, body) { - if (err) { -// return response.status(400).send({ -// message: errorHandler.getErrorMessage(err) -// }); - callback([]); - } else { - - callback(body); - - } - }); - - }else { - - /* first check memcached */ - memcached.get(memcachedKey, function (err, result) { - if (err) console.error('memcached error: ' + err); - - if (result && !err) { - - console.dir("cache hit: " + memcachedKey); - - callback(result); - - + if (err) { + callback([]); + } else { + callback(body); + /* add to memcached if it is a valid response */ + if (body != '[]' && body.length > 0 && response.statusCode == 200) { + memcached.set(memcachedKey, body, 3600 * 24 * 7, function (err, result) { + if (err) + console.error(err); + console.dir('key set ' + memcachedKey + ' : ' + result); memcached.end(); - - } else { - - //console.log(graphiteTargetUrl); - /* if no cache hit, go to graphite back end */ - client.get(graphiteTargetUrl, function (err, response, body) { - if (err) { - callback([]); - } else { - - callback(body); - - /* add to memcached if it is a valid response */ - if (body != '[]' && body.length > 0 && response.statusCode == 200) { - - memcached.set(memcachedKey, body, 3600 * 24 * 7, function (err, result) { - if (err) console.error(err); - console.dir("key set " + memcachedKey + " : " + result); - memcached.end(); - }); - } - } - }); + }); } + } }); - - } - -}; - -function createUrl(from, until, targets, maxDataPoints){ - - var graphiteTargetUrl = '/render?format=json&from=' + from + "&until=" + until + "&maxDataPoints=" + maxDataPoints; - - if (_.isArray(targets)){ - _.each(targets, function(target){ - - graphiteTargetUrl += '&target=' + target; - - }); - }else{ - - graphiteTargetUrl += '&target=' + targets; - } - - return graphiteTargetUrl; + } + }); + } } - -function createMemcachedKey (from, until, targets){ - - - var memcachedKey; - var hashedMemcachedKey; - - memcachedKey = from.toString() + until.toString(); - - if (_.isArray(targets)) { - - targets.sort(); - _.each(targets, function (target) { - - memcachedKey += target; - - }); - }else{ - - memcachedKey += targets; - } -// console.log("raw key:" + memcachedKey) - hashedMemcachedKey = md5(memcachedKey) - - return hashedMemcachedKey; - -// return memcachedKey.replace(/\s/g,''); +function createUrl(from, until, targets, maxDataPoints) { + var graphiteTargetUrl = '/render?format=json&from=' + from + '&until=' + until + '&maxDataPoints=' + maxDataPoints; + if (_.isArray(targets)) { + _.each(targets, function (target) { + graphiteTargetUrl += '&target=' + target; + }); + } else { + graphiteTargetUrl += '&target=' + targets; + } + return graphiteTargetUrl; } - -function flushMemcachedKey(key, callback){ - - var memcached = new Memcached(config.memcachedHost); - - memcached.del( key, function( err, result ){ - if( err ) callback( err ); - console.info( "deleted key: " + key + " : " + result ); - callback(); - }); - - - memcached.end(); // as we are 100% certain we are not going to use the connection again, we are going to end it - +function createMemcachedKey(from, until, targets) { + var memcachedKey; + var hashedMemcachedKey; + memcachedKey = from.toString() + until.toString(); + if (_.isArray(targets)) { + targets.sort(); + _.each(targets, function (target) { + memcachedKey += target; + }); + } else { + memcachedKey += targets; + } + // console.log("raw key:" + memcachedKey) + hashedMemcachedKey = md5(memcachedKey); + return hashedMemcachedKey; // return memcachedKey.replace(/\s/g,''); } +function flushMemcachedKey(key, callback) { + var memcached = new Memcached(config.memcachedHost); + memcached.del(key, function (err, result) { + if (err) + callback(err); + console.info('deleted key: ' + key + ' : ' + result); + callback(); + }); + memcached.end(); // as we are 100% certain we are not going to use the connection again, we are going to end it +} \ No newline at end of file diff --git a/app/controllers/import-db-legacy.server.controller.js b/app/controllers/import-db-legacy.server.controller.js index f01e1b2..2a010ad 100644 --- a/app/controllers/import-db-legacy.server.controller.js +++ b/app/controllers/import-db-legacy.server.controller.js @@ -1,212 +1,148 @@ //'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - _ = require('lodash'), - fs = require('fs'), - Event = mongoose.model('Event'), - Dashboard = mongoose.model('Dashboard'), - Product = mongoose.model('Product'), - Metric = mongoose.model('Metric'), - async = require('async'); - - -function upload (req, res) { - - console.log(req.files.file.path) - - try { - - eval(fs.readFileSync(req.files.file.path) + '') - - }catch(err){ - - if (err) console.log(err) - - }; - - /* remove existing collections */ - - Testrun.remove({}, function(err) { - if (err) console.log(err); - console.log('Testruns removed') - Event.remove({}, function (err) { - if (err) console.log(err); - console.log('Events removed') - _.each(events, function (importEvent, e) { - - - var event = new Event(); - - var splitDashboardName = importEvent.dashboardName.split('-'); - - var eventDesciption; - - switch (importEvent.eventDescription) { - - case 'Start-loadtest': - eventDesciption = 'start'; - break; - case 'End-loadtest': - eventDesciption = 'end'; - break; - default: - eventDesciption = importEvent.eventDescription; - - } - event.eventTimestamp = importEvent.timestamp; - event.productName = splitDashboardName[0]; - event.dashboardName = splitDashboardName[1]; - event.testRunId = importEvent.testRunId; - event.eventDescription = eventDesciption; - event.baseline = importEvent.baseline; - event.buildResultKey = importEvent.buildResultKey; - - event.save(function (err, savedEvent) { - if (err) console.log(err); - //console.log('Saved event #' + e); - - }); - - }); +var mongoose = require('mongoose'), _ = require('lodash'), fs = require('fs'), Event = mongoose.model('Event'), Dashboard = mongoose.model('Dashboard'), Product = mongoose.model('Product'), Metric = mongoose.model('Metric'), async = require('async'); +function upload(req, res) { + console.log(req.files.file.path); + try { + eval(fs.readFileSync(req.files.file.path) + ''); + } catch (err) { + if (err) + console.log(err); + } + /* remove existing collections */ + Testrun.remove({}, function (err) { + if (err) + console.log(err); + console.log('Testruns removed'); + Event.remove({}, function (err) { + if (err) + console.log(err); + console.log('Events removed'); + _.each(events, function (importEvent, e) { + var event = new Event(); + var splitDashboardName = importEvent.dashboardName.split('-'); + var eventDesciption; + switch (importEvent.eventDescription) { + case 'Start-loadtest': + eventDesciption = 'start'; + break; + case 'End-loadtest': + eventDesciption = 'end'; + break; + default: + eventDesciption = importEvent.eventDescription; + } + event.eventTimestamp = importEvent.timestamp; + event.productName = splitDashboardName[0]; + event.dashboardName = splitDashboardName[1]; + event.testRunId = importEvent.testRunId; + event.eventDescription = eventDesciption; + event.baseline = importEvent.baseline; + event.buildResultKey = importEvent.buildResultKey; + event.save(function (err, savedEvent) { + if (err) + console.log(err); //console.log('Saved event #' + e); }); + }); }); - - - Metric.remove({}, function(err) { - if (err) console.log(err); - console.log('Metrics removed') - - Dashboard.remove({}, function(err) { - if (err) console.log(err); - console.log('Dashoards removed') - Product.remove({}, function(err) { - if (err) console.log(err); - console.log('Products removed') - - async.forEach(products, function(importProduct, productCallback){ - - var dashboardCounter; - var metricCounter; - - var newProduct = new Product(); - - newProduct.name = importProduct.name; - newProduct.description = importProduct.description; - newProduct.dashboards = importProduct.dashboards; - - newProduct.save(function (err, NewProduct) { - if (err) return console.error(err); - //console.log('Saved product #'+ i); - var importProductDashboards = []; - _.each(dashboards, function(dashboard){ - - if (_.indexOf(importProduct.dashboards, dashboard._id)!= -1 ) - importProductDashboards.push(dashboard); - - }); - dashboardCounter = 0; - - async.forEach(importProductDashboards, function(importDashboard, dashboardCallback){ - - - var newDashboard = new Dashboard(); - var dashboardName = importDashboard.name.split('-'); - newDashboard.productId = newProduct._id; - newDashboard.name = dashboardName[1]; - newDashboard.description = importDashboard.description; - newDashboard.metrics = importDashboard.metrics; - newDashboard.granularity = importDashboard.granularity; - newDashboard.metricsRegexWily = importDashboard.metricsRegexWily; - newDashboard.hosts = importDashboard.hosts; - newDashboard.applications = importDashboard.applications; - newDashboard.instances = importDashboard.instances; - //newDashboard.tags = importDashboard.tags; - // - newDashboard.save(function(err,newDashboard){ - if(err) console.log(err); - dashboardCounter++; - if(newDashboard){ - - //console.log('Saved dashboard #'+ d); - - var importDashboardMetrics = []; - _.each(metrics, function(metric){ - - if (_.indexOf(importDashboard.metrics, metric._id)!= -1 ) - importDashboardMetrics.push(metric); - - }); - - async.forEach(importDashboardMetrics, function(importDashboardMetric, metricCallback){ - - - var newMetric = new Metric(); - var tags = []; - tags.push({text: importDashboardMetric.tag}); - newMetric.dashboardId = newDashboard._id; - newMetric.dashboardName = newDashboard.name; - newMetric.productName = newProduct.name; - newMetric.alias = importDashboardMetric.alias; - newMetric.targets = importDashboardMetric.target; - newMetric.benchmarkOperator = importDashboardMetric.benchmarkOperator; - newMetric.benchmarkValue = importDashboardMetric.benchmarkValue; - newMetric.requirementValue = importDashboardMetric.requirementValue; - newMetric.requirementOperator = importDashboardMetric.requirementOperator; - newMetric.tags = tags; - newMetric.type = importDashboardMetric.type; - - newMetric.save(function (err, newMetric) { - metricCounter++; - //console.log('Saved metric #'+ m); - metricCallback(); - }); - - }, function (err) { - - dashboardCallback(); - }); - }else{ - - dashboardCallback(); - - } - }); - - }, function (err) { - - productCallback(); - }); - - }); - - - - }, function (err) { - - console.log('import done!'); - res.sendStatus(200); - + }); + Metric.remove({}, function (err) { + if (err) + console.log(err); + console.log('Metrics removed'); + Dashboard.remove({}, function (err) { + if (err) + console.log(err); + console.log('Dashoards removed'); + Product.remove({}, function (err) { + if (err) + console.log(err); + console.log('Products removed'); + async.forEach(products, function (importProduct, productCallback) { + var dashboardCounter; + var metricCounter; + var newProduct = new Product(); + newProduct.name = importProduct.name; + newProduct.description = importProduct.description; + newProduct.dashboards = importProduct.dashboards; + newProduct.save(function (err, NewProduct) { + if (err) + return console.error(err); + //console.log('Saved product #'+ i); + var importProductDashboards = []; + _.each(dashboards, function (dashboard) { + if (_.indexOf(importProduct.dashboards, dashboard._id) != -1) + importProductDashboards.push(dashboard); + }); + dashboardCounter = 0; + async.forEach(importProductDashboards, function (importDashboard, dashboardCallback) { + var newDashboard = new Dashboard(); + var dashboardName = importDashboard.name.split('-'); + newDashboard.productId = newProduct._id; + newDashboard.name = dashboardName[1]; + newDashboard.description = importDashboard.description; + newDashboard.metrics = importDashboard.metrics; + newDashboard.granularity = importDashboard.granularity; + newDashboard.metricsRegexWily = importDashboard.metricsRegexWily; + newDashboard.hosts = importDashboard.hosts; + newDashboard.applications = importDashboard.applications; + newDashboard.instances = importDashboard.instances; + //newDashboard.tags = importDashboard.tags; + // + newDashboard.save(function (err, newDashboard) { + if (err) + console.log(err); + dashboardCounter++; + if (newDashboard) { + //console.log('Saved dashboard #'+ d); + var importDashboardMetrics = []; + _.each(metrics, function (metric) { + if (_.indexOf(importDashboard.metrics, metric._id) != -1) + importDashboardMetrics.push(metric); + }); + async.forEach(importDashboardMetrics, function (importDashboardMetric, metricCallback) { + var newMetric = new Metric(); + var tags = []; + tags.push({ text: importDashboardMetric.tag }); + newMetric.dashboardId = newDashboard._id; + newMetric.dashboardName = newDashboard.name; + newMetric.productName = newProduct.name; + newMetric.alias = importDashboardMetric.alias; + newMetric.targets = importDashboardMetric.target; + newMetric.benchmarkOperator = importDashboardMetric.benchmarkOperator; + newMetric.benchmarkValue = importDashboardMetric.benchmarkValue; + newMetric.requirementValue = importDashboardMetric.requirementValue; + newMetric.requirementOperator = importDashboardMetric.requirementOperator; + newMetric.tags = tags; + newMetric.type = importDashboardMetric.type; + newMetric.save(function (err, newMetric) { + metricCounter++; + //console.log('Saved metric #'+ m); + metricCallback(); }); - - - - }); - + }, function (err) { + dashboardCallback(); + }); + } else { + dashboardCallback(); + } + }); + }, function (err) { + productCallback(); }); - + }); + }, function (err) { + console.log('import done!'); + res.sendStatus(200); + }); + }); }); - + }); } - -function dbImport (req, res) { - - res.render('upload-legacy '); - +function dbImport(req, res) { + res.render('upload-legacy '); } - - exports.dbImport = dbImport; -exports.upload = upload; +exports.upload = upload; \ No newline at end of file diff --git a/app/controllers/import-db.server.controller.js b/app/controllers/import-db.server.controller.js index 09b2037..2bde3d8 100644 --- a/app/controllers/import-db.server.controller.js +++ b/app/controllers/import-db.server.controller.js @@ -1,254 +1,143 @@ //'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - _ = require('lodash'), - fs = require('fs'), - Event = mongoose.model('Event'), - Dashboard = mongoose.model('Dashboard'), - Product = mongoose.model('Product'), - Metric = mongoose.model('Metric'); - Testrun = mongoose.model('Testrun'), - async = require('async'); - - - -function upload (req, res) { - - console.log(req.files.file.path) - - try { - - eval(fs.readFileSync(req.files.file.path) + '') - - }catch(err){ - - if (err) console.log(err) - - }; - - /* remove existing collections */ - - Testrun.remove({}, function(err) { - if (err) console.log(err); - console.log('Testruns removed') - - Event.remove({}, function(err) { - if (err) console.log(err); - console.log('Events removed') - _.each(events, function(importEvent){ - - var event = new Event(); - - var splitDashboardName = importEvent.dashboardName.split('-'); - - var eventDesciption; - - switch(importEvent.eventDescription){ - - case 'Start-loadtest': - eventDesciption = 'start'; - break; - case 'End-loadtest': - eventDesciption = 'end'; - break; - default: - eventDesciption = importEvent.eventDescription; - - } - event.eventTimestamp = importEvent.eventTimestamp; - event.productName = importEvent.productName - event.dashboardName = importEvent.dashboardName - event.testRunId = importEvent.testRunId; - event.eventDescription = eventDesciption; - event.baseline = importEvent.baseline; - event.buildResultKey = importEvent.buildResultKey; - - event.save(function (err) { - if(err) console.log(err); - }); - - }); +var mongoose = require('mongoose'), _ = require('lodash'), fs = require('fs'), Event = mongoose.model('Event'), Dashboard = mongoose.model('Dashboard'), Product = mongoose.model('Product'), Metric = mongoose.model('Metric'), +Testrun = mongoose.model('Testrun'), async = require('async'); + +function upload(req, res) { + console.log(req.files.file.path); + try { + eval(fs.readFileSync(req.files.file.path) + ''); + } catch (err) { + if (err) + console.log(err); + } + /* remove existing collections */ + Testrun.remove({}, function (err) { + if (err) + console.log(err); + console.log('Testruns removed'); + Event.remove({}, function (err) { + if (err) + console.log(err); + console.log('Events removed'); + _.each(events, function (importEvent) { + var event = new Event(); + var splitDashboardName = importEvent.dashboardName.split('-'); + var eventDesciption; + switch (importEvent.eventDescription) { + case 'Start-loadtest': + eventDesciption = 'start'; + break; + case 'End-loadtest': + eventDesciption = 'end'; + break; + default: + eventDesciption = importEvent.eventDescription; + } + event.eventTimestamp = importEvent.eventTimestamp; + event.productName = importEvent.productName; + event.dashboardName = importEvent.dashboardName; + event.testRunId = importEvent.testRunId; + event.eventDescription = eventDesciption; + event.baseline = importEvent.baseline; + event.buildResultKey = importEvent.buildResultKey; + event.save(function (err) { + if (err) + console.log(err); }); + }); }); - - Metric.remove({}, function(err) { - if (err) console.log(err); - console.log('Metrics removed') - - Dashboard.remove({}, function(err) { - if (err) console.log(err); - console.log('Dashoards removed') - Product.remove({}, function(err) { - if (err) console.log(err); - console.log('Products removed') - - async.forEach(products, function(importProduct, productCallback){ - - var newProduct = new Product(); - - newProduct.name = importProduct.name; - newProduct.description = importProduct.description; - newProduct.dashboards = importProduct.dashboards; - - newProduct.save(function (err, NewProduct) { - if (err) return console.error(err); - - var importProductDashboards = []; - _.each(dashboards, function(dashboard){ - - if (_.indexOf(importProduct.dashboards, dashboard._id)!= -1 ) - importProductDashboards.push(dashboard); - - }); - - async.forEach(importProductDashboards, function(importDashboard, dashboardCallback){ - - var newDashboard = new Dashboard(); - //var dashboardName = importDashboard.name.split('-'); - newDashboard.productId = newProduct._id; - newDashboard.name = importDashboard.name; - newDashboard.description = importDashboard.description; - newDashboard.metrics = importDashboard.metrics; - newDashboard.granularity = importDashboard.granularity; - newDashboard.metricsRegexWily = importDashboard.metricsRegexWily; - newDashboard.hosts = importDashboard.hosts; - newDashboard.applications = importDashboard.applications; - newDashboard.instances = importDashboard.instances; - newDashboard.tags = importDashboard.tags; - newDashboard.baseline = importDashboard.baseline; - newDashboard.useInBenchmark=importDashboard.useInBenchmark; - - // - newDashboard.save(function(err,newDashboard){ - if(err) console.log(err); - if(newDashboard){ - var importDashboardMetrics = []; - _.each(metrics, function(metric){ - - if (_.indexOf(importDashboard.metrics, metric._id)!= -1 ) - importDashboardMetrics.push(metric); - - }); - - async.forEach(importDashboardMetrics, function(importDashboardMetric, metricCallback){ - - var newMetric = new Metric(); - var tags = []; - tags.push({text: importDashboardMetric.tag}); - newMetric.dashboardId = newDashboard._id; - newMetric.dashboardName = newDashboard.name; - newMetric.productName = newProduct.name; - newMetric.alias = importDashboardMetric.alias; - newMetric.targets = importDashboardMetric.targets; - newMetric.benchmarkOperator = importDashboardMetric.benchmarkOperator; - newMetric.benchmarkValue = importDashboardMetric.benchmarkValue; - newMetric.requirementValue = importDashboardMetric.requirementValue; - newMetric.requirementOperator = importDashboardMetric.requirementOperator; - newMetric.tags = importDashboardMetric.tags; - newMetric.type = importDashboardMetric.type; - - newMetric.save(function (err, newMetric) { - //console.log('Saved metric #'+ m); - metricCallback(); - }); - - }, function (err) { - - dashboardCallback(); - }); - } - }); - - }, function (err) { - - productCallback(); - }); - + }); + Metric.remove({}, function (err) { + if (err) + console.log(err); + console.log('Metrics removed'); + Dashboard.remove({}, function (err) { + if (err) + console.log(err); + console.log('Dashoards removed'); + Product.remove({}, function (err) { + if (err) + console.log(err); + console.log('Products removed'); + async.forEach(products, function (importProduct, productCallback) { + var newProduct = new Product(); + newProduct.name = importProduct.name; + newProduct.description = importProduct.description; + newProduct.dashboards = importProduct.dashboards; + newProduct.save(function (err, NewProduct) { + if (err) + return console.error(err); + var importProductDashboards = []; + _.each(dashboards, function (dashboard) { + if (_.indexOf(importProduct.dashboards, dashboard._id) !== -1) + importProductDashboards.push(dashboard); + }); + async.forEach(importProductDashboards, function (importDashboard, dashboardCallback) { + var newDashboard = new Dashboard(); + //var dashboardName = importDashboard.name.split('-'); + newDashboard.productId = newProduct._id; + newDashboard.name = importDashboard.name; + newDashboard.description = importDashboard.description; + newDashboard.metrics = importDashboard.metrics; + newDashboard.granularity = importDashboard.granularity; + newDashboard.metricsRegexWily = importDashboard.metricsRegexWily; + newDashboard.hosts = importDashboard.hosts; + newDashboard.applications = importDashboard.applications; + newDashboard.instances = importDashboard.instances; + newDashboard.tags = importDashboard.tags; + newDashboard.baseline = importDashboard.baseline; + newDashboard.useInBenchmark = importDashboard.useInBenchmark; + // + newDashboard.save(function (err, newDashboard) { + if (err) + console.log(err); + if (newDashboard) { + var importDashboardMetrics = []; + _.each(metrics, function (metric) { + if (_.indexOf(importDashboard.metrics, metric._id) !== -1) + importDashboardMetrics.push(metric); + }); + async.forEach(importDashboardMetrics, function (importDashboardMetric, metricCallback) { + var newMetric = new Metric(); + var tags = []; + tags.push({ text: importDashboardMetric.tag }); + newMetric.dashboardId = newDashboard._id; + newMetric.dashboardName = newDashboard.name; + newMetric.productName = newProduct.name; + newMetric.alias = importDashboardMetric.alias; + newMetric.targets = importDashboardMetric.targets; + newMetric.benchmarkOperator = importDashboardMetric.benchmarkOperator; + newMetric.benchmarkValue = importDashboardMetric.benchmarkValue; + newMetric.requirementValue = importDashboardMetric.requirementValue; + newMetric.requirementOperator = importDashboardMetric.requirementOperator; + newMetric.tags = importDashboardMetric.tags; + newMetric.type = importDashboardMetric.type; + newMetric.save(function (err, newMetric) { + //console.log('Saved metric #'+ m); + metricCallback(); }); - - - - }, function (err) { - - console.log('import done!'); - res.sendStatus(200); - }); - - - + }, function (err) { + dashboardCallback(); + }); + } + }); + }, function (err) { + productCallback(); }); - + }); + }, function (err) { + console.log('import done!'); + res.sendStatus(200); }); - + }); }); - - - - - - - - /* clean db */ - - - //setTimeout(function(){ - // - // - // Dashboard.find().exec(function(err, dashboards){ - // - // var activeDashboards = []; - // - // _.each(dashboards, function(dashboard){ - // - // activeDashboards.push(dashboard._id.toString()); - // }) - // - // Product.find().exec(function(err, products){ - // - // var productId; - // - // _.each(products, function(product){ - // - // productId = product.toObject()._id.toString(); - // var updatedDashboards = []; - // - // _.each(product.dashboards, function(dashboardId){ - // - // if(_.indexOf(activeDashboards, dashboardId.toString()) !== -1)updatedDashboards.push(dashboardId) - // }) - // - // Product.findOne({ _id: productId}, function (err, updateProduct) { - // - // updateProduct.dashboards = updatedDashboards; - // updateProduct.save(function(err, updateProduct){ - // - // }); - // }) - // - // - // - // }) - // }); - // res.redirect('/#!'); - // }) - // - //}, 30000); - - - - - + }); } - -function dbImport (req, res) { - - res.render('upload'); - +function dbImport(req, res) { + res.render('upload'); } - - exports.dbImport = dbImport; exports.upload = upload; diff --git a/app/controllers/jenkins.server.controller.js b/app/controllers/jenkins.server.controller.js index 40914a4..8fe2377 100644 --- a/app/controllers/jenkins.server.controller.js +++ b/app/controllers/jenkins.server.controller.js @@ -1,163 +1,120 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - _ = require('lodash'), - requestjson = require('request-json'), - config = require('../../config/config'), - Memcached = require('memcached'); - - -exports.getConsoleData = function(req, res){ - - var memcached = new Memcached(config.memcachedHost); - var jenkinsKey = req.body.consoleUrl + req.body.running - memcached.get(jenkinsKey, function( err, result ) { - if (err) console.error(err); - - if (result) { - - console.dir("cache hit jenkins: " + result); - res.jsonp(result); - - } else { - - - getJenkinsData(req.body.consoleUrl, req.body.running, req.body.start, req.body.end, function (consoleData) { - - res.jsonp(consoleData); - - memcached.set(jenkinsKey, consoleData, 10, function (err, result) { - if (err) console.error(err); - memcached.end(); - }); - }) - } - }); -} - -function getJenkinsData(jenkinsUrl, running, start, end, callback){ - - var consoleResponse ={}; - var consoleData = []; - var errorData = []; - var consoleUrl; - var separator; - - /* - * we use a different url if a test is still running - * */ - if(running === false) { - - consoleUrl = jenkinsUrl + "console"; - separator = "> "; - }else { - consoleUrl = jenkinsUrl + "logText/progressiveText?start="; - separator = "> "; +var mongoose = require('mongoose'), _ = require('lodash'), requestjson = require('request-json'), config = require('../../config/config'), Memcached = require('memcached'); +exports.getConsoleData = function (req, res) { + var memcached = new Memcached(config.memcachedHost); + var jenkinsKey = req.body.consoleUrl + req.body.running; + memcached.get(jenkinsKey, function (err, result) { + if (err) + console.error(err); + if (result) { + console.dir('cache hit jenkins: ' + result); + res.jsonp(result); + } else { + getJenkinsData(req.body.consoleUrl, req.body.running, req.body.start, req.body.end, function (consoleData) { + res.jsonp(consoleData); + memcached.set(jenkinsKey, consoleData, 10, function (err, result) { + if (err) + console.error(err); + memcached.end(); + }); + }); } - var memcached = new Memcached(config.memcachedHost); - var client = requestjson.createClient(jenkinsUrl); - var testDurationInSeconds, offset; - - - memcached.get(consoleUrl, function( err, result ){ - if( err ) console.error( err ); - - if( result ) { - - console.dir("cache hit, offset: " + result); - if(running === false){ /*no offset needed*/ - - offset = ""; - - }else{ - - offset = result; - } - - }else{ - - - if(running === false){ - - /*no offset needed*/ - - offset = ""; - - - }else{ - - /* If screen was never opened before downloading the whole console output file would lead to Jenkins out of memory + }); +}; +function getJenkinsData(jenkinsUrl, running, start, end, callback) { + var consoleResponse = {}; + var consoleData = []; + var errorData = []; + var consoleUrl; + var separator; + /* + * we use a different url if a test is still running + * */ + if (running === false) { + consoleUrl = jenkinsUrl + 'console'; + separator = '> '; + } else { + consoleUrl = jenkinsUrl + 'logText/progressiveText?start='; + separator = '> '; + } + var memcached = new Memcached(config.memcachedHost); + var client = requestjson.createClient(jenkinsUrl); + var testDurationInSeconds, offset; + memcached.get(consoleUrl, function (err, result) { + if (err) + console.error(err); + if (result) { + console.dir('cache hit, offset: ' + result); + if (running === false) { + /*no offset needed*/ + offset = ''; + } else { + offset = result; + } + } else { + if (running === false) { + /*no offset needed*/ + offset = ''; + } else { + /* If screen was never opened before downloading the whole console output file would lead to Jenkins out of memory * in case of long lasting tests. Instead make an educated guess for a suitable offset based on the test timestamps */ - - testDurationInSeconds = (new Date() / 1000) - start; - offset = Math.round(testDurationInSeconds * 500); - } - - } - - client.get(consoleUrl + offset, function (err, response, body) { -// if (err) console.error(err); - - console.log(consoleUrl + offset); - console.log("X-More-Data:"+ response.headers['x-more-data'] ); - - if(response.headers['x-text-size'] && running == true ) { - memcached.set(consoleUrl, response.headers['x-text-size'], 600, function (err, result) { - if (err) console.error(err); - console.dir("key set " + consoleUrl + " : " + response.headers['x-text-size']); - memcached.end(); + testDurationInSeconds = new Date() / 1000 - start; + offset = Math.round(testDurationInSeconds * 500); + } + } + client.get(consoleUrl + offset, function (err, response, body) { + // if (err) console.error(err); + console.log(consoleUrl + offset); + console.log('X-More-Data:' + response.headers['x-more-data']); + if (response.headers['x-text-size'] && running == true) { + memcached.set(consoleUrl, response.headers['x-text-size'], 600, function (err, result) { + if (err) + console.error(err); + console.dir('key set ' + consoleUrl + ' : ' + response.headers['x-text-size']); + memcached.end(); + }); + } + var consoleArray = body.split('Requests'); + if (consoleArray.length > 1) { + var consoleLineArray = consoleArray[consoleArray.length - 1].split(separator); + // console.log(body); + _.each(consoleLineArray, function (consoleLine, i) { + if (i > 0) { + var request = /(.*?)\s+\(OK.*/g.exec(consoleLine); + if (request) { + var OK = /.*OK=(\d+)\s+KO.*/.exec(consoleLine); + var KO = /.*KO=(\d+).*/.exec(consoleLine); + var percFailed = parseInt(OK[1]) + parseInt(KO[1]) > 0 ? (parseInt(KO[1]) * 100 / (parseInt(OK[1]) + parseInt(KO[1]))).toFixed(2).toString() + '%' : '0%'; + consoleData.push({ + 'request': request[1], + 'OK': parseInt(OK[1]), + 'KO': parseInt(KO[1]), + 'percFailed': percFailed + }); + } else { + var percentageOfErrors = /.*\(\s?(\d+\.\d+%)\)\s/g.exec(consoleLine); + if (percentageOfErrors) { + var error1 = /(.*?)\s+\d+\s\(\s?\d+\.\d+%\)\s/g.exec(consoleLine); + var error2 = /.*\s+\d+\s\(\s?\d+\.\d+%\)\s+([^\=]*)/g.exec(consoleLine); + var error = error2[1] ? error1[1] + error2[1] : error1[1]; + var numberOfErrors = /.*\s+(\d+)\s\(\s?\d+\.\d+%\)/g.exec(consoleLine); + errorData.push({ + 'error': error, + 'numberOfErrors': parseInt(numberOfErrors[1]), + 'percentageOfErrors': percentageOfErrors[1] }); + } } - - var consoleArray = body.split("Requests"); - if(consoleArray.length > 1) { - - var consoleLineArray = consoleArray[consoleArray.length - 1].split(separator) -// console.log(body); - - _.each(consoleLineArray, function (consoleLine, i) { - - if (i > 0) { - - - var request = /(.*?)\s+\(OK.*/g.exec(consoleLine); - if(request) { - - var OK = /.*OK=(\d+)\s+KO.*/.exec(consoleLine); - var KO = /.*KO=(\d+).*/.exec(consoleLine); - var percFailed = (parseInt(OK[1]) + parseInt(KO[1]) > 0) ? ((parseInt(KO[1]) * 100 / (parseInt(OK[1]) + parseInt(KO[1])))).toFixed(2).toString() + "%" : "0%"; - - consoleData.push({"request": request[1], "OK": parseInt(OK[1]), "KO": parseInt(KO[1]), "percFailed": percFailed}); - - }else{ - - var percentageOfErrors = /.*\(\s?(\d+\.\d+%)\)\s/g.exec(consoleLine); - - if (percentageOfErrors){ - - var error1 = /(.*?)\s+\d+\s\(\s?\d+\.\d+%\)\s/g.exec(consoleLine); - var error2 = /.*\s+\d+\s\(\s?\d+\.\d+%\)\s+([^\=]*)/g.exec(consoleLine); - var error = (error2[1]) ? error1[1] + error2[1] : error1[1]; - var numberOfErrors = /.*\s+(\d+)\s\(\s?\d+\.\d+%\)/g.exec(consoleLine); - - errorData.push({"error": error, "numberOfErrors": parseInt(numberOfErrors[1]), "percentageOfErrors": percentageOfErrors[1] }) - } - - } - } - }) - - consoleResponse.data = consoleData; - consoleResponse.errors = errorData; - } - - callback(consoleResponse); - + } }); + consoleResponse.data = consoleData; + consoleResponse.errors = errorData; + } + callback(consoleResponse); }); - -}; + }); +} \ No newline at end of file diff --git a/app/controllers/metrics.server.controller.js b/app/controllers/metrics.server.controller.js index bbe2672..c2e84a6 100644 --- a/app/controllers/metrics.server.controller.js +++ b/app/controllers/metrics.server.controller.js @@ -1,115 +1,91 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Metric = mongoose.model('Metric'), - testruns = require('./testruns.server.controller.js'), - _ = require('lodash'); - +var mongoose = require('mongoose'), errorHandler = require('./errors.server.controller'), Metric = mongoose.model('Metric'), testruns = require('./testruns.server.controller.js'), _ = require('lodash'); /** * Create a Metric */ -exports.create = function(req, res) { - var metric = new Metric(req.body); - metric.user = req.user; - - metric.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(metric); - } - }); +exports.create = function (req, res) { + var metric = new Metric(req.body); + metric.user = req.user; + metric.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(metric); + } + }); }; - /** * Show the current Metric */ -exports.read = function(req, res) { - res.jsonp(req.metric); +exports.read = function (req, res) { + res.jsonp(req.metric); }; - /** * Update a Metric */ -exports.update = function(req, res) { - var metric = req.metric ; - - /* update testruns if requirements have changed */ - -// if (req.metric.requirementValue !== req.body.requirementValue || req.metric.requirementOperator !== req.body.requirementOperator){ -// -// testruns.updateTestRunRequirementForMetric(req.body) -// } - - metric = _.extend(metric , req.body); - - metric.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(metric); - } - }); +exports.update = function (req, res) { + var metric = req.metric; + /* update testruns if requirements have changed */ + // if (req.metric.requirementValue !== req.body.requirementValue || req.metric.requirementOperator !== req.body.requirementOperator){ + // + // testruns.updateTestRunRequirementForMetric(req.body) + // } + metric = _.extend(metric, req.body); + metric.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(metric); + } + }); }; - /** * Delete an Metric */ -exports.delete = function(req, res) { - var metric = req.metric ; - - metric.remove(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(metric); - } - }); +exports.delete = function (req, res) { + var metric = req.metric; + metric.remove(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(metric); + } + }); }; - /** * List of Metrics */ -exports.list = function(req, res) { - Metric.find().sort('-created').populate('user', 'displayName').exec(function(err, metrics) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(metrics); - } - }); +exports.list = function (req, res) { + Metric.find().sort('-created').populate('user', 'displayName').exec(function (err, metrics) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(metrics); + } + }); }; - /** * Metric middleware */ -exports.metricByID = function(req, res, next, id) { - Metric.findById(id).populate('user', 'displayName').exec(function(err, metric) { - if (err) return next(err); - if (! metric) return next(new Error('Failed to load Metric ' + id)); - req.metric = metric ; - next(); - }); +exports.metricByID = function (req, res, next, id) { + Metric.findById(id).populate('user', 'displayName').exec(function (err, metric) { + if (err) + return next(err); + if (!metric) + return next(new Error('Failed to load Metric ' + id)); + req.metric = metric; + next(); + }); }; - /** * Metric authorization middleware */ -exports.hasAuthorization = function(req, res, next) { - if (req.metric.user.id !== req.user.id) { - return res.status(403).send('User is not authorized'); - } - next(); -}; +exports.hasAuthorization = function (req, res, next) { + if (req.metric.user.id !== req.user.id) { + return res.status(403).send('User is not authorized'); + } + next(); +}; \ No newline at end of file diff --git a/app/controllers/old.testruns.server.controller.js b/app/controllers/old.testruns.server.controller.js deleted file mode 100644 index 313862e..0000000 --- a/app/controllers/old.testruns.server.controller.js +++ /dev/null @@ -1,768 +0,0 @@ -'use strict'; - -/** - * Module dependencies. - */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Event = mongoose.model('Event'), - Testrun = mongoose.model('Testrun'), - Dashboard = mongoose.model('Dashboard'), - Product = mongoose.model('Product'), - _ = require('lodash'), - graphite = require('./graphite.server.controller'), - Utils = require('./utils.server.controller'), - Requirements = require('./testruns.requirements.server.controller'), - Benchmarks = require('./testruns.benchmarks.server.controller'), - - async = require('async'); - - -exports.updateTestRunRequirementForMetric = updateTestRunRequirementForMetric; -exports.benchmarkAndPersistTestRunById = benchmarkAndPersistTestRunById; - -/** - * select test runs for dashboard - */ -exports.testRunsForDashboard = function(req, res) { - - Testrun.find({ $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName } ] }).sort('-end').exec(function(err, testRuns) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - Event.find({$and: [{productName: req.params.productName}, {dashboardName: req.params.dashboardName}]}).sort('-eventTimestamp').exec(function (err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - createTestrunFromEvents(req.params.productName, req.params.dashboardName,events, function(eventsTestruns){ - res.jsonp(addTestrunsFromEvents(testRuns, eventsTestruns)); - }); - - } - - }); - } - }); - - function addTestrunsFromEvents(testRuns, testRunsFromEvents){ - - _.each(testRunsFromEvents, function (testRunFromEvents){ - - var exists = false; - - _.each(testRuns, function (testRun){ - - if (testRun.testRunId === testRunFromEvents.testRunId ){ - exists = true; - return exists; - } - - }) - - if (exists === false) testRuns.push(testRunFromEvents); - }) - - return testRuns.sort(Utils.dynamicSort('-start')); - - } - }; - - -function testRunById(req, res) { - - Testrun.findOne({ $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName },{ testRunId: req.params.testRunId } ] }).sort('-end').exec(function(err, testRun) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if(testRun) { - var testRunEpoch = testRun.toObject(); - testRunEpoch.startEpoch = testRun.startEpoch; - testRunEpoch.endEpoch = testRun.endEpoch; - res.jsonp(testRunEpoch); - }else{ - - Event.find({ $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName },{ testRunId: req.params.testRunId } ] }).sort('-end').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - createTestrunFromEvents(req.params.productName, req.params.dashboardName,events, function(eventsTestruns) { - - res.jsonp(eventsTestruns[0]); - - }); - } - }); - } - } - }); - - -} -exports.deleteTestRunById = function (req, res) { - - Testrun.findOne({$and: [{productName: req.params.productName}, {dashboardName: req.params.dashboardName}, {testRunId: req.params.testRunId}]}).sort('-end').exec(function (err, testRun) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if (testRun) { - - testRun.remove(function (err) { - - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } - }) - } - } - - }); -} - -exports.persistTestRunByIdFromEventsApi = function (req, res) { - - persistTestRunByIdFromEvents(req.params.productName, req.params.dashboardName, req.params.testRunId, function(persistedTestrun){ - - res.jsonp(persistedTestrun); - - }); - -} - -exports.persistTestRunByIdFromEvents = function (productName, dashboardName, testRunId, callback) { - - Event.find({ $and: [ { productName: productName }, { dashboardName: dashboardName },{ testRunId: testRunId } ] }).sort('-end').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - createTestrunFromEvents(productName, dashboardName,events, function(testrunFromEvents){ - - benchmarkAndPersistTestRunById(productName, dashboardName,testrunFromEvents[0] , function (persistedTestrun) { - - callback(persistedTestrun); - - }); - - }); - } - }); -} - - - -exports.getTestRunById = function (productName, dashboardName, testRunId, callback) { - - Testrun.findOne({ $and: [ - { productName: productName }, - { dashboardName: dashboardName }, - { testRunId: testRunId } - ] }).sort('-end').exec(function (err, testRun) { - - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if (testRun) { - - callback(testRun); - - } else { - - Event.find({ $and: [ { productName:productName }, { dashboardName: dashboardName },{ testRunId:testRunId } ] }).sort('-end').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if(events.length > 0) { - - createTestrunFromEvents(productName, dashboardName,events, function(testrunFromEvents){ - - getAndPersistTestRunById(productName, dashboardName, testrunFromEvents[0], function (persistedTestrun) { - - callback(persistedTestrun); - - }); - }); - -b }else{ - - callback(null); - } - } - }); - - } - } - - }); -} - -function benchmarkAndPersistTestRunById (productName, dashboardName, testRun, callback){ - - Testrun.findOne({testRunId: testRun.testRunId}).exec(function(err, savedTestrun) { - - if (err){ - console.log(err); - }else{ - if(savedTestrun) { - - savedTestrun.remove(function (err) { - - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - }else{ - - getDataForTestrun(productName, dashboardName, testRun, function (metrics) { - - if(metrics) console.log('Data retrieved for:' + productName + '-' + dashboardName); - - saveTestrun(testRun, metrics, function (savedTestrun) { - - if(savedTestrun) console.log('Testrun saved retrieved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestrun.testRunId); - - Requirements.setRequirementResultsForTestRun(savedTestrun, function (requirementsTestrun) { - - if(requirementsTestrun) console.log('Requirements set for:' + productName + '-' + dashboardName + 'testrunId: ' + requirementsTestrun.testRunId); - - Benchmarks.setBenchmarkResultsPreviousBuildForTestRun(requirementsTestrun, function (benchmarkPreviousBuildTestrun) { - - if(benchmarkPreviousBuildTestrun) console.log('Benchmark previous build done for:' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkPreviousBuildTestrun.testRunId); - - Benchmarks.setBenchmarkResultsFixedBaselineForTestRun(benchmarkPreviousBuildTestrun, function (benchmarkFixedBaselineTestrun) { - - if(benchmarkFixedBaselineTestrun) console.log('Benchmark fixed baseline done for:' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); - - /* Save updated test run */ - Testrun.findById(benchmarkFixedBaselineTestrun._id, function(err, savedTestRun) { - if (err) console.log(err); - if (!savedTestRun) - console.log('Could not load Document'); - else { - - savedTestRun = benchmarkFixedBaselineTestrun; - - savedTestRun.save(function(err) { - if (err) { - console.log('error') - }else { - console.log('Complete testrun saved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestRun.testRunId); - callback(savedTestRun); - } - }); - } - }); - - }); - }); - - }); - }); - - }); - - - } - - }); - - }else{ - - getDataForTestrun(productName, dashboardName, testRun, function (metrics) { - - if(metrics) console.log('Data retrieved for:' + productName + '-' + dashboardName); - - saveTestrun(testRun, metrics, function (savedTestrun) { - - if(savedTestrun) console.log('Testrun saved for: ' + productName + '-' + dashboardName + 'testrunId: ' + savedTestrun.testRunId); - - Requirements.setRequirementResultsForTestRun(savedTestrun, function (requirementsTestrun) { - - if(requirementsTestrun) console.log('Requirements set for: ' + productName + '-' + dashboardName + 'testrunId: ' + requirementsTestrun.testRunId); - - Benchmarks.setBenchmarkResultsPreviousBuildForTestRun(requirementsTestrun, function (benchmarkPreviousBuildTestrun) { - - if(benchmarkPreviousBuildTestrun) console.log('Benchmark previous build done for: ' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkPreviousBuildTestrun.testRunId); - - Benchmarks.setBenchmarkResultsFixedBaselineForTestRun(benchmarkPreviousBuildTestrun, function (benchmarkFixedBaselineTestrun) { - - if(benchmarkFixedBaselineTestrun) console.log('Benchmark fixed baseline done for: ' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); - - /* Save updated test run */ - Testrun.findById(benchmarkFixedBaselineTestrun._id, function(err, savedTestRun) { - if (err) console.log(err); - if (!savedTestRun) - console.log('Could not load Document'); - else { - - savedTestRun = benchmarkFixedBaselineTestrun; - - savedTestRun.save(function(err) { - if (err) { - console.log('error') - }else { - console.log('Complete testrun saved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestRun.testRunId); - callback(savedTestRun); - } - }); - } - }); - - }); - }); - - }); - }); - - }); - - } - } - }); - - -}; - -function getAndPersistTestRunById (productName, dashboardName, testRun, callback){ - - Testrun.findOne({testRunId: testRun.testRunId}).exec(function(err, savedTestrun) { - - if (err){ - console.log(err); - }else{ - - getDataForTestrun(productName, dashboardName, testRun, function (metrics) { - - saveTestrun(testRun, metrics, function (savedTestrun) { - - console.log('test run saved: ' + savedTestrun.testRunId); - callback(savedTestrun); - }); - - }); - - } - - }); - - -}; - - -function getDataForTestrun(productName, dashboardName, testRun, callback){ - - - - Product.findOne({name: productName}).exec(function(err, product){ - if(err) console.log(err); - - Dashboard.findOne( { $and: [ { productId: product._id }, { name: dashboardName } ] } ).populate('metrics').exec(function(err, dashboard){ - - if(err) console.log(err); - var metrics = []; - - - async.forEachLimit(dashboard.metrics, 16, function (metric, callback) { - - var targets = []; - - async.forEachLimit(metric.targets, 16, function (target, callback) { - - graphite.getGraphiteData(Math.round(testRun.start / 1000), Math.round(testRun.end / 1000), target, 900, function(body){ - - _.each(body, function(target){ - - targets.push({ - target: target.target, - value: calculateAverage(target.datapoints) - }); - - }) - callback(); - }); - - }, function (err) { - if (err) return next(err); - - metrics.push({ - _id: metric._id, - tags: metric.tags, - alias: metric.alias, - type: metric.type, - benchmarkValue: metric.benchmarkValue, - benchmarkOperator: metric.benchmarkOperator, - requirementValue: metric.requirementValue, - requirementOperator: metric.requirementOperator, - targets: targets - }); - - targets = []; - callback(); - - }); - }, function (err) { - if (err) return next(err); - - callback(metrics); - - }); - - }); - }); - -} - -function calculateAverage(datapoints){ - var count = 0; - var total = 0; - - _.each(datapoints, function(datapoint){ - - if(datapoint != null){ - - count++; - total += datapoint[0]; - - } - - }) - - return Math.round((total / (count)) * 100)/100; -} - -function saveTestrun(testrun, metrics, callback){ - - getPreviousBuild(testrun.productName, testrun.dashboardName,testrun.testRunId, function(previousBuild){ - - var persistTestrun = new Testrun(); - - persistTestrun.productName = testrun.productName; - persistTestrun.dashboardName = testrun.dashboardName; - persistTestrun.testRunId = testrun.testRunId; - persistTestrun.start = testrun.start; - persistTestrun.end = testrun.end; - persistTestrun.baseline = testrun.baseline; - persistTestrun.previousBuild = previousBuild; - persistTestrun.buildResultKey = testrun.buildResultKey; - persistTestrun.eventIds = testrun.eventIds; - persistTestrun.metrics = metrics; - - - persistTestrun.save(function(err) { - if (err) { - console.log(err); - callback(err); - } else { - callback(persistTestrun); - } - }); - - }); -} - -function getPreviousBuild(productName, dashboardName, testrunId, callback){ - - var previousBuild; - - Event.find({ $and: [ { productName: productName }, { dashboardName: dashboardName } ] }).sort('-eventTimestamp').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - createTestrunFromEvents(productName, dashboardName, events, function(testruns){ - - _.each(testruns, function (testrun, i) { - - if (testrun.testRunId === testrunId) { - if(i+1 === testruns.length){ - - return null; - - }else { - previousBuild = testruns[i + 1].testRunId; - return previousBuild; - } - } - - }) - - callback(previousBuild); - }); - } - }); -} - -function setTestrunRequirementResults(metrics){ - - var meetsRequirement = true; - - _.each(metrics, function(metric){ - - if(metric.meetsRequirement === false) { - - meetsRequirement = false; - return; - } - }) - - return meetsRequirement; -} - -function setMetricRequirementResults(targets){ - - var meetsRequirement = true; - - _.each(targets, function(target){ - - if(target.meetsRequirement === false) { - - meetsRequirement = false; - return; - } - }) - - return meetsRequirement; -} - - -function evaluateRequirement(value, requirementOperator, requirementValue){ - - var requirementResult; - - if((requirementOperator === "<" && value > requirementValue) || requirementOperator === ">" && value < requirementValue){ - - var requirementResult = false; - - }else{ - - var requirementResult = true; - } - - return requirementResult; -} - -function createTestrunFromEvents(productName, dashboardName, events, callback) { - - var testRuns = []; - - Product.findOne({name: productName}).exec(function(err, product){ - if(err) console.log(err); - - Dashboard.findOne( { $and: [ { productId: product._id }, { name: dashboardName } ] } ).exec(function(err, dashboard) { - - if (err) { - console.log(err); - } else { - - - for (var i = 0; i < events.length; i++) { - - if (events[i].eventDescription === 'start') { - - for (var j = 0; j < events.length; j++) { - - if (events[j].eventDescription === 'end' && events[j].testRunId == events[i].testRunId) { - - if (events[i].buildResultKey) { - - testRuns.push({start: events[i].eventTimestamp, startEpoch: events[i].eventTimestamp.getTime(), end: events[j].eventTimestamp, endEpoch: events[j].eventTimestamp.getTime(), productName: events[i].productName, dashboardName: events[i].dashboardName, testRunId: events[i].testRunId, buildResultKey: events[i].buildResultKey, eventIds: [events[i].id, events[j].id], meetsRequirement: null, benchmarkResultFixedOK: null, benchmarkResultPreviousOK: null, baseline: dashboard.baseline || events[i].baseline}); - } else { - - testRuns.push({start: events[i].eventTimestamp, startEpoch: events[i].eventTimestamp.getTime(), end: events[j].eventTimestamp, endEpoch: events[j].eventTimestamp.getTime(), productName: events[i].productName, dashboardName: events[i].dashboardName, testRunId: events[i].testRunId, eventIds: [events[i].id, events[j].id], meetsRequirement: null, benchmarkResultFixedOK: null, benchmarkResultPreviousOK: null, baseline: dashboard.baseline || events[i].baseline}); - } - - break; - } - - } - } - } - - callback(testRuns); - } - }); - }); -} - -/** - * Show the current Testrun - */ -exports.runningTest = function (req, res){ - - var currentTime = new Date(); - var anyEventFound = false; - - Event.find({ $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName } ] }).sort({eventTimestamp: -1}).lean().exec(function(err, events){ - - if(err) throw err; - - for(var i=0;i 176400000){ - tooOld = true - } - - - } - } - - if (endEventFound === true || tooOld === true || anyEventFound === false ) { - res.jsonp({}); - - } - - - }); - -} -/** - * Update a Testrun - */ -function updateTestRunRequirementForMetric(metric) { - - Testrun.find( { $and: [ { productName: metric.productName }, { dashboardName: metric.dashboardName } ] } ).exec(function(err, testruns) { - - _.each(testruns, function(testrun){ - - - var metricToUpdate = testrun.metrics.id(metric._id); - - metricToUpdate.requirementOperator = metric.requirementOperator; - metricToUpdate.requirementValue = metric.requirementValue; - - metricToUpdate.targets = setTargetRequirementResults( metricToUpdate.targets, metricToUpdate.requirementOperator, metricToUpdate.requirementValue ); - metricToUpdate.meetsRequirement = setMetricRequirementResults(metricToUpdate.targets) - - testrun.meetsRequirement = setTestrunRequirementResults(testrun.metrics); - - testrun.save(function(err){ - if (err) console.log("bla: " + err.stack); - }) - - }) - }) - - -}; - - - - - -function updateTestRunMetric(testrun, metric){ - - - var updatedMetric; - - updatedMetric.requirementOperator = metric.requirementOperator; - updatedMetric.requirementValue = metric.requirementValue; - - - //var updatedMetrics = []; - // - // - //_.each(testrun.metrics, function(testrunMetric){ - // - // if (testrunMetric._id.toString() === updatedMetric._id){ - // - // /* update requirement values */ - // testrunMetric.requirementOperator = updatedMetric.requirementOperator; - // testrunMetric.requirementValue = updatedMetric.requirementValue; - // - // updatedMetrics.push(setMetricRequirementResults(testrunMetric)); - // - // }else{ - // - // updatedMetrics.push(updatedMetric); - // } - // - // - //}) - // - //return updatedMetrics; - -} - -function getTargets(metrics, metricId){ - - var targets = []; - - _.each(metrics, function(metric){ - - if (metric._id === metricId){ - - _.each(metric.targets, function(target){ - - targets.push(target); - }) - - return targets; - } - - }) - - return targets; - -} -/** - * Delete an Testrun - */ -exports.delete = function(req, res) { - -}; - -/** - * List of Testruns - */ -exports.list = function(req, res) { - -}; diff --git a/app/controllers/products.server.controller.js b/app/controllers/products.server.controller.js index 3e3e2a7..2009d88 100644 --- a/app/controllers/products.server.controller.js +++ b/app/controllers/products.server.controller.js @@ -1,121 +1,102 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Product = mongoose.model('Product'), - _ = require('lodash'); - +var mongoose = require('mongoose'), errorHandler = require('./errors.server.controller'), Product = mongoose.model('Product'), _ = require('lodash'); /** * Create a Product */ -exports.create = function(req, res) { - var product = new Product(req.body); - product.user = req.user; - - product.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(product); - } - }); +exports.create = function (req, res) { + var product = new Product(req.body); + product.user = req.user; + product.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(product); + } + }); }; - /** * Show the current Product */ -exports.read = function(req, res) { - res.jsonp(req.product); +exports.read = function (req, res) { + res.jsonp(req.product); }; - /** * Update a Product */ -exports.update = function(req, res) { - var product = req.product ; - - //product = _.extend(product , req.body); - - product.name = req.body.name; - product.description = req.body.description; - - product.save(function(err) { - if (err) { - console.log(err); - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(product); - } - }); +exports.update = function (req, res) { + var product = req.product; + //product = _.extend(product , req.body); + product.name = req.body.name; + product.description = req.body.description; + product.save(function (err) { + if (err) { + console.log(err); + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(product); + } + }); }; - /** * Delete an Product */ -exports.delete = function(req, res) { - var product = req.product ; - - product.remove(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(product); - } - }); +exports.delete = function (req, res) { + var product = req.product; + product.remove(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(product); + } + }); }; - /** * List of Products */ -exports.list = function(req, res) { - Product.find().sort('name').populate({path: 'dashboards', options: { sort: { name: 1} } }).exec(function(err, products) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - res.jsonp(products); - } - }); +exports.list = function (req, res) { + Product.find().sort('name').populate({ + path: 'dashboards', + options: { sort: { name: 1 } } + }).exec(function (err, products) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + res.jsonp(products); + } + }); }; - /** * Product middleware */ -exports.productByName = function(req, res, next, name) { - Product.findOne({name: name.toUpperCase()}).populate('user', 'displayName').populate('dashboards').exec(function(err, product) { - if (err) return next(err); - if (! product) return res.status(404).send({ - message: 'No product with name' + name + 'has been found' - }); - req.product = product ; - next(); - }); +exports.productByName = function (req, res, next, name) { + Product.findOne({ name: name.toUpperCase() }).populate('user', 'displayName').populate('dashboards').exec(function (err, product) { + if (err) + return next(err); + if (!product) + return res.status(404).send({ message: 'No product with name' + name + 'has been found' }); + req.product = product; + next(); + }); }; - -exports.productById = function(req, res, next, id) { - Product.findById(id).exec(function(err, product) { - if (err) return next(err); - if (! product) return next(new Error('Failed to load Product ' + id)); - req.product = product ; - next(); - }); +exports.productById = function (req, res, next, id) { + Product.findById(id).exec(function (err, product) { + if (err) + return next(err); + if (!product) + return next(new Error('Failed to load Product ' + id)); + req.product = product; + next(); + }); }; /** * Product authorization middleware */ -exports.hasAuthorization = function(req, res, next) { - if (req.product.user.id !== req.user.id) { - return res.status(403).send('User is not authorized'); - } - next(); -}; +exports.hasAuthorization = function (req, res, next) { + if (req.product.user.id !== req.user.id) { + return res.status(403).send('User is not authorized'); + } + next(); +}; \ No newline at end of file diff --git a/app/controllers/testruns.benchmarks.server.controller.js b/app/controllers/testruns.benchmarks.server.controller.js index 0e1ebfc..9bd8b2c 100644 --- a/app/controllers/testruns.benchmarks.server.controller.js +++ b/app/controllers/testruns.benchmarks.server.controller.js @@ -1,296 +1,172 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Event = mongoose.model('Event'), - Testrun = mongoose.model('Testrun'), - Dashboard = mongoose.model('Dashboard'), - Product = mongoose.model('Product'), - _ = require('lodash'), - graphite = require('./graphite.server.controller'), - Utils = require('./utils.server.controller'), - Testruns = require('./testruns.server.controller.js'), - async = require('async'); - - +var mongoose = require('mongoose'), errorHandler = require('./errors.server.controller'), Event = mongoose.model('Event'), Testrun = mongoose.model('Testrun'), Dashboard = mongoose.model('Dashboard'), Product = mongoose.model('Product'), _ = require('lodash'), graphite = require('./graphite.server.controller'), Utils = require('./utils.server.controller'), Testruns = require('./testruns.server.controller.js'), async = require('async'); exports.setBenchmarkResultsPreviousBuildForTestRun = setBenchmarkResultsPreviousBuildForTestRun; exports.setBenchmarkResultsFixedBaselineForTestRun = setBenchmarkResultsFixedBaselineForTestRun; exports.updateFixedBaselineBenchmark = updateFixedBaselineBenchmark; exports.updateBenchmarkResults = updateBenchmarkResults; - -function updateBenchmarkResults (testRun, callback){ - - setBenchmarkResultsFixedBaselineForTestRun(testRun, function(updatedFixedBenchmark){ - - Testruns.saveTestRun(updatedFixedBenchmark, function(savedFixedBenchmark){ - - setBenchmarkResultsPreviousBuildForTestRun(savedFixedBenchmark, function(updatedPreviousBenchmark) { - - Testruns.saveTestRun(updatedPreviousBenchmark, function(updatedBenchmarksTestRun){ - - callback(updatedBenchmarksTestRun); - }); - }); +function updateBenchmarkResults(testRun, callback) { + setBenchmarkResultsFixedBaselineForTestRun(testRun, function (updatedFixedBenchmark) { + Testruns.saveTestRun(updatedFixedBenchmark, function (savedFixedBenchmark) { + setBenchmarkResultsPreviousBuildForTestRun(savedFixedBenchmark, function (updatedPreviousBenchmark) { + Testruns.saveTestRun(updatedPreviousBenchmark, function (updatedBenchmarksTestRun) { + callback(updatedBenchmarksTestRun); }); + }); }); - + }); } - -function updateFixedBaselineBenchmark(req, res){ - - var testRunToUpdate = new Testrun(req.body); - - setBenchmarkResultsFixedBaselineForTestRun(testRunToUpdate, function(updatedBenchmark){ - - /* Save updated test run */ - Testrun.findById(updatedBenchmark._id, function(err, savedTestRun) { - if (err) console.log(err); - if (!savedTestRun) - console.log('Could not load Document'); - else { - - savedTestRun.metrics = updatedBenchmark.metrics; - savedTestRun.baseline = updatedBenchmark.baseline; - savedTestRun.benchmarkResultFixedOK = updatedBenchmark.benchmarkResultFixedOK; - - - savedTestRun.save(function(err) { - if (err) { - console.log(err) - }else { - res.jsonp(savedTestRun); } - }); - } +function updateFixedBaselineBenchmark(req, res) { + var testRunToUpdate = new Testrun(req.body); + setBenchmarkResultsFixedBaselineForTestRun(testRunToUpdate, function (updatedBenchmark) { + /* Save updated test run */ + Testrun.findById(updatedBenchmark._id, function (err, savedTestRun) { + if (err) + console.log(err); + if (!savedTestRun) + console.log('Could not load Document'); + else { + savedTestRun.metrics = updatedBenchmark.metrics; + savedTestRun.baseline = updatedBenchmark.baseline; + savedTestRun.benchmarkResultFixedOK = updatedBenchmark.benchmarkResultFixedOK; + savedTestRun.save(function (err) { + if (err) { + console.log(err); + } else { + res.jsonp(savedTestRun); + } }); - + } }); - - - + }); } function setBenchmarkResultsFixedBaselineForTestRun(testRun, callback) { - - var benchmarkDone = false; - - if (testRun.baseline && testRun.baseline !== testRun.testRunId) { - - Testruns.getTestRunById(testRun.productName, testRun.dashboardName, testRun.baseline, function (fixedBaseline) { - - if(fixedBaseline) { - benchmarkTestRuns(testRun, fixedBaseline, 'benchmarkResultFixedOK', function(updatedTestrun){ - - callback(updatedTestrun); - - }) - - }else{ - - testRun.benchmarkResultFixedOK = null; - callback(testRun); - } - }) - - - } else { - + var benchmarkDone = false; + if (testRun.baseline && testRun.baseline !== testRun.testRunId) { + Testruns.getTestRunById(testRun.productName, testRun.dashboardName, testRun.baseline, function (fixedBaseline) { + if (fixedBaseline) { + benchmarkTestRuns(testRun, fixedBaseline, 'benchmarkResultFixedOK', function (updatedTestrun) { + callback(updatedTestrun); + }); + } else { testRun.benchmarkResultFixedOK = null; callback(testRun); - } + } + }); + } else { + testRun.benchmarkResultFixedOK = null; + callback(testRun); + } } - -function setBenchmarkResultsPreviousBuildForTestRun(testRun, callback){ - - if(testRun.previousBuild){ - - Testruns.getTestRunById(testRun.productName, testRun.dashboardName, testRun.previousBuild, function(previousBuildBaseline){ - - if(previousBuildBaseline) { - - benchmarkTestRuns(testRun, previousBuildBaseline, 'benchmarkResultPreviousOK', function (updatedTestrun) { - - callback(updatedTestrun); - - }) - - }else{ - - testRun.benchmarkResultPreviousOK = null; - callback(testRun); - } - }) - - }else{ - +function setBenchmarkResultsPreviousBuildForTestRun(testRun, callback) { + if (testRun.previousBuild) { + Testruns.getTestRunById(testRun.productName, testRun.dashboardName, testRun.previousBuild, function (previousBuildBaseline) { + if (previousBuildBaseline) { + benchmarkTestRuns(testRun, previousBuildBaseline, 'benchmarkResultPreviousOK', function (updatedTestrun) { + callback(updatedTestrun); + }); + } else { testRun.benchmarkResultPreviousOK = null; callback(testRun); - } - - + } + }); + } else { + testRun.benchmarkResultPreviousOK = null; + callback(testRun); + } } - - -function benchmarkTestRuns (benchmark, baseline, benchmarkType, callback){ - - var benchmarkDone = false; - var updatedTargets = []; - var updatedMetrics = []; - - - _.each(benchmark.metrics, function (benchmarkMetric) { - - if(benchmarkMetric.benchmarkValue){ - - var baselineMetric = _.filter(baseline.metrics, function(metric){ - return metric._id.toString() === benchmarkMetric._id.toString(); - }); - - - _.each(benchmarkMetric.targets, function (benchmarkMetricTarget) { - - if(baselineMetric.length > 0) { - - _.each(baselineMetric[0].targets, function (baselineMetricTarget) { - - if (benchmarkMetricTarget.target === baselineMetricTarget.target) { - - benchmarkDone = true; - - if (benchmarkType === 'benchmarkResultPreviousOK') { - - benchmarkMetricTarget.benchmarkPreviousValue = baselineMetricTarget.value; - - }else{ - - benchmarkMetricTarget.benchmarkFixedValue = baselineMetricTarget.value; - - } - - benchmarkMetricTarget[benchmarkType] = evaluateBenchmark(benchmarkMetricTarget.value, baselineMetricTarget.value, benchmarkMetric.benchmarkOperator, benchmarkMetric.benchmarkValue); - - updatedTargets.push(benchmarkMetricTarget) - - } - }) - - }else{ - - updatedTargets.push(benchmarkMetricTarget); - - } - - - }) - - if (benchmarkType === 'benchmarkResultPreviousOK') { - - updatedMetrics.push({ - _id: benchmarkMetric._id, - tags: benchmarkMetric.tags, - alias: benchmarkMetric.alias, - type: benchmarkMetric.type, - meetsRequirement: benchmarkMetric.meetsRequirement, - requirementOperator: benchmarkMetric.requirementOperator, - requirementValue: benchmarkMetric.requirementValue, - benchmarkOperator: benchmarkMetric.benchmarkOperator, - benchmarkValue: benchmarkMetric.benchmarkValue, - targets: updatedTargets, - benchmarkResultPreviousOK: getConsolidateBenchmarkResults(updatedTargets, benchmarkType), - benchmarkResultFixedOK: benchmarkMetric.benchmarkResultFixedOK - }); - - }else{ - - updatedMetrics.push({ - _id: benchmarkMetric._id, - tags: benchmarkMetric.tags, - alias: benchmarkMetric.alias, - type: benchmarkMetric.type, - meetsRequirement: benchmarkMetric.meetsRequirement, - requirementOperator: benchmarkMetric.requirementOperator, - requirementValue: benchmarkMetric.requirementValue, - benchmarkOperator: benchmarkMetric.benchmarkOperator, - benchmarkValue: benchmarkMetric.benchmarkValue, - targets: updatedTargets, - benchmarkResultFixedOK: getConsolidateBenchmarkResults(updatedTargets, benchmarkType), - benchmarkResultPreviousOK: benchmarkMetric.benchmarkResultPreviousOK - }); - +function benchmarkTestRuns(benchmark, baseline, benchmarkType, callback) { + var benchmarkDone = false; + var updatedTargets = []; + var updatedMetrics = []; + _.each(benchmark.metrics, function (benchmarkMetric) { + if (benchmarkMetric.benchmarkValue) { + var baselineMetric = _.filter(baseline.metrics, function (metric) { + return metric._id.toString() === benchmarkMetric._id.toString(); + }); + _.each(benchmarkMetric.targets, function (benchmarkMetricTarget) { + if (baselineMetric.length > 0) { + _.each(baselineMetric[0].targets, function (baselineMetricTarget) { + if (benchmarkMetricTarget.target === baselineMetricTarget.target) { + benchmarkDone = true; + if (benchmarkType === 'benchmarkResultPreviousOK') { + benchmarkMetricTarget.benchmarkPreviousValue = baselineMetricTarget.value; + } else { + benchmarkMetricTarget.benchmarkFixedValue = baselineMetricTarget.value; + } + benchmarkMetricTarget[benchmarkType] = evaluateBenchmark(benchmarkMetricTarget.value, baselineMetricTarget.value, benchmarkMetric.benchmarkOperator, benchmarkMetric.benchmarkValue); + updatedTargets.push(benchmarkMetricTarget); } - - - }else{ - - updatedMetrics.push(benchmarkMetric); - + }); + } else { + updatedTargets.push(benchmarkMetricTarget); } - - - - - updatedTargets = []; - - }) - - benchmark.metrics = updatedMetrics; - - if(benchmarkDone) - benchmark[benchmarkType] = getConsolidateBenchmarkResults(benchmark.metrics, benchmarkType); - else - benchmark[benchmarkType] = null; - - callback(benchmark); - - - -} - - -function getConsolidateBenchmarkResults(targets, benchmarkProp){ - - var benchmarkResult = true; - - _.each(targets, function(target){ - - - if(target[benchmarkProp] === false) { - - benchmarkResult = false; - return benchmarkResult; - } - - }) - - return benchmarkResult; + }); + if (benchmarkType === 'benchmarkResultPreviousOK') { + updatedMetrics.push({ + _id: benchmarkMetric._id, + tags: benchmarkMetric.tags, + alias: benchmarkMetric.alias, + type: benchmarkMetric.type, + meetsRequirement: benchmarkMetric.meetsRequirement, + requirementOperator: benchmarkMetric.requirementOperator, + requirementValue: benchmarkMetric.requirementValue, + benchmarkOperator: benchmarkMetric.benchmarkOperator, + benchmarkValue: benchmarkMetric.benchmarkValue, + targets: updatedTargets, + benchmarkResultPreviousOK: getConsolidateBenchmarkResults(updatedTargets, benchmarkType), + benchmarkResultFixedOK: benchmarkMetric.benchmarkResultFixedOK + }); + } else { + updatedMetrics.push({ + _id: benchmarkMetric._id, + tags: benchmarkMetric.tags, + alias: benchmarkMetric.alias, + type: benchmarkMetric.type, + meetsRequirement: benchmarkMetric.meetsRequirement, + requirementOperator: benchmarkMetric.requirementOperator, + requirementValue: benchmarkMetric.requirementValue, + benchmarkOperator: benchmarkMetric.benchmarkOperator, + benchmarkValue: benchmarkMetric.benchmarkValue, + targets: updatedTargets, + benchmarkResultFixedOK: getConsolidateBenchmarkResults(updatedTargets, benchmarkType), + benchmarkResultPreviousOK: benchmarkMetric.benchmarkResultPreviousOK + }); + } + } else { + updatedMetrics.push(benchmarkMetric); + } + updatedTargets = []; + }); + benchmark.metrics = updatedMetrics; + if (benchmarkDone) + benchmark[benchmarkType] = getConsolidateBenchmarkResults(benchmark.metrics, benchmarkType); + else + benchmark[benchmarkType] = null; + callback(benchmark); } - - - -function evaluateBenchmark(value, baselineValue, benchmarkOperator, benchmarkValue){ - - var result = false; - - if(benchmarkOperator === '>'){ - - if(value - baselineValue < benchmarkValue ){ - - result = true; - } - - }else{ - - if(baselineValue - value < benchmarkValue ){ - - result = true; - } - +function getConsolidateBenchmarkResults(targets, benchmarkProp) { + var benchmarkResult = true; + _.each(targets, function (target) { + if (target[benchmarkProp] === false) { + benchmarkResult = false; + return benchmarkResult; } - - - return result; + }); + return benchmarkResult; } - - - +function evaluateBenchmark(value, baselineValue, benchmarkOperator, benchmarkValue) { + var result = false; + if (benchmarkOperator === '>') { + if (value - baselineValue < benchmarkValue) { + result = true; + } + } else { + if (baselineValue - value < benchmarkValue) { + result = true; + } + } + return result; +} \ No newline at end of file diff --git a/app/controllers/testruns.requirements.server.controller.js b/app/controllers/testruns.requirements.server.controller.js index ccc8000..193b79d 100644 --- a/app/controllers/testruns.requirements.server.controller.js +++ b/app/controllers/testruns.requirements.server.controller.js @@ -1,168 +1,102 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Event = mongoose.model('Event'), - Testrun = mongoose.model('Testrun'), - Dashboard = mongoose.model('Dashboard'), - Metric = mongoose.model('Metric'), - Product = mongoose.model('Product'), - _ = require('lodash'), - graphite = require('./graphite.server.controller'), - Utils = require('./utils.server.controller'), - async = require('async'); - - +var mongoose = require('mongoose'), errorHandler = require('./errors.server.controller'), Event = mongoose.model('Event'), Testrun = mongoose.model('Testrun'), Dashboard = mongoose.model('Dashboard'), Metric = mongoose.model('Metric'), Product = mongoose.model('Product'), _ = require('lodash'), graphite = require('./graphite.server.controller'), Utils = require('./utils.server.controller'), async = require('async'); exports.setRequirementResultsForTestRun = setRequirementResultsForTestRun; exports.updateRequirementResults = updateRequirementResults; - -function updateRequirementResults(testRun, callback){ - - setRequirementResultsForTestRun(testRun, function (updatedTestRun) { - - /* Save updated test run */ - Testrun.findById(testRun._id, function (err, savedTestRun) { - if (err) console.log(err); - if (!savedTestRun) - console.log('Could not load Document'); - else { - - savedTestRun.metrics = testRun.metrics; - savedTestRun.meetsRequirement = testRun.meetsRequirement; - - - savedTestRun.save(function (err) { - if (err) { - console.log(err) - } else { - console.log("test run saved: " + savedTestRun.testRunId); - callback(savedTestRun) ; - } - }); - } - }); - - }); -} - - -function setRequirementResultsForTestRun(testRun, callback){ - - var requirementsSet = false; - var updatedMetrics = []; - - _.each(testRun.metrics, function(metric, i){ - - /* if requirement is set for metric, check requirements*/ - if(metric.requirementValue) { - requirementsSet = true; - metric.targets = setTargetRequirementResults(metric.targets, metric.requirementOperator, metric.requirementValue); - metric.meetsRequirement = setMetricRequirementResults(metric.targets); - } - - updatedMetrics.push({ - _id: metric._id, - tags: metric.tags, - alias: metric.alias, - type: metric.type, - meetsRequirement: metric.meetsRequirement, - requirementOperator: metric.requirementOperator, - requirementValue: metric.requirementValue, - benchmarkOperator: metric.benchmarkOperator, - benchmarkValue: metric.benchmarkValue, - targets:metric.targets +function updateRequirementResults(testRun, callback) { + setRequirementResultsForTestRun(testRun, function (updatedTestRun) { + /* Save updated test run */ + Testrun.findById(testRun._id, function (err, savedTestRun) { + if (err) + console.log(err); + if (!savedTestRun) + console.log('Could not load Document'); + else { + savedTestRun.metrics = testRun.metrics; + savedTestRun.meetsRequirement = testRun.meetsRequirement; + savedTestRun.save(function (err) { + if (err) { + console.log(err); + } else { + console.log('test run saved: ' + savedTestRun.testRunId); + callback(savedTestRun); + } }); - - - }) - - testRun.metrics = updatedMetrics; - - if(requirementsSet) - testRun.meetsRequirement = setTestrunRequirementResults(testRun.metrics) - else - testRun.meetsRequirement = null; - - - callback(testRun); - + } + }); + }); } - - -function setTestrunRequirementResults(metrics){ - - var meetsRequirement = true; - - _.each(metrics, function(metric){ - - if(metric.meetsRequirement === false) { - - meetsRequirement = false; - return; - } - }) - - return meetsRequirement; +function setRequirementResultsForTestRun(testRun, callback) { + var requirementsSet = false; + var updatedMetrics = []; + _.each(testRun.metrics, function (metric, i) { + /* if requirement is set for metric, check requirements*/ + if (metric.requirementValue) { + requirementsSet = true; + metric.targets = setTargetRequirementResults(metric.targets, metric.requirementOperator, metric.requirementValue); + metric.meetsRequirement = setMetricRequirementResults(metric.targets); + } + updatedMetrics.push({ + _id: metric._id, + tags: metric.tags, + alias: metric.alias, + type: metric.type, + meetsRequirement: metric.meetsRequirement, + requirementOperator: metric.requirementOperator, + requirementValue: metric.requirementValue, + benchmarkOperator: metric.benchmarkOperator, + benchmarkValue: metric.benchmarkValue, + targets: metric.targets + }); + }); + testRun.metrics = updatedMetrics; + if (requirementsSet) + testRun.meetsRequirement = setTestrunRequirementResults(testRun.metrics); + else + testRun.meetsRequirement = null; + callback(testRun); } - -function setMetricRequirementResults(targets){ - - var meetsRequirement = true; - - _.each(targets, function(target){ - - if(target.meetsRequirement === false) { - - meetsRequirement = false; - return; - } - }) - - return meetsRequirement; +function setTestrunRequirementResults(metrics) { + var meetsRequirement = true; + _.each(metrics, function (metric) { + if (metric.meetsRequirement === false) { + meetsRequirement = false; + return; + } + }); + return meetsRequirement; } - - -function evaluateRequirement(value, requirementOperator, requirementValue){ - - var requirementResult; - - if((requirementOperator === "<" && value > requirementValue) || requirementOperator === ">" && value < requirementValue){ - - var requirementResult = false; - - }else{ - - var requirementResult = true; +function setMetricRequirementResults(targets) { + var meetsRequirement = true; + _.each(targets, function (target) { + if (target.meetsRequirement === false) { + meetsRequirement = false; + return; } - - return requirementResult; + }); + return meetsRequirement; } - - - - -function setTargetRequirementResults(targets,requirementOperator, requirementValue){ - - var updatedTargets = []; - - _.each(targets, function(target){ - - var meetsRequirement = evaluateRequirement(target.value, requirementOperator, requirementValue); - - updatedTargets.push({ - meetsRequirement: meetsRequirement, - target: target.target, - value: target.value, - _id: target._id - }); - - }) - - return updatedTargets; +function evaluateRequirement(value, requirementOperator, requirementValue) { + var requirementResult; + if (requirementOperator === '<' && value > requirementValue || requirementOperator === '>' && value < requirementValue) { + var requirementResult = false; + } else { + var requirementResult = true; + } + return requirementResult; } - - - +function setTargetRequirementResults(targets, requirementOperator, requirementValue) { + var updatedTargets = []; + _.each(targets, function (target) { + var meetsRequirement = evaluateRequirement(target.value, requirementOperator, requirementValue); + updatedTargets.push({ + meetsRequirement: meetsRequirement, + target: target.target, + value: target.value, + _id: target._id + }); + }); + return updatedTargets; +} \ No newline at end of file diff --git a/app/controllers/testruns.server.controller.js b/app/controllers/testruns.server.controller.js index 008f482..3721ce2 100644 --- a/app/controllers/testruns.server.controller.js +++ b/app/controllers/testruns.server.controller.js @@ -1,24 +1,10 @@ +/*jshint maxerr: 10000 */ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - errorHandler = require('./errors.server.controller'), - Event = mongoose.model('Event'), - Testrun = mongoose.model('Testrun'), - Dashboard = mongoose.model('Dashboard'), - Product = mongoose.model('Product'), - _ = require('lodash'), - graphite = require('./graphite.server.controller'), - Utils = require('./utils.server.controller'), - Requirements = require('./testruns.requirements.server.controller'), - Benchmarks = require('./testruns.benchmarks.server.controller'), - Metric = mongoose.model('Metric'), - async = require('async'); - - -exports.benchmarkAndPersistTestRunById = benchmarkAndPersistTestRunById; +var mongoose = require('mongoose'), errorHandler = require('./errors.server.controller'), Event = mongoose.model('Event'), Testrun = mongoose.model('Testrun'), Dashboard = mongoose.model('Dashboard'), Product = mongoose.model('Product'), _ = require('lodash'), graphite = require('./graphite.server.controller'), Utils = require('./utils.server.controller'), Requirements = require('./testruns.requirements.server.controller'), Benchmarks = require('./testruns.benchmarks.server.controller'), Metric = mongoose.model('Metric'), async = require('async'); +//exports.benchmarkAndPersistTestRunById = benchmarkAndPersistTestRunById; exports.testRunsForDashboard = testRunsForDashboard; exports.deleteTestRunById = deleteTestRunById; exports.testRunById = testRunById; @@ -26,997 +12,670 @@ exports.refreshTestrun = refreshTestrun; exports.runningTest = runningTest; exports.updateTestrunsResults = updateTestrunsResults; exports.saveTestRun = saveTestRun; - -function saveTestRun (testRun, callback){ - - /* Save updated test run */ - Testrun.findById(testRun._id, function (err, savedTestRun) { - if (err) console.log(err); - if (!savedTestRun) - console.log('Could not load Document'); - else { - - savedTestRun.metrics = testRun.metrics; - savedTestRun.baseline = testRun.baseline; - savedTestRun.benchmarkResultFixedOK = testRun.benchmarkResultFixedOK; - savedTestRun.benchmarkResultPreviousOK = testRun.benchmarkResultPreviousOK; - - - savedTestRun.save(function (err) { - if (err) { - console.log(err) - } else { - callback(savedTestRun); - } - }); - } - }); -} - - -function updateTestrunsResults(req, res) { - - var updateRequirements = req.params.updateRequirements; - var updateBenchmarks = req.params.updateBenchmarks; - - Testrun.find({$and: [{productName: req.params.productName}, {dashboardName: req.params.dashboardName}]}).exec(function (err, testRuns) { +function saveTestRun(testRun, callback) { + /* Save updated test run */ + Testrun.findById(testRun._id, function (err, savedTestRun) { + if (err) + console.log(err); + if (!savedTestRun) + console.log('Could not load Document'); + else { + savedTestRun.metrics = testRun.metrics; + savedTestRun.baseline = testRun.baseline; + savedTestRun.benchmarkResultFixedOK = testRun.benchmarkResultFixedOK; + savedTestRun.benchmarkResultPreviousOK = testRun.benchmarkResultPreviousOK; + savedTestRun.save(function (err) { if (err) { - console.log(err); + console.log(err); } else { - - async.forEachLimit(testRuns, 1, function (testRun, callback) { - - updateMetricInTestrun(req.params.productName, req.params.dashboardName, req.params.metricId, testRun, function (testRunWithUpdatedMetrics) { - - if (updateRequirements === "true" && updateBenchmarks === "true") { - - Requirements.updateRequirementResults(testRunWithUpdatedMetrics, function (updatedRequirementsTestrun) { - - Benchmarks.updateBenchmarkResults(updatedRequirementsTestrun, function (updatedBenchmarkTestrun) { - - console.log('Updated requiremenst and benchmarks for: ' + updatedBenchmarkTestrun.testRunId); - callback(); - }); - }); - - } else { - - if (updateRequirements === "true" && updateBenchmarks === "false") { - - Requirements.updateRequirementResults(testRunWithUpdatedMetrics, function (updatedTestrun) { - - console.log('Updated requirememts for: ' + updatedTestrun.testRunId); - callback(); - }); - } - - if (updateRequirements === "false" && updateBenchmarks === "true") { - - Benchmarks.updateBenchmarkResults(testRunWithUpdatedMetrics, function (updatedTestrun) { - - console.log('Updated benchmarks for: ' + updatedTestrun.testRunId); - callback(); - }); - } - - } - }); - }, function (err) { - if (err) console.log(err); - - Testrun.find({$and: [{productName: req.params.productName}, {dashboardName: req.params.dashboardName}]}).exec(function (err, testRuns) { - if (err) { - console.log(err); - } else { - res.json(testRuns); - } - }); - - - }); - + callback(savedTestRun); } - }); + }); + } + }); } - - -function updateMetricInTestrun(productName, dashboardName, metricId, testRun, callback){ - - var updatedMetrics = []; - - Metric.findOne({_id: metricId}).exec(function(err, dashboardMetric){ - if(err) console.log(err); - - _.each(testRun.metrics, function(testrunMetric){ - - if(testrunMetric.alias === dashboardMetric.alias){ - - testrunMetric.requirementOperator = dashboardMetric.requirementOperator; - testrunMetric.requirementValue = dashboardMetric.requirementValue; - testrunMetric.benchmarkOperator = dashboardMetric.benchmarkOperator; - testrunMetric.benchmarkValue = dashboardMetric.benchmarkValue; - +function updateTestrunsResults(req, res) { + Testrun.find({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName } + ] + }).exec(function (err, testRuns) { + if (err) { + console.log(err); + } else { + async.forEachLimit(testRuns, 1, function (testRun, callback) { + updateMetricInTestrun(req.params.metricId, testRun, function (testRunWithUpdatedMetrics) { + if (req.params.updateRequirements === 'true' && req.params.updateBenchmarks === 'true') { + Requirements.updateRequirementResults(testRunWithUpdatedMetrics, function (updatedRequirementsTestrun) { + Benchmarks.updateBenchmarkResults(updatedRequirementsTestrun, function (updatedBenchmarkTestrun) { + console.log('Updated requiremenst and benchmarks for: ' + updatedBenchmarkTestrun.testRunId); + callback(); + }); + }); + } else { + if (req.params.updateRequirements === 'true' && req.params.updateBenchmarks === 'false') { + Requirements.updateRequirementResults(testRunWithUpdatedMetrics, function (updatedTestrun) { + console.log('Updated requirememts for: ' + updatedTestrun.testRunId); + callback(); + }); } - - updatedMetrics.push(testrunMetric); - - }) - - /* Save updated test run */ - Testrun.findById(testRun._id, function(err, savedTestRun) { - if (err) console.log(err); - if (!savedTestRun) - console.log('Could not load Document'); - else { - - savedTestRun.metrics = updatedMetrics; - - savedTestRun.save(function(err) { - if (err) { - console.log(err) - }else { - callback(savedTestRun); } - }); + if (req.params.updateRequirements === 'false' && req.params.updateBenchmarks === 'true') { + Benchmarks.updateBenchmarkResults(testRunWithUpdatedMetrics, function (updatedTestrun) { + console.log('Updated benchmarks for: ' + updatedTestrun.testRunId); + callback(); + }); } + } }); - - - }); - + }, function (err) { + if (err) + console.log(err); + Testrun.find({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName } + ] + }).exec(function (err, testRuns) { + if (err) { + console.log(err); + } else { + res.json(testRuns); + } + }); + }); + } + }); } - -function deleteTestRunById (req, res) { - - Testrun.findOne({$and: [{productName: req.params.productName}, {dashboardName: req.params.dashboardName}, {testRunId: req.params.testRunId}]}).sort('-end').exec(function (err, testRun) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if (testRun) { - - testRun.remove(function (err) { - - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } - }) - } - } - +function updateMetricInTestrun(metricId, testRun, callback) { + var updatedMetrics = []; + Metric.findOne({ _id: metricId }).exec(function (err, dashboardMetric) { + if (err) + console.log(err); + _.each(testRun.metrics, function (testrunMetric) { + if (testrunMetric.alias === dashboardMetric.alias) { + testrunMetric.requirementOperator = dashboardMetric.requirementOperator; + testrunMetric.requirementValue = dashboardMetric.requirementValue; + testrunMetric.benchmarkOperator = dashboardMetric.benchmarkOperator; + testrunMetric.benchmarkValue = dashboardMetric.benchmarkValue; + } + updatedMetrics.push(testrunMetric); + }); + /* Save updated test run */ + Testrun.findById(testRun._id, function (err, savedTestRun) { + if (err) + console.log(err); + if (!savedTestRun) + console.log('Could not load Document'); + else { + savedTestRun.metrics = updatedMetrics; + savedTestRun.save(function (err) { + if (err) { + console.log(err); + } else { + callback(savedTestRun); + } + }); + } }); + }); +} +function deleteTestRunById(req, res) { + Testrun.findOne({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName }, + { testRunId: req.params.testRunId } + ] + }).sort('-end').exec(function (err, testRun) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + if (testRun) { + testRun.remove(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } + }); + } + } + }); } /** * select test runs for dashboard */ -function testRunsForDashboard (req, res) { - - Testrun.find({ $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName } ] }).sort('-end').exec(function(err, testRuns) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if(testRuns.length > 0){ - - res.jsonp(testRuns); - }else { - Event.find({$and: [{productName: req.params.productName}, {dashboardName: req.params.dashboardName}]}).sort({eventTimestamp: 1}).exec(function (err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - createTestrunFromEvents(req.params.productName, req.params.dashboardName, events, req.params.useInBenchmark, function (eventsTestruns) { - - /* if benchmarking is not enabled, no need to persist the test runs! */ - if (req.params.useInBenchmark === 'false') { - - res.jsonp(eventsTestruns.reverse()); - - } else { - /* persist test runs that have not yet been persisted */ - persistTestrunsFromEvents(testRuns, eventsTestruns, function (persistedTestRuns) { - - res.jsonp(persistedTestRuns); - - }); - } - - }); - - } - +function testRunsForDashboard(req, res) { + Testrun.find({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName } + ] + }).sort('-end').exec(function (err, testRuns) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + if (testRuns.length > 0) { + res.jsonp(testRuns); + } else { + Event.find({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName } + ] + }).sort({ eventTimestamp: 1 }).exec(function (err, events) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + createTestrunFromEvents(req.params.productName, req.params.dashboardName, events, function (eventsTestruns) { + /* if benchmarking is not enabled, no need to persist the test runs! */ + if (req.params.useInBenchmark === 'false') { + res.jsonp(eventsTestruns.reverse()); + } else { + /* persist test runs that have not yet been persisted */ + persistTestrunsFromEvents(testRuns, eventsTestruns, function (persistedTestRuns) { + res.jsonp(persistedTestRuns); }); - } + } + }); + } + }); + } + } + }); + function persistTestrunsFromEvents(testRuns, testRunsFromEvents, callback) { + var persistedTestRuns = []; + var testRunsToBePersisted = []; + var testRunsToBenchmark = []; + _.each(testRunsFromEvents, function (testRunFromEvents) { + var exists = false; + _.each(testRuns, function (testRun) { + if (testRun.testRunId === testRunFromEvents.testRunId) { + exists = true; + persistedTestRuns.push(testRun); + return exists; } + }); + if (exists === false) { + testRunsToBePersisted.push(testRunFromEvents); + } }); - - function persistTestrunsFromEvents(testRuns, testRunsFromEvents, callback){ - - var persistedTestRuns = []; - var testRunsToBePersisted = []; - var testRunsToBenchmark = []; - - _.each(testRunsFromEvents, function (testRunFromEvents){ - - var exists = false; - - _.each(testRuns, function (testRun){ - - if (testRun.testRunId === testRunFromEvents.testRunId ){ - exists = true; - persistedTestRuns.push(testRun); - return exists; + async.forEachLimit(testRunsToBePersisted, 16, function (testRun, callback) { + getDataForTestrun(testRun.productName, testRun.dashboardName, testRun, function (metrics) { + saveTestrun(testRun, metrics, function (savedTestrun) { + console.log('test run saved: ' + savedTestrun.testRunId); + testRunsToBenchmark.push(savedTestrun); + callback(); + }); + }); + }, function (err) { + if (err) + return next(err); + testRunsToBenchmark.sort(Utils.dynamicSort('-start')); + async.forEachLimit(testRunsToBenchmark, 1, function (testRun, callback) { + Requirements.setRequirementResultsForTestRun(testRun, function (requirementsTestrun) { + if (requirementsTestrun) + console.log('Requirements set for: ' + requirementsTestrun.productName + '-' + requirementsTestrun.dashboardName + 'testrunId: ' + requirementsTestrun.testRunId); + Benchmarks.setBenchmarkResultsPreviousBuildForTestRun(requirementsTestrun, function (benchmarkPreviousBuildTestrun) { + if (benchmarkPreviousBuildTestrun) + console.log('Benchmark previous build done for: ' + benchmarkPreviousBuildTestrun.productName + '-' + benchmarkPreviousBuildTestrun.dashboardName + 'testrunId: ' + benchmarkPreviousBuildTestrun.testRunId); + Benchmarks.setBenchmarkResultsFixedBaselineForTestRun(benchmarkPreviousBuildTestrun, function (benchmarkFixedBaselineTestrun) { + if (benchmarkFixedBaselineTestrun) + console.log('Benchmark fixed baseline done for: ' + benchmarkFixedBaselineTestrun.productName + '-' + benchmarkFixedBaselineTestrun.dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); + benchmarkFixedBaselineTestrun.save(function (err) { + if (err) { + console.log(err); + callback(err); + } else { + persistedTestRuns.push(benchmarkFixedBaselineTestrun); + callback(); } - - }) - - if (exists === false) { - testRunsToBePersisted.push(testRunFromEvents); - } - - }) - - async.forEachLimit(testRunsToBePersisted, 16, function (testRun, callback) { - - getDataForTestrun(testRun.productName, testRun.dashboardName, testRun, function (metrics) { - - saveTestrun(testRun, metrics, function (savedTestrun) { - - console.log('test run saved: ' + savedTestrun.testRunId); - testRunsToBenchmark.push(savedTestrun); - callback(); - }); - + }); }); - - }, function (err) { - if (err) return next(err); - - testRunsToBenchmark.sort(Utils.dynamicSort('-start')); - - async.forEachLimit(testRunsToBenchmark, 1, function (testRun, callback) { - - Requirements.setRequirementResultsForTestRun(testRun, function (requirementsTestrun) { - - if(requirementsTestrun) console.log('Requirements set for: ' + requirementsTestrun.productName + '-' + requirementsTestrun.dashboardName + 'testrunId: ' + requirementsTestrun.testRunId); - - Benchmarks.setBenchmarkResultsPreviousBuildForTestRun(requirementsTestrun, function (benchmarkPreviousBuildTestrun) { - - if(benchmarkPreviousBuildTestrun) console.log('Benchmark previous build done for: ' + benchmarkPreviousBuildTestrun.productName + '-' + benchmarkPreviousBuildTestrun.dashboardName + 'testrunId: ' + benchmarkPreviousBuildTestrun.testRunId); - - Benchmarks.setBenchmarkResultsFixedBaselineForTestRun(benchmarkPreviousBuildTestrun, function (benchmarkFixedBaselineTestrun) { - - if(benchmarkFixedBaselineTestrun) console.log('Benchmark fixed baseline done for: ' + benchmarkFixedBaselineTestrun.productName + '-' + benchmarkFixedBaselineTestrun.dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); - - benchmarkFixedBaselineTestrun.save(function(err) { - if (err) { - console.log(err); - callback(err); - } else { - persistedTestRuns.push(benchmarkFixedBaselineTestrun); - callback(); - } - }); - - }); - }); - }); - - }, function (err) { - if (err) console.log(err); - - callback(persistedTestRuns); - - - }); - + }); }); - - - - } - }; - -function testRunById(req, res) { - - Testrun.findOne({ $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName },{ testRunId: req.params.testRunId } ] }).sort('-end').exec(function(err, testRun) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if(testRun) { - var testRunEpoch = testRun.toObject(); - testRunEpoch.startEpoch = testRun.startEpoch; - testRunEpoch.endEpoch = testRun.endEpoch; - //res.setHeader('Last-Modified', (new Date()).toUTCString()); //to prevent http 304's - res.jsonp(testRunEpoch); - }else{ - - Event.find({ $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName },{ testRunId: req.params.testRunId } ] }).sort('-end').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - createTestrunFromEvents(req.params.productName, req.params.dashboardName, events, req.params.useInBenchmark, function(eventsTestruns) { - - res.jsonp(eventsTestruns[0]); - - }); - } - }); - } - } + }, function (err) { + if (err) + console.log(err); + callback(persistedTestRuns); + }); }); - - + } } - -function refreshTestrun (req, res) { - - Testrun.findOne({ $and: [ - { productName: req.params.productName }, - { dashboardName: req.params.dashboardName }, - { testRunId: req.params.testRunId } - ]}).exec(function (err, testRun) { - - if(err) console.log(err); - - benchmarkAndPersistTestRunById(req.params.productName, req.params.dashboardName, testRun , function (persistedTestrun) { - - res.jsonp(persistedTestrun); - +function testRunById(req, res) { + Testrun.findOne({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName }, + { testRunId: req.params.testRunId } + ] + }).sort('-end').exec(function (err, testRun) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + if (testRun) { + var testRunEpoch = testRun.toObject(); + testRunEpoch.startEpoch = testRun.startEpoch; + testRunEpoch.endEpoch = testRun.endEpoch; + //res.setHeader('Last-Modified', (new Date()).toUTCString()); //to prevent http 304's + res.jsonp(testRunEpoch); + } else { + Event.find({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName }, + { testRunId: req.params.testRunId } + ] + }).sort('-end').exec(function (err, events) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + createTestrunFromEvents(req.params.productName, req.params.dashboardName, events, function (eventsTestruns) { + res.jsonp(eventsTestruns[0]); + }); + } }); + } + } + }); +} +function refreshTestrun(req, res) { + Testrun.findOne({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName }, + { testRunId: req.params.testRunId } + ] + }).exec(function (err, testRun) { + if (err) + console.log(err); + benchmarkAndPersistTestRunById(req.params.productName, req.params.dashboardName, testRun, function (persistedTestrun) { + res.jsonp(persistedTestrun); }); - + }); } - - - - exports.getTestRunById = function (productName, dashboardName, testRunId, callback) { - - Testrun.findOne({ $and: [ - { productName: productName }, - { dashboardName: dashboardName }, - { testRunId: testRunId } - ] }).sort('-end').exec(function (err, testRun) { - - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if (testRun) { - - callback(testRun); - + Testrun.findOne({ + $and: [ + { productName: productName }, + { dashboardName: dashboardName }, + { testRunId: testRunId } + ] + }).sort('-end').exec(function (err, testRun) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + if (testRun) { + callback(testRun); + } else { + Event.find({ + $and: [ + { productName: productName }, + { dashboardName: dashboardName }, + { testRunId: testRunId } + ] + }).sort('-end').exec(function (err, events) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + if (events.length > 0) { + createTestrunFromEvents(productName, dashboardName, events); } else { - - Event.find({ $and: [ { productName:productName }, { dashboardName: dashboardName },{ testRunId:testRunId } ] }).sort('-end').exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - if(events.length > 0) { - - createTestrunFromEvents(productName, dashboardName,events, function(testrunFromEvents){ - - getAndPersistTestRunById(productName, dashboardName, testrunFromEvents[0], function (persistedTestrun) { - - callback(persistedTestrun); - - }); - }); - - }else{ - - callback(null); - } - } - }); - + callback(null); } - } - - }); -} - -function benchmarkAndPersistTestRunById (productName, dashboardName, testRun, callback){ - - Testrun.findOne({testRunId: testRun.testRunId}).exec(function(err, savedTestrun) { - - if (err){ - console.log(err); - }else{ - if(savedTestrun) { - - savedTestrun.remove(function (err) { - - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - }else{ - - console.log("removed testrun: " + savedTestrun.testRunId); - getDataForTestrun(productName, dashboardName, testRun, function (metrics) { - - if(metrics) console.log('Data retrieved for:' + productName + '-' + dashboardName); - - saveTestrun(testRun, metrics, function (savedTestrun) { - - if(savedTestrun) console.log('Testrun saved retrieved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestrun.testRunId); - - Requirements.setRequirementResultsForTestRun(savedTestrun, function (requirementsTestrun) { - - if(requirementsTestrun) console.log('Requirements set for:' + productName + '-' + dashboardName + 'testrunId: ' + requirementsTestrun.testRunId); - - Benchmarks.setBenchmarkResultsPreviousBuildForTestRun(requirementsTestrun, function (benchmarkPreviousBuildTestrun) { - - if(benchmarkPreviousBuildTestrun) console.log('Benchmark previous build done for:' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkPreviousBuildTestrun.testRunId); - - Benchmarks.setBenchmarkResultsFixedBaselineForTestRun(benchmarkPreviousBuildTestrun, function (benchmarkFixedBaselineTestrun) { - - if(benchmarkFixedBaselineTestrun) console.log('Benchmark fixed baseline done for:' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); - - /* Save updated test run */ - benchmarkFixedBaselineTestrun.save(function(err) { - if (err) { - console.log('error') - }else { - console.log('Complete testrun saved for:' + benchmarkFixedBaselineTestrun.productName + '-' + benchmarkFixedBaselineTestrun.dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); - callback(benchmarkFixedBaselineTestrun); - } - }); - - - - //Testrun.findById(benchmarkFixedBaselineTestrun._id, function(err, savedTestRun) { - // if (err) console.log(err); - // if (!savedTestRun) - // console.log('Could not load Document'); - // else { - // - // savedTestRun = benchmarkFixedBaselineTestrun; - // - // savedTestRun.save(function(err) { - // if (err) { - // console.log('error') - // }else { - // console.log('Complete testrun saved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestRun.testRunId); - // callback(savedTestRun); - // } - // }); - // } - //}); - - }); - }); - - }); - }); - - }); - - - } - - }); - - }else{ - - getDataForTestrun(productName, dashboardName, testRun, function (metrics) { - - if(metrics) console.log('Data retrieved for:' + productName + '-' + dashboardName); - - saveTestrun(testRun, metrics, function (savedTestrun) { - - if(savedTestrun) console.log('Testrun saved for: ' + productName + '-' + dashboardName + 'testrunId: ' + savedTestrun.testRunId); - - Requirements.setRequirementResultsForTestRun(savedTestrun, function (requirementsTestrun) { - - if(requirementsTestrun) console.log('Requirements set for: ' + productName + '-' + dashboardName + 'testrunId: ' + requirementsTestrun.testRunId); - - Benchmarks.setBenchmarkResultsPreviousBuildForTestRun(requirementsTestrun, function (benchmarkPreviousBuildTestrun) { - - if(benchmarkPreviousBuildTestrun) console.log('Benchmark previous build done for: ' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkPreviousBuildTestrun.testRunId); - - Benchmarks.setBenchmarkResultsFixedBaselineForTestRun(benchmarkPreviousBuildTestrun, function (benchmarkFixedBaselineTestrun) { - - if(benchmarkFixedBaselineTestrun) console.log('Benchmark fixed baseline done for: ' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); - - /* Save updated test run */ - Testrun.findById(benchmarkFixedBaselineTestrun._id, function(err, savedTestRun) { - if (err) console.log(err); - if (!savedTestRun) - console.log('Could not load Document'); - else { - - savedTestRun = benchmarkFixedBaselineTestrun; - - savedTestRun.save(function(err) { - if (err) { - console.log('error') - }else { - console.log('Complete testrun saved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestRun.testRunId); - callback(savedTestRun); - } - }); - } - }); - - }); - }); - - }); - }); - - }); - - } - } - }); - - + } + }); + } + } + }); }; - -function getAndPersistTestRunById (productName, dashboardName, testRun, callback){ - - +function benchmarkAndPersistTestRunById(productName, dashboardName, testRun, callback) { + Testrun.findOne({ testRunId: testRun.testRunId }).exec(function (err, savedTestrun) { + if (err) { + console.log(err); + } else { + if (savedTestrun) { + savedTestrun.remove(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + console.log('removed testrun: ' + savedTestrun.testRunId); getDataForTestrun(productName, dashboardName, testRun, function (metrics) { - - saveTestrun(testRun, metrics, function (savedTestrun) { - - console.log('test run saved: ' + savedTestrun.testRunId); - callback(savedTestrun); - }); - - }); - - -}; - - -function getDataForTestrun(productName, dashboardName, testRun, callback){ - - - - Product.findOne({name: productName}).exec(function(err, product){ - if(err) console.log(err); - - Dashboard.findOne( { $and: [ { productId: product._id }, { name: dashboardName } ] } ).populate('metrics').exec(function(err, dashboard){ - - if(err) console.log(err); - var metrics = []; - - - async.forEachLimit(dashboard.metrics, 16, function (metric, callback) { - - var targets = []; - - async.forEachLimit(metric.targets, 16, function (target, callback) { - - graphite.getGraphiteData(Math.round(testRun.start / 1000), Math.round(testRun.end / 1000), target, 900, function(body){ - - _.each(body, function(target){ - - targets.push({ - target: target.target, - value: calculateAverage(target.datapoints) - }); - - }) - callback(); - }); - - }, function (err) { - if (err) return next(err); - - metrics.push({ - _id: metric._id, - tags: metric.tags, - alias: metric.alias, - type: metric.type, - benchmarkValue: metric.benchmarkValue, - benchmarkOperator: metric.benchmarkOperator, - requirementValue: metric.requirementValue, - requirementOperator: metric.requirementOperator, - targets: targets - }); - - targets = []; - callback(); - + if (metrics) + console.log('Data retrieved for:' + productName + '-' + dashboardName); + saveTestrun(testRun, metrics, function (savedTestrun) { + if (savedTestrun) + console.log('Testrun saved retrieved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestrun.testRunId); + Requirements.setRequirementResultsForTestRun(savedTestrun, function (requirementsTestrun) { + if (requirementsTestrun) + console.log('Requirements set for:' + productName + '-' + dashboardName + 'testrunId: ' + requirementsTestrun.testRunId); + Benchmarks.setBenchmarkResultsPreviousBuildForTestRun(requirementsTestrun, function (benchmarkPreviousBuildTestrun) { + if (benchmarkPreviousBuildTestrun) + console.log('Benchmark previous build done for:' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkPreviousBuildTestrun.testRunId); + Benchmarks.setBenchmarkResultsFixedBaselineForTestRun(benchmarkPreviousBuildTestrun, function (benchmarkFixedBaselineTestrun) { + if (benchmarkFixedBaselineTestrun) + console.log('Benchmark fixed baseline done for:' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); + /* Save updated test run */ + benchmarkFixedBaselineTestrun.save(function (err) { + if (err) { + console.log('error'); + } else { + console.log('Complete testrun saved for:' + benchmarkFixedBaselineTestrun.productName + '-' + benchmarkFixedBaselineTestrun.dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); + callback(benchmarkFixedBaselineTestrun); + } + }); //Testrun.findById(benchmarkFixedBaselineTestrun._id, function(err, savedTestRun) { + // if (err) console.log(err); + // if (!savedTestRun) + // console.log('Could not load Document'); + // else { + // + // savedTestRun = benchmarkFixedBaselineTestrun; + // + // savedTestRun.save(function(err) { + // if (err) { + // console.log('error') + // }else { + // console.log('Complete testrun saved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestRun.testRunId); + // callback(savedTestRun); + // } + // }); + // } + //}); }); - }, function (err) { - if (err) return next(err); - - callback(metrics); - + }); }); - + }); }); + } }); - -} - -function calculateAverage(datapoints){ - var count = 0; - var total = 0; - - _.each(datapoints, function(datapoint){ - - if(datapoint[0] !== null){ - - count++; - total += datapoint[0]; - - } - - }); - - if(count > 0) - return Math.round((total / count) * 100)/100; - else - return 0; -} - -function saveTestrun(testrun, metrics, callback){ - - getPreviousBuild(testrun.productName, testrun.dashboardName,testrun.testRunId, function(previousBuild){ - - var persistTestrun = new Testrun(); - - persistTestrun.productName = testrun.productName; - persistTestrun.dashboardName = testrun.dashboardName; - persistTestrun.testRunId = testrun.testRunId; - persistTestrun.start = testrun.start; - persistTestrun.end = testrun.end; - persistTestrun.baseline = testrun.baseline; - persistTestrun.previousBuild = previousBuild; - persistTestrun.buildResultKey = testrun.buildResultKey; - persistTestrun.eventIds = testrun.eventIds; - persistTestrun.metrics = metrics; - - - persistTestrun.save(function(err) { - if (err) { - console.log(err); - callback(err); - } else { - callback(persistTestrun); - } - }); - - }); -} - -function getPreviousBuild(productName, dashboardName, testrunId, callback){ - - var previousBuild; - - Event.find({ $and: [ { productName: productName }, { dashboardName: dashboardName } ] }).sort({eventTimestamp: -1}).exec(function(err, events) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - - createTestrunFromEvents(productName, dashboardName, events, false, function(testruns){ - - _.each(testruns, function (testrun, i) { - - if (testrun.testRunId === testrunId) { - if(i+1 === testruns.length){ - - return null; - - }else { - previousBuild = testruns[i + 1].testRunId; - return previousBuild; + } else { + getDataForTestrun(productName, dashboardName, testRun, function (metrics) { + if (metrics) + console.log('Data retrieved for:' + productName + '-' + dashboardName); + saveTestrun(testRun, metrics, function (savedTestrun) { + if (savedTestrun) + console.log('Testrun saved for: ' + productName + '-' + dashboardName + 'testrunId: ' + savedTestrun.testRunId); + Requirements.setRequirementResultsForTestRun(savedTestrun, function (requirementsTestrun) { + if (requirementsTestrun) + console.log('Requirements set for: ' + productName + '-' + dashboardName + 'testrunId: ' + requirementsTestrun.testRunId); + Benchmarks.setBenchmarkResultsPreviousBuildForTestRun(requirementsTestrun, function (benchmarkPreviousBuildTestrun) { + if (benchmarkPreviousBuildTestrun) + console.log('Benchmark previous build done for: ' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkPreviousBuildTestrun.testRunId); + Benchmarks.setBenchmarkResultsFixedBaselineForTestRun(benchmarkPreviousBuildTestrun, function (benchmarkFixedBaselineTestrun) { + if (benchmarkFixedBaselineTestrun) + console.log('Benchmark fixed baseline done for: ' + productName + '-' + dashboardName + 'testrunId: ' + benchmarkFixedBaselineTestrun.testRunId); + /* Save updated test run */ + Testrun.findById(benchmarkFixedBaselineTestrun._id, function (err, savedTestRun) { + if (err) + console.log(err); + if (!savedTestRun) + console.log('Could not load Document'); + else { + savedTestRun = benchmarkFixedBaselineTestrun; + savedTestRun.save(function (err) { + if (err) { + console.log('error'); + } else { + console.log('Complete testrun saved for:' + productName + '-' + dashboardName + 'testrunId: ' + savedTestRun.testRunId); + callback(savedTestRun); } + }); } - - }) - - callback(previousBuild); + }); + }); + }); }); - } - }); -} - -function setTestrunRequirementResults(metrics){ - - var meetsRequirement = true; - - _.each(metrics, function(metric){ - - if(metric.meetsRequirement === false) { - - meetsRequirement = false; - return; - } - }) - - return meetsRequirement; + }); + }); + } + } + }); } - -function setMetricRequirementResults(targets){ - - var meetsRequirement = true; - - _.each(targets, function(target){ - - if(target.meetsRequirement === false) { - - meetsRequirement = false; - return; - } - }) - - return meetsRequirement; +function getDataForTestrun(productName, dashboardName, testRun, callback) { + Product.findOne({ name: productName }).exec(function (err, product) { + if (err) + console.log(err); + Dashboard.findOne({ + $and: [ + { productId: product._id }, + { name: dashboardName } + ] + }).populate('metrics').exec(function (err, dashboard) { + if (err) + console.log(err); + var metrics = []; + async.forEachLimit(dashboard.metrics, 16, function (metric, callback) { + var targets = []; + async.forEachLimit(metric.targets, 16, function (target, callback) { + graphite.getGraphiteData(Math.round(testRun.start / 1000), Math.round(testRun.end / 1000), target, 900, function (body) { + _.each(body, function (target) { + targets.push({ + target: target.target, + value: calculateAverage(target.datapoints) + }); + }); + callback(); + }); + }, function (err) { + if (err) + return next(err); + metrics.push({ + _id: metric._id, + tags: metric.tags, + alias: metric.alias, + type: metric.type, + benchmarkValue: metric.benchmarkValue, + benchmarkOperator: metric.benchmarkOperator, + requirementValue: metric.requirementValue, + requirementOperator: metric.requirementOperator, + targets: targets + }); + targets = []; + callback(); + }); + }, function (err) { + if (err) + return next(err); + callback(metrics); + }); + }); + }); } - - -function evaluateRequirement(value, requirementOperator, requirementValue){ - - var requirementResult; - - if((requirementOperator === "<" && value > requirementValue) || requirementOperator === ">" && value < requirementValue){ - - var requirementResult = false; - - }else{ - - var requirementResult = true; +function calculateAverage(datapoints) { + var count = 0; + var total = 0; + _.each(datapoints, function (datapoint) { + if (datapoint[0] !== null) { + count++; + total += datapoint[0]; } - - return requirementResult; + }); + if (count > 0) + return Math.round(total / count * 100) / 100; + else + return 0; } - -function createTestrunFromEvents(productName, dashboardName, events, useInBenchmark, callback) { - - var testRuns = []; - var baseline; - var dashboardBaseline; - - Product.findOne({name: productName}).exec(function(err, product){ - if(err) console.log(err); - - Dashboard.findOne( { $and: [ { productId: product._id }, { name: dashboardName } ] } ).exec(function(err, dashboard) { - - if (err) { - console.log(err); +function saveTestrun(testrun, metrics, callback) { + getPreviousBuild(testrun.productName, testrun.dashboardName, testrun.testRunId, function (previousBuild) { + var persistTestrun = new Testrun(); + persistTestrun.productName = testrun.productName; + persistTestrun.dashboardName = testrun.dashboardName; + persistTestrun.testRunId = testrun.testRunId; + persistTestrun.start = testrun.start; + persistTestrun.end = testrun.end; + persistTestrun.baseline = testrun.baseline; + persistTestrun.previousBuild = previousBuild; + persistTestrun.buildResultKey = testrun.buildResultKey; + persistTestrun.eventIds = testrun.eventIds; + persistTestrun.metrics = metrics; + persistTestrun.save(function (err) { + if (err) { + console.log(err); + callback(err); + } else { + callback(persistTestrun); + } + }); + }); +} +function getPreviousBuild(productName, dashboardName, testrunId, callback) { + var previousBuild; + Event.find({ + $and: [ + { productName: productName }, + { dashboardName: dashboardName } + ] + }).sort({ eventTimestamp: -1 }).exec(function (err, events) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + createTestrunFromEvents(productName, dashboardName, events, function (testruns) { + _.each(testruns, function (testrun, i) { + if (testrun.testRunId === testrunId) { + if (i + 1 === testruns.length) { + return null; } else { - - dashboardBaseline = dashboard.baseline ? dashboard.baseline : baseline; - - for (var i = 0; i < events.length; i++) { - - if (events[i].eventDescription === 'start') { - - for (var j = 0; j < events.length; j++) { - - if (events[j].eventDescription === 'end' && events[j].testRunId == events[i].testRunId) { - - /* If no baseline has been set for this dashboard, set the first test run as baseline*/ - - if (!dashboardBaseline && !baseline){ - - baseline = events[i].testRunId; - dashboardBaseline = events[i].testRunId; - } else{ - - baseline = dashboardBaseline; - } - - if (events[i].buildResultKey) { - - testRuns.push({start: events[i].eventTimestamp, startEpoch: events[i].eventTimestamp.getTime(), end: events[j].eventTimestamp, endEpoch: events[j].eventTimestamp.getTime(), productName: events[i].productName, dashboardName: events[i].dashboardName, testRunId: events[i].testRunId, buildResultKey: events[i].buildResultKey, eventIds: [events[i].id, events[j].id], meetsRequirement: null, benchmarkResultFixedOK: null, benchmarkResultPreviousOK: null, baseline: baseline}); - } else { - - testRuns.push({start: events[i].eventTimestamp, startEpoch: events[i].eventTimestamp.getTime(), end: events[j].eventTimestamp, endEpoch: events[j].eventTimestamp.getTime(), productName: events[i].productName, dashboardName: events[i].dashboardName, testRunId: events[i].testRunId, eventIds: [events[i].id, events[j].id], meetsRequirement: null, benchmarkResultFixedOK: null, benchmarkResultPreviousOK: null, baseline: baseline}); - } - - break; - } - - } - } - } - - - - /* If no baseline has been set for this dashboard, set the first test run as baseline*/ - if (!dashboard.baseline && testRuns){ - - dashboard.baseline = dashboardBaseline; - dashboard.save(function(err) { - if (err) { - console.log(err); - }else{ - - callback(testRuns); - } - }); - }else{ - - callback(testRuns); - } - - + previousBuild = testruns[i + 1].testRunId; + return previousBuild; } + } }); - }); + callback(previousBuild); + }); + } + }); } - -/** - * Show the current Testrun - */ -function runningTest (req, res){ - - var currentTime = new Date(); - var anyEventFound = false; - - Event.find({ $and: [ { productName: req.params.productName }, { dashboardName: req.params.dashboardName } ] }).sort({eventTimestamp: -1}).lean().exec(function(err, events){ - - if(err) throw err; - - for(var i=0;i 176400000){ - tooOld = true + if (events[i].buildResultKey) { + testRuns.push({ + start: events[i].eventTimestamp, + startEpoch: events[i].eventTimestamp.getTime(), + end: events[j].eventTimestamp, + endEpoch: events[j].eventTimestamp.getTime(), + productName: events[i].productName, + dashboardName: events[i].dashboardName, + testRunId: events[i].testRunId, + buildResultKey: events[i].buildResultKey, + eventIds: [ + events[i].id, + events[j].id + ], + meetsRequirement: null, + benchmarkResultFixedOK: null, + benchmarkResultPreviousOK: null, + baseline: baseline + }); + } else { + testRuns.push({ + start: events[i].eventTimestamp, + startEpoch: events[i].eventTimestamp.getTime(), + end: events[j].eventTimestamp, + endEpoch: events[j].eventTimestamp.getTime(), + productName: events[i].productName, + dashboardName: events[i].dashboardName, + testRunId: events[i].testRunId, + eventIds: [ + events[i].id, + events[j].id + ], + meetsRequirement: null, + benchmarkResultFixedOK: null, + benchmarkResultPreviousOK: null, + baseline: baseline + }); } - - + break; + } } + } } - - if (endEventFound === true || tooOld === true || anyEventFound === false ) { - res.jsonp({}); - + /* If no baseline has been set for this dashboard, set the first test run as baseline*/ + if (!dashboard.baseline && testRuns) { + dashboard.baseline = dashboardBaseline; + dashboard.save(function (err) { + if (err) { + console.log(err); + } else { + callback(testRuns); + } + }); + } else { + callback(testRuns); } - - + } }); - + }); } /** - * Update a Testrun + * Show the current Testrun */ -function updateTestRunRequirementForMetric(metric) { - - Testrun.find( { $and: [ { productName: metric.productName }, { dashboardName: metric.dashboardName } ] } ).exec(function(err, testruns) { - - _.each(testruns, function(testrun){ - - - var metricToUpdate = testrun.metrics.id(metric._id); - - metricToUpdate.requirementOperator = metric.requirementOperator; - metricToUpdate.requirementValue = metric.requirementValue; - - metricToUpdate.targets = setTargetRequirementResults( metricToUpdate.targets, metricToUpdate.requirementOperator, metricToUpdate.requirementValue ); - metricToUpdate.meetsRequirement = setMetricRequirementResults(metricToUpdate.targets) - - testrun.meetsRequirement = setTestrunRequirementResults(testrun.metrics); - - testrun.save(function(err){ - if (err) console.log("bla: " + err.stack); - }) - - }) - }) - - -}; - - - - - -function updateTestRunMetric(testrun, metric){ - - - var updatedMetric; - - updatedMetric.requirementOperator = metric.requirementOperator; - updatedMetric.requirementValue = metric.requirementValue; - - - //var updatedMetrics = []; - // - // - //_.each(testrun.metrics, function(testrunMetric){ - // - // if (testrunMetric._id.toString() === updatedMetric._id){ - // - // /* update requirement values */ - // testrunMetric.requirementOperator = updatedMetric.requirementOperator; - // testrunMetric.requirementValue = updatedMetric.requirementValue; - // - // updatedMetrics.push(setMetricRequirementResults(testrunMetric)); - // - // }else{ - // - // updatedMetrics.push(updatedMetric); - // } - // - // - //}) - // - //return updatedMetrics; - -} - -function getTargets(metrics, metricId){ - - var targets = []; - - _.each(metrics, function(metric){ - - if (metric._id === metricId){ - - _.each(metric.targets, function(target){ - - targets.push(target); - }) - - return targets; +function runningTest(req, res) { + var currentTime = new Date(); + var anyEventFound = false; + Event.find({ + $and: [ + { productName: req.params.productName }, + { dashboardName: req.params.dashboardName } + ] + }).sort({ eventTimestamp: -1 }).lean().exec(function (err, events) { + if (err) + throw err; + for (var i = 0; i < events.length; i++) { + if (events[i].eventDescription === 'start') { + var endEventFound = false; + var tooOld = false; + anyEventFound = true; + for (var j = 0; j < events.length; j++) { + if (events[i].testRunId === events[j].testRunId && events[j].eventDescription === 'end') + endEventFound = true; + } + if (endEventFound === false && currentTime.getTime() - events[i].eventTimestamp.getTime() < 176400000) { + var returnEvent = events[i]; + res.jsonp(returnEvent); + break; /* If running test is older than 48 hours, leave it*/ + } else if (currentTime.getTime() - events[i].eventTimestamp.getTime() > 176400000) { + tooOld = true; } - - }) - - return targets; - + } + } + if (endEventFound === true || tooOld === true || anyEventFound === false) { + res.jsonp({}); + } + }); } /** * Delete an Testrun */ -exports.delete = function(req, res) { - +exports.delete = function (req, res) { }; - /** * List of Testruns */ -exports.list = function(req, res) { - +exports.list = function (req, res) { }; diff --git a/app/controllers/users.server.controller.js b/app/controllers/users.server.controller.js index 64e772e..51b12a9 100644 --- a/app/controllers/users.server.controller.js +++ b/app/controllers/users.server.controller.js @@ -1,16 +1,9 @@ 'use strict'; - /** * Module dependencies. */ var _ = require('lodash'); - /** * Extend user's controller */ -module.exports = _.extend( - require('./users/users.authentication.server.controller'), - require('./users/users.authorization.server.controller'), - require('./users/users.password.server.controller'), - require('./users/users.profile.server.controller') -); \ No newline at end of file +module.exports = _.extend(require('./users/users.authentication.server.controller'), require('./users/users.authorization.server.controller'), require('./users/users.password.server.controller'), require('./users/users.profile.server.controller')); \ No newline at end of file diff --git a/app/controllers/users/users.authentication.server.controller.js b/app/controllers/users/users.authentication.server.controller.js index c15c8a1..0f3c548 100644 --- a/app/controllers/users/users.authentication.server.controller.js +++ b/app/controllers/users/users.authentication.server.controller.js @@ -1,206 +1,177 @@ 'use strict'; - /** * Module dependencies. */ -var _ = require('lodash'), - errorHandler = require('../errors.server.controller'), - mongoose = require('mongoose'), - passport = require('passport'), - User = mongoose.model('User'); - +var _ = require('lodash'), errorHandler = require('../errors.server.controller'), mongoose = require('mongoose'), passport = require('passport'), User = mongoose.model('User'); /** * Signup */ -exports.signup = function(req, res) { - // For security measurement we remove the roles from the req.body object - delete req.body.roles; - - // Init Variables - var user = new User(req.body); - var message = null; - - // Add missing user fields - user.provider = 'local'; - user.displayName = user.firstName + ' ' + user.lastName; - - // Then save the user - user.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - // Remove sensitive data before login - user.password = undefined; - user.salt = undefined; - - req.login(user, function(err) { - if (err) { - res.status(400).send(err); - } else { - res.json(user); - } - }); - } - }); +exports.signup = function (req, res) { + // For security measurement we remove the roles from the req.body object + delete req.body.roles; + // Init Variables + var user = new User(req.body); + var message = null; + // Add missing user fields + user.provider = 'local'; + user.displayName = user.firstName + ' ' + user.lastName; + // Then save the user + user.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + // Remove sensitive data before login + user.password = undefined; + user.salt = undefined; + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + } + }); }; - /** * Signin after passport authentication */ -exports.signin = function(req, res, next) { - passport.authenticate('local', function(err, user, info) { - if (err || !user) { - res.status(400).send(info); - } else { - // Remove sensitive data before login - user.password = undefined; - user.salt = undefined; - - req.login(user, function(err) { - if (err) { - res.status(400).send(err); - } else { - res.json(user); - } - }); - } - })(req, res, next); +exports.signin = function (req, res, next) { + passport.authenticate('local', function (err, user, info) { + if (err || !user) { + res.status(400).send(info); + } else { + // Remove sensitive data before login + user.password = undefined; + user.salt = undefined; + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + } + })(req, res, next); }; - /** * Signout */ -exports.signout = function(req, res) { - req.logout(); - res.redirect('/'); +exports.signout = function (req, res) { + req.logout(); + res.redirect('/'); }; - /** * OAuth callback */ -exports.oauthCallback = function(strategy) { - return function(req, res, next) { - passport.authenticate(strategy, function(err, user, redirectURL) { - if (err || !user) { - return res.redirect('/#!/signin'); - } - req.login(user, function(err) { - if (err) { - return res.redirect('/#!/signin'); - } - - return res.redirect(redirectURL || '/'); - }); - })(req, res, next); - }; +exports.oauthCallback = function (strategy) { + return function (req, res, next) { + passport.authenticate(strategy, function (err, user, redirectURL) { + if (err || !user) { + return res.redirect('/#!/signin'); + } + req.login(user, function (err) { + if (err) { + return res.redirect('/#!/signin'); + } + return res.redirect(redirectURL || '/'); + }); + })(req, res, next); + }; }; - /** * Helper function to save or update a OAuth user profile */ -exports.saveOAuthUserProfile = function(req, providerUserProfile, done) { - if (!req.user) { - // Define a search query fields - var searchMainProviderIdentifierField = 'providerData.' + providerUserProfile.providerIdentifierField; - var searchAdditionalProviderIdentifierField = 'additionalProvidersData.' + providerUserProfile.provider + '.' + providerUserProfile.providerIdentifierField; - - // Define main provider search query - var mainProviderSearchQuery = {}; - mainProviderSearchQuery.provider = providerUserProfile.provider; - mainProviderSearchQuery[searchMainProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField]; - - // Define additional provider search query - var additionalProviderSearchQuery = {}; - additionalProviderSearchQuery[searchAdditionalProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField]; - - // Define a search query to find existing user with current provider profile - var searchQuery = { - $or: [mainProviderSearchQuery, additionalProviderSearchQuery] - }; - - User.findOne(searchQuery, function(err, user) { - if (err) { - return done(err); - } else { - if (!user) { - var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.email.split('@')[0] : ''); - - User.findUniqueUsername(possibleUsername, null, function(availableUsername) { - user = new User({ - firstName: providerUserProfile.firstName, - lastName: providerUserProfile.lastName, - username: availableUsername, - displayName: providerUserProfile.displayName, - email: providerUserProfile.email, - provider: providerUserProfile.provider, - providerData: providerUserProfile.providerData - }); - - // And save the user - user.save(function(err) { - return done(err, user); - }); - }); - } else { - return done(err, user); - } - } - }); - } else { - // User is already logged in, join the provider data to the existing user - var user = req.user; - - // Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured - if (user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) { - // Add the provider data to the additional provider data field - if (!user.additionalProvidersData) user.additionalProvidersData = {}; - user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData; - - // Then tell mongoose that we've updated the additionalProvidersData field - user.markModified('additionalProvidersData'); - - // And save the user - user.save(function(err) { - return done(err, user, '/#!/settings/accounts'); - }); - } else { - return done(new Error('User is already connected using this provider'), user); - } - } +exports.saveOAuthUserProfile = function (req, providerUserProfile, done) { + if (!req.user) { + // Define a search query fields + var searchMainProviderIdentifierField = 'providerData.' + providerUserProfile.providerIdentifierField; + var searchAdditionalProviderIdentifierField = 'additionalProvidersData.' + providerUserProfile.provider + '.' + providerUserProfile.providerIdentifierField; + // Define main provider search query + var mainProviderSearchQuery = {}; + mainProviderSearchQuery.provider = providerUserProfile.provider; + mainProviderSearchQuery[searchMainProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField]; + // Define additional provider search query + var additionalProviderSearchQuery = {}; + additionalProviderSearchQuery[searchAdditionalProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField]; + // Define a search query to find existing user with current provider profile + var searchQuery = { + $or: [ + mainProviderSearchQuery, + additionalProviderSearchQuery + ] + }; + User.findOne(searchQuery, function (err, user) { + if (err) { + return done(err); + } else { + if (!user) { + var possibleUsername = providerUserProfile.username || (providerUserProfile.email ? providerUserProfile.email.split('@')[0] : ''); + User.findUniqueUsername(possibleUsername, null, function (availableUsername) { + user = new User({ + firstName: providerUserProfile.firstName, + lastName: providerUserProfile.lastName, + username: availableUsername, + displayName: providerUserProfile.displayName, + email: providerUserProfile.email, + provider: providerUserProfile.provider, + providerData: providerUserProfile.providerData + }); + // And save the user + user.save(function (err) { + return done(err, user); + }); + }); + } else { + return done(err, user); + } + } + }); + } else { + // User is already logged in, join the provider data to the existing user + var user = req.user; + // Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured + if (user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) { + // Add the provider data to the additional provider data field + if (!user.additionalProvidersData) + user.additionalProvidersData = {}; + user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData; + // Then tell mongoose that we've updated the additionalProvidersData field + user.markModified('additionalProvidersData'); + // And save the user + user.save(function (err) { + return done(err, user, '/#!/settings/accounts'); + }); + } else { + return done(new Error('User is already connected using this provider'), user); + } + } }; - /** * Remove OAuth provider */ -exports.removeOAuthProvider = function(req, res, next) { - var user = req.user; - var provider = req.param('provider'); - - if (user && provider) { - // Delete the additional provider - if (user.additionalProvidersData[provider]) { - delete user.additionalProvidersData[provider]; - - // Then tell mongoose that we've updated the additionalProvidersData field - user.markModified('additionalProvidersData'); - } - - user.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - req.login(user, function(err) { - if (err) { - res.status(400).send(err); - } else { - res.json(user); - } - }); - } - }); - } +exports.removeOAuthProvider = function (req, res, next) { + var user = req.user; + var provider = req.param('provider'); + if (user && provider) { + // Delete the additional provider + if (user.additionalProvidersData[provider]) { + delete user.additionalProvidersData[provider]; + // Then tell mongoose that we've updated the additionalProvidersData field + user.markModified('additionalProvidersData'); + } + user.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + } + }); + } }; \ No newline at end of file diff --git a/app/controllers/users/users.authorization.server.controller.js b/app/controllers/users/users.authorization.server.controller.js index efa3b69..b7cd969 100644 --- a/app/controllers/users/users.authorization.server.controller.js +++ b/app/controllers/users/users.authorization.server.controller.js @@ -1,54 +1,42 @@ 'use strict'; - /** * Module dependencies. */ -var _ = require('lodash'), - mongoose = require('mongoose'), - User = mongoose.model('User'); - +var _ = require('lodash'), mongoose = require('mongoose'), User = mongoose.model('User'); /** * User middleware */ -exports.userByID = function(req, res, next, id) { - User.findOne({ - _id: id - }).exec(function(err, user) { - if (err) return next(err); - if (!user) return next(new Error('Failed to load User ' + id)); - req.profile = user; - next(); - }); +exports.userByID = function (req, res, next, id) { + User.findOne({ _id: id }).exec(function (err, user) { + if (err) + return next(err); + if (!user) + return next(new Error('Failed to load User ' + id)); + req.profile = user; + next(); + }); }; - /** * Require login routing middleware */ -exports.requiresLogin = function(req, res, next) { - if (!req.isAuthenticated()) { - return res.status(401).send({ - message: 'User is not logged in' - }); - } - - next(); +exports.requiresLogin = function (req, res, next) { + if (!req.isAuthenticated()) { + return res.status(401).send({ message: 'User is not logged in' }); + } + next(); }; - /** * User authorizations routing middleware */ -exports.hasAuthorization = function(roles) { - var _this = this; - - return function(req, res, next) { - _this.requiresLogin(req, res, function() { - if (_.intersection(req.user.roles, roles).length) { - return next(); - } else { - return res.status(403).send({ - message: 'User is not authorized' - }); - } - }); - }; +exports.hasAuthorization = function (roles) { + var _this = this; + return function (req, res, next) { + _this.requiresLogin(req, res, function () { + if (_.intersection(req.user.roles, roles).length) { + return next(); + } else { + return res.status(403).send({ message: 'User is not authorized' }); + } + }); + }; }; \ No newline at end of file diff --git a/app/controllers/users/users.password.server.controller.js b/app/controllers/users/users.password.server.controller.js index 1d4ae65..1bbd422 100644 --- a/app/controllers/users/users.password.server.controller.js +++ b/app/controllers/users/users.password.server.controller.js @@ -1,245 +1,191 @@ 'use strict'; - /** * Module dependencies. */ -var _ = require('lodash'), - errorHandler = require('../errors.server.controller'), - mongoose = require('mongoose'), - passport = require('passport'), - User = mongoose.model('User'), - config = require('../../../config/config'), - nodemailer = require('nodemailer'), - async = require('async'), - crypto = require('crypto'); - +var _ = require('lodash'), errorHandler = require('../errors.server.controller'), mongoose = require('mongoose'), passport = require('passport'), User = mongoose.model('User'), config = require('../../../config/config'), nodemailer = require('nodemailer'), async = require('async'), crypto = require('crypto'); /** * Forgot for reset password (forgot POST) */ -exports.forgot = function(req, res, next) { - async.waterfall([ - // Generate random token - function(done) { - crypto.randomBytes(20, function(err, buffer) { - var token = buffer.toString('hex'); - done(err, token); - }); - }, - // Lookup user by username - function(token, done) { - if (req.body.username) { - User.findOne({ - username: req.body.username - }, '-salt -password', function(err, user) { - if (!user) { - return res.status(400).send({ - message: 'No account with that username has been found' - }); - } else if (user.provider !== 'local') { - return res.status(400).send({ - message: 'It seems like you signed up using your ' + user.provider + ' account' - }); - } else { - user.resetPasswordToken = token; - user.resetPasswordExpires = Date.now() + 3600000; // 1 hour - - user.save(function(err) { - done(err, token, user); - }); - } - }); - } else { - return res.status(400).send({ - message: 'Username field must not be blank' - }); - } - }, - function(token, user, done) { - res.render('templates/reset-password-email', { - name: user.displayName, - appName: config.app.title, - url: 'http://' + req.headers.host + '/auth/reset/' + token - }, function(err, emailHTML) { - done(err, emailHTML, user); - }); - }, - // If valid email, send reset email using service - function(emailHTML, user, done) { - var smtpTransport = nodemailer.createTransport(config.mailer.options); - var mailOptions = { - to: user.email, - from: config.mailer.from, - subject: 'Password Reset', - html: emailHTML - }; - smtpTransport.sendMail(mailOptions, function(err) { - if (!err) { - res.send({ - message: 'An email has been sent to ' + user.email + ' with further instructions.' - }); - } - - done(err); - }); - } - ], function(err) { - if (err) return next(err); - }); +exports.forgot = function (req, res, next) { + async.waterfall([ + // Generate random token + function (done) { + crypto.randomBytes(20, function (err, buffer) { + var token = buffer.toString('hex'); + done(err, token); + }); + }, + // Lookup user by username + function (token, done) { + if (req.body.username) { + User.findOne({ username: req.body.username }, '-salt -password', function (err, user) { + if (!user) { + return res.status(400).send({ message: 'No account with that username has been found' }); + } else if (user.provider !== 'local') { + return res.status(400).send({ message: 'It seems like you signed up using your ' + user.provider + ' account' }); + } else { + user.resetPasswordToken = token; + user.resetPasswordExpires = Date.now() + 3600000; + // 1 hour + user.save(function (err) { + done(err, token, user); + }); + } + }); + } else { + return res.status(400).send({ message: 'Username field must not be blank' }); + } + }, + function (token, user, done) { + res.render('templates/reset-password-email', { + name: user.displayName, + appName: config.app.title, + url: 'http://' + req.headers.host + '/auth/reset/' + token + }, function (err, emailHTML) { + done(err, emailHTML, user); + }); + }, + // If valid email, send reset email using service + function (emailHTML, user, done) { + var smtpTransport = nodemailer.createTransport(config.mailer.options); + var mailOptions = { + to: user.email, + from: config.mailer.from, + subject: 'Password Reset', + html: emailHTML + }; + smtpTransport.sendMail(mailOptions, function (err) { + if (!err) { + res.send({ message: 'An email has been sent to ' + user.email + ' with further instructions.' }); + } + done(err); + }); + } + ], function (err) { + if (err) + return next(err); + }); }; - /** * Reset password GET from email token */ -exports.validateResetToken = function(req, res) { - User.findOne({ - resetPasswordToken: req.params.token, - resetPasswordExpires: { - $gt: Date.now() - } - }, function(err, user) { - if (!user) { - return res.redirect('/#!/password/reset/invalid'); - } - - res.redirect('/#!/password/reset/' + req.params.token); - }); +exports.validateResetToken = function (req, res) { + User.findOne({ + resetPasswordToken: req.params.token, + resetPasswordExpires: { $gt: Date.now() } + }, function (err, user) { + if (!user) { + return res.redirect('/#!/password/reset/invalid'); + } + res.redirect('/#!/password/reset/' + req.params.token); + }); }; - /** * Reset password POST from email token */ -exports.reset = function(req, res, next) { - // Init Variables - var passwordDetails = req.body; - - async.waterfall([ - - function(done) { - User.findOne({ - resetPasswordToken: req.params.token, - resetPasswordExpires: { - $gt: Date.now() - } - }, function(err, user) { - if (!err && user) { - if (passwordDetails.newPassword === passwordDetails.verifyPassword) { - user.password = passwordDetails.newPassword; - user.resetPasswordToken = undefined; - user.resetPasswordExpires = undefined; - - user.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - req.login(user, function(err) { - if (err) { - res.status(400).send(err); - } else { - // Return authenticated user - res.json(user); - - done(err, user); - } - }); - } - }); - } else { - return res.status(400).send({ - message: 'Passwords do not match' - }); - } - } else { - return res.status(400).send({ - message: 'Password reset token is invalid or has expired.' - }); - } - }); - }, - function(user, done) { - res.render('templates/reset-password-confirm-email', { - name: user.displayName, - appName: config.app.title - }, function(err, emailHTML) { - done(err, emailHTML, user); - }); - }, - // If valid email, send reset email using service - function(emailHTML, user, done) { - var smtpTransport = nodemailer.createTransport(config.mailer.options); - var mailOptions = { - to: user.email, - from: config.mailer.from, - subject: 'Your password has been changed', - html: emailHTML - }; - - smtpTransport.sendMail(mailOptions, function(err) { - done(err, 'done'); - }); - } - ], function(err) { - if (err) return next(err); - }); +exports.reset = function (req, res, next) { + // Init Variables + var passwordDetails = req.body; + async.waterfall([ + function (done) { + User.findOne({ + resetPasswordToken: req.params.token, + resetPasswordExpires: { $gt: Date.now() } + }, function (err, user) { + if (!err && user) { + if (passwordDetails.newPassword === passwordDetails.verifyPassword) { + user.password = passwordDetails.newPassword; + user.resetPasswordToken = undefined; + user.resetPasswordExpires = undefined; + user.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + // Return authenticated user + res.json(user); + done(err, user); + } + }); + } + }); + } else { + return res.status(400).send({ message: 'Passwords do not match' }); + } + } else { + return res.status(400).send({ message: 'Password reset token is invalid or has expired.' }); + } + }); + }, + function (user, done) { + res.render('templates/reset-password-confirm-email', { + name: user.displayName, + appName: config.app.title + }, function (err, emailHTML) { + done(err, emailHTML, user); + }); + }, + // If valid email, send reset email using service + function (emailHTML, user, done) { + var smtpTransport = nodemailer.createTransport(config.mailer.options); + var mailOptions = { + to: user.email, + from: config.mailer.from, + subject: 'Your password has been changed', + html: emailHTML + }; + smtpTransport.sendMail(mailOptions, function (err) { + done(err, 'done'); + }); + } + ], function (err) { + if (err) + return next(err); + }); }; - /** * Change Password */ -exports.changePassword = function(req, res) { - // Init Variables - var passwordDetails = req.body; - - if (req.user) { - if (passwordDetails.newPassword) { - User.findById(req.user.id, function(err, user) { - if (!err && user) { - if (user.authenticate(passwordDetails.currentPassword)) { - if (passwordDetails.newPassword === passwordDetails.verifyPassword) { - user.password = passwordDetails.newPassword; - - user.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - req.login(user, function(err) { - if (err) { - res.status(400).send(err); - } else { - res.send({ - message: 'Password changed successfully' - }); - } - }); - } - }); - } else { - res.status(400).send({ - message: 'Passwords do not match' - }); - } - } else { - res.status(400).send({ - message: 'Current password is incorrect' - }); - } - } else { - res.status(400).send({ - message: 'User is not found' - }); - } - }); - } else { - res.status(400).send({ - message: 'Please provide a new password' - }); - } - } else { - res.status(400).send({ - message: 'User is not signed in' - }); - } +exports.changePassword = function (req, res) { + // Init Variables + var passwordDetails = req.body; + if (req.user) { + if (passwordDetails.newPassword) { + User.findById(req.user.id, function (err, user) { + if (!err && user) { + if (user.authenticate(passwordDetails.currentPassword)) { + if (passwordDetails.newPassword === passwordDetails.verifyPassword) { + user.password = passwordDetails.newPassword; + user.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.send({ message: 'Password changed successfully' }); + } + }); + } + }); + } else { + res.status(400).send({ message: 'Passwords do not match' }); + } + } else { + res.status(400).send({ message: 'Current password is incorrect' }); + } + } else { + res.status(400).send({ message: 'User is not found' }); + } + }); + } else { + res.status(400).send({ message: 'Please provide a new password' }); + } + } else { + res.status(400).send({ message: 'User is not signed in' }); + } }; \ No newline at end of file diff --git a/app/controllers/users/users.profile.server.controller.js b/app/controllers/users/users.profile.server.controller.js index dd38936..f0fd60c 100644 --- a/app/controllers/users/users.profile.server.controller.js +++ b/app/controllers/users/users.profile.server.controller.js @@ -1,56 +1,42 @@ 'use strict'; - /** * Module dependencies. */ -var _ = require('lodash'), - errorHandler = require('../errors.server.controller.js'), - mongoose = require('mongoose'), - passport = require('passport'), - User = mongoose.model('User'); - +var _ = require('lodash'), errorHandler = require('../errors.server.controller.js'), mongoose = require('mongoose'), passport = require('passport'), User = mongoose.model('User'); /** * Update user details */ -exports.update = function(req, res) { - // Init Variables - var user = req.user; - var message = null; - - // For security measurement we remove the roles from the req.body object - delete req.body.roles; - - if (user) { - // Merge existing user - user = _.extend(user, req.body); - user.updated = Date.now(); - user.displayName = user.firstName + ' ' + user.lastName; - - user.save(function(err) { - if (err) { - return res.status(400).send({ - message: errorHandler.getErrorMessage(err) - }); - } else { - req.login(user, function(err) { - if (err) { - res.status(400).send(err); - } else { - res.json(user); - } - }); - } - }); - } else { - res.status(400).send({ - message: 'User is not signed in' - }); - } +exports.update = function (req, res) { + // Init Variables + var user = req.user; + var message = null; + // For security measurement we remove the roles from the req.body object + delete req.body.roles; + if (user) { + // Merge existing user + user = _.extend(user, req.body); + user.updated = Date.now(); + user.displayName = user.firstName + ' ' + user.lastName; + user.save(function (err) { + if (err) { + return res.status(400).send({ message: errorHandler.getErrorMessage(err) }); + } else { + req.login(user, function (err) { + if (err) { + res.status(400).send(err); + } else { + res.json(user); + } + }); + } + }); + } else { + res.status(400).send({ message: 'User is not signed in' }); + } }; - /** * Send User */ -exports.me = function(req, res) { - res.json(req.user || null); +exports.me = function (req, res) { + res.json(req.user || null); }; \ No newline at end of file diff --git a/app/controllers/utils.server.controller.js b/app/controllers/utils.server.controller.js index ba156e0..0933a57 100644 --- a/app/controllers/utils.server.controller.js +++ b/app/controllers/utils.server.controller.js @@ -1,55 +1,42 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - _ = require('lodash'); - +var mongoose = require('mongoose'), _ = require('lodash'); exports.dynamicSort = dynamicSort; exports.dynamicSortMultiple = dynamicSortMultiple; - function dynamicSort(property) { - - - - var sortOrder = 1; - if(property[0] === "-") { - sortOrder = -1; - property = property.substr(1); - } - return function (a,b) { - var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; - - - return result * sortOrder; - } + var sortOrder = 1; + if (property[0] === '-') { + sortOrder = -1; + property = property.substr(1); + } + return function (a, b) { + var result = a[property] < b[property] ? -1 : a[property] > b[property] ? 1 : 0; + return result * sortOrder; + }; } - function dynamicSortMultiple() { - /* + /* * save the arguments object as it will be overwritten * note that arguments object is an array-like object * consisting of the names of the properties to sort by */ - var props = arguments; - return function (obj1, obj2) { - var i = 0, result = 0, numberOfProperties = props.length; - /* try getting a different result from 0 (equal) + var props = arguments; + return function (obj1, obj2) { + var i = 0, result = 0, numberOfProperties = props.length; + /* try getting a different result from 0 (equal) * as long as we have extra properties to compare */ - while(result === 0 && i < numberOfProperties) { - result = dynamicSort(props[i])(obj1, obj2); - i++; - } - return result; + while (result === 0 && i < numberOfProperties) { + result = dynamicSort(props[i])(obj1, obj2); + i++; } - -}; - + return result; + }; +} /** * List of Utils */ -exports.list = function(req, res) { - -}; +exports.list = function (req, res) { +}; \ No newline at end of file diff --git a/app/models/article.server.model.js b/app/models/article.server.model.js index 3f6fd0d..f0b9f88 100644 --- a/app/models/article.server.model.js +++ b/app/models/article.server.model.js @@ -1,34 +1,30 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema; - +var mongoose = require('mongoose'), Schema = mongoose.Schema; /** * Article Schema */ var ArticleSchema = new Schema({ - created: { - type: Date, - default: Date.now - }, - title: { - type: String, - default: '', - trim: true, - required: 'Title cannot be blank' - }, - content: { - type: String, - default: '', - trim: true - }, - user: { - type: Schema.ObjectId, - ref: 'User' - } + created: { + type: Date, + default: Date.now + }, + title: { + type: String, + default: '', + trim: true, + required: 'Title cannot be blank' + }, + content: { + type: String, + default: '', + trim: true + }, + user: { + type: Schema.ObjectId, + ref: 'User' + } }); - mongoose.model('Article', ArticleSchema); \ No newline at end of file diff --git a/app/models/dashboard.server.model.js b/app/models/dashboard.server.model.js index b600aed..af1fc39 100644 --- a/app/models/dashboard.server.model.js +++ b/app/models/dashboard.server.model.js @@ -1,45 +1,94 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema; - +var mongoose = require('mongoose'), Schema = mongoose.Schema; /** * Dashboard Schema */ - var dashboardSchema = new mongoose.Schema({ - "productId": { type: Schema.Types.ObjectId, ref: "Product"}, - "name": { type: String, uppercase: true }, - "description": String, - "metrics": [ - { type: Schema.Types.ObjectId, ref: "Metric"} - ], - "granularity": {type: Number, default: 15}, - "baseline": {type: String, default: null}, - "useInBenchmark":{type: Boolean, default: false}, - "tags": {type:[{text: String, default: Boolean}], default: [{text: 'Load', default: true},{text: 'JVM', default: false}, {text: 'Database', default: false}, {text:'CPU', default: false}, {text:'Frontend', default: false}, {text: 'JDBC', default: false}, {text: 'Garbage Collection', default: false}, {text: 'Heap', default: false}, {text: 'Sessions', default: false}, {text: 'Threads', default: false}]} + 'productId': { + type: Schema.Types.ObjectId, + ref: 'Product' + }, + 'name': { + type: String, + uppercase: true + }, + 'description': String, + 'metrics': [{ + type: Schema.Types.ObjectId, + ref: 'Metric' + }], + 'granularity': { + type: Number, + default: 15 + }, + 'baseline': { + type: String, + default: null + }, + 'useInBenchmark': { + type: Boolean, + default: false + }, + 'tags': { + type: [{ + text: String, + default: Boolean + }], + default: [ + { + text: 'Load', + default: true + }, + { + text: 'JVM', + default: false + }, + { + text: 'Database', + default: false + }, + { + text: 'CPU', + default: false + }, + { + text: 'Frontend', + default: false + }, + { + text: 'JDBC', + default: false + }, + { + text: 'Garbage Collection', + default: false + }, + { + text: 'Heap', + default: false + }, + { + text: 'Sessions', + default: false + }, + { + text: 'Threads', + default: false + } + ] + } }); - -dashboardSchema.pre('remove', function(next){ - this.model('Product').update( - {_id: this.productId}, - {$pull: {dashboards: this._id}}, - {multi: true}, - next - ); +dashboardSchema.pre('remove', function (next) { + this.model('Product').update({ _id: this.productId }, { $pull: { dashboards: this._id } }, { multi: true }, next); }); - -dashboardSchema.pre('save', function(next){ - this.model('Product').update( - {_id: this.productId}, - {$addToSet: {dashboards: this._id}}, - next - ); +dashboardSchema.pre('save', function (next) { + this.model('Product').update({ _id: this.productId }, { $addToSet: { dashboards: this._id } }, next); }); - -dashboardSchema.index({ name: 1, productId: 1}, { unique: true }); - -mongoose.model('Dashboard', dashboardSchema); +dashboardSchema.index({ + name: 1, + productId: 1 +}, { unique: true }); +mongoose.model('Dashboard', dashboardSchema); \ No newline at end of file diff --git a/app/models/event.server.model.js b/app/models/event.server.model.js index 55a3dd6..d8099d1 100644 --- a/app/models/event.server.model.js +++ b/app/models/event.server.model.js @@ -1,33 +1,44 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema, - config = require('../../config/config'); - +var mongoose = require('mongoose'), Schema = mongoose.Schema, config = require('../../config/config'); /** * Event Schema */ var eventSchema = new mongoose.Schema({ - "productName": { type: String, uppercase: true }, - "dashboardName": { type: String, uppercase: true }, - "testRunId": String, - "eventDescription": String, - "eventTimestamp" : {type: Date, default: Date.now, expires: config.graphiteRetentionPeriod}, - "baseline": {type: String, default: 'none'}, - "buildResultKey": {type: String} + 'productName': { + type: String, + uppercase: true + }, + 'dashboardName': { + type: String, + uppercase: true + }, + 'testRunId': String, + 'eventDescription': String, + 'eventTimestamp': { + type: Date, + default: Date.now, + expires: config.graphiteRetentionPeriod + }, + 'baseline': { + type: String, + default: 'none' + }, + 'buildResultKey': { type: String } }); - -eventSchema.index({ productName: 1, dashboardName: 1, testRunId: 1, eventDescription: 1}, { unique: true }); - -eventSchema.on('index', function(err) { - if (err) { - console.error('User index error: %s', err); - } else { - console.info('User indexing complete'); - } +eventSchema.index({ + productName: 1, + dashboardName: 1, + testRunId: 1, + eventDescription: 1 +}, { unique: true }); +eventSchema.on('index', function (err) { + if (err) { + console.error('User index error: %s', err); + } else { + console.info('User indexing complete'); + } }); - -mongoose.model('Event', eventSchema); +mongoose.model('Event', eventSchema); \ No newline at end of file diff --git a/app/models/metric.server.model.js b/app/models/metric.server.model.js index 77ff9c0..3afb90b 100644 --- a/app/models/metric.server.model.js +++ b/app/models/metric.server.model.js @@ -1,42 +1,49 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema; - +var mongoose = require('mongoose'), Schema = mongoose.Schema; /** * Metric Schema */ var metricSchema = new mongoose.Schema({ - "dashboardId": { type: Schema.Types.ObjectId, ref: "Dashboard"}, - "dashboardName": String, - "productName": String, - "alias": {type: String, default: null}, - "targets": [String], - "benchmarkValue": {type: Number, default: null}, - "benchmarkOperator": {type: String, default: null}, - "requirementValue": {type: Number, default: null}, - "requirementOperator": {type: String, default: null}, - "tags": [{text: String}], - "type": {type: String, default: 'Average'} + 'dashboardId': { + type: Schema.Types.ObjectId, + ref: 'Dashboard' + }, + 'dashboardName': String, + 'productName': String, + 'alias': { + type: String, + default: null + }, + 'targets': [String], + 'benchmarkValue': { + type: Number, + default: null + }, + 'benchmarkOperator': { + type: String, + default: null + }, + 'requirementValue': { + type: Number, + default: null + }, + 'requirementOperator': { + type: String, + default: null + }, + 'tags': [{ text: String }], + 'type': { + type: String, + default: 'Average' + } }); - -metricSchema.pre('remove', function(next){ - this.model('Dashboard').update( - {_id: this.dashboardId}, - {$pull: {metrics: this._id}}, - {multi: true}, - next - ); +metricSchema.pre('remove', function (next) { + this.model('Dashboard').update({ _id: this.dashboardId }, { $pull: { metrics: this._id } }, { multi: true }, next); }); - -metricSchema.pre('save', function(next){ - this.model('Dashboard').update( - {_id: this.dashboardId}, - {$addToSet: {metrics: this._id}}, - next - ); +metricSchema.pre('save', function (next) { + this.model('Dashboard').update({ _id: this.dashboardId }, { $addToSet: { metrics: this._id } }, next); }); -mongoose.model('Metric', metricSchema); +mongoose.model('Metric', metricSchema); \ No newline at end of file diff --git a/app/models/product.server.model.js b/app/models/product.server.model.js index ab58109..4ceaf97 100644 --- a/app/models/product.server.model.js +++ b/app/models/product.server.model.js @@ -1,25 +1,21 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema; - +var mongoose = require('mongoose'), Schema = mongoose.Schema; /** * Product Schema */ - var ProductSchema = new mongoose.Schema({ - "name": { type: String, uppercase: true }, - "description": String, - "dashboards": [ - { type: Schema.Types.ObjectId, ref: "Dashboard"} - ] - + 'name': { + type: String, + uppercase: true + }, + 'description': String, + 'dashboards': [{ + type: Schema.Types.ObjectId, + ref: 'Dashboard' + }] }); - - -ProductSchema.index({ name: 1}, { unique: true }); - -mongoose.model('Product', ProductSchema); +ProductSchema.index({ name: 1 }, { unique: true }); +mongoose.model('Product', ProductSchema); \ No newline at end of file diff --git a/app/models/testrun.server.model.js b/app/models/testrun.server.model.js index 8b0a282..fc466da 100644 --- a/app/models/testrun.server.model.js +++ b/app/models/testrun.server.model.js @@ -1,79 +1,80 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema, - config = require('../../config/config'); - - - +var mongoose = require('mongoose'), Schema = mongoose.Schema, config = require('../../config/config'); var testRunTargetSchema = new Schema({ - "meetsRequirement": Boolean, - "benchmarkResultFixedOK": Boolean, - "benchmarkResultPreviousOK": Boolean, - "target": String, - "value": Number, - "benchmarkPreviousValue": Number, - "benchmarkFixedValue": Number + 'meetsRequirement': Boolean, + 'benchmarkResultFixedOK': Boolean, + 'benchmarkResultPreviousOK': Boolean, + 'target': String, + 'value': Number, + 'benchmarkPreviousValue': Number, + 'benchmarkFixedValue': Number }); - - mongoose.model('TestrunTarget', testRunTargetSchema); - var testRunMetricSchema = new Schema({ - "alias": String, - "type": String, - "tags": [{text: String}], - "requirementOperator": String, - "requirementValue": String, - "benchmarkOperator": String, - "benchmarkValue": String, - "meetsRequirement": {type:Boolean, default: null}, - "benchmarkResultFixedOK": {type:Boolean, default: null}, - "benchmarkResultPreviousOK": {type:Boolean, default: null}, - "annotation": String, - "targets": [testRunTargetSchema] - + 'alias': String, + 'type': String, + 'tags': [{ text: String }], + 'requirementOperator': String, + 'requirementValue': String, + 'benchmarkOperator': String, + 'benchmarkValue': String, + 'meetsRequirement': { + type: Boolean, + default: null + }, + 'benchmarkResultFixedOK': { + type: Boolean, + default: null + }, + 'benchmarkResultPreviousOK': { + type: Boolean, + default: null + }, + 'annotation': String, + 'targets': [testRunTargetSchema] }); - - mongoose.model('TestrunMetric', testRunMetricSchema); - - /** * Testrun Schema */ var TestrunSchema = new Schema({ - "productName": { type: String, uppercase: true }, - "dashboardName": { type: String, uppercase: true }, - "testRunId": String, - "start": {type:Date, expires: config.graphiteRetentionPeriod}, - "end": Date, - "baseline" : String, - "previousBuild": {type:String, default:null}, - "meetsRequirement": Boolean, - "benchmarkResultFixedOK": Boolean, - "benchmarkResultPreviousOK": Boolean, - "buildResultKey": String, - "eventIds": [String], - "metrics":[testRunMetricSchema] - }, - { - toObject: {getters: true} - }); - -TestrunSchema.virtual('startEpoch').get(function() { - return this.start.getTime(); + 'productName': { + type: String, + uppercase: true + }, + 'dashboardName': { + type: String, + uppercase: true + }, + 'testRunId': String, + 'start': { + type: Date, + expires: config.graphiteRetentionPeriod + }, + 'end': Date, + 'baseline': String, + 'previousBuild': { + type: String, + default: null + }, + 'meetsRequirement': Boolean, + 'benchmarkResultFixedOK': Boolean, + 'benchmarkResultPreviousOK': Boolean, + 'buildResultKey': String, + 'eventIds': [String], + 'metrics': [testRunMetricSchema] +}, { toObject: { getters: true } }); +TestrunSchema.virtual('startEpoch').get(function () { + return this.start.getTime(); }); - -TestrunSchema.virtual('endEpoch').get(function() { - return this.end.getTime(); +TestrunSchema.virtual('endEpoch').get(function () { + return this.end.getTime(); }); - -TestrunSchema.index({ testRunId: 1, dashboardId:1}, { unique: true }); - -mongoose.model('Testrun', TestrunSchema); - - +TestrunSchema.index({ + testRunId: 1, + dashboardId: 1 +}, { unique: true }); +mongoose.model('Testrun', TestrunSchema); \ No newline at end of file diff --git a/app/models/user.server.model.js b/app/models/user.server.model.js index 9370da0..00c8913 100644 --- a/app/models/user.server.model.js +++ b/app/models/user.server.model.js @@ -1,146 +1,141 @@ 'use strict'; - /** * Module dependencies. */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema, - crypto = require('crypto'); - +var mongoose = require('mongoose'), Schema = mongoose.Schema, crypto = require('crypto'); /** * A Validation function for local strategy properties */ -var validateLocalStrategyProperty = function(property) { - return ((this.provider !== 'local' && !this.updated) || property.length); +var validateLocalStrategyProperty = function (property) { + return this.provider !== 'local' && !this.updated || property.length; }; - /** * A Validation function for local strategy password */ -var validateLocalStrategyPassword = function(password) { - return (this.provider !== 'local' || (password && password.length > 6)); +var validateLocalStrategyPassword = function (password) { + return this.provider !== 'local' || password && password.length > 6; }; - /** * User Schema */ var UserSchema = new Schema({ - firstName: { - type: String, - trim: true, - default: '', - validate: [validateLocalStrategyProperty, 'Please fill in your first name'] - }, - lastName: { - type: String, - trim: true, - default: '', - validate: [validateLocalStrategyProperty, 'Please fill in your last name'] - }, - displayName: { - type: String, - trim: true - }, - email: { - type: String, - trim: true, - default: '', - validate: [validateLocalStrategyProperty, 'Please fill in your email'], - match: [/.+\@.+\..+/, 'Please fill a valid email address'] - }, - username: { - type: String, - unique: 'testing error message', - required: 'Please fill in a username', - trim: true - }, - password: { - type: String, - default: '', - validate: [validateLocalStrategyPassword, 'Password should be longer'] - }, - salt: { - type: String - }, - provider: { - type: String, - required: 'Provider is required' - }, - providerData: {}, - additionalProvidersData: {}, - roles: { - type: [{ - type: String, - enum: ['user', 'admin'] - }], - default: ['user'] - }, - updated: { - type: Date - }, - created: { - type: Date, - default: Date.now - }, - /* For reset password */ - resetPasswordToken: { - type: String - }, - resetPasswordExpires: { - type: Date - } + firstName: { + type: String, + trim: true, + default: '', + validate: [ + validateLocalStrategyProperty, + 'Please fill in your first name' + ] + }, + lastName: { + type: String, + trim: true, + default: '', + validate: [ + validateLocalStrategyProperty, + 'Please fill in your last name' + ] + }, + displayName: { + type: String, + trim: true + }, + email: { + type: String, + trim: true, + default: '', + validate: [ + validateLocalStrategyProperty, + 'Please fill in your email' + ], + match: [ + /.+\@.+\..+/, + 'Please fill a valid email address' + ] + }, + username: { + type: String, + unique: 'testing error message', + required: 'Please fill in a username', + trim: true + }, + password: { + type: String, + default: '', + validate: [ + validateLocalStrategyPassword, + 'Password should be longer' + ] + }, + salt: { type: String }, + provider: { + type: String, + required: 'Provider is required' + }, + providerData: {}, + additionalProvidersData: {}, + roles: { + type: [{ + type: String, + enum: [ + 'user', + 'admin' + ] + }], + default: ['user'] + }, + updated: { type: Date }, + created: { + type: Date, + default: Date.now + }, + /* For reset password */ + resetPasswordToken: { type: String }, + resetPasswordExpires: { type: Date } }); - /** * Hook a pre save method to hash the password */ -UserSchema.pre('save', function(next) { - if (this.password && this.password.length > 6) { - this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64'); - this.password = this.hashPassword(this.password); - } - - next(); +UserSchema.pre('save', function (next) { + if (this.password && this.password.length > 6) { + this.salt = new Buffer(crypto.randomBytes(16).toString('base64'), 'base64'); + this.password = this.hashPassword(this.password); + } + next(); }); - /** * Create instance method for hashing a password */ -UserSchema.methods.hashPassword = function(password) { - if (this.salt && password) { - return crypto.pbkdf2Sync(password, this.salt, 10000, 64).toString('base64'); - } else { - return password; - } +UserSchema.methods.hashPassword = function (password) { + if (this.salt && password) { + return crypto.pbkdf2Sync(password, this.salt, 10000, 64).toString('base64'); + } else { + return password; + } }; - /** * Create instance method for authenticating user */ -UserSchema.methods.authenticate = function(password) { - return this.password === this.hashPassword(password); +UserSchema.methods.authenticate = function (password) { + return this.password === this.hashPassword(password); }; - /** * Find possible not used username */ -UserSchema.statics.findUniqueUsername = function(username, suffix, callback) { - var _this = this; - var possibleUsername = username + (suffix || ''); - - _this.findOne({ - username: possibleUsername - }, function(err, user) { - if (!err) { - if (!user) { - callback(possibleUsername); - } else { - return _this.findUniqueUsername(username, (suffix || 0) + 1, callback); - } - } else { - callback(null); - } - }); +UserSchema.statics.findUniqueUsername = function (username, suffix, callback) { + var _this = this; + var possibleUsername = username + (suffix || ''); + _this.findOne({ username: possibleUsername }, function (err, user) { + if (!err) { + if (!user) { + callback(possibleUsername); + } else { + return _this.findUniqueUsername(username, (suffix || 0) + 1, callback); + } + } else { + callback(null); + } + }); }; - mongoose.model('User', UserSchema); \ No newline at end of file diff --git a/app/routes/articles.server.routes.js b/app/routes/articles.server.routes.js index 7d840e6..1959c38 100644 --- a/app/routes/articles.server.routes.js +++ b/app/routes/articles.server.routes.js @@ -1,22 +1,12 @@ 'use strict'; - /** * Module dependencies. */ -var users = require('../../app/controllers/users.server.controller'), - articles = require('../../app/controllers/articles.server.controller'); - -module.exports = function(app) { - // Article Routes - app.route('/articles') - .get(articles.list) - .post(users.requiresLogin, articles.create); - - app.route('/articles/:articleId') - .get(articles.read) - .put(users.requiresLogin, articles.hasAuthorization, articles.update) - .delete(users.requiresLogin, articles.hasAuthorization, articles.delete); - - // Finish by binding the article middleware - app.param('articleId', articles.articleByID); +var users = require('../../app/controllers/users.server.controller'), articles = require('../../app/controllers/articles.server.controller'); +module.exports = function (app) { + // Article Routes + app.route('/articles').get(articles.list).post(users.requiresLogin, articles.create); + app.route('/articles/:articleId').get(articles.read).put(users.requiresLogin, articles.hasAuthorization, articles.update).delete(users.requiresLogin, articles.hasAuthorization, articles.delete); + // Finish by binding the article middleware + app.param('articleId', articles.articleByID); }; \ No newline at end of file diff --git a/app/routes/core.server.routes.js b/app/routes/core.server.routes.js index 1db9d40..5459116 100644 --- a/app/routes/core.server.routes.js +++ b/app/routes/core.server.routes.js @@ -1,7 +1,6 @@ 'use strict'; - -module.exports = function(app) { - // Root routing - var core = require('../../app/controllers/core.server.controller'); - app.route('/').get(core.index); +module.exports = function (app) { + // Root routing + var core = require('../../app/controllers/core.server.controller'); + app.route('/').get(core.index); }; \ No newline at end of file diff --git a/app/routes/dashboards.server.routes.js b/app/routes/dashboards.server.routes.js index 79fb148..f38a747 100644 --- a/app/routes/dashboards.server.routes.js +++ b/app/routes/dashboards.server.routes.js @@ -1,26 +1,17 @@ 'use strict'; - -module.exports = function(app) { - var users = require('../../app/controllers/users.server.controller'); - var dashboards = require('../../app/controllers/dashboards.server.controller'); - - // Dashboards Routes - app.route('/dashboards/:productName') - .get(dashboards.list) - .post(dashboards.create);//users.requiresLogin, - - app.route('/dashboards/:productName/:dashboardName') - .get(dashboards.read) - - app.route('/dashboards/:dashboardId') - .put(dashboards.update) // users.requiresLogin, dashboards.hasAuthorization, - .delete(dashboards.delete); //users.requiresLogin, dashboards.hasAuthorization, - - app.route('/clone/dashboards/:dashboardId') - .get(dashboards.clone) - - // Finish by binding the Dashboard middleware - app.param('dashboardId', dashboards.dashboardByID); -// app.param('dashboardName', dashboards.dashboardByName); - app.param('productName', dashboards.dashboardByProductName); -}; +module.exports = function (app) { + var users = require('../../app/controllers/users.server.controller'); + var dashboards = require('../../app/controllers/dashboards.server.controller'); + // Dashboards Routes + app.route('/dashboards/:productName').get(dashboards.list).post(dashboards.create); + //users.requiresLogin, + app.route('/dashboards/:productName/:dashboardName').get(dashboards.read); + app.route('/dashboards/:dashboardId').put(dashboards.update) // users.requiresLogin, dashboards.hasAuthorization, +.delete(dashboards.delete); + //users.requiresLogin, dashboards.hasAuthorization, + app.route('/clone/dashboards/:dashboardId').get(dashboards.clone); + // Finish by binding the Dashboard middleware + app.param('dashboardId', dashboards.dashboardByID); + // app.param('dashboardName', dashboards.dashboardByName); + app.param('productName', dashboards.dashboardByProductName); +}; \ No newline at end of file diff --git a/app/routes/events.server.routes.js b/app/routes/events.server.routes.js index a9a6643..053466b 100644 --- a/app/routes/events.server.routes.js +++ b/app/routes/events.server.routes.js @@ -1,28 +1,15 @@ 'use strict'; - -module.exports = function(app) { - var users = require('../../app/controllers/users.server.controller'); - var events = require('../../app/controllers/events.server.controller'); - - // Events Routes - app.route('/events') - .get(events.list) - .post(events.create) - - app.route('/check-events/:productName/:dashboardName/:testRunId/:eventDescription') - .get(events.checkEvents) - - app.route('/events-dashboard/:productName/:dashboardName') - .get(events.eventsForDashboard) - - app.route('/events-testrun/:productName/:dashboardName/:from/:until') - .get(events.eventsForTestRun) - - app.route('/events/:eventId') - .get(events.read) - .put(events.update) //users.requiresLogin, events.hasAuthorization, - .delete(events.delete); //users.requiresLogin, events.hasAuthorization, - - // Finish by binding the Event middleware - app.param('eventId', events.eventByID); -}; +module.exports = function (app) { + var users = require('../../app/controllers/users.server.controller'); + var events = require('../../app/controllers/events.server.controller'); + // Events Routes + app.route('/events').get(events.list).post(events.create); + app.route('/check-events/:productName/:dashboardName/:testRunId/:eventDescription').get(events.checkEvents); + app.route('/events-dashboard/:productName/:dashboardName').get(events.eventsForDashboard); + app.route('/events-testrun/:productName/:dashboardName/:from/:until').get(events.eventsForTestRun); + app.route('/events/:eventId').get(events.read).put(events.update) //users.requiresLogin, events.hasAuthorization, +.delete(events.delete); + //users.requiresLogin, events.hasAuthorization, + // Finish by binding the Event middleware + app.param('eventId', events.eventByID); +}; \ No newline at end of file diff --git a/app/routes/export-db.server.routes.js b/app/routes/export-db.server.routes.js index 8cd9f6f..deef917 100644 --- a/app/routes/export-db.server.routes.js +++ b/app/routes/export-db.server.routes.js @@ -1,14 +1,8 @@ 'use strict'; - -module.exports = function(app) { - var exportDb = require('../../app/controllers/export-db.server.controller'); - - // Events Routes - //app.route('/import-db') - // .get(importDb.dbImport); - - app.route('/download') - .get(exportDb.dbExport); - - -}; +module.exports = function (app) { + var exportDb = require('../../app/controllers/export-db.server.controller'); + // Events Routes + //app.route('/import-db') + // .get(importDb.dbImport); + app.route('/download').get(exportDb.dbExport); +}; \ No newline at end of file diff --git a/app/routes/graphite.server.routes.js b/app/routes/graphite.server.routes.js index 6e2d70e..f1b0d0a 100644 --- a/app/routes/graphite.server.routes.js +++ b/app/routes/graphite.server.routes.js @@ -1,11 +1,6 @@ 'use strict'; - -module.exports = function(app) { - var graphite = require('../../app/controllers/graphite.server.controller'); - - // Events Routes - app.route('/graphite') - .get(graphite.getData) - - -}; +module.exports = function (app) { + var graphite = require('../../app/controllers/graphite.server.controller'); + // Events Routes + app.route('/graphite').get(graphite.getData); +}; \ No newline at end of file diff --git a/app/routes/import-db.server.routes.js b/app/routes/import-db.server.routes.js index 9e3315a..8eff73f 100644 --- a/app/routes/import-db.server.routes.js +++ b/app/routes/import-db.server.routes.js @@ -1,19 +1,12 @@ 'use strict'; - -module.exports = function(app) { - var importDb = require('../../app/controllers/import-db.server.controller'); - var importDbLegacy = require('../../app/controllers/import-db-legacy.server.controller'); - var multipart = require('connect-multiparty'); - var multipartMiddleware = multipart(); - - // Events Routes - //app.route('/import-db') - // .get(importDb.dbImport); - - app.route('/upload') - .post(multipartMiddleware, importDb.upload); - - app.route('/upload-legacy') - .post(multipartMiddleware, importDbLegacy.upload); - -}; +module.exports = function (app) { + var importDb = require('../../app/controllers/import-db.server.controller'); + var importDbLegacy = require('../../app/controllers/import-db-legacy.server.controller'); + var multipart = require('connect-multiparty'); + var multipartMiddleware = multipart(); + // Events Routes + //app.route('/import-db') + // .get(importDb.dbImport); + app.route('/upload').post(multipartMiddleware, importDb.upload); + app.route('/upload-legacy').post(multipartMiddleware, importDbLegacy.upload); +}; \ No newline at end of file diff --git a/app/routes/jenkins.server.routes.js b/app/routes/jenkins.server.routes.js index b5a6c6e..2932151 100644 --- a/app/routes/jenkins.server.routes.js +++ b/app/routes/jenkins.server.routes.js @@ -1,11 +1,6 @@ 'use strict'; - -module.exports = function(app) { - var jenkins = require('../../app/controllers/jenkins.server.controller'); - - // Events Routes - app.route('/jenkins-stdout') - .post(jenkins.getConsoleData) - - -}; +module.exports = function (app) { + var jenkins = require('../../app/controllers/jenkins.server.controller'); + // Events Routes + app.route('/jenkins-stdout').post(jenkins.getConsoleData); +}; \ No newline at end of file diff --git a/app/routes/metrics.server.routes.js b/app/routes/metrics.server.routes.js index 36c3e97..bab8630 100644 --- a/app/routes/metrics.server.routes.js +++ b/app/routes/metrics.server.routes.js @@ -1,19 +1,13 @@ 'use strict'; - -module.exports = function(app) { - var users = require('../../app/controllers/users.server.controller'); - var metrics = require('../../app/controllers/metrics.server.controller'); - - // Metrics Routes - app.route('/metrics') - .get(metrics.list) - .post(metrics.create); //users.requiresLogin, - - app.route('/metrics/:metricId') - .get(metrics.read) - .put( metrics.update) //users.requiresLogin, metrics.hasAuthorization, - .delete( metrics.delete); //users.requiresLogin, metrics.hasAuthorization, - - // Finish by binding the Metric middleware - app.param('metricId', metrics.metricByID); -}; +module.exports = function (app) { + var users = require('../../app/controllers/users.server.controller'); + var metrics = require('../../app/controllers/metrics.server.controller'); + // Metrics Routes + app.route('/metrics').get(metrics.list).post(metrics.create); + //users.requiresLogin, + app.route('/metrics/:metricId').get(metrics.read).put(metrics.update) //users.requiresLogin, metrics.hasAuthorization, +.delete(metrics.delete); + //users.requiresLogin, metrics.hasAuthorization, + // Finish by binding the Metric middleware + app.param('metricId', metrics.metricByID); +}; \ No newline at end of file diff --git a/app/routes/products.server.routes.js b/app/routes/products.server.routes.js index cdd99c6..fb98302 100644 --- a/app/routes/products.server.routes.js +++ b/app/routes/products.server.routes.js @@ -1,23 +1,15 @@ 'use strict'; - -module.exports = function(app) { - var users = require('../../app/controllers/users.server.controller'); - var products = require('../../app/controllers/products.server.controller'); - - // Products Routes - app.route('/products') - .get(products.list) - .post( products.create);//users.requiresLogin, - - app.route('/products/:productName') - .get(products.read); - - - app.route('/product-by-id/:productId') - .delete(products.delete) //users.requiresLogin, products.hasAuthorization, - .put(products.update); //users.requiresLogin, products.hasAuthorization, - - // Finish by binding the Product middleware - app.param('productName', products.productByName); - app.param('productId', products.productById); -}; +module.exports = function (app) { + var users = require('../../app/controllers/users.server.controller'); + var products = require('../../app/controllers/products.server.controller'); + // Products Routes + app.route('/products').get(products.list).post(products.create); + //users.requiresLogin, + app.route('/products/:productName').get(products.read); + app.route('/product-by-id/:productId').delete(products.delete) //users.requiresLogin, products.hasAuthorization, +.put(products.update); + //users.requiresLogin, products.hasAuthorization, + // Finish by binding the Product middleware + app.param('productName', products.productByName); + app.param('productId', products.productById); +}; \ No newline at end of file diff --git a/app/routes/testruns.server.routes.js b/app/routes/testruns.server.routes.js index 1434e3c..0ef1708 100644 --- a/app/routes/testruns.server.routes.js +++ b/app/routes/testruns.server.routes.js @@ -1,28 +1,12 @@ 'use strict'; - -module.exports = function(app) { - - var testruns = require('../../app/controllers/testruns.server.controller.js'); - var benchmarks = require('../../app/controllers/testruns.benchmarks.server.controller'); - var requirements = require('../../app/controllers/testruns.requirements.server.controller'); - - app.route('/testruns-dashboard/:productName/:dashboardName/:useInBenchmark') - .get(testruns.testRunsForDashboard); - - app.route('/testrun/:productName/:dashboardName/:testRunId') - .get(testruns.testRunById) - .delete(testruns.deleteTestRunById); - - app.route('/refresh-testrun/:productName/:dashboardName/:testRunId') - .get(testruns.refreshTestrun); - - app.route('/update-testruns-results/:productName/:dashboardName/:metricId/:updateRequirements/:updateBenchmarks') - .get(testruns.updateTestrunsResults); - - - app.route('/running-test/:productName/:dashboardName') - .get(testruns.runningTest); - - app.route('/update-fixed-baseline-benchmark') - .post(benchmarks.updateFixedBaselineBenchmark); -}; +module.exports = function (app) { + var testruns = require('../../app/controllers/testruns.server.controller.js'); + var benchmarks = require('../../app/controllers/testruns.benchmarks.server.controller'); + var requirements = require('../../app/controllers/testruns.requirements.server.controller'); + app.route('/testruns-dashboard/:productName/:dashboardName/:useInBenchmark').get(testruns.testRunsForDashboard); + app.route('/testrun/:productName/:dashboardName/:testRunId').get(testruns.testRunById).delete(testruns.deleteTestRunById); + app.route('/refresh-testrun/:productName/:dashboardName/:testRunId').get(testruns.refreshTestrun); + app.route('/update-testruns-results/:productName/:dashboardName/:metricId/:updateRequirements/:updateBenchmarks').get(testruns.updateTestrunsResults); + app.route('/running-test/:productName/:dashboardName').get(testruns.runningTest); + app.route('/update-fixed-baseline-benchmark').post(benchmarks.updateFixedBaselineBenchmark); +}; \ No newline at end of file diff --git a/app/routes/users.server.routes.js b/app/routes/users.server.routes.js index 3120e9a..1087cba 100644 --- a/app/routes/users.server.routes.js +++ b/app/routes/users.server.routes.js @@ -1,57 +1,44 @@ 'use strict'; - /** * Module dependencies. */ var passport = require('passport'); - -module.exports = function(app) { - // User Routes - var users = require('../../app/controllers/users.server.controller'); - - // Setting up the users profile api - app.route('/users/me').get(users.me); - app.route('/users').put(users.update); - app.route('/users/accounts').delete(users.removeOAuthProvider); - - // Setting up the users password api - app.route('/users/password').post(users.changePassword); - app.route('/auth/forgot').post(users.forgot); - app.route('/auth/reset/:token').get(users.validateResetToken); - app.route('/auth/reset/:token').post(users.reset); - - // Setting up the users authentication api - app.route('/auth/signup').post(users.signup); - app.route('/auth/signin').post(users.signin); - app.route('/auth/signout').get(users.signout); - - // Setting the facebook oauth routes - app.route('/auth/facebook').get(passport.authenticate('facebook', { - scope: ['email'] - })); - app.route('/auth/facebook/callback').get(users.oauthCallback('facebook')); - - // Setting the twitter oauth routes - app.route('/auth/twitter').get(passport.authenticate('twitter')); - app.route('/auth/twitter/callback').get(users.oauthCallback('twitter')); - - // Setting the google oauth routes - app.route('/auth/google').get(passport.authenticate('google', { - scope: [ - 'https://www.googleapis.com/auth/userinfo.profile', - 'https://www.googleapis.com/auth/userinfo.email' - ] - })); - app.route('/auth/google/callback').get(users.oauthCallback('google')); - - // Setting the linkedin oauth routes - app.route('/auth/linkedin').get(passport.authenticate('linkedin')); - app.route('/auth/linkedin/callback').get(users.oauthCallback('linkedin')); - - // Setting the github oauth routes - app.route('/auth/github').get(passport.authenticate('github')); - app.route('/auth/github/callback').get(users.oauthCallback('github')); - - // Finish by binding the user middleware - app.param('userId', users.userByID); +module.exports = function (app) { + // User Routes + var users = require('../../app/controllers/users.server.controller'); + // Setting up the users profile api + app.route('/users/me').get(users.me); + app.route('/users').put(users.update); + app.route('/users/accounts').delete(users.removeOAuthProvider); + // Setting up the users password api + app.route('/users/password').post(users.changePassword); + app.route('/auth/forgot').post(users.forgot); + app.route('/auth/reset/:token').get(users.validateResetToken); + app.route('/auth/reset/:token').post(users.reset); + // Setting up the users authentication api + app.route('/auth/signup').post(users.signup); + app.route('/auth/signin').post(users.signin); + app.route('/auth/signout').get(users.signout); + // Setting the facebook oauth routes + app.route('/auth/facebook').get(passport.authenticate('facebook', { scope: ['email'] })); + app.route('/auth/facebook/callback').get(users.oauthCallback('facebook')); + // Setting the twitter oauth routes + app.route('/auth/twitter').get(passport.authenticate('twitter')); + app.route('/auth/twitter/callback').get(users.oauthCallback('twitter')); + // Setting the google oauth routes + app.route('/auth/google').get(passport.authenticate('google', { + scope: [ + 'https://www.googleapis.com/auth/userinfo.profile', + 'https://www.googleapis.com/auth/userinfo.email' + ] + })); + app.route('/auth/google/callback').get(users.oauthCallback('google')); + // Setting the linkedin oauth routes + app.route('/auth/linkedin').get(passport.authenticate('linkedin')); + app.route('/auth/linkedin/callback').get(users.oauthCallback('linkedin')); + // Setting the github oauth routes + app.route('/auth/github').get(passport.authenticate('github')); + app.route('/auth/github/callback').get(users.oauthCallback('github')); + // Finish by binding the user middleware + app.param('userId', users.userByID); }; \ No newline at end of file diff --git a/app/tests/article.server.model.test.js b/app/tests/article.server.model.test.js index e3dd60c..93735c6 100644 --- a/app/tests/article.server.model.test.js +++ b/app/tests/article.server.model.test.js @@ -1,64 +1,52 @@ 'use strict'; - /** * Module dependencies. */ -var should = require('should'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Article = mongoose.model('Article'); - +var should = require('should'), mongoose = require('mongoose'), User = mongoose.model('User'), Article = mongoose.model('Article'); /** * Globals */ var user, article; - /** * Unit tests */ -describe('Article Model Unit Tests:', function() { - beforeEach(function(done) { - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password' - }); - - user.save(function() { - article = new Article({ - title: 'Article Title', - content: 'Article Content', - user: user - }); - - done(); - }); - }); - - describe('Method Save', function() { - it('should be able to save without problems', function(done) { - return article.save(function(err) { - should.not.exist(err); - done(); - }); - }); - - it('should be able to show an error when try to save without title', function(done) { - article.title = ''; - - return article.save(function(err) { - should.exist(err); - done(); - }); - }); - }); - - afterEach(function(done) { - Article.remove().exec(); - User.remove().exec(); - done(); - }); +describe('Article Model Unit Tests:', function () { + beforeEach(function (done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password' + }); + user.save(function () { + article = new Article({ + title: 'Article Title', + content: 'Article Content', + user: user + }); + done(); + }); + }); + describe('Method Save', function () { + it('should be able to save without problems', function (done) { + return article.save(function (err) { + should.not.exist(err); + done(); + }); + }); + it('should be able to show an error when try to save without title', function (done) { + article.title = ''; + return article.save(function (err) { + should.exist(err); + done(); + }); + }); + }); + afterEach(function (done) { + Article.remove().exec(); + User.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/article.server.routes.test.js b/app/tests/article.server.routes.test.js index 2576095..56a96da 100644 --- a/app/tests/article.server.routes.test.js +++ b/app/tests/article.server.routes.test.js @@ -1,269 +1,189 @@ 'use strict'; - -var should = require('should'), - request = require('supertest'), - app = require('../../server'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Article = mongoose.model('Article'), - agent = request.agent(app); - +var should = require('should'), request = require('supertest'), app = require('../../server'), mongoose = require('mongoose'), User = mongoose.model('User'), Article = mongoose.model('Article'), agent = request.agent(app); /** * Globals */ var credentials, user, article; - /** * Article routes tests */ -describe('Article CRUD tests', function() { - beforeEach(function(done) { - // Create user credentials - credentials = { - username: 'username', - password: 'password' - }; - - // Create a new user - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: credentials.username, - password: credentials.password, - provider: 'local' - }); - - // Save a user to the test db and create new article - user.save(function() { - article = { - title: 'Article Title', - content: 'Article Content' - }; - - done(); - }); - }); - - it('should be able to save an article if logged in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/articles') - .send(article) - .expect(200) - .end(function(articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) done(articleSaveErr); - - // Get a list of articles - agent.get('/articles') - .end(function(articlesGetErr, articlesGetRes) { - // Handle article save error - if (articlesGetErr) done(articlesGetErr); - - // Get articles list - var articles = articlesGetRes.body; - - // Set assertions - (articles[0].user._id).should.equal(userId); - (articles[0].title).should.match('Article Title'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to save an article if not logged in', function(done) { - agent.post('/articles') - .send(article) - .expect(401) - .end(function(articleSaveErr, articleSaveRes) { - // Call the assertion callback - done(articleSaveErr); - }); - }); - - it('should not be able to save an article if no title is provided', function(done) { - // Invalidate title field - article.title = ''; - - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/articles') - .send(article) - .expect(400) - .end(function(articleSaveErr, articleSaveRes) { - // Set message assertion - (articleSaveRes.body.message).should.match('Title cannot be blank'); - - // Handle article save error - done(articleSaveErr); - }); - }); - }); - - it('should be able to update an article if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/articles') - .send(article) - .expect(200) - .end(function(articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) done(articleSaveErr); - - // Update article title - article.title = 'WHY YOU GOTTA BE SO MEAN?'; - - // Update an existing article - agent.put('/articles/' + articleSaveRes.body._id) - .send(article) - .expect(200) - .end(function(articleUpdateErr, articleUpdateRes) { - // Handle article update error - if (articleUpdateErr) done(articleUpdateErr); - - // Set assertions - (articleUpdateRes.body._id).should.equal(articleSaveRes.body._id); - (articleUpdateRes.body.title).should.match('WHY YOU GOTTA BE SO MEAN?'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should be able to get a list of articles if not signed in', function(done) { - // Create new article model instance - var articleObj = new Article(article); - - // Save the article - articleObj.save(function() { - // Request articles - request(app).get('/articles') - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Array.with.lengthOf(1); - - // Call the assertion callback - done(); - }); - - }); - }); - - - it('should be able to get a single article if not signed in', function(done) { - // Create new article model instance - var articleObj = new Article(article); - - // Save the article - articleObj.save(function() { - request(app).get('/articles/' + articleObj._id) - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Object.with.property('title', article.title); - - // Call the assertion callback - done(); - }); - }); - }); - - it('should be able to delete an article if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new article - agent.post('/articles') - .send(article) - .expect(200) - .end(function(articleSaveErr, articleSaveRes) { - // Handle article save error - if (articleSaveErr) done(articleSaveErr); - - // Delete an existing article - agent.delete('/articles/' + articleSaveRes.body._id) - .send(article) - .expect(200) - .end(function(articleDeleteErr, articleDeleteRes) { - // Handle article error error - if (articleDeleteErr) done(articleDeleteErr); - - // Set assertions - (articleDeleteRes.body._id).should.equal(articleSaveRes.body._id); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to delete an article if not signed in', function(done) { - // Set article user - article.user = user; - - // Create new article model instance - var articleObj = new Article(article); - - // Save the article - articleObj.save(function() { - // Try deleting article - request(app).delete('/articles/' + articleObj._id) - .expect(401) - .end(function(articleDeleteErr, articleDeleteRes) { - // Set message assertion - (articleDeleteRes.body.message).should.match('User is not logged in'); - - // Handle article error error - done(articleDeleteErr); - }); - - }); - }); - - afterEach(function(done) { - User.remove().exec(); - Article.remove().exec(); - done(); - }); +describe('Article CRUD tests', function () { + beforeEach(function (done) { + // Create user credentials + credentials = { + username: 'username', + password: 'password' + }; + // Create a new user + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: credentials.username, + password: credentials.password, + provider: 'local' + }); + // Save a user to the test db and create new article + user.save(function () { + article = { + title: 'Article Title', + content: 'Article Content' + }; + done(); + }); + }); + it('should be able to save an article if logged in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new article + agent.post('/articles').send(article).expect(200).end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) + done(articleSaveErr); + // Get a list of articles + agent.get('/articles').end(function (articlesGetErr, articlesGetRes) { + // Handle article save error + if (articlesGetErr) + done(articlesGetErr); + // Get articles list + var articles = articlesGetRes.body; + // Set assertions + articles[0].user._id.should.equal(userId); + articles[0].title.should.match('Article Title'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to save an article if not logged in', function (done) { + agent.post('/articles').send(article).expect(401).end(function (articleSaveErr, articleSaveRes) { + // Call the assertion callback + done(articleSaveErr); + }); + }); + it('should not be able to save an article if no title is provided', function (done) { + // Invalidate title field + article.title = ''; + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new article + agent.post('/articles').send(article).expect(400).end(function (articleSaveErr, articleSaveRes) { + // Set message assertion + articleSaveRes.body.message.should.match('Title cannot be blank'); + // Handle article save error + done(articleSaveErr); + }); + }); + }); + it('should be able to update an article if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new article + agent.post('/articles').send(article).expect(200).end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) + done(articleSaveErr); + // Update article title + article.title = 'WHY YOU GOTTA BE SO MEAN?'; + // Update an existing article + agent.put('/articles/' + articleSaveRes.body._id).send(article).expect(200).end(function (articleUpdateErr, articleUpdateRes) { + // Handle article update error + if (articleUpdateErr) + done(articleUpdateErr); + // Set assertions + articleUpdateRes.body._id.should.equal(articleSaveRes.body._id); + articleUpdateRes.body.title.should.match('WHY YOU GOTTA BE SO MEAN?'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should be able to get a list of articles if not signed in', function (done) { + // Create new article model instance + var articleObj = new Article(article); + // Save the article + articleObj.save(function () { + // Request articles + request(app).get('/articles').end(function (req, res) { + // Set assertion + res.body.should.be.an.Array.with.lengthOf(1); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to get a single article if not signed in', function (done) { + // Create new article model instance + var articleObj = new Article(article); + // Save the article + articleObj.save(function () { + request(app).get('/articles/' + articleObj._id).end(function (req, res) { + // Set assertion + res.body.should.be.an.Object.with.property('title', article.title); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to delete an article if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new article + agent.post('/articles').send(article).expect(200).end(function (articleSaveErr, articleSaveRes) { + // Handle article save error + if (articleSaveErr) + done(articleSaveErr); + // Delete an existing article + agent.delete('/articles/' + articleSaveRes.body._id).send(article).expect(200).end(function (articleDeleteErr, articleDeleteRes) { + // Handle article error error + if (articleDeleteErr) + done(articleDeleteErr); + // Set assertions + articleDeleteRes.body._id.should.equal(articleSaveRes.body._id); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to delete an article if not signed in', function (done) { + // Set article user + article.user = user; + // Create new article model instance + var articleObj = new Article(article); + // Save the article + articleObj.save(function () { + // Try deleting article + request(app).delete('/articles/' + articleObj._id).expect(401).end(function (articleDeleteErr, articleDeleteRes) { + // Set message assertion + articleDeleteRes.body.message.should.match('User is not logged in'); + // Handle article error error + done(articleDeleteErr); + }); + }); + }); + afterEach(function (done) { + User.remove().exec(); + Article.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/dashboard.server.model.test.js b/app/tests/dashboard.server.model.test.js index 60b5d1a..e3dfddb 100644 --- a/app/tests/dashboard.server.model.test.js +++ b/app/tests/dashboard.server.model.test.js @@ -1,64 +1,51 @@ 'use strict'; - /** * Module dependencies. */ -var should = require('should'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Dashboard = mongoose.model('Dashboard'); - +var should = require('should'), mongoose = require('mongoose'), User = mongoose.model('User'), Dashboard = mongoose.model('Dashboard'); /** * Globals */ var user, dashboard; - /** * Unit tests */ -describe('Dashboard Model Unit Tests:', function() { - beforeEach(function(done) { - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password' - }); - - user.save(function() { - dashboard = new Dashboard({ - name: 'Dashboard Name', - user: user - }); - - done(); - }); - }); - - describe('Method Save', function() { - it('should be able to save without problems', function(done) { - return dashboard.save(function(err) { - should.not.exist(err); - done(); - }); - }); - - it('should be able to show an error when try to save without name', function(done) { - dashboard.name = ''; - - return dashboard.save(function(err) { - should.exist(err); - done(); - }); - }); - }); - - afterEach(function(done) { - Dashboard.remove().exec(); - User.remove().exec(); - - done(); - }); +describe('Dashboard Model Unit Tests:', function () { + beforeEach(function (done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password' + }); + user.save(function () { + dashboard = new Dashboard({ + name: 'Dashboard Name', + user: user + }); + done(); + }); + }); + describe('Method Save', function () { + it('should be able to save without problems', function (done) { + return dashboard.save(function (err) { + should.not.exist(err); + done(); + }); + }); + it('should be able to show an error when try to save without name', function (done) { + dashboard.name = ''; + return dashboard.save(function (err) { + should.exist(err); + done(); + }); + }); + }); + afterEach(function (done) { + Dashboard.remove().exec(); + User.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/dashboard.server.routes.test.js b/app/tests/dashboard.server.routes.test.js index d0ab979..6ae2499 100644 --- a/app/tests/dashboard.server.routes.test.js +++ b/app/tests/dashboard.server.routes.test.js @@ -1,268 +1,186 @@ 'use strict'; - -var should = require('should'), - request = require('supertest'), - app = require('../../server'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Dashboard = mongoose.model('Dashboard'), - agent = request.agent(app); - +var should = require('should'), request = require('supertest'), app = require('../../server'), mongoose = require('mongoose'), User = mongoose.model('User'), Dashboard = mongoose.model('Dashboard'), agent = request.agent(app); /** * Globals */ var credentials, user, dashboard; - /** * Dashboard routes tests */ -describe('Dashboard CRUD tests', function() { - beforeEach(function(done) { - // Create user credentials - credentials = { - username: 'username', - password: 'password' - }; - - // Create a new user - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: credentials.username, - password: credentials.password, - provider: 'local' - }); - - // Save a user to the test db and create new Dashboard - user.save(function() { - dashboard = { - name: 'Dashboard Name' - }; - - done(); - }); - }); - - it('should be able to save Dashboard instance if logged in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Dashboard - agent.post('/dashboards') - .send(dashboard) - .expect(200) - .end(function(dashboardSaveErr, dashboardSaveRes) { - // Handle Dashboard save error - if (dashboardSaveErr) done(dashboardSaveErr); - - // Get a list of Dashboards - agent.get('/dashboards') - .end(function(dashboardsGetErr, dashboardsGetRes) { - // Handle Dashboard save error - if (dashboardsGetErr) done(dashboardsGetErr); - - // Get Dashboards list - var dashboards = dashboardsGetRes.body; - - // Set assertions - (dashboards[0].user._id).should.equal(userId); - (dashboards[0].name).should.match('Dashboard Name'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to save Dashboard instance if not logged in', function(done) { - agent.post('/dashboards') - .send(dashboard) - .expect(401) - .end(function(dashboardSaveErr, dashboardSaveRes) { - // Call the assertion callback - done(dashboardSaveErr); - }); - }); - - it('should not be able to save Dashboard instance if no name is provided', function(done) { - // Invalidate name field - dashboard.name = ''; - - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Dashboard - agent.post('/dashboards') - .send(dashboard) - .expect(400) - .end(function(dashboardSaveErr, dashboardSaveRes) { - // Set message assertion - (dashboardSaveRes.body.message).should.match('Please fill Dashboard name'); - - // Handle Dashboard save error - done(dashboardSaveErr); - }); - }); - }); - - it('should be able to update Dashboard instance if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Dashboard - agent.post('/dashboards') - .send(dashboard) - .expect(200) - .end(function(dashboardSaveErr, dashboardSaveRes) { - // Handle Dashboard save error - if (dashboardSaveErr) done(dashboardSaveErr); - - // Update Dashboard name - dashboard.name = 'WHY YOU GOTTA BE SO MEAN?'; - - // Update existing Dashboard - agent.put('/dashboards/' + dashboardSaveRes.body._id) - .send(dashboard) - .expect(200) - .end(function(dashboardUpdateErr, dashboardUpdateRes) { - // Handle Dashboard update error - if (dashboardUpdateErr) done(dashboardUpdateErr); - - // Set assertions - (dashboardUpdateRes.body._id).should.equal(dashboardSaveRes.body._id); - (dashboardUpdateRes.body.name).should.match('WHY YOU GOTTA BE SO MEAN?'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should be able to get a list of Dashboards if not signed in', function(done) { - // Create new Dashboard model instance - var dashboardObj = new Dashboard(dashboard); - - // Save the Dashboard - dashboardObj.save(function() { - // Request Dashboards - request(app).get('/dashboards') - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Array.with.lengthOf(1); - - // Call the assertion callback - done(); - }); - - }); - }); - - - it('should be able to get a single Dashboard if not signed in', function(done) { - // Create new Dashboard model instance - var dashboardObj = new Dashboard(dashboard); - - // Save the Dashboard - dashboardObj.save(function() { - request(app).get('/dashboards/' + dashboardObj._id) - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Object.with.property('name', dashboard.name); - - // Call the assertion callback - done(); - }); - }); - }); - - it('should be able to delete Dashboard instance if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Dashboard - agent.post('/dashboards') - .send(dashboard) - .expect(200) - .end(function(dashboardSaveErr, dashboardSaveRes) { - // Handle Dashboard save error - if (dashboardSaveErr) done(dashboardSaveErr); - - // Delete existing Dashboard - agent.delete('/dashboards/' + dashboardSaveRes.body._id) - .send(dashboard) - .expect(200) - .end(function(dashboardDeleteErr, dashboardDeleteRes) { - // Handle Dashboard error error - if (dashboardDeleteErr) done(dashboardDeleteErr); - - // Set assertions - (dashboardDeleteRes.body._id).should.equal(dashboardSaveRes.body._id); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to delete Dashboard instance if not signed in', function(done) { - // Set Dashboard user - dashboard.user = user; - - // Create new Dashboard model instance - var dashboardObj = new Dashboard(dashboard); - - // Save the Dashboard - dashboardObj.save(function() { - // Try deleting Dashboard - request(app).delete('/dashboards/' + dashboardObj._id) - .expect(401) - .end(function(dashboardDeleteErr, dashboardDeleteRes) { - // Set message assertion - (dashboardDeleteRes.body.message).should.match('User is not logged in'); - - // Handle Dashboard error error - done(dashboardDeleteErr); - }); - - }); - }); - - afterEach(function(done) { - User.remove().exec(); - Dashboard.remove().exec(); - done(); - }); +describe('Dashboard CRUD tests', function () { + beforeEach(function (done) { + // Create user credentials + credentials = { + username: 'username', + password: 'password' + }; + // Create a new user + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: credentials.username, + password: credentials.password, + provider: 'local' + }); + // Save a user to the test db and create new Dashboard + user.save(function () { + dashboard = { name: 'Dashboard Name' }; + done(); + }); + }); + it('should be able to save Dashboard instance if logged in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Dashboard + agent.post('/dashboards').send(dashboard).expect(200).end(function (dashboardSaveErr, dashboardSaveRes) { + // Handle Dashboard save error + if (dashboardSaveErr) + done(dashboardSaveErr); + // Get a list of Dashboards + agent.get('/dashboards').end(function (dashboardsGetErr, dashboardsGetRes) { + // Handle Dashboard save error + if (dashboardsGetErr) + done(dashboardsGetErr); + // Get Dashboards list + var dashboards = dashboardsGetRes.body; + // Set assertions + dashboards[0].user._id.should.equal(userId); + dashboards[0].name.should.match('Dashboard Name'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to save Dashboard instance if not logged in', function (done) { + agent.post('/dashboards').send(dashboard).expect(401).end(function (dashboardSaveErr, dashboardSaveRes) { + // Call the assertion callback + done(dashboardSaveErr); + }); + }); + it('should not be able to save Dashboard instance if no name is provided', function (done) { + // Invalidate name field + dashboard.name = ''; + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Dashboard + agent.post('/dashboards').send(dashboard).expect(400).end(function (dashboardSaveErr, dashboardSaveRes) { + // Set message assertion + dashboardSaveRes.body.message.should.match('Please fill Dashboard name'); + // Handle Dashboard save error + done(dashboardSaveErr); + }); + }); + }); + it('should be able to update Dashboard instance if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Dashboard + agent.post('/dashboards').send(dashboard).expect(200).end(function (dashboardSaveErr, dashboardSaveRes) { + // Handle Dashboard save error + if (dashboardSaveErr) + done(dashboardSaveErr); + // Update Dashboard name + dashboard.name = 'WHY YOU GOTTA BE SO MEAN?'; + // Update existing Dashboard + agent.put('/dashboards/' + dashboardSaveRes.body._id).send(dashboard).expect(200).end(function (dashboardUpdateErr, dashboardUpdateRes) { + // Handle Dashboard update error + if (dashboardUpdateErr) + done(dashboardUpdateErr); + // Set assertions + dashboardUpdateRes.body._id.should.equal(dashboardSaveRes.body._id); + dashboardUpdateRes.body.name.should.match('WHY YOU GOTTA BE SO MEAN?'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should be able to get a list of Dashboards if not signed in', function (done) { + // Create new Dashboard model instance + var dashboardObj = new Dashboard(dashboard); + // Save the Dashboard + dashboardObj.save(function () { + // Request Dashboards + request(app).get('/dashboards').end(function (req, res) { + // Set assertion + res.body.should.be.an.Array.with.lengthOf(1); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to get a single Dashboard if not signed in', function (done) { + // Create new Dashboard model instance + var dashboardObj = new Dashboard(dashboard); + // Save the Dashboard + dashboardObj.save(function () { + request(app).get('/dashboards/' + dashboardObj._id).end(function (req, res) { + // Set assertion + res.body.should.be.an.Object.with.property('name', dashboard.name); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to delete Dashboard instance if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Dashboard + agent.post('/dashboards').send(dashboard).expect(200).end(function (dashboardSaveErr, dashboardSaveRes) { + // Handle Dashboard save error + if (dashboardSaveErr) + done(dashboardSaveErr); + // Delete existing Dashboard + agent.delete('/dashboards/' + dashboardSaveRes.body._id).send(dashboard).expect(200).end(function (dashboardDeleteErr, dashboardDeleteRes) { + // Handle Dashboard error error + if (dashboardDeleteErr) + done(dashboardDeleteErr); + // Set assertions + dashboardDeleteRes.body._id.should.equal(dashboardSaveRes.body._id); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to delete Dashboard instance if not signed in', function (done) { + // Set Dashboard user + dashboard.user = user; + // Create new Dashboard model instance + var dashboardObj = new Dashboard(dashboard); + // Save the Dashboard + dashboardObj.save(function () { + // Try deleting Dashboard + request(app).delete('/dashboards/' + dashboardObj._id).expect(401).end(function (dashboardDeleteErr, dashboardDeleteRes) { + // Set message assertion + dashboardDeleteRes.body.message.should.match('User is not logged in'); + // Handle Dashboard error error + done(dashboardDeleteErr); + }); + }); + }); + afterEach(function (done) { + User.remove().exec(); + Dashboard.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/event.server.model.test.js b/app/tests/event.server.model.test.js index f220e7f..d319339 100644 --- a/app/tests/event.server.model.test.js +++ b/app/tests/event.server.model.test.js @@ -1,64 +1,51 @@ 'use strict'; - /** * Module dependencies. */ -var should = require('should'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Event = mongoose.model('Event'); - +var should = require('should'), mongoose = require('mongoose'), User = mongoose.model('User'), Event = mongoose.model('Event'); /** * Globals */ var user, event; - /** * Unit tests */ -describe('Event Model Unit Tests:', function() { - beforeEach(function(done) { - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password' - }); - - user.save(function() { - event = new Event({ - name: 'Event Name', - user: user - }); - - done(); - }); - }); - - describe('Method Save', function() { - it('should be able to save without problems', function(done) { - return event.save(function(err) { - should.not.exist(err); - done(); - }); - }); - - it('should be able to show an error when try to save without name', function(done) { - event.name = ''; - - return event.save(function(err) { - should.exist(err); - done(); - }); - }); - }); - - afterEach(function(done) { - Event.remove().exec(); - User.remove().exec(); - - done(); - }); +describe('Event Model Unit Tests:', function () { + beforeEach(function (done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password' + }); + user.save(function () { + event = new Event({ + name: 'Event Name', + user: user + }); + done(); + }); + }); + describe('Method Save', function () { + it('should be able to save without problems', function (done) { + return event.save(function (err) { + should.not.exist(err); + done(); + }); + }); + it('should be able to show an error when try to save without name', function (done) { + event.name = ''; + return event.save(function (err) { + should.exist(err); + done(); + }); + }); + }); + afterEach(function (done) { + Event.remove().exec(); + User.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/event.server.routes.test.js b/app/tests/event.server.routes.test.js index 5db26fa..f748e16 100644 --- a/app/tests/event.server.routes.test.js +++ b/app/tests/event.server.routes.test.js @@ -1,268 +1,186 @@ 'use strict'; - -var should = require('should'), - request = require('supertest'), - app = require('../../server'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Event = mongoose.model('Event'), - agent = request.agent(app); - +var should = require('should'), request = require('supertest'), app = require('../../server'), mongoose = require('mongoose'), User = mongoose.model('User'), Event = mongoose.model('Event'), agent = request.agent(app); /** * Globals */ var credentials, user, event; - /** * Event routes tests */ -describe('Event CRUD tests', function() { - beforeEach(function(done) { - // Create user credentials - credentials = { - username: 'username', - password: 'password' - }; - - // Create a new user - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: credentials.username, - password: credentials.password, - provider: 'local' - }); - - // Save a user to the test db and create new Event - user.save(function() { - event = { - name: 'Event Name' - }; - - done(); - }); - }); - - it('should be able to save Event instance if logged in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Event - agent.post('/events') - .send(event) - .expect(200) - .end(function(eventSaveErr, eventSaveRes) { - // Handle Event save error - if (eventSaveErr) done(eventSaveErr); - - // Get a list of Events - agent.get('/events') - .end(function(eventsGetErr, eventsGetRes) { - // Handle Event save error - if (eventsGetErr) done(eventsGetErr); - - // Get Events list - var events = eventsGetRes.body; - - // Set assertions - (events[0].user._id).should.equal(userId); - (events[0].name).should.match('Event Name'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to save Event instance if not logged in', function(done) { - agent.post('/events') - .send(event) - .expect(401) - .end(function(eventSaveErr, eventSaveRes) { - // Call the assertion callback - done(eventSaveErr); - }); - }); - - it('should not be able to save Event instance if no name is provided', function(done) { - // Invalidate name field - event.name = ''; - - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Event - agent.post('/events') - .send(event) - .expect(400) - .end(function(eventSaveErr, eventSaveRes) { - // Set message assertion - (eventSaveRes.body.message).should.match('Please fill Event name'); - - // Handle Event save error - done(eventSaveErr); - }); - }); - }); - - it('should be able to update Event instance if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Event - agent.post('/events') - .send(event) - .expect(200) - .end(function(eventSaveErr, eventSaveRes) { - // Handle Event save error - if (eventSaveErr) done(eventSaveErr); - - // Update Event name - event.name = 'WHY YOU GOTTA BE SO MEAN?'; - - // Update existing Event - agent.put('/events/' + eventSaveRes.body._id) - .send(event) - .expect(200) - .end(function(eventUpdateErr, eventUpdateRes) { - // Handle Event update error - if (eventUpdateErr) done(eventUpdateErr); - - // Set assertions - (eventUpdateRes.body._id).should.equal(eventSaveRes.body._id); - (eventUpdateRes.body.name).should.match('WHY YOU GOTTA BE SO MEAN?'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should be able to get a list of Events if not signed in', function(done) { - // Create new Event model instance - var eventObj = new Event(event); - - // Save the Event - eventObj.save(function() { - // Request Events - request(app).get('/events') - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Array.with.lengthOf(1); - - // Call the assertion callback - done(); - }); - - }); - }); - - - it('should be able to get a single Event if not signed in', function(done) { - // Create new Event model instance - var eventObj = new Event(event); - - // Save the Event - eventObj.save(function() { - request(app).get('/events/' + eventObj._id) - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Object.with.property('name', event.name); - - // Call the assertion callback - done(); - }); - }); - }); - - it('should be able to delete Event instance if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Event - agent.post('/events') - .send(event) - .expect(200) - .end(function(eventSaveErr, eventSaveRes) { - // Handle Event save error - if (eventSaveErr) done(eventSaveErr); - - // Delete existing Event - agent.delete('/events/' + eventSaveRes.body._id) - .send(event) - .expect(200) - .end(function(eventDeleteErr, eventDeleteRes) { - // Handle Event error error - if (eventDeleteErr) done(eventDeleteErr); - - // Set assertions - (eventDeleteRes.body._id).should.equal(eventSaveRes.body._id); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to delete Event instance if not signed in', function(done) { - // Set Event user - event.user = user; - - // Create new Event model instance - var eventObj = new Event(event); - - // Save the Event - eventObj.save(function() { - // Try deleting Event - request(app).delete('/events/' + eventObj._id) - .expect(401) - .end(function(eventDeleteErr, eventDeleteRes) { - // Set message assertion - (eventDeleteRes.body.message).should.match('User is not logged in'); - - // Handle Event error error - done(eventDeleteErr); - }); - - }); - }); - - afterEach(function(done) { - User.remove().exec(); - Event.remove().exec(); - done(); - }); +describe('Event CRUD tests', function () { + beforeEach(function (done) { + // Create user credentials + credentials = { + username: 'username', + password: 'password' + }; + // Create a new user + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: credentials.username, + password: credentials.password, + provider: 'local' + }); + // Save a user to the test db and create new Event + user.save(function () { + event = { name: 'Event Name' }; + done(); + }); + }); + it('should be able to save Event instance if logged in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Event + agent.post('/events').send(event).expect(200).end(function (eventSaveErr, eventSaveRes) { + // Handle Event save error + if (eventSaveErr) + done(eventSaveErr); + // Get a list of Events + agent.get('/events').end(function (eventsGetErr, eventsGetRes) { + // Handle Event save error + if (eventsGetErr) + done(eventsGetErr); + // Get Events list + var events = eventsGetRes.body; + // Set assertions + events[0].user._id.should.equal(userId); + events[0].name.should.match('Event Name'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to save Event instance if not logged in', function (done) { + agent.post('/events').send(event).expect(401).end(function (eventSaveErr, eventSaveRes) { + // Call the assertion callback + done(eventSaveErr); + }); + }); + it('should not be able to save Event instance if no name is provided', function (done) { + // Invalidate name field + event.name = ''; + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Event + agent.post('/events').send(event).expect(400).end(function (eventSaveErr, eventSaveRes) { + // Set message assertion + eventSaveRes.body.message.should.match('Please fill Event name'); + // Handle Event save error + done(eventSaveErr); + }); + }); + }); + it('should be able to update Event instance if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Event + agent.post('/events').send(event).expect(200).end(function (eventSaveErr, eventSaveRes) { + // Handle Event save error + if (eventSaveErr) + done(eventSaveErr); + // Update Event name + event.name = 'WHY YOU GOTTA BE SO MEAN?'; + // Update existing Event + agent.put('/events/' + eventSaveRes.body._id).send(event).expect(200).end(function (eventUpdateErr, eventUpdateRes) { + // Handle Event update error + if (eventUpdateErr) + done(eventUpdateErr); + // Set assertions + eventUpdateRes.body._id.should.equal(eventSaveRes.body._id); + eventUpdateRes.body.name.should.match('WHY YOU GOTTA BE SO MEAN?'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should be able to get a list of Events if not signed in', function (done) { + // Create new Event model instance + var eventObj = new Event(event); + // Save the Event + eventObj.save(function () { + // Request Events + request(app).get('/events').end(function (req, res) { + // Set assertion + res.body.should.be.an.Array.with.lengthOf(1); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to get a single Event if not signed in', function (done) { + // Create new Event model instance + var eventObj = new Event(event); + // Save the Event + eventObj.save(function () { + request(app).get('/events/' + eventObj._id).end(function (req, res) { + // Set assertion + res.body.should.be.an.Object.with.property('name', event.name); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to delete Event instance if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Event + agent.post('/events').send(event).expect(200).end(function (eventSaveErr, eventSaveRes) { + // Handle Event save error + if (eventSaveErr) + done(eventSaveErr); + // Delete existing Event + agent.delete('/events/' + eventSaveRes.body._id).send(event).expect(200).end(function (eventDeleteErr, eventDeleteRes) { + // Handle Event error error + if (eventDeleteErr) + done(eventDeleteErr); + // Set assertions + eventDeleteRes.body._id.should.equal(eventSaveRes.body._id); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to delete Event instance if not signed in', function (done) { + // Set Event user + event.user = user; + // Create new Event model instance + var eventObj = new Event(event); + // Save the Event + eventObj.save(function () { + // Try deleting Event + request(app).delete('/events/' + eventObj._id).expect(401).end(function (eventDeleteErr, eventDeleteRes) { + // Set message assertion + eventDeleteRes.body.message.should.match('User is not logged in'); + // Handle Event error error + done(eventDeleteErr); + }); + }); + }); + afterEach(function (done) { + User.remove().exec(); + Event.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/metric.server.model.test.js b/app/tests/metric.server.model.test.js index 4c75f15..96e69a2 100644 --- a/app/tests/metric.server.model.test.js +++ b/app/tests/metric.server.model.test.js @@ -1,64 +1,51 @@ 'use strict'; - /** * Module dependencies. */ -var should = require('should'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Metric = mongoose.model('Metric'); - +var should = require('should'), mongoose = require('mongoose'), User = mongoose.model('User'), Metric = mongoose.model('Metric'); /** * Globals */ var user, metric; - /** * Unit tests */ -describe('Metric Model Unit Tests:', function() { - beforeEach(function(done) { - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password' - }); - - user.save(function() { - metric = new Metric({ - name: 'Metric Name', - user: user - }); - - done(); - }); - }); - - describe('Method Save', function() { - it('should be able to save without problems', function(done) { - return metric.save(function(err) { - should.not.exist(err); - done(); - }); - }); - - it('should be able to show an error when try to save without name', function(done) { - metric.name = ''; - - return metric.save(function(err) { - should.exist(err); - done(); - }); - }); - }); - - afterEach(function(done) { - Metric.remove().exec(); - User.remove().exec(); - - done(); - }); +describe('Metric Model Unit Tests:', function () { + beforeEach(function (done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password' + }); + user.save(function () { + metric = new Metric({ + name: 'Metric Name', + user: user + }); + done(); + }); + }); + describe('Method Save', function () { + it('should be able to save without problems', function (done) { + return metric.save(function (err) { + should.not.exist(err); + done(); + }); + }); + it('should be able to show an error when try to save without name', function (done) { + metric.name = ''; + return metric.save(function (err) { + should.exist(err); + done(); + }); + }); + }); + afterEach(function (done) { + Metric.remove().exec(); + User.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/metric.server.routes.test.js b/app/tests/metric.server.routes.test.js index 7133a48..6d7a72b 100644 --- a/app/tests/metric.server.routes.test.js +++ b/app/tests/metric.server.routes.test.js @@ -1,268 +1,186 @@ 'use strict'; - -var should = require('should'), - request = require('supertest'), - app = require('../../server'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Metric = mongoose.model('Metric'), - agent = request.agent(app); - +var should = require('should'), request = require('supertest'), app = require('../../server'), mongoose = require('mongoose'), User = mongoose.model('User'), Metric = mongoose.model('Metric'), agent = request.agent(app); /** * Globals */ var credentials, user, metric; - /** * Metric routes tests */ -describe('Metric CRUD tests', function() { - beforeEach(function(done) { - // Create user credentials - credentials = { - username: 'username', - password: 'password' - }; - - // Create a new user - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: credentials.username, - password: credentials.password, - provider: 'local' - }); - - // Save a user to the test db and create new Metric - user.save(function() { - metric = { - name: 'Metric Name' - }; - - done(); - }); - }); - - it('should be able to save Metric instance if logged in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Metric - agent.post('/metrics') - .send(metric) - .expect(200) - .end(function(metricSaveErr, metricSaveRes) { - // Handle Metric save error - if (metricSaveErr) done(metricSaveErr); - - // Get a list of Metrics - agent.get('/metrics') - .end(function(metricsGetErr, metricsGetRes) { - // Handle Metric save error - if (metricsGetErr) done(metricsGetErr); - - // Get Metrics list - var metrics = metricsGetRes.body; - - // Set assertions - (metrics[0].user._id).should.equal(userId); - (metrics[0].name).should.match('Metric Name'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to save Metric instance if not logged in', function(done) { - agent.post('/metrics') - .send(metric) - .expect(401) - .end(function(metricSaveErr, metricSaveRes) { - // Call the assertion callback - done(metricSaveErr); - }); - }); - - it('should not be able to save Metric instance if no name is provided', function(done) { - // Invalidate name field - metric.name = ''; - - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Metric - agent.post('/metrics') - .send(metric) - .expect(400) - .end(function(metricSaveErr, metricSaveRes) { - // Set message assertion - (metricSaveRes.body.message).should.match('Please fill Metric name'); - - // Handle Metric save error - done(metricSaveErr); - }); - }); - }); - - it('should be able to update Metric instance if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Metric - agent.post('/metrics') - .send(metric) - .expect(200) - .end(function(metricSaveErr, metricSaveRes) { - // Handle Metric save error - if (metricSaveErr) done(metricSaveErr); - - // Update Metric name - metric.name = 'WHY YOU GOTTA BE SO MEAN?'; - - // Update existing Metric - agent.put('/metrics/' + metricSaveRes.body._id) - .send(metric) - .expect(200) - .end(function(metricUpdateErr, metricUpdateRes) { - // Handle Metric update error - if (metricUpdateErr) done(metricUpdateErr); - - // Set assertions - (metricUpdateRes.body._id).should.equal(metricSaveRes.body._id); - (metricUpdateRes.body.name).should.match('WHY YOU GOTTA BE SO MEAN?'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should be able to get a list of Metrics if not signed in', function(done) { - // Create new Metric model instance - var metricObj = new Metric(metric); - - // Save the Metric - metricObj.save(function() { - // Request Metrics - request(app).get('/metrics') - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Array.with.lengthOf(1); - - // Call the assertion callback - done(); - }); - - }); - }); - - - it('should be able to get a single Metric if not signed in', function(done) { - // Create new Metric model instance - var metricObj = new Metric(metric); - - // Save the Metric - metricObj.save(function() { - request(app).get('/metrics/' + metricObj._id) - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Object.with.property('name', metric.name); - - // Call the assertion callback - done(); - }); - }); - }); - - it('should be able to delete Metric instance if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Metric - agent.post('/metrics') - .send(metric) - .expect(200) - .end(function(metricSaveErr, metricSaveRes) { - // Handle Metric save error - if (metricSaveErr) done(metricSaveErr); - - // Delete existing Metric - agent.delete('/metrics/' + metricSaveRes.body._id) - .send(metric) - .expect(200) - .end(function(metricDeleteErr, metricDeleteRes) { - // Handle Metric error error - if (metricDeleteErr) done(metricDeleteErr); - - // Set assertions - (metricDeleteRes.body._id).should.equal(metricSaveRes.body._id); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to delete Metric instance if not signed in', function(done) { - // Set Metric user - metric.user = user; - - // Create new Metric model instance - var metricObj = new Metric(metric); - - // Save the Metric - metricObj.save(function() { - // Try deleting Metric - request(app).delete('/metrics/' + metricObj._id) - .expect(401) - .end(function(metricDeleteErr, metricDeleteRes) { - // Set message assertion - (metricDeleteRes.body.message).should.match('User is not logged in'); - - // Handle Metric error error - done(metricDeleteErr); - }); - - }); - }); - - afterEach(function(done) { - User.remove().exec(); - Metric.remove().exec(); - done(); - }); +describe('Metric CRUD tests', function () { + beforeEach(function (done) { + // Create user credentials + credentials = { + username: 'username', + password: 'password' + }; + // Create a new user + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: credentials.username, + password: credentials.password, + provider: 'local' + }); + // Save a user to the test db and create new Metric + user.save(function () { + metric = { name: 'Metric Name' }; + done(); + }); + }); + it('should be able to save Metric instance if logged in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Metric + agent.post('/metrics').send(metric).expect(200).end(function (metricSaveErr, metricSaveRes) { + // Handle Metric save error + if (metricSaveErr) + done(metricSaveErr); + // Get a list of Metrics + agent.get('/metrics').end(function (metricsGetErr, metricsGetRes) { + // Handle Metric save error + if (metricsGetErr) + done(metricsGetErr); + // Get Metrics list + var metrics = metricsGetRes.body; + // Set assertions + metrics[0].user._id.should.equal(userId); + metrics[0].name.should.match('Metric Name'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to save Metric instance if not logged in', function (done) { + agent.post('/metrics').send(metric).expect(401).end(function (metricSaveErr, metricSaveRes) { + // Call the assertion callback + done(metricSaveErr); + }); + }); + it('should not be able to save Metric instance if no name is provided', function (done) { + // Invalidate name field + metric.name = ''; + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Metric + agent.post('/metrics').send(metric).expect(400).end(function (metricSaveErr, metricSaveRes) { + // Set message assertion + metricSaveRes.body.message.should.match('Please fill Metric name'); + // Handle Metric save error + done(metricSaveErr); + }); + }); + }); + it('should be able to update Metric instance if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Metric + agent.post('/metrics').send(metric).expect(200).end(function (metricSaveErr, metricSaveRes) { + // Handle Metric save error + if (metricSaveErr) + done(metricSaveErr); + // Update Metric name + metric.name = 'WHY YOU GOTTA BE SO MEAN?'; + // Update existing Metric + agent.put('/metrics/' + metricSaveRes.body._id).send(metric).expect(200).end(function (metricUpdateErr, metricUpdateRes) { + // Handle Metric update error + if (metricUpdateErr) + done(metricUpdateErr); + // Set assertions + metricUpdateRes.body._id.should.equal(metricSaveRes.body._id); + metricUpdateRes.body.name.should.match('WHY YOU GOTTA BE SO MEAN?'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should be able to get a list of Metrics if not signed in', function (done) { + // Create new Metric model instance + var metricObj = new Metric(metric); + // Save the Metric + metricObj.save(function () { + // Request Metrics + request(app).get('/metrics').end(function (req, res) { + // Set assertion + res.body.should.be.an.Array.with.lengthOf(1); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to get a single Metric if not signed in', function (done) { + // Create new Metric model instance + var metricObj = new Metric(metric); + // Save the Metric + metricObj.save(function () { + request(app).get('/metrics/' + metricObj._id).end(function (req, res) { + // Set assertion + res.body.should.be.an.Object.with.property('name', metric.name); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to delete Metric instance if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Metric + agent.post('/metrics').send(metric).expect(200).end(function (metricSaveErr, metricSaveRes) { + // Handle Metric save error + if (metricSaveErr) + done(metricSaveErr); + // Delete existing Metric + agent.delete('/metrics/' + metricSaveRes.body._id).send(metric).expect(200).end(function (metricDeleteErr, metricDeleteRes) { + // Handle Metric error error + if (metricDeleteErr) + done(metricDeleteErr); + // Set assertions + metricDeleteRes.body._id.should.equal(metricSaveRes.body._id); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to delete Metric instance if not signed in', function (done) { + // Set Metric user + metric.user = user; + // Create new Metric model instance + var metricObj = new Metric(metric); + // Save the Metric + metricObj.save(function () { + // Try deleting Metric + request(app).delete('/metrics/' + metricObj._id).expect(401).end(function (metricDeleteErr, metricDeleteRes) { + // Set message assertion + metricDeleteRes.body.message.should.match('User is not logged in'); + // Handle Metric error error + done(metricDeleteErr); + }); + }); + }); + afterEach(function (done) { + User.remove().exec(); + Metric.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/product.server.model.test.js b/app/tests/product.server.model.test.js index 248fdc7..e0afdc3 100644 --- a/app/tests/product.server.model.test.js +++ b/app/tests/product.server.model.test.js @@ -1,64 +1,51 @@ 'use strict'; - /** * Module dependencies. */ -var should = require('should'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Product = mongoose.model('Product'); - +var should = require('should'), mongoose = require('mongoose'), User = mongoose.model('User'), Product = mongoose.model('Product'); /** * Globals */ var user, product; - /** * Unit tests */ -describe('Product Model Unit Tests:', function() { - beforeEach(function(done) { - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password' - }); - - user.save(function() { - product = new Product({ - name: 'Product Name', - user: user - }); - - done(); - }); - }); - - describe('Method Save', function() { - it('should be able to save without problems', function(done) { - return product.save(function(err) { - should.not.exist(err); - done(); - }); - }); - - it('should be able to show an error when try to save without name', function(done) { - product.name = ''; - - return product.save(function(err) { - should.exist(err); - done(); - }); - }); - }); - - afterEach(function(done) { - Product.remove().exec(); - User.remove().exec(); - - done(); - }); +describe('Product Model Unit Tests:', function () { + beforeEach(function (done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password' + }); + user.save(function () { + product = new Product({ + name: 'Product Name', + user: user + }); + done(); + }); + }); + describe('Method Save', function () { + it('should be able to save without problems', function (done) { + return product.save(function (err) { + should.not.exist(err); + done(); + }); + }); + it('should be able to show an error when try to save without name', function (done) { + product.name = ''; + return product.save(function (err) { + should.exist(err); + done(); + }); + }); + }); + afterEach(function (done) { + Product.remove().exec(); + User.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/product.server.routes.test.js b/app/tests/product.server.routes.test.js index 3c6c5c8..11f6a6f 100644 --- a/app/tests/product.server.routes.test.js +++ b/app/tests/product.server.routes.test.js @@ -1,268 +1,186 @@ 'use strict'; - -var should = require('should'), - request = require('supertest'), - app = require('../../server'), - mongoose = require('mongoose'), - User = mongoose.model('User'), - Product = mongoose.model('Product'), - agent = request.agent(app); - +var should = require('should'), request = require('supertest'), app = require('../../server'), mongoose = require('mongoose'), User = mongoose.model('User'), Product = mongoose.model('Product'), agent = request.agent(app); /** * Globals */ var credentials, user, product; - /** * Product routes tests */ -describe('Product CRUD tests', function() { - beforeEach(function(done) { - // Create user credentials - credentials = { - username: 'username', - password: 'password' - }; - - // Create a new user - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: credentials.username, - password: credentials.password, - provider: 'local' - }); - - // Save a user to the test db and create new Product - user.save(function() { - product = { - name: 'Product Name' - }; - - done(); - }); - }); - - it('should be able to save Product instance if logged in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Product - agent.post('/products') - .send(product) - .expect(200) - .end(function(productSaveErr, productSaveRes) { - // Handle Product save error - if (productSaveErr) done(productSaveErr); - - // Get a list of Products - agent.get('/products') - .end(function(productsGetErr, productsGetRes) { - // Handle Product save error - if (productsGetErr) done(productsGetErr); - - // Get Products list - var products = productsGetRes.body; - - // Set assertions - (products[0].user._id).should.equal(userId); - (products[0].name).should.match('Product Name'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to save Product instance if not logged in', function(done) { - agent.post('/products') - .send(product) - .expect(401) - .end(function(productSaveErr, productSaveRes) { - // Call the assertion callback - done(productSaveErr); - }); - }); - - it('should not be able to save Product instance if no name is provided', function(done) { - // Invalidate name field - product.name = ''; - - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Product - agent.post('/products') - .send(product) - .expect(400) - .end(function(productSaveErr, productSaveRes) { - // Set message assertion - (productSaveRes.body.message).should.match('Please fill Product name'); - - // Handle Product save error - done(productSaveErr); - }); - }); - }); - - it('should be able to update Product instance if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Product - agent.post('/products') - .send(product) - .expect(200) - .end(function(productSaveErr, productSaveRes) { - // Handle Product save error - if (productSaveErr) done(productSaveErr); - - // Update Product name - product.name = 'WHY YOU GOTTA BE SO MEAN?'; - - // Update existing Product - agent.put('/products/' + productSaveRes.body._id) - .send(product) - .expect(200) - .end(function(productUpdateErr, productUpdateRes) { - // Handle Product update error - if (productUpdateErr) done(productUpdateErr); - - // Set assertions - (productUpdateRes.body._id).should.equal(productSaveRes.body._id); - (productUpdateRes.body.name).should.match('WHY YOU GOTTA BE SO MEAN?'); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should be able to get a list of Products if not signed in', function(done) { - // Create new Product model instance - var productObj = new Product(product); - - // Save the Product - productObj.save(function() { - // Request Products - request(app).get('/products') - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Array.with.lengthOf(1); - - // Call the assertion callback - done(); - }); - - }); - }); - - - it('should be able to get a single Product if not signed in', function(done) { - // Create new Product model instance - var productObj = new Product(product); - - // Save the Product - productObj.save(function() { - request(app).get('/products/' + productObj._id) - .end(function(req, res) { - // Set assertion - res.body.should.be.an.Object.with.property('name', product.name); - - // Call the assertion callback - done(); - }); - }); - }); - - it('should be able to delete Product instance if signed in', function(done) { - agent.post('/auth/signin') - .send(credentials) - .expect(200) - .end(function(signinErr, signinRes) { - // Handle signin error - if (signinErr) done(signinErr); - - // Get the userId - var userId = user.id; - - // Save a new Product - agent.post('/products') - .send(product) - .expect(200) - .end(function(productSaveErr, productSaveRes) { - // Handle Product save error - if (productSaveErr) done(productSaveErr); - - // Delete existing Product - agent.delete('/products/' + productSaveRes.body._id) - .send(product) - .expect(200) - .end(function(productDeleteErr, productDeleteRes) { - // Handle Product error error - if (productDeleteErr) done(productDeleteErr); - - // Set assertions - (productDeleteRes.body._id).should.equal(productSaveRes.body._id); - - // Call the assertion callback - done(); - }); - }); - }); - }); - - it('should not be able to delete Product instance if not signed in', function(done) { - // Set Product user - product.user = user; - - // Create new Product model instance - var productObj = new Product(product); - - // Save the Product - productObj.save(function() { - // Try deleting Product - request(app).delete('/products/' + productObj._id) - .expect(401) - .end(function(productDeleteErr, productDeleteRes) { - // Set message assertion - (productDeleteRes.body.message).should.match('User is not logged in'); - - // Handle Product error error - done(productDeleteErr); - }); - - }); - }); - - afterEach(function(done) { - User.remove().exec(); - Product.remove().exec(); - done(); - }); +describe('Product CRUD tests', function () { + beforeEach(function (done) { + // Create user credentials + credentials = { + username: 'username', + password: 'password' + }; + // Create a new user + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: credentials.username, + password: credentials.password, + provider: 'local' + }); + // Save a user to the test db and create new Product + user.save(function () { + product = { name: 'Product Name' }; + done(); + }); + }); + it('should be able to save Product instance if logged in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Product + agent.post('/products').send(product).expect(200).end(function (productSaveErr, productSaveRes) { + // Handle Product save error + if (productSaveErr) + done(productSaveErr); + // Get a list of Products + agent.get('/products').end(function (productsGetErr, productsGetRes) { + // Handle Product save error + if (productsGetErr) + done(productsGetErr); + // Get Products list + var products = productsGetRes.body; + // Set assertions + products[0].user._id.should.equal(userId); + products[0].name.should.match('Product Name'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to save Product instance if not logged in', function (done) { + agent.post('/products').send(product).expect(401).end(function (productSaveErr, productSaveRes) { + // Call the assertion callback + done(productSaveErr); + }); + }); + it('should not be able to save Product instance if no name is provided', function (done) { + // Invalidate name field + product.name = ''; + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Product + agent.post('/products').send(product).expect(400).end(function (productSaveErr, productSaveRes) { + // Set message assertion + productSaveRes.body.message.should.match('Please fill Product name'); + // Handle Product save error + done(productSaveErr); + }); + }); + }); + it('should be able to update Product instance if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Product + agent.post('/products').send(product).expect(200).end(function (productSaveErr, productSaveRes) { + // Handle Product save error + if (productSaveErr) + done(productSaveErr); + // Update Product name + product.name = 'WHY YOU GOTTA BE SO MEAN?'; + // Update existing Product + agent.put('/products/' + productSaveRes.body._id).send(product).expect(200).end(function (productUpdateErr, productUpdateRes) { + // Handle Product update error + if (productUpdateErr) + done(productUpdateErr); + // Set assertions + productUpdateRes.body._id.should.equal(productSaveRes.body._id); + productUpdateRes.body.name.should.match('WHY YOU GOTTA BE SO MEAN?'); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should be able to get a list of Products if not signed in', function (done) { + // Create new Product model instance + var productObj = new Product(product); + // Save the Product + productObj.save(function () { + // Request Products + request(app).get('/products').end(function (req, res) { + // Set assertion + res.body.should.be.an.Array.with.lengthOf(1); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to get a single Product if not signed in', function (done) { + // Create new Product model instance + var productObj = new Product(product); + // Save the Product + productObj.save(function () { + request(app).get('/products/' + productObj._id).end(function (req, res) { + // Set assertion + res.body.should.be.an.Object.with.property('name', product.name); + // Call the assertion callback + done(); + }); + }); + }); + it('should be able to delete Product instance if signed in', function (done) { + agent.post('/auth/signin').send(credentials).expect(200).end(function (signinErr, signinRes) { + // Handle signin error + if (signinErr) + done(signinErr); + // Get the userId + var userId = user.id; + // Save a new Product + agent.post('/products').send(product).expect(200).end(function (productSaveErr, productSaveRes) { + // Handle Product save error + if (productSaveErr) + done(productSaveErr); + // Delete existing Product + agent.delete('/products/' + productSaveRes.body._id).send(product).expect(200).end(function (productDeleteErr, productDeleteRes) { + // Handle Product error error + if (productDeleteErr) + done(productDeleteErr); + // Set assertions + productDeleteRes.body._id.should.equal(productSaveRes.body._id); + // Call the assertion callback + done(); + }); + }); + }); + }); + it('should not be able to delete Product instance if not signed in', function (done) { + // Set Product user + product.user = user; + // Create new Product model instance + var productObj = new Product(product); + // Save the Product + productObj.save(function () { + // Try deleting Product + request(app).delete('/products/' + productObj._id).expect(401).end(function (productDeleteErr, productDeleteRes) { + // Set message assertion + productDeleteRes.body.message.should.match('User is not logged in'); + // Handle Product error error + done(productDeleteErr); + }); + }); + }); + afterEach(function (done) { + User.remove().exec(); + Product.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/app/tests/user.server.model.test.js b/app/tests/user.server.model.test.js index 7369d41..751ee0f 100644 --- a/app/tests/user.server.model.test.js +++ b/app/tests/user.server.model.test.js @@ -1,75 +1,64 @@ 'use strict'; - /** * Module dependencies. */ -var should = require('should'), - mongoose = require('mongoose'), - User = mongoose.model('User'); - +var should = require('should'), mongoose = require('mongoose'), User = mongoose.model('User'); /** * Globals */ var user, user2; - /** * Unit tests */ -describe('User Model Unit Tests:', function() { - before(function(done) { - user = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password', - provider: 'local' - }); - user2 = new User({ - firstName: 'Full', - lastName: 'Name', - displayName: 'Full Name', - email: 'test@test.com', - username: 'username', - password: 'password', - provider: 'local' - }); - - done(); - }); - - describe('Method Save', function() { - it('should begin with no users', function(done) { - User.find({}, function(err, users) { - users.should.have.length(0); - done(); - }); - }); - - it('should be able to save without problems', function(done) { - user.save(done); - }); - - it('should fail to save an existing user again', function(done) { - user.save(); - return user2.save(function(err) { - should.exist(err); - done(); - }); - }); - - it('should be able to show an error when try to save without first name', function(done) { - user.firstName = ''; - return user.save(function(err) { - should.exist(err); - done(); - }); - }); - }); - - after(function(done) { - User.remove().exec(); - done(); - }); +describe('User Model Unit Tests:', function () { + before(function (done) { + user = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password', + provider: 'local' + }); + user2 = new User({ + firstName: 'Full', + lastName: 'Name', + displayName: 'Full Name', + email: 'test@test.com', + username: 'username', + password: 'password', + provider: 'local' + }); + done(); + }); + describe('Method Save', function () { + it('should begin with no users', function (done) { + User.find({}, function (err, users) { + users.should.have.length(0); + done(); + }); + }); + it('should be able to save without problems', function (done) { + user.save(done); + }); + it('should fail to save an existing user again', function (done) { + user.save(); + return user2.save(function (err) { + should.exist(err); + done(); + }); + }); + it('should be able to show an error when try to save without first name', function (done) { + user.firstName = ''; + return user.save(function (err) { + should.exist(err); + done(); + }); + }); + }); + after(function (done) { + User.remove().exec(); + done(); + }); }); \ No newline at end of file diff --git a/package.json b/package.json index 729fcde..ec943b7 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,8 @@ "connect-mongo": "~0.4.1", "consolidate": "~0.10.0", "cookie-parser": "~1.3.2", - "express": "~4.10.1", - "express-session": "~1.9.1", + "express": "^4.13.1", + "express-session": "^1.11.3", "forever": "~0.11.0", "glob": "~4.0.5", "grunt-cli": "~0.1.13", diff --git a/public/images/assets/ic_check_black_36px.svg b/public/images/assets/ic_check_black_36px.svg new file mode 100644 index 0000000..0465e0e --- /dev/null +++ b/public/images/assets/ic_check_black_36px.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/images/assets/ic_link_black_36px.svg b/public/images/assets/ic_link_black_36px.svg new file mode 100644 index 0000000..6256157 --- /dev/null +++ b/public/images/assets/ic_link_black_36px.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/images/assets/ic_refresh_black_36px.svg b/public/images/assets/ic_refresh_black_36px.svg new file mode 100644 index 0000000..8830228 --- /dev/null +++ b/public/images/assets/ic_refresh_black_36px.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/public/modules/core/config/core.client.routes.js b/public/modules/core/config/core.client.routes.js index 5c5da88..74199db 100644 --- a/public/modules/core/config/core.client.routes.js +++ b/public/modules/core/config/core.client.routes.js @@ -1,17 +1,15 @@ 'use strict'; - // Setting up route -angular.module('core',['dashboards']).config(['$stateProvider', '$urlRouterProvider', - function($stateProvider, $urlRouterProvider) { - // Redirect to home view when route not found - $urlRouterProvider.otherwise('/'); - - // Home state routing - $stateProvider. - - state('home', { - url: '/', - templateUrl: 'modules/core/views/home.client.view.html' - }); - } -]); +angular.module('core', ['dashboards']).config([ + '$stateProvider', + '$urlRouterProvider', + function ($stateProvider, $urlRouterProvider) { + // Redirect to home view when route not found + $urlRouterProvider.otherwise('/'); + // Home state routing + $stateProvider.state('home', { + url: '/', + templateUrl: 'modules/core/views/home.client.view.html' + }); + } +]); \ No newline at end of file diff --git a/public/modules/core/controllers/delete-modal.client.controller.js b/public/modules/core/controllers/delete-modal.client.controller.js index a3c4e0f..e00e673 100644 --- a/public/modules/core/controllers/delete-modal.client.controller.js +++ b/public/modules/core/controllers/delete-modal.client.controller.js @@ -1,19 +1,17 @@ 'use strict'; - -angular.module('core').controller('ModalInstanceController', ['$scope', '$modalInstance','ConfirmModal', - function($scope, $modalInstance, ConfirmModal) { - - $scope.itemType = ConfirmModal.itemType; - $scope.selectedItemId = ConfirmModal.selectedItemId; - $scope.selectedItemDescription = ConfirmModal.selectedItemDescription; - - $scope.ok = function () { - $modalInstance.close($scope.selectedItemId); - }; - - $scope.cancel = function () { - $modalInstance.dismiss('cancel'); - }; - - } -]); +angular.module('core').controller('ModalInstanceController', [ + '$scope', + '$modalInstance', + 'ConfirmModal', + function ($scope, $modalInstance, ConfirmModal) { + $scope.itemType = ConfirmModal.itemType; + $scope.selectedItemId = ConfirmModal.selectedItemId; + $scope.selectedItemDescription = ConfirmModal.selectedItemDescription; + $scope.ok = function () { + $modalInstance.close($scope.selectedItemId); + }; + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + } +]); \ No newline at end of file diff --git a/public/modules/core/controllers/header.client.controller.js b/public/modules/core/controllers/header.client.controller.js index 29df9b5..037ff8a 100644 --- a/public/modules/core/controllers/header.client.controller.js +++ b/public/modules/core/controllers/header.client.controller.js @@ -1,36 +1,34 @@ 'use strict'; - -angular.module('core').controller('HeaderController', ['$scope', 'Authentication', 'Menus', '$location','$http','$window', - function($scope, Authentication, Menus, $location, $http, $window) { - $scope.authentication = Authentication; - $scope.isCollapsed = false; - $scope.menu = Menus.getMenu('topbar'); - - $scope.toggleCollapsibleMenu = function() { - $scope.isCollapsed = !$scope.isCollapsed; - }; - - - // Collapsing the menu after navigation - $scope.$on('$stateChangeSuccess', function() { - $scope.isCollapsed = false; - }); - - $scope.go = function ( path ) { - $location.path( path ); - }; - - $scope.backup = function(){ - - var url = 'http://' + $window.location.host + '/download'; - // $log.log(url); - $window.location.href = url; - }; - var originatorEv; - $scope.openMenu = function($mdOpenMenu, ev) { - originatorEv = ev; - $mdOpenMenu(ev); - }; - - } -]); +angular.module('core').controller('HeaderController', [ + '$scope', + 'Authentication', + 'Menus', + '$location', + '$http', + '$window', + function ($scope, Authentication, Menus, $location, $http, $window) { + $scope.authentication = Authentication; + $scope.isCollapsed = false; + $scope.menu = Menus.getMenu('topbar'); + $scope.toggleCollapsibleMenu = function () { + $scope.isCollapsed = !$scope.isCollapsed; + }; + // Collapsing the menu after navigation + $scope.$on('$stateChangeSuccess', function () { + $scope.isCollapsed = false; + }); + $scope.go = function (path) { + $location.path(path); + }; + $scope.backup = function () { + var url = 'http://' + $window.location.host + '/download'; + // $log.log(url); + $window.location.href = url; + }; + var originatorEv; + $scope.openMenu = function ($mdOpenMenu, ev) { + originatorEv = ev; + $mdOpenMenu(ev); + }; + } +]); \ No newline at end of file diff --git a/public/modules/core/controllers/home.client.controller.js b/public/modules/core/controllers/home.client.controller.js index 63d0f29..c18bebd 100644 --- a/public/modules/core/controllers/home.client.controller.js +++ b/public/modules/core/controllers/home.client.controller.js @@ -1,9 +1,9 @@ 'use strict'; - - -angular.module('core').controller('HomeController', ['$scope', 'Authentication', - function($scope, Authentication) { - // This provides Authentication context. - $scope.authentication = Authentication; - } +angular.module('core').controller('HomeController', [ + '$scope', + 'Authentication', + function ($scope, Authentication) { + // This provides Authentication context. + $scope.authentication = Authentication; + } ]); \ No newline at end of file diff --git a/public/modules/core/controllers/sidebar.client.controller.js b/public/modules/core/controllers/sidebar.client.controller.js index 67939c2..d8f7531 100644 --- a/public/modules/core/controllers/sidebar.client.controller.js +++ b/public/modules/core/controllers/sidebar.client.controller.js @@ -1,79 +1,62 @@ 'use strict'; - -angular.module('core').controller('SidebarController', ['$scope', '$stateParams', '$state', '$location', 'Products', 'SideMenu', - function($scope, $stateParams, $state, $location, Products, SideMenu) { - - - function isOpen(section) { - var regex = new RegExp('.*\/' + section.matcher + '(\/|$)'); - var open = regex.test($location.path()); - if(SideMenu.openedSection) - return SideMenu.isSectionSelected(section); - else - return open; - } - - function toggleOpen(section) { - SideMenu.toggleSelectSection(section); - } - - var vm = this; - - //functions for menu-link and menu-toggle - vm.isOpen = isOpen; - vm.toggleOpen = toggleOpen; - vm.autoFocusContent = false; - vm.menu = SideMenu; - - vm.status = { - isFirstOpen: true, - isFirstDisabled: false - }; - - - - - $scope.clearProductFilter = function(){ - - SideMenu.productFilter = ''; - }; - - - Products.fetch().success(function(products){ - SideMenu.addProducts(products); - - }); - - - $scope.$watch(function(scope) { return Products.items; }, - function() { - - $scope.products = Products.items; - SideMenu.addProducts(Products.items); - } - ); - - $scope.$watch(function(scope) { return SideMenu.productFilter; }, - function() { - - $scope.productFilter = SideMenu.productFilter; - - } - ); - - // $scope.productIsActive = function(productName) { - // return $location.path().indexOf(productName)!== -1; - // }; - // - // $scope.dashboardIsActive = function(dashboardName) { - // if ($location.path().indexOf(dashboardName)!== -1) return 'dashboard-selected'; - // }; - // - // $scope.viewProduct = function(index, productName){ - // - // Products.selected = $scope.products[index]; - // $state.go('viewProduct', {productName: productName}); - // } - // - } -]); +angular.module('core').controller('SidebarController', [ + '$scope', + '$stateParams', + '$state', + '$location', + 'Products', + 'SideMenu', + function ($scope, $stateParams, $state, $location, Products, SideMenu) { + function isOpen(section) { + var regex = new RegExp('.*/' + section.matcher + '(/|$)'); + var open = regex.test($location.path()); + if (SideMenu.openedSection) + return SideMenu.isSectionSelected(section); + else + return open; + } + function toggleOpen(section) { + SideMenu.toggleSelectSection(section); + } + var vm = this; + //functions for menu-link and menu-toggle + vm.isOpen = isOpen; + vm.toggleOpen = toggleOpen; + vm.autoFocusContent = false; + vm.menu = SideMenu; + vm.status = { + isFirstOpen: true, + isFirstDisabled: false + }; + $scope.clearProductFilter = function () { + SideMenu.productFilter = ''; + }; + Products.fetch().success(function (products) { + SideMenu.addProducts(products); + }); + $scope.$watch(function (scope) { + return Products.items; + }, function () { + $scope.products = Products.items; + SideMenu.addProducts(Products.items); + }); + $scope.$watch(function (scope) { + return SideMenu.productFilter; + }, function () { + $scope.productFilter = SideMenu.productFilter; + }); // $scope.productIsActive = function(productName) { + // return $location.path().indexOf(productName)!== -1; + // }; + // + // $scope.dashboardIsActive = function(dashboardName) { + // if ($location.path().indexOf(dashboardName)!== -1) return 'dashboard-selected'; + // }; + // + // $scope.viewProduct = function(index, productName){ + // + // Products.selected = $scope.products[index]; + // $state.go('viewProduct', {productName: productName}); + // } + // + } +]); \ No newline at end of file diff --git a/public/modules/core/controllers/upload.client.controller.js b/public/modules/core/controllers/upload.client.controller.js index d802d00..28c2009 100644 --- a/public/modules/core/controllers/upload.client.controller.js +++ b/public/modules/core/controllers/upload.client.controller.js @@ -1,22 +1,20 @@ 'use strict'; - - -angular.module('core').controller('UploadController', ['$scope', 'Authentication','Upload','Products', 'SideMenu', - function($scope, Authentication, Upload, Products, SideMenu) { - - $scope.uploadFile = function (uploadUrl) { - var file = $scope.myFile; - console.log('file is '); - console.dir(file); - Upload.uploadFileToUrl(file, uploadUrl).then(function(){ - - Products.fetch().success(function(products){ - SideMenu.addProducts(products); - - }); - - - }); - }; - } -]); +angular.module('core').controller('UploadController', [ + '$scope', + 'Authentication', + 'Upload', + 'Products', + 'SideMenu', + function ($scope, Authentication, Upload, Products, SideMenu) { + $scope.uploadFile = function (uploadUrl) { + var file = $scope.myFile; + console.log('file is '); + console.dir(file); + Upload.uploadFileToUrl(file, uploadUrl).then(function () { + Products.fetch().success(function (products) { + SideMenu.addProducts(products); + }); + }); + }; + } +]); \ No newline at end of file diff --git a/public/modules/core/core.client.module.js b/public/modules/core/core.client.module.js index 0edda04..e672fca 100644 --- a/public/modules/core/core.client.module.js +++ b/public/modules/core/core.client.module.js @@ -1,4 +1,3 @@ 'use strict'; - // Use Applicaion configuration module to register a new module ApplicationConfiguration.registerModule('core'); \ No newline at end of file diff --git a/public/modules/core/css/core.css b/public/modules/core/css/core.css index c510891..f3c3c16 100644 --- a/public/modules/core/css/core.css +++ b/public/modules/core/css/core.css @@ -1,15 +1,19 @@ .content { - margin-top: 50px; + margin-top: 50px; } + .undecorated-link:hover { - text-decoration: none; + text-decoration: none; } + [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { - display: none !important; + display: none !important; } + .ng-invalid.ng-dirty { - border-color: #FA787E; + border-color: #FA787E; } + .ng-valid.ng-dirty { - border-color: #78FA89; -} \ No newline at end of file + border-color: #78FA89; +} diff --git a/public/modules/core/directives/check-if-exists.client.directive.js b/public/modules/core/directives/check-if-exists.client.directive.js index e6404a2..0968c50 100644 --- a/public/modules/core/directives/check-if-exists.client.directive.js +++ b/public/modules/core/directives/check-if-exists.client.directive.js @@ -1,63 +1,47 @@ -(function() { - 'use strict'; - - - - angular.module('core') - .directive('recordAvailabilityValidator', - ['$http','$filter', function($http, $filter) { - - - return { - require : 'ngModel', - link : function(scope, element, attrs, ngModel) { - var apiUrl = attrs.recordAvailabilityValidator ; - - scope.$watch('dashboard.name', function(val) { - scope.dashboard.name = $filter('uppercase')(val); - }, true); - - scope.$watch('product.name', function(val) { - scope.product.name = $filter('uppercase')(val); - }, true); - - scope.$watch('event.dashboardName', function(val) { - scope.event.dashboardName = $filter('uppercase')(val); - }, true); - - scope.$watch('event.productName', function(val) { - scope.event.productName = $filter('uppercase')(val); - }, true); - - - function setAsLoading(bool) { - ngModel.$setValidity('recordLoading', !bool); - } - - function setAsAvailable(bool) { - ngModel.$setValidity('recordAvailable', bool); - } - - ngModel.$parsers.push(function(value) { - if(!value || value.length === 0) return; - - setAsLoading(true); - setAsAvailable(false); - - $http.get(apiUrl + '/' + value, { v : value }) - .success(function() { - setAsLoading(false); - setAsAvailable(false); - }) - .error(function() { - setAsLoading(false); - setAsAvailable(true); - - }); - - return value; - }); - } - }; - }]); -}()); +(function () { + 'use strict'; + angular.module('core').directive('recordAvailabilityValidator', [ + '$http', + '$filter', + function ($http, $filter) { + return { + require: 'ngModel', + link: function (scope, element, attrs, ngModel) { + var apiUrl = attrs.recordAvailabilityValidator; + scope.$watch('dashboard.name', function (val) { + scope.dashboard.name = $filter('uppercase')(val); + }, true); + scope.$watch('product.name', function (val) { + scope.product.name = $filter('uppercase')(val); + }, true); + scope.$watch('event.dashboardName', function (val) { + scope.event.dashboardName = $filter('uppercase')(val); + }, true); + scope.$watch('event.productName', function (val) { + scope.event.productName = $filter('uppercase')(val); + }, true); + function setAsLoading(bool) { + ngModel.$setValidity('recordLoading', !bool); + } + function setAsAvailable(bool) { + ngModel.$setValidity('recordAvailable', bool); + } + ngModel.$parsers.push(function (value) { + if (!value || value.length === 0) + return; + setAsLoading(true); + setAsAvailable(false); + $http.get(apiUrl + '/' + value, { v: value }).success(function () { + setAsLoading(false); + setAsAvailable(false); + }).error(function () { + setAsLoading(false); + setAsAvailable(true); + }); + return value; + }); + } + }; + } + ]); +}()); \ No newline at end of file diff --git a/public/modules/core/directives/menu-link.client.directive.js b/public/modules/core/directives/menu-link.client.directive.js index 12e9cc8..6c0b09c 100644 --- a/public/modules/core/directives/menu-link.client.directive.js +++ b/public/modules/core/directives/menu-link.client.directive.js @@ -1,40 +1,30 @@ -(function(){ - 'use strict'; - - angular.module('core') - .run(['$templateCache', function ($templateCache) { - $templateCache.put('partials/menu-link.tmpl.html', - '\n' + - ' {{section.name}}\n' + - ' \n' + - ' current page\n' + - ' \n' + - '\n' + - ''); - }]) - .directive('menuLink', ['$location', function ($location ) { - return { - scope: { - section: '=' - }, - templateUrl: 'partials/menu-link.tmpl.html', - link: function ($scope, $element) { - var controller = $element.parent().controller(); - - $scope.isActive = function (viewLocation) { - var regex = new RegExp('.*\/' + viewLocation + '(\/|$)'); - var active = regex.test($location.path()); - return active; - }; - - $scope.focusSection = function () { - // set flag to be used later when - // $locationChangeSuccess calls openPage() - controller.autoFocusContent = true; - }; - } - }; - }]); -})(); +(function () { + 'use strict'; + angular.module('core').run([ + '$templateCache', + function ($templateCache) { + $templateCache.put('partials/menu-link.tmpl.html', '\n' + ' {{section.name}}\n' + ' \n' + ' current page\n' + ' \n' + '\n' + ''); + } + ]).directive('menuLink', [ + '$location', + function ($location) { + return { + scope: { section: '=' }, + templateUrl: 'partials/menu-link.tmpl.html', + link: function ($scope, $element) { + var controller = $element.parent().controller(); + $scope.isActive = function (viewLocation) { + var regex = new RegExp('.*/' + viewLocation + '(/|$)'); + var active = regex.test($location.path()); + return active; + }; + $scope.focusSection = function () { + // set flag to be used later when + // $locationChangeSuccess calls openPage() + controller.autoFocusContent = true; + }; + } + }; + } + ]); +}()); \ No newline at end of file diff --git a/public/modules/core/directives/menu-toggle.client.directive.js b/public/modules/core/directives/menu-toggle.client.directive.js index d1f2df9..ef7c4af 100644 --- a/public/modules/core/directives/menu-toggle.client.directive.js +++ b/public/modules/core/directives/menu-toggle.client.directive.js @@ -1,49 +1,31 @@ -(function() { - 'use strict'; - - - - angular.module('core') - .run(['$templateCache', function ($templateCache) { - $templateCache.put('partials/menu-toggle.tmpl.html', - '\n' + - ' {{section.name}}\n' + - ' \n' + - '\n' + - '\n' + - ''); - }]) - .directive('menuToggle', ['$timeout', function ($timeout ) { - return { - scope: { - section: '=' - }, - templateUrl: 'partials/menu-toggle.tmpl.html', - link: function (scope, element) { - var controller = element.parent().controller(); - - scope.isOpen = function () { - return controller.isOpen(scope.section); - }; - scope.toggle = function () { - controller.toggleOpen(scope.section); - }; - - var parentNode = element[0].parentNode.parentNode.parentNode; - if (parentNode.classList.contains('parent-list-item')) { - var heading = parentNode.querySelector('h2'); - element[0].firstChild.setAttribute('aria-describedby', heading.id); - } - } - }; - }]); -}()); +(function () { + 'use strict'; + angular.module('core').run([ + '$templateCache', + function ($templateCache) { + $templateCache.put('partials/menu-toggle.tmpl.html', '\n' + ' {{section.name}}\n' + ' \n' + '\n' + '\n' + ''); + } + ]).directive('menuToggle', [ + '$timeout', + function ($timeout) { + return { + scope: { section: '=' }, + templateUrl: 'partials/menu-toggle.tmpl.html', + link: function (scope, element) { + var controller = element.parent().controller(); + scope.isOpen = function () { + return controller.isOpen(scope.section); + }; + scope.toggle = function () { + controller.toggleOpen(scope.section); + }; + var parentNode = element[0].parentNode.parentNode.parentNode; + if (parentNode.classList.contains('parent-list-item')) { + var heading = parentNode.querySelector('h2'); + element[0].firstChild.setAttribute('aria-describedby', heading.id); + } + } + }; + } + ]); +}()); \ No newline at end of file diff --git a/public/modules/core/services/menus.client.service.js b/public/modules/core/services/menus.client.service.js index e348c4a..d5446c6 100644 --- a/public/modules/core/services/menus.client.service.js +++ b/public/modules/core/services/menus.client.service.js @@ -1,140 +1,138 @@ 'use strict'; //Menu service used for managing menus -angular.module('core').service('Menus', [ - function() { -// Define a set of default roles - this.defaultRoles = ['*']; -// Define the menus object - this.menus = {}; -// A private function for rendering decision - var shouldRender = function(user) { - if (user) { - if (!!~this.roles.indexOf('*')) { - return true; - } else { - for (var userRoleIndex in user.roles) { - for (var roleIndex in this.roles) { - if (this.roles[roleIndex] === user.roles[userRoleIndex]) { - return true; - } - } - } - } - } else { - return this.isPublic; - } - return false; - }; -// Validate menu existance - this.validateMenuExistance = function(menuId) { - if (menuId && menuId.length) { - if (this.menus[menuId]) { - return true; - } else { - throw new Error('Menu does not exists'); - } - } else { - throw new Error('MenuId was not provided'); - } - return false; - }; -// Get the menu object by menu id - this.getMenu = function(menuId) { -// Validate that the menu exists - this.validateMenuExistance(menuId); -// Return the menu object - return this.menus[menuId]; - }; -// Add new menu object by menu id - this.addMenu = function(menuId, isPublic, roles) { -// Create the new menu - this.menus[menuId] = { - isPublic: isPublic || false, - roles: roles || this.defaultRoles, - items: [], - shouldRender: shouldRender - }; -// Return the menu object - return this.menus[menuId]; - }; -// Remove existing menu object by menu id - this.removeMenu = function(menuId) { -// Validate that the menu exists - this.validateMenuExistance(menuId); -// Return the menu object - delete this.menus[menuId]; - }; -// Add menu item object - this.addMenuItem = function(menuId, menuItemTitle, menuItemURL, menuItemType, menuItemUIRoute, isPublic, roles, position) { -// Validate that the menu exists - this.validateMenuExistance(menuId); -// Push new menu item - this.menus[menuId].items.push({ - title: menuItemTitle, - link: menuItemURL, - menuItemType: menuItemType || 'item', - menuItemClass: menuItemType, - uiRoute: menuItemUIRoute || ('/' + menuItemURL), - isPublic: ((isPublic === null || typeof isPublic === 'undefined') ? this.menus[menuId].isPublic : isPublic), - roles: ((roles === null || typeof roles === 'undefined') ? this.menus[menuId].roles : roles), - position: position || 0, - items: [], - shouldRender: shouldRender - }); -// Return the menu object - return this.menus[menuId]; - }; -// Add submenu item object - this.addSubMenuItem = function(menuId, rootMenuItemURL, menuItemTitle, menuItemURL, menuItemUIRoute, isPublic, roles, position) { -// Validate that the menu exists - this.validateMenuExistance(menuId); -// Search for menu item - for (var itemIndex in this.menus[menuId].items) { - if (this.menus[menuId].items[itemIndex].link === rootMenuItemURL) { -// Push new submenu item - this.menus[menuId].items[itemIndex].items.push({ - title: menuItemTitle, - link: menuItemURL, - uiRoute: menuItemUIRoute || ('/' + menuItemURL), - isPublic: ((isPublic === null || typeof isPublic === 'undefined') ? this.menus[menuId].items[itemIndex].isPublic : isPublic), - roles: ((roles === null || typeof roles === 'undefined') ? this.menus[menuId].items[itemIndex].roles : roles), - position: position || 0, - shouldRender: shouldRender - }); - } - } -// Return the menu object - return this.menus[menuId]; - }; -// Remove existing menu object by menu id - this.removeMenuItem = function(menuId, menuItemURL) { -// Validate that the menu exists - this.validateMenuExistance(menuId); -// Search for menu item to remove - for (var itemIndex in this.menus[menuId].items) { - if (this.menus[menuId].items[itemIndex].link === menuItemURL) { - this.menus[menuId].items.splice(itemIndex, 1); - } - } -// Return the menu object - return this.menus[menuId]; - }; -// Remove existing menu object by menu id - this.removeSubMenuItem = function(menuId, submenuItemURL) { -// Validate that the menu exists - this.validateMenuExistance(menuId); -// Search for menu item to remove - for (var itemIndex in this.menus[menuId].items) { - for (var subitemIndex in this.menus[menuId].items[itemIndex].items) { - if (this.menus[menuId].items[itemIndex].items[subitemIndex].link === submenuItemURL) { - this.menus[menuId].items[itemIndex].items.splice(subitemIndex, 1); - } - } - } -// Return the menu object - return this.menus[menuId]; - }; -//Adding the topbar menu - this.addMenu('topbar'); - } -]); +angular.module('core').service('Menus', [function () { + // Define a set of default roles + this.defaultRoles = ['*']; + // Define the menus object + this.menus = {}; + // A private function for rendering decision + var shouldRender = function (user) { + if (user) { + if (!!~this.roles.indexOf('*')) { + return true; + } else { + for (var userRoleIndex in user.roles) { + for (var roleIndex in this.roles) { + if (this.roles[roleIndex] === user.roles[userRoleIndex]) { + return true; + } + } + } + } + } else { + return this.isPublic; + } + return false; + }; + // Validate menu existance + this.validateMenuExistance = function (menuId) { + if (menuId && menuId.length) { + if (this.menus[menuId]) { + return true; + } else { + throw new Error('Menu does not exists'); + } + } else { + throw new Error('MenuId was not provided'); + } + return false; + }; + // Get the menu object by menu id + this.getMenu = function (menuId) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + // Return the menu object + return this.menus[menuId]; + }; + // Add new menu object by menu id + this.addMenu = function (menuId, isPublic, roles) { + // Create the new menu + this.menus[menuId] = { + isPublic: isPublic || false, + roles: roles || this.defaultRoles, + items: [], + shouldRender: shouldRender + }; + // Return the menu object + return this.menus[menuId]; + }; + // Remove existing menu object by menu id + this.removeMenu = function (menuId) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + // Return the menu object + delete this.menus[menuId]; + }; + // Add menu item object + this.addMenuItem = function (menuId, menuItemTitle, menuItemURL, menuItemType, menuItemUIRoute, isPublic, roles, position) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + // Push new menu item + this.menus[menuId].items.push({ + title: menuItemTitle, + link: menuItemURL, + menuItemType: menuItemType || 'item', + menuItemClass: menuItemType, + uiRoute: menuItemUIRoute || '/' + menuItemURL, + isPublic: isPublic === null || typeof isPublic === 'undefined' ? this.menus[menuId].isPublic : isPublic, + roles: roles === null || typeof roles === 'undefined' ? this.menus[menuId].roles : roles, + position: position || 0, + items: [], + shouldRender: shouldRender + }); + // Return the menu object + return this.menus[menuId]; + }; + // Add submenu item object + this.addSubMenuItem = function (menuId, rootMenuItemURL, menuItemTitle, menuItemURL, menuItemUIRoute, isPublic, roles, position) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + // Search for menu item + for (var itemIndex in this.menus[menuId].items) { + if (this.menus[menuId].items[itemIndex].link === rootMenuItemURL) { + // Push new submenu item + this.menus[menuId].items[itemIndex].items.push({ + title: menuItemTitle, + link: menuItemURL, + uiRoute: menuItemUIRoute || '/' + menuItemURL, + isPublic: isPublic === null || typeof isPublic === 'undefined' ? this.menus[menuId].items[itemIndex].isPublic : isPublic, + roles: roles === null || typeof roles === 'undefined' ? this.menus[menuId].items[itemIndex].roles : roles, + position: position || 0, + shouldRender: shouldRender + }); + } + } + // Return the menu object + return this.menus[menuId]; + }; + // Remove existing menu object by menu id + this.removeMenuItem = function (menuId, menuItemURL) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + // Search for menu item to remove + for (var itemIndex in this.menus[menuId].items) { + if (this.menus[menuId].items[itemIndex].link === menuItemURL) { + this.menus[menuId].items.splice(itemIndex, 1); + } + } + // Return the menu object + return this.menus[menuId]; + }; + // Remove existing menu object by menu id + this.removeSubMenuItem = function (menuId, submenuItemURL) { + // Validate that the menu exists + this.validateMenuExistance(menuId); + // Search for menu item to remove + for (var itemIndex in this.menus[menuId].items) { + for (var subitemIndex in this.menus[menuId].items[itemIndex].items) { + if (this.menus[menuId].items[itemIndex].items[subitemIndex].link === submenuItemURL) { + this.menus[menuId].items[itemIndex].items.splice(subitemIndex, 1); + } + } + } + // Return the menu object + return this.menus[menuId]; + }; + //Adding the topbar menu + this.addMenu('topbar'); + }]); \ No newline at end of file diff --git a/public/modules/core/services/modal.client.service.js b/public/modules/core/services/modal.client.service.js index 6e315c0..b99b08e 100644 --- a/public/modules/core/services/modal.client.service.js +++ b/public/modules/core/services/modal.client.service.js @@ -1,14 +1,9 @@ 'use strict'; - -angular.module('core').factory('ConfirmModal', [ - function() { - - var ConfirmModal = { - itemType: '', - selectedItemId: '', - selectedItemDescription: '' - }; - - return ConfirmModal; - } -]); +angular.module('core').factory('ConfirmModal', [function () { + var ConfirmModal = { + itemType: '', + selectedItemId: '', + selectedItemDescription: '' + }; + return ConfirmModal; + }]); \ No newline at end of file diff --git a/public/modules/core/services/side-menu.client.service.js b/public/modules/core/services/side-menu.client.service.js index 35f7c88..c5fabf6 100644 --- a/public/modules/core/services/side-menu.client.service.js +++ b/public/modules/core/services/side-menu.client.service.js @@ -1,103 +1,65 @@ - -(function(){ - - 'use strict'; - - angular.module('core') - .factory('SideMenu', [ - '$location', - '$rootScope', - '$state', - function ($location, $state) { - - - function toggleSelectSection (section) { - SideMenu.openedSection = (SideMenu.openedSection === section ? null : section); - } - - function selectPage(section, page) { - page && page.url && $location.path(page.url); - SideMenu.currentSection = section; - SideMenu.currentPage = page; - } - - function isSectionSelected (section) { - return SideMenu.openedSection === section; - - } - - function sortByHumanName(a, b) { - return (a.humanName < b.humanName) ? -1 : - (a.humanName > b.humanName) ? 1 : 0; - } - - - function addProducts(products){ - - var url ; - var pages = []; - SideMenu.sections = []; - - //SideMenu.sections.push({ - // name: 'Add product', - // type: 'link', - // url: 'add/product', - // icon: 'glyphicon glyphicon-plus', - // matcher: 'add/product' - // - //}) - - _.each(products, function(product){ - - _.each(product.dashboards, function(dashboard){ - - url = 'browse/' + product.name + '/' + dashboard.name ; - pages.push({ - name: dashboard.name, - type: 'link', - url: url, - matcher: product.name + '/' + dashboard.name - }); - - - - }); - - pages.push({ - name: 'Add dashboard', - type: 'link', - url: 'add/dashboard/' + product.name, - icon: 'glyphicon glyphicon-plus', - matcher: 'add/dashboard/' + product.name - }); - - SideMenu.sections.push( - { - name: product.name, - type: 'toggle', - pages: pages, - matcher: product.name - } - ); - /* reset pages*/ - pages = []; - }); - } - - - var SideMenu = { - sections: [], - toggleSelectSection: toggleSelectSection, - isSectionSelected: isSectionSelected , - selectPage: selectPage, - addProducts: addProducts, - productFilter: '' - }; - - return SideMenu; - - - - }]); - -})(); +(function () { + 'use strict'; + angular.module('core').factory('SideMenu', [ + '$location', + '$rootScope', + '$state', + function ($location, $state) { + function toggleSelectSection(section) { + SideMenu.openedSection = SideMenu.openedSection === section ? null : section; + } + //function selectPage(section, page) { + // page && page.url && $location.path(page.url); + // SideMenu.currentSection = section; + // SideMenu.currentPage = page; + //} + function isSectionSelected(section) { + return SideMenu.openedSection === section; + } + function sortByHumanName(a, b) { + return a.humanName < b.humanName ? -1 : a.humanName > b.humanName ? 1 : 0; + } + function addProducts(products) { + var url; + var pages = []; + SideMenu.sections = []; + + _.each(products, function (product) { + _.each(product.dashboards, function (dashboard) { + url = 'browse/' + product.name + '/' + dashboard.name; + pages.push({ + name: dashboard.name, + type: 'link', + url: url, + matcher: product.name + '/' + dashboard.name + }); + }); + pages.push({ + name: 'Add dashboard', + type: 'link', + url: 'add/dashboard/' + product.name, + icon: 'glyphicon glyphicon-plus', + matcher: 'add/dashboard/' + product.name + }); + SideMenu.sections.push({ + name: product.name, + type: 'toggle', + pages: pages, + matcher: product.name + }); + /* reset pages*/ + pages = []; + }); + } + var SideMenu = { + sections: [], + toggleSelectSection: toggleSelectSection, + isSectionSelected: isSectionSelected, + //selectPage: selectPage, + addProducts: addProducts, + productFilter: '' + }; + return SideMenu; + } + ]); +}()); diff --git a/public/modules/core/tests/header.client.controller.test.js b/public/modules/core/tests/header.client.controller.test.js index 76ee4fb..af333cd 100644 --- a/public/modules/core/tests/header.client.controller.test.js +++ b/public/modules/core/tests/header.client.controller.test.js @@ -1,24 +1,16 @@ 'use strict'; - -(function() { - describe('HeaderController', function() { - //Initialize global variables - var scope, - HeaderController; - - // Load the main application module - beforeEach(module(ApplicationConfiguration.applicationModuleName)); - - beforeEach(inject(function($controller, $rootScope) { - scope = $rootScope.$new(); - - HeaderController = $controller('HeaderController', { - $scope: scope - }); - })); - - it('should expose the authentication service', function() { - expect(scope.authentication).toBeTruthy(); - }); - }); -})(); \ No newline at end of file +(function () { + describe('HeaderController', function () { + //Initialize global variables + var scope, HeaderController; + // Load the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); + beforeEach(inject(function ($controller, $rootScope) { + scope = $rootScope.$new(); + HeaderController = $controller('HeaderController', { $scope: scope }); + })); + it('should expose the authentication service', function () { + expect(scope.authentication).toBeTruthy(); + }); + }); +}()); \ No newline at end of file diff --git a/public/modules/core/tests/home.client.controller.test.js b/public/modules/core/tests/home.client.controller.test.js index a5b1a56..7f9419d 100644 --- a/public/modules/core/tests/home.client.controller.test.js +++ b/public/modules/core/tests/home.client.controller.test.js @@ -1,24 +1,16 @@ 'use strict'; - -(function() { - describe('HomeController', function() { - //Initialize global variables - var scope, - HomeController; - - // Load the main application module - beforeEach(module(ApplicationConfiguration.applicationModuleName)); - - beforeEach(inject(function($controller, $rootScope) { - scope = $rootScope.$new(); - - HomeController = $controller('HomeController', { - $scope: scope - }); - })); - - it('should expose the authentication service', function() { - expect(scope.authentication).toBeTruthy(); - }); - }); -})(); \ No newline at end of file +(function () { + describe('HomeController', function () { + //Initialize global variables + var scope, HomeController; + // Load the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); + beforeEach(inject(function ($controller, $rootScope) { + scope = $rootScope.$new(); + HomeController = $controller('HomeController', { $scope: scope }); + })); + it('should expose the authentication service', function () { + expect(scope.authentication).toBeTruthy(); + }); + }); +}()); \ No newline at end of file diff --git a/public/modules/core/views/header.client.view.html b/public/modules/core/views/header.client.view.html index c5f99d9..e68727c 100644 --- a/public/modules/core/views/header.client.view.html +++ b/public/modules/core/views/header.client.view.html @@ -6,8 +6,8 @@

TARGETS-IO

-
- +
+ @@ -31,62 +31,62 @@

-
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/modules/core/views/home.client.view.html b/public/modules/core/views/home.client.view.html index dbe2090..7001521 100644 --- a/public/modules/core/views/home.client.view.html +++ b/public/modules/core/views/home.client.view.html @@ -1,64 +1,67 @@
-
-
-
- TARGETS-IO -
-
-
+
+
+
+ TARGETS-IO +
+
+
-
-
-

Welcome to targets-io, the open source performance test dashboard!

-

-

To get started:

-
    -
  • - Configure your load test tool to send - metrics to your graphite instance -
  • -
  • - Configure your load test tool to send - start and end events and - to the dashboard api. -
  • -
  • - Send - SUT metrics to your graphite instance -
  • -
  • - Click - + Product - to add a new product. -
  • -
  • - Click - + Dashboard - to add a new dashboard. -
  • -
  • - Configure metrics in your - dashboard -
  • -
  • - Start hitting those targets! -
  • +
+
+

Welcome to targets-io, the open source performance test dashboard!

- -
-
-

targets-io Documentation

-

+

- -

-
+

To get started:

+
    +
  • + Configure your load test tool to send + metrics to your graphite instance +
  • +
  • + Configure your load test tool to send + start and end events and + to the dashboard api. +
  • +
  • + Send + SUT metrics to your graphite instance +
  • +
  • + Click + + Product + to add a new product. +
  • +
  • + Click + + Dashboard + to add a new dashboard. +
  • +
  • + Configure metrics in your + dashboard +
  • +
  • + Start hitting those targets! +
  • + +
+
+
+

targets-io Documentation

+ +

+ +

+

+
diff --git a/public/modules/core/views/sidebar.client.view.html b/public/modules/core/views/sidebar.client.view.html index e59c7d3..5677291 100644 --- a/public/modules/core/views/sidebar.client.view.html +++ b/public/modules/core/views/sidebar.client.view.html @@ -3,13 +3,15 @@
- + - +
Add product
- +
  • New Dashboard
    - + - -
    + + +
    Dashboard name is required.
    Checking database...
    The dashboard name already exists for this product
    - + -
    + +
    Dashboard description is required.
    @@ -26,12 +35,12 @@

    New Dashboard

    - Submit + Submit Cancel
    - - + +
    diff --git a/public/modules/dashboards/views/edit-dashboard.client.view.html b/public/modules/dashboards/views/edit-dashboard.client.view.html index ff42729..0e2384e 100644 --- a/public/modules/dashboards/views/edit-dashboard.client.view.html +++ b/public/modules/dashboards/views/edit-dashboard.client.view.html @@ -2,34 +2,44 @@ -
    + +
    -
    - - - -
    -
    Dashboard name is required.
    -
    Checking database...
    -
    The dashboard name already exists for this product
    -
    -
    - - - -
    -
    Dashboard description is required.
    -
    -
    - - Benchmark test runs for this dashboard - -
    -
    - Submit - Cancel - Delete dashboard -
    + + + + +
    +
    Dashboard name is required.
    +
    Checking database...
    +
    The dashboard name already exists for this product
    +
    +
    + + + + +
    +
    Dashboard description is required.
    +
    +
    + + Benchmark test runs for this dashboard +
    - +
    + Submit + + Cancel + Delete dashboard +
    +
    + diff --git a/public/modules/dashboards/views/list-dashboards.client.view.html b/public/modules/dashboards/views/list-dashboards.client.view.html index 3a292a7..a2cec0f 100644 --- a/public/modules/dashboards/views/list-dashboards.client.view.html +++ b/public/modules/dashboards/views/list-dashboards.client.view.html @@ -3,17 +3,18 @@

    Dashboards

    - No Dashboards yet, why don't you create one? + No Dashboards yet, why don't you create one?
    - \ No newline at end of file + diff --git a/public/modules/dashboards/views/manage-tags.client.view.html b/public/modules/dashboards/views/manage-tags.client.view.html index 55c788e..09f81c7 100644 --- a/public/modules/dashboards/views/manage-tags.client.view.html +++ b/public/modules/dashboards/views/manage-tags.client.view.html @@ -13,7 +13,8 @@ {{tag.text}} - + + diff --git a/public/modules/dashboards/views/view-dashboard-metrics.client.view.html b/public/modules/dashboards/views/view-dashboard-metrics.client.view.html index 4222f87..ed2f772 100644 --- a/public/modules/dashboards/views/view-dashboard-metrics.client.view.html +++ b/public/modules/dashboards/views/view-dashboard-metrics.client.view.html @@ -1,27 +1,32 @@
    - - - - - - - - - - - - - - - - - - +
    MetricTagRequirementAllowed deviation
    {{metric.alias}} - {{tag.text}}, - {{metric.requirementOperator}} {{metric.requirementValue}}{{metric.benchmarkOperator === '>'?'+':'-'}} {{metric.benchmarkValue}} -
    + + + + + + + + + + + + + + + + +
    MetricTagRequirementAllowed deviation
    + {{metric.alias}} + + {{tag.text}}, + {{metric.requirementOperator}} {{metric.requirementValue}}{{metric.benchmarkOperator === '>'?'+':'-'}} {{metric.benchmarkValue}} + + +
    diff --git a/public/modules/dashboards/views/view-dashboard.client.view.html b/public/modules/dashboards/views/view-dashboard.client.view.html index 72e1c38..e805750 100644 --- a/public/modules/dashboards/views/view-dashboard.client.view.html +++ b/public/modules/dashboards/views/view-dashboard.client.view.html @@ -5,6 +5,7 @@

    {{productName}}-{{dashboard.name}}

    +

    {{dashboard.description}}

    @@ -58,24 +59,24 @@

    {{dashboard.description}}

    -
    - - - - - Set baseline - - - - - - {{testRun.testRunId}} - - - - -
    + + + + + + + + + + + + + + + + + +
diff --git a/public/modules/events/config/events.client.config.js b/public/modules/events/config/events.client.config.js index 4e562ab..e8b8bdc 100644 --- a/public/modules/events/config/events.client.config.js +++ b/public/modules/events/config/events.client.config.js @@ -1,11 +1,11 @@ 'use strict'; - // Configuring the Articles module -angular.module('events').run(['Menus', - function(Menus) { - // Set top bar menu items - Menus.addMenuItem('topbar', 'Events', 'events', 'dropdown', '/events(/create)?'); - Menus.addSubMenuItem('topbar', 'events', 'List Events', 'events'); - Menus.addSubMenuItem('topbar', 'events', 'New Event', 'events/create'); - } +angular.module('events').run([ + 'Menus', + function (Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', 'Events', 'events', 'dropdown', '/events(/create)?'); + Menus.addSubMenuItem('topbar', 'events', 'List Events', 'events'); + Menus.addSubMenuItem('topbar', 'events', 'New Event', 'events/create'); + } ]); \ No newline at end of file diff --git a/public/modules/events/config/events.client.routes.js b/public/modules/events/config/events.client.routes.js index 8c34400..a0eb581 100644 --- a/public/modules/events/config/events.client.routes.js +++ b/public/modules/events/config/events.client.routes.js @@ -1,25 +1,21 @@ 'use strict'; - //Setting up route -angular.module('events').config(['$stateProvider', - function($stateProvider) { - // Events state routing - $stateProvider. - state('listEvents', { - url: '/events', - templateUrl: 'modules/events/views/list-events-dashboard.client.view.html' - }). - state('createEvent', { - url: '/create/event/:productName/:dashboardName', - templateUrl: 'modules/events/views/create-event.client.view.html' - }). - state('viewEvent', { - url: '/events/:eventId', - templateUrl: 'modules/events/views/view-event.client.view.html' - }). - state('editEvent', { - url: '/edit/event/:productName/:dashboardName/:eventId', - templateUrl: 'modules/events/views/edit-event.client.view.html' - }); - } -]); +angular.module('events').config([ + '$stateProvider', + function ($stateProvider) { + // Events state routing + $stateProvider.state('listEvents', { + url: '/events', + templateUrl: 'modules/events/views/list-events-dashboard.client.view.html' + }).state('createEvent', { + url: '/create/event/:productName/:dashboardName', + templateUrl: 'modules/events/views/create-event.client.view.html' + }).state('viewEvent', { + url: '/events/:eventId', + templateUrl: 'modules/events/views/view-event.client.view.html' + }).state('editEvent', { + url: '/edit/event/:productName/:dashboardName/:eventId', + templateUrl: 'modules/events/views/edit-event.client.view.html' + }); + } +]); \ No newline at end of file diff --git a/public/modules/events/controllers/events.client.controller.js b/public/modules/events/controllers/events.client.controller.js index cb5de67..fb4fcc8 100644 --- a/public/modules/events/controllers/events.client.controller.js +++ b/public/modules/events/controllers/events.client.controller.js @@ -1,188 +1,136 @@ 'use strict'; - // Events controller -angular.module('events').controller('EventsController', ['$scope', '$rootScope', '$stateParams', '$state', '$location', '$modal', 'Authentication', 'Events', 'Dashboards', - function($scope, $rootScope, $stateParams, $state, $location, $modal, Authentication, Events, Dashboards) { - - - - $scope.isOpen = false; - - $scope.openCalendar = function(e) { - e.preventDefault(); - e.stopPropagation(); - $scope.isOpen = true; - }; - - $scope.productName = $stateParams.productName; - - - $scope.event = Events.selected; - - - - $scope.initEventForm = function (){ - - - $scope.testRunIds = Events.getTestRunId(Events.list); - $scope.descriptions = Events.getDescriptions(Events.list); - - - //$scope.dateOptions = { - // startingDay: 1, - // showWeeks: false - //}; - }; - - // Open update event form - $scope.addEventForDashboard = function () { - - - $scope.event.eventTimestamp = new Date(); - $scope.event.productName = $stateParams.productName; - $scope.event.dashboardName = $stateParams.dashboardName; - $state.go('createEvent',{productName: $stateParams.productName, dashboardName: $stateParams.dashboardName}); - - }; - - // Create new Event - $scope.create = function () { - - Events.create($scope.event).then(function (event) { - Events.selected = {}; - //$state.go('viewDashboard', { - // "productName": $scope.event.productName, - // "dashboardName": $scope.event.dashboardName - //}); - - if ($rootScope.previousStateParams) - $state.go($rootScope.previousState, $rootScope.previousStateParams); - else - $state.go($rootScope.previousState); - - }, function (errorResponse) { - $scope.error = errorResponse.data.message; - $scope.eventForm['eventDescription'].$setValidity('server', false); - }); - - }; - - // Update Event - $scope.update = function () { - - Events.update(Events.selected).then(function (event) { - - Events.selected = {}; - - /* reset form*/ - $scope.eventForm.$setPristine(); - - /* return to previous state */ - if ($rootScope.previousStateParams) - $state.go($rootScope.previousState, $rootScope.previousStateParams); - else - $state.go($rootScope.previousState); - - - }, function (errorResponse) { - $scope.error = errorResponse.data.message; - $scope.eventForm['eventDescription'].$setValidity('server', false); - - }); - - }; - - $scope.cancel = function () { - - Events.selected = {}; - - /* reset form*/ - $scope.eventForm.$setPristine(); - - - if ($rootScope.previousStateParams) - $state.go($rootScope.previousState, $rootScope.previousStateParams); - else - $state.go($rootScope.previousState); - - - } - - - $scope.listEventsForDashboard = function () { - - Events.listEventsForDashboard($scope.productName, $scope.dashboardName).success(function (events) { - - Events.list = events; - $scope.events = events; - - }, function (errorResponse) { - $scope.error = errorResponse.data.message; - }); - - }; - - $scope.editEvent = function (index) { - - Events.selected = $scope.events[index]; - - $state.go('editEvent', { - "productName": $stateParams.productName, - "dashboardName": $stateParams.dashboardName, - "eventId": Events.selected._id - }); - - }; - - //// Find existing Event - //$scope.findOne = function () { - // $scope.event = Events.get({ - // eventId: $stateParams.eventId - // }); - //}; - - - $scope.open = function (size, index) { - - Events.selected = $scope.events[index]; - - var modalInstance = $modal.open({ - templateUrl: 'myModalContent.html', - controller: 'EventModalInstanceCtrl', - size: size - }); - - modalInstance.result.then(function (eventId) { - - Events.delete(eventId).success(function (event) { - - ///* refresh events*/ - Events.listEventsForDashboard($scope.productName, $scope.dashboardName).success(function (events) { - - $scope.events = events; - - }, function (errorResponse) { - $scope.error = errorResponse.data.message; - }); - }); - - }, function () { - //$log.info('Modal dismissed at: ' + new Date()); - }); - }; - - } -]).controller('EventModalInstanceCtrl',['$scope','$modalInstance', 'Events', function($scope, $modalInstance, Events) { - +angular.module('events').controller('EventsController', [ + '$scope', + '$rootScope', + '$stateParams', + '$state', + '$location', + '$modal', + 'Authentication', + 'Events', + 'Dashboards', + function ($scope, $rootScope, $stateParams, $state, $location, $modal, Authentication, Events, Dashboards) { + $scope.isOpen = false; + $scope.openCalendar = function (e) { + e.preventDefault(); + e.stopPropagation(); + $scope.isOpen = true; + }; + $scope.productName = $stateParams.productName; + $scope.event = Events.selected; + $scope.initEventForm = function () { + $scope.testRunIds = Events.getTestRunId(Events.list); + $scope.descriptions = Events.getDescriptions(Events.list); //$scope.dateOptions = { + // startingDay: 1, + // showWeeks: false + //}; + }; + // Open update event form + $scope.addEventForDashboard = function () { + $scope.event.eventTimestamp = new Date(); + $scope.event.productName = $stateParams.productName; + $scope.event.dashboardName = $stateParams.dashboardName; + $state.go('createEvent', { + productName: $stateParams.productName, + dashboardName: $stateParams.dashboardName + }); + }; + // Create new Event + $scope.create = function () { + Events.create($scope.event).then(function (event) { + Events.selected = {}; + //$state.go('viewDashboard', { + // "productName": $scope.event.productName, + // "dashboardName": $scope.event.dashboardName + //}); + if ($rootScope.previousStateParams) + $state.go($rootScope.previousState, $rootScope.previousStateParams); + else + $state.go($rootScope.previousState); + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + $scope.eventForm.eventDescription.$setValidity('server', false); + }); + }; + // Update Event + $scope.update = function () { + Events.update(Events.selected).then(function (event) { + Events.selected = {}; + /* reset form*/ + $scope.eventForm.$setPristine(); + /* return to previous state */ + if ($rootScope.previousStateParams) + $state.go($rootScope.previousState, $rootScope.previousStateParams); + else + $state.go($rootScope.previousState); + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + $scope.eventForm.eventDescription.$setValidity('server', false); + }); + }; + $scope.cancel = function () { + Events.selected = {}; + /* reset form*/ + $scope.eventForm.$setPristine(); + if ($rootScope.previousStateParams) + $state.go($rootScope.previousState, $rootScope.previousStateParams); + else + $state.go($rootScope.previousState); + }; + $scope.listEventsForDashboard = function () { + Events.listEventsForDashboard($scope.productName, $scope.dashboardName).success(function (events) { + Events.list = events; + $scope.events = events; + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; + $scope.editEvent = function (index) { + Events.selected = $scope.events[index]; + $state.go('editEvent', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'eventId': Events.selected._id + }); + }; + //// Find existing Event + //$scope.findOne = function () { + // $scope.event = Events.get({ + // eventId: $stateParams.eventId + // }); + //}; + $scope.open = function (size, index) { + Events.selected = $scope.events[index]; + var modalInstance = $modal.open({ + templateUrl: 'myModalContent.html', + controller: 'EventModalInstanceCtrl', + size: size + }); + modalInstance.result.then(function (eventId) { + Events.delete(eventId).success(function (event) { + ///* refresh events*/ + Events.listEventsForDashboard($scope.productName, $scope.dashboardName).success(function (events) { + $scope.events = events; + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }); + }, function () { + }); + }; + } +]).controller('EventModalInstanceCtrl', [ + '$scope', + '$modalInstance', + 'Events', + function ($scope, $modalInstance, Events) { $scope.selectedEvent = Events.selected; - $scope.ok = function () { - $modalInstance.close($scope.selectedEvent._id); + $modalInstance.close($scope.selectedEvent._id); }; - $scope.cancel = function () { - $modalInstance.dismiss('cancel'); + $modalInstance.dismiss('cancel'); }; - -} -]); + } +]); \ No newline at end of file diff --git a/public/modules/events/events.client.module.js b/public/modules/events/events.client.module.js index 51bcb32..f3a51c6 100644 --- a/public/modules/events/events.client.module.js +++ b/public/modules/events/events.client.module.js @@ -1,4 +1,3 @@ 'use strict'; - // Use applicaion configuration module to register a new module ApplicationConfiguration.registerModule('events'); \ No newline at end of file diff --git a/public/modules/events/services/events.client.service.js b/public/modules/events/services/events.client.service.js index 92855e2..4ed6077 100644 --- a/public/modules/events/services/events.client.service.js +++ b/public/modules/events/services/events.client.service.js @@ -1,76 +1,53 @@ 'use strict'; - //Events service used to communicate Events REST endpoints -angular.module('events').factory('Events', ['$http', 'Products', 'Dashboards', - function($http, Products, Dashboards) { - - var Events = { - selected: {}, - getTestRunId: getTestRunId, - getDescriptions: getDescriptions, - listEventsForDashboard: listEventsForDashboard, - listEventsForTestRun: listEventsForTestRun, - list: [], - update: update, - create: create, - delete: deleteFn - - }; - - return Events; - - function deleteFn(eventId){ - return $http.delete('/events/' + eventId); - } - - function listEventsForDashboard(productName, dashboardName){ - - return $http.get('/events-dashboard/' + productName + '/' + dashboardName); - - }; - - function listEventsForTestRun(productName, dashboardName, from, until){ - - return $http.get('/events-testrun/' + productName + '/' + dashboardName + '/' + from + '/' + until); - - }; - - function getTestRunId(events){ - - var listOfTestRunIds= []; - - _.each(events, function (event){ - - listOfTestRunIds.push(event.testRunId); - - }) - - return _.uniq(listOfTestRunIds); - - - }; - - function getDescriptions(events){ - - var descriptions = ['start', 'end']; - - _.each(events, function (event){ - - descriptions.push(event.eventDescription); - - }) - - return _.uniq(descriptions); - - } - - function create(event){ - return $http.post('/events', event); - } - - function update(event){ - return $http.put('/events/' + event._id, event); - } - +angular.module('events').factory('Events', [ + '$http', + 'Products', + 'Dashboards', + function ($http, Products, Dashboards) { + var Events = { + selected: {}, + getTestRunId: getTestRunId, + getDescriptions: getDescriptions, + listEventsForDashboard: listEventsForDashboard, + listEventsForTestRun: listEventsForTestRun, + list: [], + update: update, + create: create, + delete: deleteFn + }; + return Events; + function deleteFn(eventId) { + return $http.delete('/events/' + eventId); } -]); + function listEventsForDashboard(productName, dashboardName) { + return $http.get('/events-dashboard/' + productName + '/' + dashboardName); + } + function listEventsForTestRun(productName, dashboardName, from, until) { + return $http.get('/events-testrun/' + productName + '/' + dashboardName + '/' + from + '/' + until); + } + function getTestRunId(events) { + var listOfTestRunIds = []; + _.each(events, function (event) { + listOfTestRunIds.push(event.testRunId); + }); + return _.uniq(listOfTestRunIds); + } + function getDescriptions(events) { + var descriptions = [ + 'start', + 'end' + ]; + _.each(events, function (event) { + descriptions.push(event.eventDescription); + }); + return _.uniq(descriptions); + } + function create(event) { + return $http.post('/events', event); + } + function update(event) { + return $http.put('/events/' + event._id, event); + } + } +]); \ No newline at end of file diff --git a/public/modules/events/tests/events.client.controller.test.js b/public/modules/events/tests/events.client.controller.test.js index 9640464..db4d48e 100644 --- a/public/modules/events/tests/events.client.controller.test.js +++ b/public/modules/events/tests/events.client.controller.test.js @@ -1,163 +1,114 @@ 'use strict'; - -(function() { - // Events Controller Spec - describe('Events Controller Tests', function() { - // Initialize global variables - var EventsController, - scope, - $httpBackend, - $stateParams, - $location; - - // The $resource service augments the response object with methods for updating and deleting the resource. - // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match - // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. - // When the toEqualData matcher compares two objects, it takes only object properties into - // account and ignores methods. - beforeEach(function() { - jasmine.addMatchers({ - toEqualData: function(util, customEqualityTesters) { - return { - compare: function(actual, expected) { - return { - pass: angular.equals(actual, expected) - }; - } - }; - } - }); - }); - - // Then we can start by loading the main application module - beforeEach(module(ApplicationConfiguration.applicationModuleName)); - - // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). - // This allows us to inject a service but then attach it to a variable - // with the same name as the service. - beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { - // Set a new global scope - scope = $rootScope.$new(); - - // Point global variables to injected services - $stateParams = _$stateParams_; - $httpBackend = _$httpBackend_; - $location = _$location_; - - // Initialize the Events controller. - EventsController = $controller('EventsController', { - $scope: scope - }); - })); - - it('$scope.find() should create an array with at least one Event object fetched from XHR', inject(function(Events) { - // Create sample Event using the Events service - var sampleEvent = new Events({ - name: 'New Event' - }); - - // Create a sample Events array that includes the new Event - var sampleEvents = [sampleEvent]; - - // Set GET response - $httpBackend.expectGET('events').respond(sampleEvents); - - // Run controller functionality - scope.find(); - $httpBackend.flush(); - - // Test scope value - expect(scope.events).toEqualData(sampleEvents); - })); - - it('$scope.findOne() should create an array with one Event object fetched from XHR using a eventId URL parameter', inject(function(Events) { - // Define a sample Event object - var sampleEvent = new Events({ - name: 'New Event' - }); - - // Set the URL parameter - $stateParams.eventId = '525a8422f6d0f87f0e407a33'; - - // Set GET response - $httpBackend.expectGET(/events\/([0-9a-fA-F]{24})$/).respond(sampleEvent); - - // Run controller functionality - scope.findOne(); - $httpBackend.flush(); - - // Test scope value - expect(scope.event).toEqualData(sampleEvent); - })); - - it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function(Events) { - // Create a sample Event object - var sampleEventPostData = new Events({ - name: 'New Event' - }); - - // Create a sample Event response - var sampleEventResponse = new Events({ - _id: '525cf20451979dea2c000001', - name: 'New Event' - }); - - // Fixture mock form input values - scope.name = 'New Event'; - - // Set POST response - $httpBackend.expectPOST('events', sampleEventPostData).respond(sampleEventResponse); - - // Run controller functionality - scope.create(); - $httpBackend.flush(); - - // Test form inputs are reset - expect(scope.name).toEqual(''); - - // Test URL redirection after the Event was created - expect($location.path()).toBe('/events/' + sampleEventResponse._id); - })); - - it('$scope.update() should update a valid Event', inject(function(Events) { - // Define a sample Event put data - var sampleEventPutData = new Events({ - _id: '525cf20451979dea2c000001', - name: 'New Event' - }); - - // Mock Event in scope - scope.event = sampleEventPutData; - - // Set PUT response - $httpBackend.expectPUT(/events\/([0-9a-fA-F]{24})$/).respond(); - - // Run controller functionality - scope.update(); - $httpBackend.flush(); - - // Test URL location to new object - expect($location.path()).toBe('/events/' + sampleEventPutData._id); - })); - - it('$scope.remove() should send a DELETE request with a valid eventId and remove the Event from the scope', inject(function(Events) { - // Create new Event object - var sampleEvent = new Events({ - _id: '525a8422f6d0f87f0e407a33' - }); - - // Create new Events array and include the Event - scope.events = [sampleEvent]; - - // Set expected DELETE response - $httpBackend.expectDELETE(/events\/([0-9a-fA-F]{24})$/).respond(204); - - // Run controller functionality - scope.remove(sampleEvent); - $httpBackend.flush(); - - // Test array after successful delete - expect(scope.events.length).toBe(0); - })); - }); +(function () { + // Events Controller Spec + describe('Events Controller Tests', function () { + // Initialize global variables + var EventsController, scope, $httpBackend, $stateParams, $location; + // The $resource service augments the response object with methods for updating and deleting the resource. + // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match + // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. + // When the toEqualData matcher compares two objects, it takes only object properties into + // account and ignores methods. + beforeEach(function () { + jasmine.addMatchers({ + toEqualData: function (util, customEqualityTesters) { + return { + compare: function (actual, expected) { + return { pass: angular.equals(actual, expected) }; + } + }; + } + }); + }); + // Then we can start by loading the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); + // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). + // This allows us to inject a service but then attach it to a variable + // with the same name as the service. + beforeEach(inject(function ($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { + // Set a new global scope + scope = $rootScope.$new(); + // Point global variables to injected services + $stateParams = _$stateParams_; + $httpBackend = _$httpBackend_; + $location = _$location_; + // Initialize the Events controller. + EventsController = $controller('EventsController', { $scope: scope }); + })); + it('$scope.find() should create an array with at least one Event object fetched from XHR', inject(function (Events) { + // Create sample Event using the Events service + var sampleEvent = new Events({ name: 'New Event' }); + // Create a sample Events array that includes the new Event + var sampleEvents = [sampleEvent]; + // Set GET response + $httpBackend.expectGET('events').respond(sampleEvents); + // Run controller functionality + scope.find(); + $httpBackend.flush(); + // Test scope value + expect(scope.events).toEqualData(sampleEvents); + })); + it('$scope.findOne() should create an array with one Event object fetched from XHR using a eventId URL parameter', inject(function (Events) { + // Define a sample Event object + var sampleEvent = new Events({ name: 'New Event' }); + // Set the URL parameter + $stateParams.eventId = '525a8422f6d0f87f0e407a33'; + // Set GET response + $httpBackend.expectGET(/events\/([0-9a-fA-F]{24})$/).respond(sampleEvent); + // Run controller functionality + scope.findOne(); + $httpBackend.flush(); + // Test scope value + expect(scope.event).toEqualData(sampleEvent); + })); + it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function (Events) { + // Create a sample Event object + var sampleEventPostData = new Events({ name: 'New Event' }); + // Create a sample Event response + var sampleEventResponse = new Events({ + _id: '525cf20451979dea2c000001', + name: 'New Event' + }); + // Fixture mock form input values + scope.name = 'New Event'; + // Set POST response + $httpBackend.expectPOST('events', sampleEventPostData).respond(sampleEventResponse); + // Run controller functionality + scope.create(); + $httpBackend.flush(); + // Test form inputs are reset + expect(scope.name).toEqual(''); + // Test URL redirection after the Event was created + expect($location.path()).toBe('/events/' + sampleEventResponse._id); + })); + it('$scope.update() should update a valid Event', inject(function (Events) { + // Define a sample Event put data + var sampleEventPutData = new Events({ + _id: '525cf20451979dea2c000001', + name: 'New Event' + }); + // Mock Event in scope + scope.event = sampleEventPutData; + // Set PUT response + $httpBackend.expectPUT(/events\/([0-9a-fA-F]{24})$/).respond(); + // Run controller functionality + scope.update(); + $httpBackend.flush(); + // Test URL location to new object + expect($location.path()).toBe('/events/' + sampleEventPutData._id); + })); + it('$scope.remove() should send a DELETE request with a valid eventId and remove the Event from the scope', inject(function (Events) { + // Create new Event object + var sampleEvent = new Events({ _id: '525a8422f6d0f87f0e407a33' }); + // Create new Events array and include the Event + scope.events = [sampleEvent]; + // Set expected DELETE response + $httpBackend.expectDELETE(/events\/([0-9a-fA-F]{24})$/).respond(204); + // Run controller functionality + scope.remove(sampleEvent); + $httpBackend.flush(); + // Test array after successful delete + expect(scope.events.length).toBe(0); + })); + }); }()); \ No newline at end of file diff --git a/public/modules/events/views/create-event.client.view.html b/public/modules/events/views/create-event.client.view.html index c6e4c73..187313a 100644 --- a/public/modules/events/views/create-event.client.view.html +++ b/public/modules/events/views/create-event.client.view.html @@ -7,41 +7,66 @@

Create Event

- + - - -
+ + + +
Timestamp is required.
- +
- + - -
+ + +
Product name is required.
- + - -
+ + +
Dashboard name is required.
- + - -
+ + +
Test run ID is required.
- + - -
+ + +
Description is required.
{{error}}
@@ -59,6 +84,6 @@

Create Event

Cancel
-
+
diff --git a/public/modules/events/views/edit-event.client.view.html b/public/modules/events/views/edit-event.client.view.html index ccd3184..501970d 100644 --- a/public/modules/events/views/edit-event.client.view.html +++ b/public/modules/events/views/edit-event.client.view.html @@ -1,47 +1,72 @@
- + - - -
+ + + +
Timestamp is required.
- +
- + - -
+ + +
Product name is required.
- + - -
+ + +
Dashboard name is required.
- + - -
+ + +
Test run ID is required.
- + - -
+ + +
Description is required.
{{error}}
@@ -52,7 +77,7 @@

Create Event

- +
Submit diff --git a/public/modules/events/views/list-events-dashboard.client.view.html b/public/modules/events/views/list-events-dashboard.client.view.html index 7004bf6..2b14295 100644 --- a/public/modules/events/views/list-events-dashboard.client.view.html +++ b/public/modules/events/views/list-events-dashboard.client.view.html @@ -26,7 +26,8 @@ {{event.eventTimestamp | date:'EEEE, dd-M-yyyy H:mm:ss'}} {{event.testRunId}} {{event.eventDescription}} - + + diff --git a/public/modules/events/views/view-event.client.view.html b/public/modules/events/views/view-event.client.view.html index 5186ec2..ee2a2b6 100644 --- a/public/modules/events/views/view-event.client.view.html +++ b/public/modules/events/views/view-event.client.view.html @@ -1,21 +1,21 @@
- - - - - Posted on - - by - - - + + + + + Posted on + + by + + +
diff --git a/public/modules/graphs/config/graphs.client.routes.js b/public/modules/graphs/config/graphs.client.routes.js index f440223..122bec2 100644 --- a/public/modules/graphs/config/graphs.client.routes.js +++ b/public/modules/graphs/config/graphs.client.routes.js @@ -1,28 +1,26 @@ 'use strict'; - //Setting up route -angular.module('graphs').config(['ngClipProvider', function(ngClipProvider) { - ngClipProvider.setPath("lib/zeroclipboard/dist/ZeroClipboard.swf"); - - }]).config(['$stateProvider', - function($stateProvider) { - // Graphs state routing - $stateProvider. - state('viewGraphs', { - url: '/graphs/:productName/:dashboardName/:testRunId/:tag', - templateUrl: 'modules/graphs/views/graphs.client.view.html' - }). - state('deepLinkGraph', { - url: '/graphs/:productName/:dashboardName/:testRunId/:tag/:metricId?zoomFrom&zoomUntil', - templateUrl: 'modules/graphs/views/graphs.client.view.html' - }). - state('viewLiveGraphs', { - url: '/graphs-live/:productName/:dashboardName/:tag', - templateUrl: 'modules/graphs/views/graphs-live.client.view.html' - }). - state('deepLinkLiveGraph', { - url: '/graphs-live/:productName/:dashboardName/:tag/:metricId?zoomFrom&zoomUntil', - templateUrl: 'modules/graphs/views/graphs-live.client.view.html' - }); - } -]); +angular.module('graphs').config([ + 'ngClipProvider', + function (ngClipProvider) { + ngClipProvider.setPath('lib/zeroclipboard/dist/ZeroClipboard.swf'); + } +]).config([ + '$stateProvider', + function ($stateProvider) { + // Graphs state routing + $stateProvider.state('viewGraphs', { + url: '/graphs/:productName/:dashboardName/:testRunId/:tag', + templateUrl: 'modules/graphs/views/graphs.client.view.html' + }).state('deepLinkGraph', { + url: '/graphs/:productName/:dashboardName/:testRunId/:tag/:metricId?zoomFrom&zoomUntil', + templateUrl: 'modules/graphs/views/graphs.client.view.html' + }).state('viewLiveGraphs', { + url: '/graphs-live/:productName/:dashboardName/:tag', + templateUrl: 'modules/graphs/views/graphs-live.client.view.html' + }).state('deepLinkLiveGraph', { + url: '/graphs-live/:productName/:dashboardName/:tag/:metricId?zoomFrom&zoomUntil', + templateUrl: 'modules/graphs/views/graphs-live.client.view.html' + }); + } +]); \ No newline at end of file diff --git a/public/modules/graphs/controllers/graphs.client.controller.js b/public/modules/graphs/controllers/graphs.client.controller.js index eae4a43..7a7d7fc 100644 --- a/public/modules/graphs/controllers/graphs.client.controller.js +++ b/public/modules/graphs/controllers/graphs.client.controller.js @@ -1,237 +1,158 @@ 'use strict'; - -angular.module('graphs').controller('GraphsController', ['$scope', '$modal', '$rootScope', '$state', '$stateParams', 'Dashboards','Graphite','TestRuns', 'Metrics','$log', 'Tags', 'ConfirmModal', 'Utils', 'SideMenu', - function($scope, $modal, $rootScope, $state, $stateParams, Dashboards, Graphite, TestRuns, Metrics, $log, Tags, ConfirmModal, Utils, SideMenu) { - - /* Set product Filter in side menu */ - - SideMenu.productFilter = $stateParams.productName; - - - $scope.$watch('selectedIndex', function(current, old) { - Utils.selectedIndex = current; - }); - - - - - $scope.gatlingDetails = ($stateParams.tag === 'Gatling') ? true : false; - /* Get deeplink zoom params from query string */ - - if($state.params.zoomFrom) TestRuns.zoomFrom = $state.params.zoomFrom; - - if($state.params.zoomUntil) TestRuns.zoomUntil = $state.params.zoomUntil; - - - $scope.value = $stateParams.tag; - - /* reset zoom*/ - $scope.resetZoom = function(){ - - /*reset zoom*/ - TestRuns.zoomFrom = ""; - TestRuns.zoomUntil = ""; - - $state.go($state.current, {}, {reload: true}); - - } - - /* Zoom lock enabled by default */ - $scope.zoomLock = true; - - $scope.init = function(){ - - /* use local time in graphs */ - Highcharts.setOptions({ - global: { - useUTC: false - } - }); - - Dashboards.get($stateParams.productName, $stateParams.dashboardName).then(function (dashboard){ - - - $scope.dashboard = Dashboards.selected; - - $scope.metrics = addAccordionState(Dashboards.selected.metrics); - - - /* Get tags used in metrics */ - $scope.tags = Tags.setTags($scope.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); - - - - /* if reloading a non-existing tag is in $statParams */ - $scope.value = (checkIfTagExists($stateParams.tag)) ? $stateParams.tag : 'All'; - - /* set the tab index */ - - $scope.selectedIndex = Tags.getTagIndex($scope.value, $scope.tags); - - if($stateParams.testRunId) { - - TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { - - TestRuns.selected = testRun; - - }); - - } - }); - +angular.module('graphs').controller('GraphsController', [ + '$scope', + '$modal', + '$rootScope', + '$state', + '$stateParams', + 'Dashboards', + 'Graphite', + 'TestRuns', + 'Metrics', + '$log', + 'Tags', + 'ConfirmModal', + 'Utils', + 'SideMenu', + function ($scope, $modal, $rootScope, $state, $stateParams, Dashboards, Graphite, TestRuns, Metrics, $log, Tags, ConfirmModal, Utils, SideMenu) { + /* Set product Filter in side menu */ + SideMenu.productFilter = $stateParams.productName; + $scope.$watch('selectedIndex', function (current, old) { + Utils.selectedIndex = current; + }); + $scope.gatlingDetails = $stateParams.tag === 'Gatling' ? true : false; + /* Get deeplink zoom params from query string */ + if ($state.params.zoomFrom) + TestRuns.zoomFrom = $state.params.zoomFrom; + if ($state.params.zoomUntil) + TestRuns.zoomUntil = $state.params.zoomUntil; + $scope.value = $stateParams.tag; + /* reset zoom*/ + $scope.resetZoom = function () { + /*reset zoom*/ + TestRuns.zoomFrom = ''; + TestRuns.zoomUntil = ''; + $state.go($state.current, {}, { reload: true }); }; - - function checkIfTagExists (tag) { - - var exists = false; - - _.each($scope.tags, function(existingTag){ - - if(tag === existingTag.text){ - exists = true; - return; - } - - }) - - return exists; - + /* Zoom lock enabled by default */ + $scope.zoomLock = true; + $scope.init = function () { + /* use local time in graphs */ + Highcharts.setOptions({ global: { useUTC: false } }); + Dashboards.get($stateParams.productName, $stateParams.dashboardName).then(function (dashboard) { + $scope.dashboard = Dashboards.selected; + $scope.metrics = addAccordionState(Dashboards.selected.metrics); + /* Get tags used in metrics */ + $scope.tags = Tags.setTags($scope.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); + /* if reloading a non-existing tag is in $statParams */ + $scope.value = checkIfTagExists($stateParams.tag) ? $stateParams.tag : 'All'; + /* set the tab index */ + $scope.selectedIndex = Tags.getTagIndex($scope.value, $scope.tags); + if ($stateParams.testRunId) { + TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { + TestRuns.selected = testRun; + }); } - function addAccordionState(metrics){ - - _.each(metrics, function(metric){ - - metric.isOpen = false; - }) - - return metrics; + }); + }; + function checkIfTagExists(tag) { + var exists = false; + _.each($scope.tags, function (existingTag) { + if (tag === existingTag.text) { + exists = true; + return; } - /* default zoom range for live graphs is -10m */ - $scope.zoomRange = (TestRuns.zoomRange !== '')? TestRuns.zoomRange : '-10min'; - - /* Set active tab */ - $scope.isActive = function (tag){ - - return $scope.value === tag; - }; - - - $scope.editMetric = function(metricId){ - - $state.go('editMetric', {productName: $stateParams.productName, dashboardName: $stateParams.dashboardName, metricId: metricId}); + }); + return exists; + } + function addAccordionState(metrics) { + _.each(metrics, function (metric) { + metric.isOpen = false; + }); + return metrics; + } + /* default zoom range for live graphs is -10m */ + $scope.zoomRange = TestRuns.zoomRange !== '' ? TestRuns.zoomRange : '-10min'; + /* Set active tab */ + $scope.isActive = function (tag) { + return $scope.value === tag; + }; + $scope.editMetric = function (metricId) { + $state.go('editMetric', { + productName: $stateParams.productName, + dashboardName: $stateParams.dashboardName, + metricId: metricId + }); + }; + $scope.loadTags = function (query) { + var matchedTags = []; + _.each(Dashboards.selected.tags, function (tag) { + if (tag.text.toLowerCase().match(query.toLowerCase())) + matchedTags.push(tag); + }); + return matchedTags; + }; + function updateFilterTags(filterTags, filterOperator, persistTag, callback) { + var combinedTag; + var newTags = []; + _.each(filterTags, function (filterTag, index) { + switch (index) { + case 0: + combinedTag = filterTag.text + filterOperator; + break; + case filterTags.length - 1: + combinedTag += filterTag.text; + break; + default: + combinedTag += filterTag.text + filterOperator; } - - - $scope.loadTags = function(query){ - - var matchedTags = []; - - _.each(Dashboards.selected.tags, function(tag){ - - if(tag.text.toLowerCase().match(query.toLowerCase())) - matchedTags.push(tag); - }); - - return matchedTags; - - }; - - function updateFilterTags (filterTags, filterOperator, persistTag, callback) { - - - var combinedTag; - var newTags = []; - - - _.each(filterTags, function (filterTag, index) { - - switch (index) { - - case 0: - combinedTag = filterTag.text + filterOperator; - break; - case filterTags.length - 1: - combinedTag += filterTag.text; - break; - default: - combinedTag += filterTag.text + filterOperator; - - - } - - }) - - newTags.push({text: combinedTag}) - - - Dashboards.updateTags($stateParams.productName, $stateParams.dashboardName, newTags, function(tagsUpdated){ - - /* if persist tag is checked and tags are updated, update dashboard tags*/ - if(tagsUpdated && persistTag) { - - Dashboards.update().success(function (dashboard) { - - $scope.dashboard = Dashboards.selected; - /* Get tags used in metrics */ - //$scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); - - callback(newTags); - }); - - }else{ - - callback(newTags); - } - - }); - - + }); + newTags.push({ text: combinedTag }); + Dashboards.updateTags($stateParams.productName, $stateParams.dashboardName, newTags, function (tagsUpdated) { + /* if persist tag is checked and tags are updated, update dashboard tags*/ + if (tagsUpdated && persistTag) { + Dashboards.update().success(function (dashboard) { + $scope.dashboard = Dashboards.selected; + /* Get tags used in metrics */ + //$scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); + callback(newTags); + }); + } else { + callback(newTags); } - - $scope.removeTag = function(removeTag) { - - var updatedTags = []; - - _.each(Dashboards.selected.tags, function(tag){ - - if(tag !== removeTag) updatedTags.push({text: tag.text}); - }) - - Dashboards.selected.tags = updatedTags; - Dashboards.update().success(function(dashboard){}); - + }); } - + $scope.removeTag = function (removeTag) { + var updatedTags = []; + _.each(Dashboards.selected.tags, function (tag) { + if (tag !== removeTag) + updatedTags.push({ text: tag.text }); + }); + Dashboards.selected.tags = updatedTags; + Dashboards.update().success(function (dashboard) { + }); + }; $scope.openTagsFilterModal = function (size) { - - var modalInstance = $modal.open({ - templateUrl: 'tagFilterModal.html', - controller: 'TagFilterModalInstanceController', - size: size - - }); - - modalInstance.result.then(function (data) { - - updateFilterTags(data.filterTags, data.filterOperator, data.persistTag, function(newTag){ - - /* Get tags used in metrics */ - $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); - - $scope.value = newTag[0].text; - - /* set tab index */ - setTimeout(function(){ - $scope.$apply(function (){ - $scope.selectedIndex = Tags.getTagIndex($scope.value, $scope.tags); - }); - },1000); + var modalInstance = $modal.open({ + templateUrl: 'tagFilterModal.html', + controller: 'TagFilterModalInstanceController', + size: size + }); + modalInstance.result.then(function (data) { + updateFilterTags(data.filterTags, data.filterOperator, data.persistTag, function (newTag) { + /* Get tags used in metrics */ + $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); + $scope.value = newTag[0].text; + /* set tab index */ + setTimeout(function () { + $scope.$apply(function () { + $scope.selectedIndex = Tags.getTagIndex($scope.value, $scope.tags); }); - - }, function () { - $log.info('Modal dismissed at: ' + new Date()); + }, 1000); }); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); }; - - } -]); + } +]); \ No newline at end of file diff --git a/public/modules/graphs/controllers/highcharts-live.client.controller.js b/public/modules/graphs/controllers/highcharts-live.client.controller.js index 816255f..0676def 100644 --- a/public/modules/graphs/controllers/highcharts-live.client.controller.js +++ b/public/modules/graphs/controllers/highcharts-live.client.controller.js @@ -1,621 +1,449 @@ +/*jshint maxerr: 10000 */ 'use strict'; - -angular.module('graphs').controller('HighchartsLiveController', ['$scope', 'Interval', '$stateParams', '$state', 'Graphite', 'TestRuns', 'Metrics', 'Dashboards', 'Tags', '$q','$http', '$log','Events', - function($scope, Interval, $stateParams, $state, Graphite, TestRuns, Metrics, Dashboards, Tags, $q, $http, $log, Events) { - - /* Zero copied logic */ - - $scope.clipClicked = function(){ - +angular.module('graphs').controller('HighchartsLiveController', [ + '$scope', + 'Interval', + '$stateParams', + '$state', + 'Graphite', + 'TestRuns', + 'Metrics', + 'Dashboards', + 'Tags', + '$q', + '$http', + '$log', + 'Events', + function ($scope, Interval, $stateParams, $state, Graphite, TestRuns, Metrics, Dashboards, Tags, $q, $http, $log, Events) { + /* Zero copied logic */ + $scope.clipClicked = function () { + $scope.showUrl = false; + }; + $scope.hasFlash = function () { + var hasFlash = false; + try { + var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); + if (fo) { + hasFlash = true; + return hasFlash; + } + } catch (e) { + if (navigator.mimeTypes && navigator.mimeTypes['application/x-shockwave-flash'] !== undefined && navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { + hasFlash = true; + return hasFlash; + } + } + }; + /* set Tags form graph */ + $scope.setTags = function () { + if ($scope.showTags) { + switch ($scope.showTags) { + case true: + $scope.showTags = false; + break; + case false: + $scope.showTags = true; + break; + } + } else { + $scope.showTags = true; + } + }; + /* update Tags form graph */ + /* update Tags form graph */ + $scope.updateTags = function () { + $scope.showTags = false; + Metrics.update($scope.metric).success(function (metric) { + Dashboards.updateTags($stateParams.productName, $stateParams.dashboardName, metric.tags, function (updated) { + if (updated) { + Dashboards.update().success(function (dashboard) { + $scope.dashboard = Dashboards.selected; + /* Get tags used in metrics */ + $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); + }); + } + }); + $state.go('viewGraphs', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': $stateParams.testRunId, + tag: metric.tags[metric.tags.length - 1].text + }); + }); + }; + $scope.tagRemoved = function (tag) { + if (tag.text === $stateParams.tag) { + Metrics.update($scope.metric).success(function (metric) { + if (Dashboards.updateTags($scope.metric.tags)) { + Dashboards.update().success(function (dashboard) { + $scope.dashboard = Dashboards.selected; + /* Get tags used in metrics */ + $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); + }); + } + $state.go($state.current, {}, { reload: true }); + }); + } + }; + /* generate deeplink to share metric graph */ + $scope.setMetricShareUrl = function (metricId) { + if (TestRuns.zoomFrom) { + $scope.metricShareUrl = location.host + '/#!/graphs-live/' + $stateParams.productName + '/' + $stateParams.dashboardName + '/' + $stateParams.tag + '/' + metricId + '?zoomFrom=' + TestRuns.zoomFrom + '&zoomUntil=' + TestRuns.zoomUntil; + } else { + $scope.metricShareUrl = location.host + '/#!/graphs-live/' + $stateParams.productName + '/' + $stateParams.dashboardName + '/' + $stateParams.tag + '/' + metricId; + } + if ($scope.showUrl) { + switch ($scope.showUrl) { + case true: $scope.showUrl = false; - + break; + case false: + $scope.showUrl = true; + break; } - - $scope.hasFlash = function () { - var hasFlash = false; - try { - var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); - if (fo) { - hasFlash = true; - return hasFlash; - } - } catch (e) { - if (navigator.mimeTypes - && navigator.mimeTypes['application/x-shockwave-flash'] != undefined - && navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { - hasFlash = true; - return hasFlash; - } - } + } else { + $scope.showUrl = true; + } + }; + /* If zoom is applied, replace series */ + //$scope.$watch(function (scope) { + // return TestRuns.zoomFrom + // }, + // function (newVal, oldVal) { + // + // if (newVal !== oldVal) { + // + // + // var from = (TestRuns.zoomFrom) ? TestRuns.zoomFrom : TestRuns.selected.start; + // var until = (TestRuns.zoomUntil) ? TestRuns.zoomUntil : TestRuns.selected.end; + // + // updateGraph(from, until, $scope.metric.targets, function(series) { + // + // $scope.config.loading = false; + // $scope.config.series = series; + // + // + // }); + // + // } + // } + //); + /* If zoom lock is checked, update all graphs when zoom is applied in one */ + $scope.$watch(function (scope) { + return TestRuns.zoomFrom; + }, function (newVal, oldVal) { + if (newVal !== oldVal) { + Interval.clearAll(); + var from = TestRuns.zoomFrom ? TestRuns.zoomFrom : TestRuns.selected.startEpoch; + var until = TestRuns.zoomUntil ? TestRuns.zoomUntil : TestRuns.selected.endEpoch; + var chart = angular.element($scope.graphSelector).highcharts(); + while (chart.series.length > 0) { + chart.series[0].remove(false); //deletes all series } - - /* set Tags form graph */ - - $scope.setTags = function (){ - - if ($scope.showTags) { - - switch ($scope.showTags) { - - case true: - $scope.showTags = false; - break; - case false: - $scope.showTags = true; - break; - } - - } else { - - $scope.showTags = true; - } - - + chart.showLoading('Loading data ...'); + updateGraph(TestRuns.zoomFrom, TestRuns.zoomUntil, $scope.metric.targets, function (series) { + chart.hideLoading(); + _.each(series, function (serie) { + chart.addSeries(serie, false); + }); + chart.redraw(); + }); + } + }); + /* Open accordion by default, except for the "All" tab */ + $scope.$watch('value', function (newVal, oldVal) { + if ($stateParams.metricId) { + _.each($scope.metrics, function (metric, i) { + if (metric._id === $stateParams.metricId) + $scope.metrics[i].isOpen = true; + }); + } else { + if (newVal !== 'All') { + _.each($scope.metrics, function (metric, i) { + $scope.metrics[i].isOpen = true; + }); } - - /* update Tags form graph */ - - /* update Tags form graph */ - - $scope.updateTags = function(){ - - $scope.showTags = false; - - Metrics.update($scope.metric).success(function(metric){ - - Dashboards.updateTags($stateParams.productName, $stateParams.dashboardName, metric.tags, function(updated){ - - if(updated) { - - Dashboards.update().success(function (dashboard) { - - $scope.dashboard = Dashboards.selected; - /* Get tags used in metrics */ - $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); - + } + }); + /* stop data polling when accordion is closed */ + $scope.$watch('metric.isOpen', function (newVal, oldVal) { + if (newVal !== oldVal && newVal === false) + Interval.clearIntervalForMetric($scope.metric._id); + }); + /* stop data polling when element is destroyed by ng-if */ + $scope.$on('$destroy', function () { + Interval.clearIntervalForMetric($scope.metric._id); + }); + /* reinitialise graph when zoomRange is changed */ + $scope.$watch('zoomRange', function (newVal, oldVal) { + if (newVal !== oldVal) { + TestRuns.zoomRange = $scope.zoomRange; + //var seriesArray = $scope.config.series; + //var seriesArraySize = seriesArray.length; + // + //for (var i = 0; i < seriesArraySize; i++) { + // + // seriesArray.splice(0, 1); + //} + var chart = angular.element($scope.graphSelector).highcharts(); + chart.destroy(); + $scope.initConfig($scope.metric, $scope.chartIndex); + } + }); + var defaultChartConfig = { + chart: { + type: 'line', + zoomType: 'x', + height: 500, + events: { + click: function (e) { + // Upon cmd-click of the chart area, go to add Event dialog + var addEvent = e.metaKey || e.ctrlKey; + if (addEvent) { + var eventTimestamp = new Date(Math.round(e.xAxis[0].value)); + Events.selected.productName = $stateParams.productName; + Events.selected.dashboardName = $stateParams.dashboardName; + Events.selected.eventTimestamp = eventTimestamp; + Events.selected.testRunId = $stateParams.testRunId; + $state.go('createEvent', { + productName: $stateParams.productName, + dashboardName: $stateParams.dashboardName + }); + } + }, + load: function () { + /* Clear interval that might be already running for this metric */ + Interval.clearIntervalForMetric($scope.metric._id); + var chart = angular.element($scope.graphSelector).highcharts(); + var intervalId = setInterval(function () { + Graphite.getData($scope.zoomRange, 'now', $scope.metric.targets, 900, $stateParams.productName, $stateParams.dashboardName).then(function (graphiteSeries) { + Graphite.addEvents(graphiteSeries, $scope.zoomRange, 'now', $stateParams.productName, $stateParams.dashboardName).then(function (series) { + /* update series */ + _.each(series, function (serie) { + _.each(chart.series, function (existingSerie, i) { + if (serie.name === existingSerie.name) { + var newDatapoints = _.filter(serie.data, function (newDataPoint) { + var isNew = true; + _.each(existingSerie.data, function (existingDataPoint) { + if (newDataPoint[0] === existingDataPoint.x) + isNew = false; + }); + return isNew; }); - } + if (newDatapoints.length > 0) { + _.each(newDatapoints, function (datapoint) { + chart.series[i].addPoint([ + datapoint[0], + datapoint[1] + ], true, true, true); //chart.series[i].data.push([datapoint[0], datapoint[1]]); + }); + } //return; + } + }); + }); }); - - - $state.go('viewGraphs',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : $stateParams.testRunId, tag: metric.tags[metric.tags.length -1].text}); - - + }); //console.log('intervalIds:' + Interval.active) + }, 10000); + Interval.active.push({ + intervalId: intervalId, + metricId: $scope.metric._id }); - + } } - - $scope.tagRemoved = function(tag){ - - if(tag.text === $stateParams.tag){ - - Metrics.update($scope.metric).success(function(metric){ - - if(Dashboards.updateTags($scope.metric.tags)){ - - Dashboards.update().success(function(dashboard){ - - $scope.dashboard = Dashboards.selected; - /* Get tags used in metrics */ - $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); - - }); - + }, + rangeSelector: { enabled: false }, + navigator: { enabled: false }, + legend: { + enabled: true, + align: 'center', + verticalAlign: 'bottom', + maxHeight: 100, + labelFormatter: hcLabelRender, + itemWidth: 300 + }, + tooltip: { + enabled: true, + shared: false, + valueDecimals: 1 + }, + plotOptions: { + series: { + cursor: 'pointer', + events: { + legendItemClick: function (e) { + // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items. + var hideAllOthers = e.browserEvent.metaKey || e.browserEvent.ctrlKey; + if (hideAllOthers) { + var seriesIndex = this.index; + var series = this.chart.series; + for (var i = 0; i < series.length; i++) { + // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then + // call chart.redraw --- this is significantly faster since it involves fewer chart redraws + if (series[i].index === seriesIndex) { + if (!series[i].visible) + series[i].setVisible(true, false); + } else { + if (series[i].visible) { + series[i].setVisible(false, false); + } else { + series[i].setVisible(true, false); } - - $state.go($state.current, {}, {reload: true}); - - - }); - - } - - } - - /* generate deeplink to share metric graph */ - - $scope.setMetricShareUrl = function(metricId){ - - if(TestRuns.zoomFrom){ - - $scope.metricShareUrl = location.host + '/#!/graphs-live/' + $stateParams.productName + '/' + $stateParams.dashboardName + '/' + $stateParams.tag + '/' + metricId + '?zoomFrom=' + TestRuns.zoomFrom + '&zoomUntil=' + TestRuns.zoomUntil; - - }else { - - $scope.metricShareUrl = location.host + '/#!/graphs-live/' + $stateParams.productName + '/' + $stateParams.dashboardName + '/' + $stateParams.tag + '/' + metricId; - - } - if($scope.showUrl){ - - switch($scope.showUrl){ - - case true: - $scope.showUrl = false; - break; - case false: - $scope.showUrl = true; - break; + } } - - }else{ - - $scope.showUrl = true; - } - } - - - /* If zoom is applied, replace series */ - //$scope.$watch(function (scope) { - // return TestRuns.zoomFrom - // }, - // function (newVal, oldVal) { - // - // if (newVal !== oldVal) { - // - // - // var from = (TestRuns.zoomFrom) ? TestRuns.zoomFrom : TestRuns.selected.start; - // var until = (TestRuns.zoomUntil) ? TestRuns.zoomUntil : TestRuns.selected.end; - // - // updateGraph(from, until, $scope.metric.targets, function(series) { - // - // $scope.config.loading = false; - // $scope.config.series = series; - // - // - // }); - // - // } - // } - //); - - /* If zoom lock is checked, update all graphs when zoom is applied in one */ - $scope.$watch(function (scope) { - return TestRuns.zoomFrom + this.chart.redraw(); + return false; + } }, - function (newVal, oldVal) { - - if (newVal !== oldVal) { - - - Interval.clearAll(); - - var from = (TestRuns.zoomFrom) ? TestRuns.zoomFrom : TestRuns.selected.startEpoch; - var until = (TestRuns.zoomUntil) ? TestRuns.zoomUntil : TestRuns.selected.endEpoch; - - var chart = angular.element($scope.graphSelector).highcharts(); - - while(chart.series.length >0){ - chart.series[0].remove(false); //deletes all series + click: function (event) { + // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items. + var hideAllOthers = event.metaKey || event.ctrlKey; + var seriesIndex = this.index; + var series = this.chart.series; + if (hideAllOthers) { + for (var i = 0; i < series.length; i++) { + // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then + // call chart.redraw --- this is significantly faster since it involves fewer chart redraws + if (series[i].index === seriesIndex) { + if (!series[i].visible) + series[i].setVisible(true, false); + } else { + if (series[i].visible) { + series[i].setVisible(false, false); + } else { + series[i].setVisible(true, false); } - - chart.showLoading('Loading data ...'); - - updateGraph(TestRuns.zoomFrom, TestRuns.zoomUntil, $scope.metric.targets, function(series) { - - chart.hideLoading(); - - _.each(series, function(serie){ - - chart.addSeries(serie, false); - }); - - chart.redraw(); - - }); - + } } + } else { + series[seriesIndex].setVisible(false, false); + } + this.chart.redraw(); + return false; } - ); - - /* Open accordion by default, except for the "All" tab */ - - $scope.$watch('value', function (newVal, oldVal) { - - if($stateParams.metricId){ - - _.each($scope.metrics, function (metric, i) { - - if(metric._id === $stateParams.metricId ) - $scope.metrics[i].isOpen = true; - - }) - - }else { - - if (newVal !== 'All') { - - _.each($scope.metrics, function (metric, i) { - - $scope.metrics[i].isOpen = true; - - }) - - } + } + } + }, + //series: $scope.series, + title: { text: 'Hello' }, + xAxis: { + minRange: 10000, + events: { + setExtremes: function (e) { + var from = typeof e.min === 'undefined' && typeof e.max === 'undefined' ? TestRuns.selected.startEpoch : Math.round(e.min); + var until = typeof e.min === 'undefined' && typeof e.max === 'undefined' ? TestRuns.selected.endEpoch : Math.round(e.max); + /* If zoom lock is checked, set zoom timestamps in TestRuns service */ + if ($scope.zoomLock === true) { + TestRuns.zoomFrom = from; + TestRuns.zoomUntil = until; + $scope.$apply(); + } else { + var chart = angular.element($scope.graphSelector).highcharts(); + while (chart.series.length > 0) { + chart.series[0].remove(false); //deletes all series + } + chart.showLoading('Loading data ...'); + updateGraph(from, until, $scope.metric.targets, function (series) { + chart.hideLoading(); + _.each(series, function (serie) { + chart.addSeries(serie, false); + }); + chart.redraw(); + }); } - }); - - /* stop data polling when accordion is closed */ - - $scope.$watch('metric.isOpen', function (newVal, oldVal) { - - if (newVal !== oldVal && newVal === false) Interval.clearIntervalForMetric($scope.metric._id); - - }); - - /* stop data polling when element is destroyed by ng-if */ - - $scope.$on("$destroy", function() { - - Interval.clearIntervalForMetric($scope.metric._id); - - }); - - - /* reinitialise graph when zoomRange is changed */ - - $scope.$watch('zoomRange', function (newVal, oldVal) { - - if (newVal !== oldVal) { - - - TestRuns.zoomRange = $scope.zoomRange; - - - //var seriesArray = $scope.config.series; - //var seriesArraySize = seriesArray.length; - // - //for (var i = 0; i < seriesArraySize; i++) { - // - // seriesArray.splice(0, 1); - //} - - var chart = angular.element($scope.graphSelector).highcharts(); - chart.destroy(); - $scope.initConfig( $scope.metric, $scope.chartIndex); + } + }, + plotLines: [] + }, + series: [], + yAxis: { + min: 0, + // this sets minimum values of y to 0 + plotLines: [{ + value: $scope.metric.requirementValue, + width: 2, + color: 'green', + dashStyle: 'dash', + label: { + text: 'Requirement', + align: 'left', + y: -10, + x: 0 + } + }] + } + }; + $scope.initConfig = function (metric, index) { + $scope.chartIndex = index; + $scope.metric = metric; + $scope.graphSelector = '#chart-' + index; + $scope.config = angular.extend(defaultChartConfig); + $scope.config.title.text = metric.alias; + if (!metric.requirementValue) + $scope.config.yAxis.plotLines = []; + //$scope.config.chart.renderTo = 'chart-' + index; + setTimeout(function () { + angular.element($scope.graphSelector).highcharts('StockChart', $scope.config); + var chart = angular.element($scope.graphSelector).highcharts(); + chart.showLoading('Loading data ...'); + var from = TestRuns.zoomFrom ? TestRuns.zoomFrom : $scope.zoomRange; + var until = TestRuns.zoomUntil ? TestRuns.zoomUntil : 'now'; + updateGraph(from, until, metric.targets, function (series) { + while (chart.series.length > 0) { + chart.series[0].remove(false); //deletes all series + } + chart.hideLoading(); + _.each(series, function (serie) { + chart.addSeries(serie, false); + }); + if (series.length > 0) { + /* draw xAxis plotlines for events*/ + if (series[series.length - 1].type) { + _.each(series[series.length - 1].data, function (flag) { + chart.options.xAxis[0].plotLines.push({ + value: flag.x, + width: 1, + color: 'blue', + dashStyle: 'dash' + }); + }); } + } else { + chart.showLoading('No data to display'); + } + chart.redraw(); }); - - var defaultChartConfig = - { - chart: { - type: 'line', - zoomType: 'x', - height: 500, - events: { - click: function (e) { - // Upon cmd-click of the chart area, go to add Event dialog - var addEvent = e.metaKey || e.ctrlKey; - if (addEvent) { - var eventTimestamp = new Date(Math.round(e.xAxis[0].value)); - Events.selected.productName = $stateParams.productName - Events.selected.dashboardName = $stateParams.dashboardName - Events.selected.eventTimestamp = eventTimestamp; - Events.selected.testRunId = $stateParams.testRunId; - $state.go('createEvent', { - productName: $stateParams.productName, - dashboardName: $stateParams.dashboardName - }); - } - }, - load: function () { - - /* Clear interval that might be already running for this metric */ - Interval.clearIntervalForMetric($scope.metric._id); - - var chart = angular.element($scope.graphSelector).highcharts(); - - var intervalId = setInterval(function () { - - Graphite.getData($scope.zoomRange, 'now', $scope.metric.targets, 900, $stateParams.productName, $stateParams.dashboardName).then(function (graphiteSeries) { - - Graphite.addEvents(graphiteSeries, $scope.zoomRange, 'now', $stateParams.productName, $stateParams.dashboardName).then(function (series) { - - /* update series */ - _.each(series, function (serie) { - - _.each(chart.series, function (existingSerie, i) { - - - if (serie.name === existingSerie.name) { - - var newDatapoints = _.filter(serie.data, function (newDataPoint) { - - var isNew = true; - _.each(existingSerie.data, function (existingDataPoint) { - - if (newDataPoint[0] === existingDataPoint.x) isNew = false; - - }) - - return isNew; - - }) - - if (newDatapoints.length > 0) { - - _.each(newDatapoints, function (datapoint) { - - chart.series[i].addPoint([datapoint[0], datapoint[1]], true, true, true); - //chart.series[i].data.push([datapoint[0], datapoint[1]]); - }) - - } - - - //return; - } - }) - - - }) - - }); - }); - - - //console.log('intervalIds:' + Interval.active) - - }, 10000); - - Interval.active.push({intervalId: intervalId, metricId: $scope.metric._id}); - - } - } - - }, - - rangeSelector: { - enabled: false - }, - navigator: { - enabled: false - }, - - legend: { - enabled: true, - align: 'center', - verticalAlign: 'bottom', - maxHeight: 100, - labelFormatter: hcLabelRender, - itemWidth: 300 - }, - tooltip: { - enabled: true, - shared: false, - valueDecimals: 1 - - }, - - plotOptions: { - series: { - cursor: 'pointer', - events: { - legendItemClick: function (e) { - // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items. - var hideAllOthers = e.browserEvent.metaKey || e.browserEvent.ctrlKey; - if (hideAllOthers) { - var seriesIndex = this.index; - var series = this.chart.series; - - - for (var i = 0; i < series.length; i++) { - // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then - // call chart.redraw --- this is significantly faster since it involves fewer chart redraws - if (series[i].index === seriesIndex) { - if (!series[i].visible) series[i].setVisible(true, false); - } else { - if (series[i].visible) { - series[i].setVisible(false, false); - } else { - series[i].setVisible(true, false); - } - } - } - this.chart.redraw(); - return false; - } - }, - click: function (event) { - // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items. - var hideAllOthers = event.metaKey || event.ctrlKey; - var seriesIndex = this.index; - var series = this.chart.series; - - if (hideAllOthers) { - - for (var i = 0; i < series.length; i++) { - // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then - // call chart.redraw --- this is significantly faster since it involves fewer chart redraws - if (series[i].index === seriesIndex) { - if (!series[i].visible) series[i].setVisible(true, false); - } else { - if (series[i].visible) { - series[i].setVisible(false, false); - } else { - series[i].setVisible(true, false); - } - } - } - } else { - - series[seriesIndex].setVisible(false, false); - } - - this.chart.redraw(); - return false; - - } - } - } - }, - //series: $scope.series, - title: { - text: 'Hello' - }, - xAxis: { - minRange: 10000, - events: { - setExtremes: function (e) { - - var from = (typeof e.min == 'undefined' && typeof e.max == 'undefined') ? TestRuns.selected.startEpoch : Math.round(e.min); - var until = (typeof e.min == 'undefined' && typeof e.max == 'undefined') ? TestRuns.selected.endEpoch : Math.round(e.max); - - /* If zoom lock is checked, set zoom timestamps in TestRuns service */ - if ($scope.zoomLock === true) { - - TestRuns.zoomFrom = from; - TestRuns.zoomUntil = until; - $scope.$apply(); - - } else { - - var chart = angular.element($scope.graphSelector).highcharts(); - - while (chart.series.length > 0) { - chart.series[0].remove(false); //deletes all series - } - - chart.showLoading('Loading data ...'); - - updateGraph(from, until, $scope.metric.targets, function (series) { - - chart.hideLoading(); - - _.each(series, function (serie) { - - chart.addSeries(serie, false); - }); - - chart.redraw(); - - }); - - } - } - }, - plotLines: [] - }, - series: [], - yAxis: { - min: 0, // this sets minimum values of y to 0 - plotLines: [{ - value: $scope.metric.requirementValue, - width: 2, - color: 'green', - dashStyle: 'dash', - label: { - text: 'Requirement', - align: 'left', - y: -10, - x: 0 - } - }] - } - } - - - - $scope.initConfig = function (metric, index) { - - - $scope.chartIndex = index; - $scope.metric = metric; - $scope.graphSelector = '#chart-' + index; - $scope.config = angular.extend(defaultChartConfig); - $scope.config.title.text = metric.alias; - if(!metric.requirementValue) $scope.config.yAxis.plotLines=[]; - //$scope.config.chart.renderTo = 'chart-' + index; - - setTimeout(function(){ - angular.element($scope.graphSelector).highcharts('StockChart', $scope.config); - var chart = angular.element($scope.graphSelector).highcharts(); - - chart.showLoading('Loading data ...'); - - - var from = (TestRuns.zoomFrom) ? TestRuns.zoomFrom : $scope.zoomRange; - var until = (TestRuns.zoomUntil) ? TestRuns.zoomUntil : 'now'; - - updateGraph(from, until, metric.targets, function(series) { - - while(chart.series.length >0){ - chart.series[0].remove(false); //deletes all series - } - - chart.hideLoading(); - - _.each(series, function(serie){ - - chart.addSeries(serie, false); - }); - - if(series.length > 0) { - /* draw xAxis plotlines for events*/ - if (series[series.length - 1].type) { - - _.each(series[series.length - 1].data, function (flag) { - - chart.options.xAxis[0].plotLines.push( - { - value: flag.x, - width: 1, - color: 'blue', - dashStyle: 'dash' - } - ); - }) - } - }else{ - - chart.showLoading('No data to display'); - - } - - chart.redraw(); - - }); - - },100) - } - - function updateGraph(from, until, targets, callback){ - - - Graphite.getData(from, until, targets, 900).then(function (series) { - - if(series.length > 0) { - - Graphite.addEvents(series, from, until, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).then(function (seriesEvents) { - - callback(seriesEvents); - - }); - - }else{ - callback(series); - - } - }); - + }, 100); + }; + function updateGraph(from, until, targets, callback) { + Graphite.getData(from, until, targets, 900).then(function (series) { + if (series.length > 0) { + Graphite.addEvents(series, from, until, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).then(function (seriesEvents) { + callback(seriesEvents); + }); + } else { + callback(series); } - - function hcLabelRender(){ - var s = this.name; - var r = ""; - var lastAppended = 0; - var lastSpace = -1; - for (var i = 0; i < s.length; i++) { - if (s.charAt(i) == ' ') lastSpace = i; - if (i - lastAppended > 40) { - if (lastSpace == -1) lastSpace = i; - r += s.substring(lastAppended, lastSpace); - lastAppended = lastSpace; - lastSpace = -1; - r += "
"; - } - } - r += s.substring(lastAppended, s.length); - return r; + }); + } + function hcLabelRender() { + var s = this.name; + var r = ''; + var lastAppended = 0; + var lastSpace = -1; + for (var i = 0; i < s.length; i++) { + if (s.charAt(i) === ' ') + lastSpace = i; + if (i - lastAppended > 40) { + if (lastSpace === -1) + lastSpace = i; + r += s.substring(lastAppended, lastSpace); + lastAppended = lastSpace; + lastSpace = -1; + r += '
'; } + } + r += s.substring(lastAppended, s.length); + return r; } + } ]); diff --git a/public/modules/graphs/controllers/highcharts.client.controller.js b/public/modules/graphs/controllers/highcharts.client.controller.js index e225f97..d8f98c5 100644 --- a/public/modules/graphs/controllers/highcharts.client.controller.js +++ b/public/modules/graphs/controllers/highcharts.client.controller.js @@ -1,519 +1,373 @@ 'use strict'; - -angular.module('graphs').controller('HighchartsController', ['$scope','Graphite','$stateParams', '$state', 'TestRuns', 'Metrics', 'Dashboards', 'Tags','Events','$document', - function($scope, Graphite, $stateParams, $state, TestRuns, Metrics, Dashboards, Tags, Events, $document) { - - - /* Zero copied logic */ - - $scope.clipClicked = function(){ - - $scope.showUrl = false; - +angular.module('graphs').controller('HighchartsController', [ + '$scope', + 'Graphite', + '$stateParams', + '$state', + 'TestRuns', + 'Metrics', + 'Dashboards', + 'Tags', + 'Events', + '$document', + function ($scope, Graphite, $stateParams, $state, TestRuns, Metrics, Dashboards, Tags, Events, $document) { + /* Zero copied logic */ + $scope.clipClicked = function () { + $scope.showUrl = false; + }; + $scope.hasFlash = function () { + var hasFlash = false; + try { + var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); + if (fo) { + hasFlash = true; + return hasFlash; } - - $scope.hasFlash = function () { - var hasFlash = false; - try { - var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash'); - if (fo) { - hasFlash = true; - return hasFlash; - } - } catch (e) { - if (navigator.mimeTypes - && navigator.mimeTypes['application/x-shockwave-flash'] != undefined - && navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { - hasFlash = true; - return hasFlash; - } - } + } catch (e) { + if (navigator.mimeTypes && navigator.mimeTypes['application/x-shockwave-flash'] != undefined && navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin) { + hasFlash = true; + return hasFlash; } - /* set Tags form graph */ - - $scope.setTags = function (){ - - if ($scope.showTags) { - - switch ($scope.showTags) { - - case true: - $scope.showTags = false; - break; - case false: - $scope.showTags = true; - break; - } - - } else { - - $scope.showTags = true; - } - - + } + }; + /* set Tags form graph */ + $scope.setTags = function () { + if ($scope.showTags) { + switch ($scope.showTags) { + case true: + $scope.showTags = false; + break; + case false: + $scope.showTags = true; + break; } - - /* update Tags form graph */ - - $scope.updateTags = function(){ - - $scope.showTags = false; - - Metrics.update($scope.metric).success(function(metric){ - - Dashboards.updateTags($stateParams.productName, $stateParams.dashboardName, metric.tags, function(updated){ - - if(updated) { - - Dashboards.update().success(function (dashboard) { - - $scope.dashboard = Dashboards.selected; - /* Get tags used in metrics */ - $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); - - }); - } - }); - - - $state.go('viewGraphs',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : $stateParams.testRunId, tag: metric.tags[metric.tags.length -1].text}); - - + } else { + $scope.showTags = true; + } + }; + /* update Tags form graph */ + $scope.updateTags = function () { + $scope.showTags = false; + Metrics.update($scope.metric).success(function (metric) { + Dashboards.updateTags($stateParams.productName, $stateParams.dashboardName, metric.tags, function (updated) { + if (updated) { + Dashboards.update().success(function (dashboard) { + $scope.dashboard = Dashboards.selected; + /* Get tags used in metrics */ + $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); }); - - } - - $scope.tagRemoved = function(tag){ - - if(tag.text === $stateParams.tag){ - - Metrics.update($scope.metric).success(function(metric){ - - if(Dashboards.updateTags($scope.metric.tags)){ - - Dashboards.update().success(function(dashboard){ - - $scope.dashboard = Dashboards.selected; - /* Get tags used in metrics */ - $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); - - }); - - } - - $state.go($state.current, {}, {reload: true}); - - - - }); - - } - + } + }); + $state.go('viewGraphs', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': $stateParams.testRunId, + tag: metric.tags[metric.tags.length - 1].text + }); + }); + }; + $scope.tagRemoved = function (tag) { + if (tag.text === $stateParams.tag) { + Metrics.update($scope.metric).success(function (metric) { + if (Dashboards.updateTags($scope.metric.tags)) { + Dashboards.update().success(function (dashboard) { + $scope.dashboard = Dashboards.selected; + /* Get tags used in metrics */ + $scope.tags = Tags.setTags(Dashboards.selected.metrics, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId, Dashboards.selected.tags); + }); + } + $state.go($state.current, {}, { reload: true }); + }); + } + }; + /* generate deeplink to share metric graph */ + $scope.setMetricShareUrl = function (metricId) { + if (TestRuns.zoomFrom) { + $scope.metricShareUrl = location.host + '/#!/graphs/' + $stateParams.productName + '/' + $stateParams.dashboardName + '/' + $stateParams.testRunId + '/' + $stateParams.tag + '/' + metricId + '?zoomFrom=' + TestRuns.zoomFrom + '&zoomUntil=' + TestRuns.zoomUntil; + } else { + $scope.metricShareUrl = location.host + '/#!/graphs/' + $stateParams.productName + '/' + $stateParams.dashboardName + '/' + $stateParams.testRunId + '/' + $stateParams.tag + '/' + metricId; + } + if ($scope.showUrl) { + switch ($scope.showUrl) { + case true: + $scope.showUrl = false; + break; + case false: + $scope.showUrl = true; + break; } - - /* generate deeplink to share metric graph */ - $scope.setMetricShareUrl = function (metricId) { - - - if(TestRuns.zoomFrom){ - - $scope.metricShareUrl = location.host + '/#!/graphs/' + $stateParams.productName + '/' + $stateParams.dashboardName + '/' + $stateParams.testRunId + '/' + $stateParams.tag + '/' + metricId + '?zoomFrom=' + TestRuns.zoomFrom + '&zoomUntil=' + TestRuns.zoomUntil; - - }else{ - - $scope.metricShareUrl = location.host + '/#!/graphs/' + $stateParams.productName + '/' + $stateParams.dashboardName + '/' + $stateParams.testRunId + '/' + $stateParams.tag + '/' + metricId; - } - - if ($scope.showUrl) { - - switch ($scope.showUrl) { - - case true: - $scope.showUrl = false; - break; - case false: - $scope.showUrl = true; - break; - } - - } else { - - $scope.showUrl = true; - } - - + } else { + $scope.showUrl = true; + } + }; + /* Open accordion by default, except for the "All" tab */ + $scope.$watch('value', function (newVal, oldVal) { + if ($stateParams.metricId) { + _.each($scope.metrics, function (metric, i) { + if (metric._id === $stateParams.metricId) + $scope.metrics[i].isOpen = true; + }); + } else { + if (newVal !== 'All') { + _.each($scope.metrics, function (metric, i) { + $scope.metrics[i].isOpen = true; + }); } - - /* Open accordion by default, except for the "All" tab */ - - - $scope.$watch('value', function (newVal, oldVal) { - - if ($stateParams.metricId) { - - _.each($scope.metrics, function (metric, i) { - - if (metric._id === $stateParams.metricId) - $scope.metrics[i].isOpen = true; - - }) - - } else { - - if (newVal !== 'All') { - - _.each($scope.metrics, function (metric, i) { - - $scope.metrics[i].isOpen = true; - - }) - - } - } + } + }); + $scope.$watch('value', function (newVal, oldVal) { + if ($stateParams.metricId) { + _.each($scope.metrics, function (metric, i) { + if (metric._id === $stateParams.metricId) + $scope.metrics[i].isOpen = true; }); - - $scope.$watch('value', function (newVal, oldVal) { - - if ($stateParams.metricId) { - - _.each($scope.metrics, function (metric, i) { - - if (metric._id === $stateParams.metricId) - $scope.metrics[i].isOpen = true; - - }) - - } else { - - if (newVal !== 'All') { - - _.each($scope.metrics, function (metric, i) { - - $scope.metrics[i].isOpen = true; - - }) - - } - } + } else { + if (newVal !== 'All') { + _.each($scope.metrics, function (metric, i) { + $scope.metrics[i].isOpen = true; + }); + } + } + }); + /* If zoom lock is checked, update all graphs when zoom is applied in one */ + $scope.$watch(function (scope) { + return TestRuns.zoomFrom; + }, function (newVal, oldVal) { + if (newVal !== oldVal) { + var from = TestRuns.zoomFrom ? TestRuns.zoomFrom : TestRuns.selected.startEpoch; + var until = TestRuns.zoomUntil ? TestRuns.zoomUntil : TestRuns.selected.endEpoch; + var chart = angular.element($scope.graphSelector).highcharts(); + while (chart.series.length > 0) { + chart.series[0].remove(false); //deletes all series + } + chart.showLoading('Loading data ...'); + updateGraph(TestRuns.zoomFrom, TestRuns.zoomUntil, $scope.metric.targets, function (series) { + chart.hideLoading(); + _.each(series, function (serie) { + chart.addSeries(serie, false); + }); + chart.redraw(); }); - - /* If zoom lock is checked, update all graphs when zoom is applied in one */ - $scope.$watch(function (scope) { - return TestRuns.zoomFrom - }, - function (newVal, oldVal) { - - if (newVal !== oldVal) { - - - var from = (TestRuns.zoomFrom) ? TestRuns.zoomFrom : TestRuns.selected.startEpoch; - var until = (TestRuns.zoomUntil) ? TestRuns.zoomUntil : TestRuns.selected.endEpoch; - - var chart = angular.element($scope.graphSelector).highcharts(); - - while(chart.series.length >0){ - chart.series[0].remove(false); //deletes all series - } - - chart.showLoading('Loading data ...'); - - updateGraph(TestRuns.zoomFrom, TestRuns.zoomUntil, $scope.metric.targets, function(series) { - - chart.hideLoading(); - - _.each(series, function(serie){ - - chart.addSeries(serie, false); - }); - - chart.redraw(); - - }); - - } + } + }); + var defaultChartConfig = { + chart: { + type: 'line', + zoomType: 'x', + height: 500, + events: { + click: function (e) { + // Upon cmd-click of the chart area, go to add Event dialog + var addEvent = e.metaKey || e.ctrlKey; + if (addEvent) { + var eventTimestamp = new Date(Math.round(e.xAxis[0].value)); + Events.selected.productName = $stateParams.productName; + Events.selected.dashboardName = $stateParams.dashboardName; + Events.selected.eventTimestamp = eventTimestamp; + Events.selected.testRunId = $stateParams.testRunId; + $state.go('createEvent', { + productName: $stateParams.productName, + dashboardName: $stateParams.dashboardName + }); } - ); - - - var defaultChartConfig = - { - chart: { - type: 'line', - zoomType: 'x', - height: 500, - events: { - click: function (e) { - // Upon cmd-click of the chart area, go to add Event dialog - var addEvent = e.metaKey || e.ctrlKey; - if (addEvent) { - var eventTimestamp = new Date( Math.round(e.xAxis[0].value)); - Events.selected.productName = $stateParams.productName - Events.selected.dashboardName = $stateParams.dashboardName - Events.selected.eventTimestamp = eventTimestamp; - Events.selected.testRunId = $stateParams.testRunId; - $state.go('createEvent', { - productName: $stateParams.productName, - dashboardName: $stateParams.dashboardName - }); - } + } + } + }, + rangeSelector: { enabled: false }, + navigator: { enabled: false }, + legend: { + enabled: true, + align: 'center', + verticalAlign: 'bottom', + maxHeight: 100, + labelFormatter: hcLabelRender, + itemWidth: 300 + }, + tooltip: { + enabled: true, + shared: false, + valueDecimals: 1 + }, + plotOptions: { + series: { + cursor: 'pointer', + events: { + legendItemClick: function (e) { + // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items. + var hideAllOthers = e.browserEvent.metaKey || e.browserEvent.ctrlKey; + if (hideAllOthers) { + var seriesIndex = this.index; + var series = this.chart.series; + for (var i = 0; i < series.length; i++) { + // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then + // call chart.redraw --- this is significantly faster since it involves fewer chart redraws + if (series[i].index === seriesIndex) { + if (!series[i].visible) + series[i].setVisible(true, false); + } else { + if (series[i].visible) { + series[i].setVisible(false, false); + } else { + series[i].setVisible(true, false); } + } } - - }, - - rangeSelector: { - enabled: false - }, - navigator: { - enabled: false + this.chart.redraw(); + return false; + } }, - - legend: { - enabled: true, - align: 'center', - verticalAlign: 'bottom', - maxHeight: 100, - labelFormatter: hcLabelRender, - itemWidth: 300 - }, - tooltip: { - enabled: true, - shared: false, - valueDecimals: 1 - - }, - - plotOptions: { - series: { - cursor: 'pointer', - events: { - legendItemClick: function(e) { - // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items. - var hideAllOthers = e.browserEvent.metaKey || e.browserEvent.ctrlKey; - if (hideAllOthers) { - var seriesIndex = this.index; - var series = this.chart.series; - - - for (var i = 0; i < series.length; i++) { - // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then - // call chart.redraw --- this is significantly faster since it involves fewer chart redraws - if (series[i].index === seriesIndex) { - if (!series[i].visible) series[i].setVisible(true, false); - } else { - if (series[i].visible) { - series[i].setVisible(false, false); - } else { - series[i].setVisible(true, false); - } - } - } - this.chart.redraw(); - return false; - } - }, - click: function (event) { - // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items. - var hideAllOthers = event.metaKey || event.ctrlKey; - var seriesIndex = this.index; - var series = this.chart.series; - - if (hideAllOthers) { - - for (var i = 0; i < series.length; i++) { - // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then - // call chart.redraw --- this is significantly faster since it involves fewer chart redraws - if (series[i].index === seriesIndex) { - if (!series[i].visible) series[i].setVisible(true, false); - } else { - if (series[i].visible) { - series[i].setVisible(false, false); - } else { - series[i].setVisible(true, false); - } - } - } - }else{ - - series[seriesIndex].setVisible(false, false); - } - - this.chart.redraw(); - return false; - - } + click: function (event) { + // Upon cmd-click of a legend item, rather than toggling visibility, we want to hide all other items. + var hideAllOthers = event.metaKey || event.ctrlKey; + var seriesIndex = this.index; + var series = this.chart.series; + if (hideAllOthers) { + for (var i = 0; i < series.length; i++) { + // rather than calling 'show()' and 'hide()' on the series', we use setVisible and then + // call chart.redraw --- this is significantly faster since it involves fewer chart redraws + if (series[i].index === seriesIndex) { + if (!series[i].visible) + series[i].setVisible(true, false); + } else { + if (series[i].visible) { + series[i].setVisible(false, false); + } else { + series[i].setVisible(true, false); } + } } - }, - //series: $scope.series, - title: { - text: 'Hello' - }, - xAxis: { - minRange: 10000, - events: { - setExtremes: function (e) { - - var from = (typeof e.min == 'undefined' && typeof e.max == 'undefined') ? TestRuns.selected.startEpoch : Math.round(e.min); - var until = (typeof e.min == 'undefined' && typeof e.max == 'undefined') ? TestRuns.selected.endEpoch : Math.round(e.max); - - /* If zoom lock is checked, set zoom timestamps in TestRuns service */ - if ($scope.zoomLock === true) { - - TestRuns.zoomFrom = from; - TestRuns.zoomUntil = until; - $scope.$apply(); - - } else { - - var chart = angular.element($scope.graphSelector).highcharts(); - - while(chart.series.length >0){ - chart.series[0].remove(false); //deletes all series - } - - chart.showLoading('Loading data ...'); - - updateGraph(from, until, $scope.metric.targets, function(series){ - - chart.hideLoading(); - - _.each(series, function(serie){ - - chart.addSeries(serie, false); - }); - - chart.redraw(); - - }); - - } - } - }, - plotLines: [] - }, - series:[], - yAxis: { - min: 0, // this sets minimum values of y to 0 - plotLines: [{ - value: $scope.metric.requirementValue, - width: 2, - color: 'green', - dashStyle: 'dash', - label: { - text: 'Requirement', - align: 'left', - y: -10, - x: 0 - } - }] + } else { + series[seriesIndex].setVisible(false, false); + } + this.chart.redraw(); + return false; } + } } - - - $scope.initConfig = function (metric, index) { - - $scope.graphSelector = '#chart-' + index; - $scope.config = angular.extend(defaultChartConfig); - $scope.config.title.text = metric.alias; - if(!metric.requirementValue) $scope.config.yAxis.plotLines=[]; - //$scope.config.chart.renderTo = 'chart-' + index; - - setTimeout(function(){ - angular.element($scope.graphSelector).highcharts('StockChart', $scope.config); - var chart = angular.element($scope.graphSelector).highcharts(); - - chart.showLoading('Loading data ...'); - - /* Set the TestRuns.selected based on $stateParams*/ - - TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { - - TestRuns.selected = testRun; - - var from = (TestRuns.zoomFrom) ? TestRuns.zoomFrom : TestRuns.selected.startEpoch; - var until = (TestRuns.zoomUntil) ? TestRuns.zoomUntil : TestRuns.selected.endEpoch; - - updateGraph(from, until, metric.targets, function(series) { - - while(chart.series.length >0){ - chart.series[0].remove(false); //deletes all series - } - - chart.hideLoading(); - - _.each(series, function(serie){ - - chart.addSeries(serie, false); - }); - - if(series.length > 0) { - /* draw xAxis plotlines for events*/ - if (series[series.length - 1].type) { - - _.each(series[series.length - 1].data, function (flag) { - - chart.options.xAxis[0].plotLines.push( - { - value: flag.x, - width: 1, - color: 'blue', - dashStyle: 'dash' - } - ); - }) - } - }else{ - - chart.showLoading('No data to display'); - - } - - chart.redraw(); - - }); + }, + //series: $scope.series, + title: { text: 'Hello' }, + xAxis: { + minRange: 10000, + events: { + setExtremes: function (e) { + var from = typeof e.min == 'undefined' && typeof e.max == 'undefined' ? TestRuns.selected.startEpoch : Math.round(e.min); + var until = typeof e.min == 'undefined' && typeof e.max == 'undefined' ? TestRuns.selected.endEpoch : Math.round(e.max); + /* If zoom lock is checked, set zoom timestamps in TestRuns service */ + if ($scope.zoomLock === true) { + TestRuns.zoomFrom = from; + TestRuns.zoomUntil = until; + $scope.$apply(); + } else { + var chart = angular.element($scope.graphSelector).highcharts(); + while (chart.series.length > 0) { + chart.series[0].remove(false); //deletes all series + } + chart.showLoading('Loading data ...'); + updateGraph(from, until, $scope.metric.targets, function (series) { + chart.hideLoading(); + _.each(series, function (serie) { + chart.addSeries(serie, false); }); - },100) - } - - function updateGraph(from, until, targets, callback){ - - - Graphite.getData(from, until, targets, 900).then(function (series) { - - if(series.length > 0) { - - Graphite.addEvents(series, from, until, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).then(function (seriesEvents) { - - callback(seriesEvents); - - }); - - }else{ - callback(series); - - } + chart.redraw(); + }); + } + } + }, + plotLines: [] + }, + series: [], + yAxis: { + min: 0, + // this sets minimum values of y to 0 + plotLines: [{ + value: $scope.metric.requirementValue, + width: 2, + color: 'green', + dashStyle: 'dash', + label: { + text: 'Requirement', + align: 'left', + y: -10, + x: 0 + } + }] + } + }; + $scope.initConfig = function (metric, index) { + $scope.graphSelector = '#chart-' + index; + $scope.config = angular.extend(defaultChartConfig); + $scope.config.title.text = metric.alias; + if (!metric.requirementValue) + $scope.config.yAxis.plotLines = []; + //$scope.config.chart.renderTo = 'chart-' + index; + setTimeout(function () { + angular.element($scope.graphSelector).highcharts('StockChart', $scope.config); + var chart = angular.element($scope.graphSelector).highcharts(); + chart.showLoading('Loading data ...'); + /* Set the TestRuns.selected based on $stateParams*/ + TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { + TestRuns.selected = testRun; + var from = TestRuns.zoomFrom ? TestRuns.zoomFrom : TestRuns.selected.startEpoch; + var until = TestRuns.zoomUntil ? TestRuns.zoomUntil : TestRuns.selected.endEpoch; + updateGraph(from, until, metric.targets, function (series) { + while (chart.series.length > 0) { + chart.series[0].remove(false); //deletes all series + } + chart.hideLoading(); + _.each(series, function (serie) { + chart.addSeries(serie, false); }); - - } - - function hcLabelRender(){ - var s = this.name; - var r = ""; - var lastAppended = 0; - var lastSpace = -1; - for (var i = 0; i < s.length; i++) { - if (s.charAt(i) == ' ') lastSpace = i; - if (i - lastAppended > 40) { - if (lastSpace == -1) lastSpace = i; - r += s.substring(lastAppended, lastSpace); - lastAppended = lastSpace; - lastSpace = -1; - r += "
"; - } + if (series.length > 0) { + /* draw xAxis plotlines for events*/ + if (series[series.length - 1].type) { + _.each(series[series.length - 1].data, function (flag) { + chart.options.xAxis[0].plotLines.push({ + value: flag.x, + width: 1, + color: 'blue', + dashStyle: 'dash' + }); + }); + } + } else { + chart.showLoading('No data to display'); } - r += s.substring(lastAppended, s.length); - return r; + chart.redraw(); + }); + }); + }, 100); + }; + function updateGraph(from, until, targets, callback) { + Graphite.getData(from, until, targets, 900).then(function (series) { + if (series.length > 0) { + Graphite.addEvents(series, from, until, $stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).then(function (seriesEvents) { + callback(seriesEvents); + }); + } else { + callback(series); + } + }); + } + function hcLabelRender() { + var s = this.name; + var r = ''; + var lastAppended = 0; + var lastSpace = -1; + for (var i = 0; i < s.length; i++) { + if (s.charAt(i) == ' ') + lastSpace = i; + if (i - lastAppended > 40) { + if (lastSpace == -1) + lastSpace = i; + r += s.substring(lastAppended, lastSpace); + lastAppended = lastSpace; + lastSpace = -1; + r += '
'; } + } + r += s.substring(lastAppended, s.length); + return r; } -]); + } +]); \ No newline at end of file diff --git a/public/modules/graphs/controllers/tags-filter-modal.client.controller.js b/public/modules/graphs/controllers/tags-filter-modal.client.controller.js index a92bd29..8e0df6b 100644 --- a/public/modules/graphs/controllers/tags-filter-modal.client.controller.js +++ b/public/modules/graphs/controllers/tags-filter-modal.client.controller.js @@ -1,52 +1,38 @@ 'use strict'; - -angular.module('graphs').controller('TagFilterModalInstanceController', ['$scope', '$modalInstance','ConfirmModal', 'Dashboards', - function($scope, $modalInstance, ConfirmModal, Dashboards) { - - $scope.filterOperatorOptions = - [ - { - label: " AND ", - value: " AND " - }, { - label: " OR ", - value: " OR " - } - ] - - - - $scope.persistTag = false; - - $scope.loadTags = function(query){ - - var matchedTags = []; - - _.each(Dashboards.selected.tags, function(tag){ - - if(tag.text.toLowerCase().match(query.toLowerCase())) - matchedTags.push(tag); - }); - - return matchedTags; - - }; - - - - $scope.ok = function () { - - var data = {}; - data.filterOperator = $scope.filterOperator.value; - data.persistTag = $scope.persistTag; - data.filterTags = $scope.filterTags; - - $modalInstance.close(data); - }; - - $scope.cancel = function () { - $modalInstance.dismiss('cancel'); - }; - - } -]); +angular.module('graphs').controller('TagFilterModalInstanceController', [ + '$scope', + '$modalInstance', + 'ConfirmModal', + 'Dashboards', + function ($scope, $modalInstance, ConfirmModal, Dashboards) { + $scope.filterOperatorOptions = [ + { + label: ' AND ', + value: ' AND ' + }, + { + label: ' OR ', + value: ' OR ' + } + ]; + $scope.persistTag = false; + $scope.loadTags = function (query) { + var matchedTags = []; + _.each(Dashboards.selected.tags, function (tag) { + if (tag.text.toLowerCase().match(query.toLowerCase())) + matchedTags.push(tag); + }); + return matchedTags; + }; + $scope.ok = function () { + var data = {}; + data.filterOperator = $scope.filterOperator.value; + data.persistTag = $scope.persistTag; + data.filterTags = $scope.filterTags; + $modalInstance.close(data); + }; + $scope.cancel = function () { + $modalInstance.dismiss('cancel'); + }; + } +]); \ No newline at end of file diff --git a/public/modules/graphs/directives/fix-to-top.client.directive.js b/public/modules/graphs/directives/fix-to-top.client.directive.js index 6bc6e7b..e1d65ba 100644 --- a/public/modules/graphs/directives/fix-to-top.client.directive.js +++ b/public/modules/graphs/directives/fix-to-top.client.directive.js @@ -1,24 +1,24 @@ 'use strict'; - -angular.module('graphs').directive('fixToTop', [ '$window', - function($window) { - - var $win = angular.element($window); // wrap window object as jQuery object - - return { - restrict: 'A', - link: function (scope, element, attrs) { - var topClass = attrs.fixToTop, // get CSS class from directive's attribute value - offsetTop = element.prop('offsetTop'); // get element's top relative to the document - - $win.on('scroll', function (e) { - if ($win[0].pageYOffset >= offsetTop) { - element.addClass(topClass); - } else { - element.removeClass(topClass); - } - }); - } - } - } -]); +angular.module('graphs').directive('fixToTop', [ + '$window', + function ($window) { + var $win = angular.element($window); + // wrap window object as jQuery object + return { + restrict: 'A', + link: function (scope, element, attrs) { + var topClass = attrs.fixToTop, + // get CSS class from directive's attribute value + offsetTop = element.prop('offsetTop'); + // get element's top relative to the document + $win.on('scroll', function (e) { + if ($win[0].pageYOffset >= offsetTop) { + element.addClass(topClass); + } else { + element.removeClass(topClass); + } + }); + } + }; + } +]); \ No newline at end of file diff --git a/public/modules/graphs/directives/gatling-details.client.directive.js b/public/modules/graphs/directives/gatling-details.client.directive.js index 443d998..2c49dd3 100644 --- a/public/modules/graphs/directives/gatling-details.client.directive.js +++ b/public/modules/graphs/directives/gatling-details.client.directive.js @@ -1,114 +1,77 @@ -(function() { - 'use strict'; - - /* public/modules/graphs/directives/gatling-details.client.directive.js */ - - /** +(function () { + 'use strict'; + /* public/modules/graphs/directives/gatling-details.client.directive.js */ + /** * @desc * @example
*/ - angular - .module('graphs') - .directive( - 'gatlingDetails', GatlingDetailsDirective) - .directive( - 'loadingContainer', LoadingContainerDirective); - - function GatlingDetailsDirective() { - var directive = { - restrict: 'EA', - templateUrl: 'modules/graphs/views/gatling-details.client.view.html', - controller: GatlingDetailsController, - controllerAs: 'vm' - }; - - return directive; - - /* @ngInject */ - function GatlingDetailsController ( - $scope, - $timeout, - $filter, - $stateParams, - GatlingConsoleDetails, - TestRuns, - ngTableParams - - ) { - - $scope.tabNumber = 0; - - $scope.setTab = function(newValue){ - $scope.tabNumber = newValue; - $scope.tableParams.filter({}); - $scope.tableParams.reload(); - } - - $scope.isSet = function(tabNumber){ - return $scope.tabNumber === tabNumber; - }; - - - TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { - - TestRuns.selected = testRun; - - $scope.tableParams = new ngTableParams({ - page: 1, // show first page - count: 50, // count per page - sorting: { - KO: 'desc', // initial sorting - OK: 'desc', - numberOfErrors: 'desc' - - } - }, { - total: 0, // length of data - getData: function($defer, params) { - // ajax request to api - GatlingConsoleDetails.getData(TestRuns.selected.buildResultKey, false).success(function(response) { - - $timeout(function() { - - var data = ($scope.tabNumber === 0) ? response.data : response.errors; - - var filteredData = params.filter() ? - $filter('filter')(data, params.filter()) : - data; - var orderedData = params.sorting() ? - $filter('orderBy')(filteredData, params.orderBy()) : - filteredData; - // update table params - params.total(orderedData.length); - // set new data - $defer.resolve(orderedData); - }, 500); - }); - } - }); + angular.module('graphs').directive('gatlingDetails', GatlingDetailsDirective).directive('loadingContainer', LoadingContainerDirective); + function GatlingDetailsDirective() { + var directive = { + restrict: 'EA', + templateUrl: 'modules/graphs/views/gatling-details.client.view.html', + controller: GatlingDetailsController, + controllerAs: 'vm' + }; + return directive; + /* @ngInject */ + function GatlingDetailsController($scope, $timeout, $filter, $stateParams, GatlingConsoleDetails, TestRuns, ngTableParams) { + $scope.tabNumber = 0; + $scope.setTab = function (newValue) { + $scope.tabNumber = newValue; + $scope.tableParams.filter({}); + $scope.tableParams.reload(); + }; + $scope.isSet = function (tabNumber) { + return $scope.tabNumber === tabNumber; + }; + TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { + TestRuns.selected = testRun; + $scope.tableParams = new ngTableParams({ + page: 1, + // show first page + count: 50, + // count per page + sorting: { + KO: 'desc', + // initial sorting + OK: 'desc', + numberOfErrors: 'desc' + } + }, { + total: 0, + // length of data + getData: function ($defer, params) { + // ajax request to api + GatlingConsoleDetails.getData(TestRuns.selected.buildResultKey, false).success(function (response) { + $timeout(function () { + var data = $scope.tabNumber === 0 ? response.data : response.errors; + var filteredData = params.filter() ? $filter('filter')(data, params.filter()) : data; + var orderedData = params.sorting() ? $filter('orderBy')(filteredData, params.orderBy()) : filteredData; + // update table params + params.total(orderedData.length); + // set new data + $defer.resolve(orderedData); + }, 500); }); - - - - } + } + }); + }); } - - function LoadingContainerDirective (){ - - var directive = { - restrict: 'A', - scope: false, - link: function (scope, element, attrs) { - var loadingLayer = angular.element('
'); - element.append(loadingLayer); - element.addClass('loading-container'); - scope.$watch(attrs.loadingContainer, function (value) { - loadingLayer.toggleClass('ng-hide', !value); - }); - } - }; - - return directive; - - } -}()); + } + function LoadingContainerDirective() { + var directive = { + restrict: 'A', + scope: false, + link: function (scope, element, attrs) { + var loadingLayer = angular.element('
'); + element.append(loadingLayer); + element.addClass('loading-container'); + scope.$watch(attrs.loadingContainer, function (value) { + loadingLayer.toggleClass('ng-hide', !value); + }); + } + }; + return directive; + } +}()); \ No newline at end of file diff --git a/public/modules/graphs/directives/share-graph-url.client.directive.js b/public/modules/graphs/directives/share-graph-url.client.directive.js index 543845b..b584e6e 100644 --- a/public/modules/graphs/directives/share-graph-url.client.directive.js +++ b/public/modules/graphs/directives/share-graph-url.client.directive.js @@ -1,19 +1,18 @@ 'use strict'; - -angular.module('graphs').directive('shareGraphUrl', [ '$timeout', - function($timeout) { - return { - restrict: "A", - link: function(scope, element, attrs) { - //On click - //$(elem).click(function() { - // $(this).select(); - //}); - $timeout(function () { - element[0].select(); - }); - } - } - } - -]); +angular.module('graphs').directive('shareGraphUrl', [ + '$timeout', + function ($timeout) { + return { + restrict: 'A', + link: function (scope, element, attrs) { + //On click + //$(elem).click(function() { + // $(this).select(); + //}); + $timeout(function () { + element[0].select(); + }); + } + }; + } +]); \ No newline at end of file diff --git a/public/modules/graphs/filters/tags.client.filter.js b/public/modules/graphs/filters/tags.client.filter.js index 2909079..6cc0cc7 100644 --- a/public/modules/graphs/filters/tags.client.filter.js +++ b/public/modules/graphs/filters/tags.client.filter.js @@ -1,107 +1,65 @@ 'use strict'; - -angular.module('graphs').filter('tagsFilter', [ - function() { - - function parseString(input) { - return input.split("."); - } - - function getValue(element, propertyArray) { - var value = element; - - _.forEach(propertyArray, function (property) { - value = value[property]; - }); - - return value; - } - - return function (array, propertyString, inputTarget) { - var properties = parseString(propertyString); - var filterOperator; - - if (inputTarget.indexOf(" AND ") > -1) { - - filterOperator = " AND "; - - } else if (inputTarget.indexOf(" OR ") > -1) { - - filterOperator = " OR "; - } - - var target = inputTarget.split(filterOperator); - - - /* if single target*/ - if (target.length == 1) { - /* if target is 'All', filter none */ - if (target[0] === 'All') { - return array; - } else { - return _.filter(array, function (item) { - - var matchResult = false; - - _.each(getValue(item, properties), function (arrayItem) { - - if (target[0] === arrayItem.text) matchResult = true; - - }) - return matchResult; - }); - } - } else { - - if (filterOperator === " AND ") { - - return _.filter(array, function (item) { - - var matchResults = []; - - _.each(target, function (matchtarget) { - - var targetMatchResult = false; - - _.each(getValue(item, properties), function (arrayItem) { - - if (matchtarget === arrayItem.text)targetMatchResult = true; - - - }) - - matchResults.push(targetMatchResult); - - }) - - - return matchResults.indexOf(false) > -1 ? false : true; - }); - - /* filterOperator = OR*/ - } else { - - return _.filter(array, function (item) { - - var targetMatchResult = false; - - _.each(target, function (matchtarget) { - - _.each(getValue(item, properties), function (arrayItem) { - - if (matchtarget === arrayItem.text)targetMatchResult = true; - - }) - - }) - - - return targetMatchResult; - }); - - } - } - } +angular.module('graphs').filter('tagsFilter', [function () { + function parseString(input) { + return input.split('.'); + } + function getValue(element, propertyArray) { + var value = element; + _.forEach(propertyArray, function (property) { + value = value[property]; + }); + return value; } - -]); + return function (array, propertyString, inputTarget) { + var properties = parseString(propertyString); + var filterOperator; + if (inputTarget.indexOf(' AND ') > -1) { + filterOperator = ' AND '; + } else if (inputTarget.indexOf(' OR ') > -1) { + filterOperator = ' OR '; + } + var target = inputTarget.split(filterOperator); + /* if single target*/ + if (target.length == 1) { + /* if target is 'All', filter none */ + if (target[0] === 'All') { + return array; + } else { + return _.filter(array, function (item) { + var matchResult = false; + _.each(getValue(item, properties), function (arrayItem) { + if (target[0] === arrayItem.text) + matchResult = true; + }); + return matchResult; + }); + } + } else { + if (filterOperator === ' AND ') { + return _.filter(array, function (item) { + var matchResults = []; + _.each(target, function (matchtarget) { + var targetMatchResult = false; + _.each(getValue(item, properties), function (arrayItem) { + if (matchtarget === arrayItem.text) + targetMatchResult = true; + }); + matchResults.push(targetMatchResult); + }); + return matchResults.indexOf(false) > -1 ? false : true; + }); /* filterOperator = OR*/ + } else { + return _.filter(array, function (item) { + var targetMatchResult = false; + _.each(target, function (matchtarget) { + _.each(getValue(item, properties), function (arrayItem) { + if (matchtarget === arrayItem.text) + targetMatchResult = true; + }); + }); + return targetMatchResult; + }); + } + } + }; + }]); \ No newline at end of file diff --git a/public/modules/graphs/graphs.client.module.js b/public/modules/graphs/graphs.client.module.js index dd0e761..88c1101 100644 --- a/public/modules/graphs/graphs.client.module.js +++ b/public/modules/graphs/graphs.client.module.js @@ -1,4 +1,3 @@ 'use strict'; - // Use application configuration module to register a new module -ApplicationConfiguration.registerModule('graphs'); +ApplicationConfiguration.registerModule('graphs'); \ No newline at end of file diff --git a/public/modules/graphs/lib/highcharts-ng.js b/public/modules/graphs/lib/highcharts-ng.js index f122934..fcdf348 100644 --- a/public/modules/graphs/lib/highcharts-ng.js +++ b/public/modules/graphs/lib/highcharts-ng.js @@ -1,17 +1,15 @@ -if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.exports === exports){ +if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.exports === exports) { module.exports = 'highcharts-ng'; } - (function () { 'use strict'; /*global angular: false, Highcharts: false */ - - - angular.module('highcharts-ng', []) - .provider('highchartsNG', highchartsNGProvider) - .directive('highchart', ['highchartsNG', '$timeout', highchart]); - - function highchartsNGProvider(){ + angular.module('highcharts-ng', []).provider('highchartsNG', highchartsNGProvider).directive('highchart', [ + 'highchartsNG', + '$timeout', + highchart + ]); + function highchartsNGProvider() { var modules = []; var basePath = false; var lazyLoad = false; @@ -29,24 +27,31 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex } lazyLoad = true; }, - $get: ['$window', '$rootScope', function ($window, $rootScope) { - if (!basePath) { - basePath = (window.location.protocol === 'https:' ? 'https' : 'http') + '://code.highcharts.com/'; + $get: [ + '$window', + '$rootScope', + function ($window, $rootScope) { + if (!basePath) { + basePath = (window.location.protocol === 'https:' ? 'https' : 'http') + '://code.highcharts.com/'; + } + return highchartsNG($window, $rootScope, lazyLoad, basePath, modules); } - return highchartsNG($window, $rootScope, lazyLoad, basePath, modules); - }] + ] }; } function highchartsNG($window, $rootScope, lazyload, basePath, modules) { var readyQueue = []; var loading = false; return { - lazyLoad:lazyload, + lazyLoad: lazyload, ready: function (callback, thisArg) { if (typeof $window.Highcharts !== 'undefined' || !lazyload) { callback(); } else { - readyQueue.push([callback, thisArg]); + readyQueue.push([ + callback, + thisArg + ]); if (loading) { return; } @@ -80,16 +85,18 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex document.getElementsByTagName('body')[0].appendChild(s); }, //IE8 support - indexOf: function (arr, find, i /*opt*/) { - if (i === undefined) i = 0; - if (i < 0) i += arr.length; - if (i < 0) i = 0; + indexOf: function (arr, find, i) { + if (i === undefined) + i = 0; + if (i < 0) + i += arr.length; + if (i < 0) + i = 0; for (var n = arr.length; i < n; i++) if (i in arr && arr[i] === find) return i; return -1; }, - prependMethod: function (obj, method, func) { var original = obj[method]; obj[method] = function () { @@ -100,10 +107,8 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex } else { return; } - }; }, - deepExtend: function deepExtend(destination, source) { //Slightly strange behaviour in edge cases (e.g. passing in non objects) //But does the job for current use cases. @@ -124,14 +129,12 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex } }; } - function highchart(highchartsNGUtils, $timeout) { - // acceptable shared state var seriesId = 0; var ensureIds = function (series) { var changed = false; - angular.forEach(series, function(s) { + angular.forEach(series, function (s) { if (!angular.isDefined(s.id)) { s.id = 'series-' + seriesId++; changed = true; @@ -139,51 +142,40 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex }); return changed; }; - // immutable - var axisNames = [ 'xAxis', 'yAxis' ]; + var axisNames = [ + 'xAxis', + 'yAxis' + ]; var chartTypeMap = { 'stock': 'StockChart', - 'map': 'Map', + 'map': 'Map', 'chart': 'Chart' }; - var getMergedOptions = function (scope, element, config) { var mergedOptions = {}; - var defaultOptions = { - chart: { - events: {} - }, + chart: { events: {} }, title: {}, subtitle: {}, series: [], credits: {}, plotOptions: {}, - navigator: {enabled: false}, - xAxis: { - events: {} - }, - yAxis: { - events: {} - } + navigator: { enabled: false }, + xAxis: { events: {} }, + yAxis: { events: {} } }; - if (config.options) { mergedOptions = highchartsNGUtils.deepExtend(defaultOptions, config.options); } else { mergedOptions = defaultOptions; } mergedOptions.chart.renderTo = element[0]; - - angular.forEach(axisNames, function(axisName) { - if(angular.isDefined(config[axisName])) { + angular.forEach(axisNames, function (axisName) { + if (angular.isDefined(config[axisName])) { mergedOptions[axisName] = highchartsNGUtils.deepExtend(mergedOptions[axisName] || {}, config[axisName]); - - if(angular.isDefined(config[axisName].currentMin) || - angular.isDefined(config[axisName].currentMax)) { - - highchartsNGUtils.prependMethod(mergedOptions.chart.events, 'selection', function(e){ + if (angular.isDefined(config[axisName].currentMin) || angular.isDefined(config[axisName].currentMax)) { + highchartsNGUtils.prependMethod(mergedOptions.chart.events, 'selection', function (e) { var thisChart = this; if (e[axisName]) { scope.$apply(function () { @@ -198,17 +190,18 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex }); } }); - - highchartsNGUtils.prependMethod(mergedOptions.chart.events, 'addSeries', function(e){ + highchartsNGUtils.prependMethod(mergedOptions.chart.events, 'addSeries', function (e) { scope.config[axisName].currentMin = this[axisName][0].min || scope.config[axisName].currentMin; scope.config[axisName].currentMax = this[axisName][0].max || scope.config[axisName].currentMax; }); highchartsNGUtils.prependMethod(mergedOptions[axisName].events, 'setExtremes', function (e) { - if (e.trigger && e.trigger !== 'zoom') { // zoom trigger is handled by selection event + if (e.trigger && e.trigger !== 'zoom') { + // zoom trigger is handled by selection event $timeout(function () { scope.config[axisName].currentMin = e.min; scope.config[axisName].currentMax = e.max; - scope.config[axisName].min = e.min; // set min and max to adjust scrollbar/navigator + scope.config[axisName].min = e.min; + // set min and max to adjust scrollbar/navigator scope.config[axisName].max = e.max; }, 0); } @@ -216,8 +209,7 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex } } }); - - if(config.title) { + if (config.title) { mergedOptions.title = config.title; } if (config.subtitle) { @@ -226,7 +218,7 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex if (config.credits) { mergedOptions.credits = config.credits; } - if(config.size) { + if (config.size) { if (config.size.width) { mergedOptions.chart.width = config.size.width; } @@ -236,10 +228,9 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex } return mergedOptions; }; - var updateZoom = function (axis, modelAxis) { var extremes = axis.getExtremes(); - if(modelAxis.currentMin !== extremes.dataMin || modelAxis.currentMax !== extremes.dataMax) { + if (modelAxis.currentMin !== extremes.dataMin || modelAxis.currentMax !== extremes.dataMax) { if (axis.setExtremes) { axis.setExtremes(modelAxis.currentMin, modelAxis.currentMax, false); } else { @@ -247,26 +238,22 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex } } }; - - var processExtremes = function(chart, axis, axisName) { - if(axis.currentMin || axis.currentMax) { + var processExtremes = function (chart, axis, axisName) { + if (axis.currentMin || axis.currentMax) { chart[axisName][0].setExtremes(axis.currentMin, axis.currentMax, true); } }; - var chartOptionsWithoutEasyOptions = function (options) { - return angular.extend( - highchartsNGUtils.deepExtend({}, options), - { data: null, visible: null } - ); + return angular.extend(highchartsNGUtils.deepExtend({}, options), { + data: null, + visible: null + }); }; - - var getChartType = function(scope) { - if (scope.config === undefined) return 'Chart'; - return chartTypeMap[('' + scope.config.chartType).toLowerCase()] || - (scope.config.useHighStocks ? 'StockChart' : 'Chart'); + var getChartType = function (scope) { + if (scope.config === undefined) + return 'Chart'; + return chartTypeMap[('' + scope.config.chartType).toLowerCase()] || (scope.config.useHighStocks ? 'StockChart' : 'Chart'); }; - var res = { restrict: 'EAC', replace: true, @@ -278,31 +265,24 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex link: function (scope, element, attrs) { // We keep some chart-specific variables here as a closure // instead of storing them on 'scope'. - // prevSeriesOptions is maintained by processSeries var prevSeriesOptions = {}; - - var processSeries = function(series) { + var processSeries = function (series) { var i; var ids = []; - - if(series) { + if (series) { var setIds = ensureIds(series); - if(setIds && !scope.disableDataWatch) { + if (setIds && !scope.disableDataWatch) { //If we have set some ids this will trigger another digest cycle. //In this scenario just return early and let the next cycle take care of changes return false; } - //remove all existing series - while( chart.series.length > 0 ) { - chart.series[0].remove( false ); + while (chart.series.length > 0) { + chart.series[0].remove(false); } - //Find series to add or update - angular.forEach(series, function(s) { - - + angular.forEach(series, function (s) { //ids.push(s.id); //var chartSeries = chart.get(s.id); //if (chartSeries) { @@ -315,23 +295,18 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex // chartSeries.setData(angular.copy(s.data), false); // //} //} else { - chart.addSeries(angular.copy(s), false); - //} - //prevSeriesOptions[s.id] = chartOptionsWithoutEasyOptions(s); + chart.addSeries(angular.copy(s), false); //} + //prevSeriesOptions[s.id] = chartOptionsWithoutEasyOptions(s); }); - // Shows no data text if all series are empty - if(scope.config.noData) { + if (scope.config.noData) { var chartContainsData = false; - - for(i = 0; i < series.length; i++) { + for (i = 0; i < series.length; i++) { if (series[i].data && series[i].data.length > 0) { chartContainsData = true; - break; } } - if (!chartContainsData) { chart.showLoading(scope.config.noData); } else { @@ -339,7 +314,6 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex } } } - //Now remove any missing series //for(i = chart.series.length - 1; i >= 0; i--) { // var s = chart.series[i]; @@ -347,39 +321,33 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex // s.remove(false); // } //} - return true; }; - // chart is maintained by initChart var chart = false; - var initChart = function() { - if (chart) chart.destroy(); + var initChart = function () { + if (chart) + chart.destroy(); prevSeriesOptions = {}; var config = scope.config || {}; var mergedOptions = getMergedOptions(scope, element, config); var func = config.func || undefined; var chartType = getChartType(scope); - chart = new Highcharts[chartType](mergedOptions, func); - for (var i = 0; i < axisNames.length; i++) { if (config[axisNames[i]]) { processExtremes(chart, config[axisNames[i]], axisNames[i]); } } - if(config.loading) { + if (config.loading) { chart.showLoading(); } - config.getHighcharts = function() { + config.getHighcharts = function () { return chart; }; - }; initChart(); - - - if(scope.disableDataWatch){ + if (scope.disableDataWatch) { scope.$watchCollection('config.series', function (newSeries, oldSeries) { processSeries(newSeries); chart.redraw(); @@ -387,33 +355,29 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex } else { scope.$watch('config.series', function (newSeries, oldSeries) { var needsRedraw = processSeries(newSeries); - if(needsRedraw) { + if (needsRedraw) { chart.redraw(); } }, true); } - scope.$watch('config.title', function (newTitle) { chart.setTitle(newTitle, true); }, true); - scope.$watch('config.subtitle', function (newSubtitle) { chart.setTitle(true, newSubtitle); }, true); - scope.$watch('config.loading', function (loading) { - if(loading) { + if (loading) { chart.showLoading(loading === true ? null : loading); } else { chart.hideLoading(); } }); scope.$watch('config.noData', function (noData) { - if(scope.config && scope.config.loading) { + if (scope.config && scope.config.loading) { chart.showLoading(noData); } }, true); - scope.$watch('config.credits.enabled', function (enabled) { if (enabled) { chart.credits.show(); @@ -421,85 +385,73 @@ if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.ex chart.credits.hide(); } }); - scope.$watch(getChartType, function (chartType, oldChartType) { - if (chartType === oldChartType) return; + if (chartType === oldChartType) + return; initChart(); }); - - angular.forEach(axisNames, function(axisName) { - scope.$watch('config.' + axisName, function(newAxes, oldAxes) { + angular.forEach(axisNames, function (axisName) { + scope.$watch('config.' + axisName, function (newAxes, oldAxes) { if (newAxes === oldAxes || !newAxes) { return; } - if (angular.isArray(newAxes)) { - for (var axisIndex = 0; axisIndex < newAxes.length; axisIndex++) { var axis = newAxes[axisIndex]; - if (axisIndex < chart[axisName].length) { chart[axisName][axisIndex].update(axis, false); updateZoom(chart[axisName][axisIndex], angular.copy(axis)); } - } - } else { // update single axis chart[axisName][0].update(newAxes, false); updateZoom(chart[axisName][0], angular.copy(newAxes)); } - chart.redraw(); }, true); }); scope.$watch('config.options', function (newOptions, oldOptions, scope) { //do nothing when called on registration - if (newOptions === oldOptions) return; + if (newOptions === oldOptions) + return; initChart(); processSeries(scope.config.series); chart.redraw(); }, true); - scope.$watch('config.size', function (newSize, oldSize) { - if(newSize === oldSize) return; - if(newSize) { + if (newSize === oldSize) + return; + if (newSize) { chart.setSize(newSize.width || chart.chartWidth, newSize.height || chart.chartHeight); } }, true); - scope.$on('highchartsng.reflow', function () { chart.reflow(); }); - - scope.$on('$destroy', function() { + scope.$on('$destroy', function () { if (chart) { - try{ + try { chart.destroy(); - }catch(ex){ - // fail silently as highcharts will throw exception if element doesn't exist + } catch (ex) { } - - $timeout(function(){ + $timeout(function () { element.remove(); }, 0); } }); - } }; - // override link fn if lazy loading is enabled - if(highchartsNGUtils.lazyLoad){ + if (highchartsNGUtils.lazyLoad) { var oldLink = res.link; - res.link = function(){ + res.link = function () { var args = arguments; - highchartsNGUtils.ready(function(){ + highchartsNGUtils.ready(function () { oldLink.apply(this, args); }, this); }; } return res; } -}()); +}()); \ No newline at end of file diff --git a/public/modules/graphs/services/gatling-console-details.client.service.js b/public/modules/graphs/services/gatling-console-details.client.service.js index 2f9ab69..5e40582 100644 --- a/public/modules/graphs/services/gatling-console-details.client.service.js +++ b/public/modules/graphs/services/gatling-console-details.client.service.js @@ -1,18 +1,15 @@ 'use strict'; - -angular.module('graphs').factory('GatlingConsoleDetails', ['$http', - function($http) { - var GatlingConsoleDetails = { - getData: getData - }; - - return GatlingConsoleDetails; - - function getData(consoleUrl, running){ - - var postData = {consoleUrl: consoleUrl, running: running }; - - return $http.post('/jenkins-stdout', postData); - } - } -]); +angular.module('graphs').factory('GatlingConsoleDetails', [ + '$http', + function ($http) { + var GatlingConsoleDetails = { getData: getData }; + return GatlingConsoleDetails; + function getData(consoleUrl, running) { + var postData = { + consoleUrl: consoleUrl, + running: running + }; + return $http.post('/jenkins-stdout', postData); + } + } +]); \ No newline at end of file diff --git a/public/modules/graphs/services/graphite.client.service.js b/public/modules/graphs/services/graphite.client.service.js index 3a5cc0c..004d33d 100644 --- a/public/modules/graphs/services/graphite.client.service.js +++ b/public/modules/graphs/services/graphite.client.service.js @@ -1,228 +1,148 @@ 'use strict'; - -angular.module('graphs').factory('Graphite', ['$http','$q', '$log', '$state', 'Events', 'Utils', - function($http, $q, $log, $state, Events, Utils) { - - var Graphite = { - getData: getData, - addEvents: addEvents//, - //createHighstockSeries: createHighstockSeries - - }; - - return Graphite; - - - function addFlagData (series, events, productName, dashboardName, testRunId){ - - var flags = { - "type": "flags", - //"onSeries": series, - showInLegend: false, - "shape": "squarepin", - "events":{ - "click" : function (e){ - - Events.selected = {}; - - Events.selected.productName = productName; - Events.selected.dashboardName = dashboardName; - Events.selected.testRunId = testRunId; - Events.selected._id = e.point.id; - Events.selected.eventTimestamp = e.point.x; - Events.selected.eventDescription = e.point.text; - - - $state.go('editEvent', { - "productName": productName, - "dashboardName": dashboardName, - "eventId": e.point.id - }); - - } - } - - }; - - var flagsData = []; - var sortedEvents = events.sort(Utils.dynamicSort('eventTimestamp')); - var eventDescriptionPattern = new RegExp(/^([0-9]+)/); - var eventIndex = 1; - - - _.each(sortedEvents, function(event, i){ - if(event.eventDescription !== 'start' && event.eventDescription !== 'end') { - - var epochTimestamp = new Date(event.eventTimestamp).getTime(); - - var eventTitle = (eventDescriptionPattern.test(event.eventDescription)) ? event.eventDescription.match(eventDescriptionPattern)[1] : eventIndex; - - - flagsData.push({x: epochTimestamp, - title: eventTitle, - text: event.eventDescription, - id: event._id - }); - eventIndex++; - } - }) - - flags.data = flagsData; - - - series.push(flags); - - return series; - - } - - function addEvents(series, from, until, productName, dashboardName, testRunId){ - - var deferred = $q.defer(); - var promise = deferred.promise; - - var convertedFrom = convertTime(from); - var convertedUntil = convertTime(until); - - Events.listEventsForTestRun(productName, dashboardName, convertedFrom, convertedUntil) - .success(function(events){ - deferred.resolve( - addFlagData (series, events, productName, dashboardName, testRunId) - ) - }).error(function(msg, code) { - deferred.reject(msg); - $log.error(msg, code); - }); - - - return promise; - +angular.module('graphs').factory('Graphite', [ + '$http', + '$q', + '$log', + '$state', + 'Events', + 'Utils', + function ($http, $q, $log, $state, Events, Utils) { + var Graphite = { + getData: getData, + addEvents: addEvents //, + //createHighstockSeries: createHighstockSeries + }; + return Graphite; + function addFlagData(series, events, productName, dashboardName, testRunId) { + var flags = { + 'type': 'flags', + //"onSeries": series, + showInLegend: false, + 'shape': 'squarepin', + 'events': { + 'click': function (e) { + Events.selected = {}; + Events.selected.productName = productName; + Events.selected.dashboardName = dashboardName; + Events.selected.testRunId = testRunId; + Events.selected._id = e.point.id; + Events.selected.eventTimestamp = e.point.x; + Events.selected.eventDescription = e.point.text; + $state.go('editEvent', { + 'productName': productName, + 'dashboardName': dashboardName, + 'eventId': e.point.id + }); + } } - - function createChartSeries (graphiteData){ - - var series = []; - for (var j = 0; j < graphiteData.length; j++) { - - var data = []; - - for (var i = 0; i < graphiteData[j].datapoints.length; i++) { - - if (graphiteData[j].datapoints[i][0] !== null) { - - data.push([graphiteData[j].datapoints[i][1] * 1000, graphiteData[j].datapoints[i][0]]); - - } - - } - - if(data.length > 0){ - - series.push({ - name: graphiteData[j].target, - data: data, - tooltip: { - yDecimals: 0 - } - }); - } - } - - return series; - - + }; + var flagsData = []; + var sortedEvents = events.sort(Utils.dynamicSort('eventTimestamp')); + var eventDescriptionPattern = new RegExp(/^([0-9]+)/); + var eventIndex = 1; + _.each(sortedEvents, function (event, i) { + if (event.eventDescription !== 'start' && event.eventDescription !== 'end') { + var epochTimestamp = new Date(event.eventTimestamp).getTime(); + var eventTitle = eventDescriptionPattern.test(event.eventDescription) ? event.eventDescription.match(eventDescriptionPattern)[1] : eventIndex; + flagsData.push({ + x: epochTimestamp, + title: eventTitle, + text: event.eventDescription, + id: event._id + }); + eventIndex++; } - - - - function getData(from, until, targets, maxDataPoints) { - - var urlEncodedTargetUrl = ''; - - var queryFrom = /^\d+$/.test(from) ? Math.round(from / 1000) : from; - var queryUntil = /^\d+$/.test(until) ? Math.round(until / 1000) : until; - - _.each(targets, function(target){ - - urlEncodedTargetUrl = urlEncodedTargetUrl + '&target=' + encodeURI(target); - - }); - - var deferred = $q.defer(); - var promise = deferred.promise; - - - $http.jsonp('/graphite?' + urlEncodedTargetUrl + '&from=' + queryFrom + '&until=' + queryUntil + '&maxDataPoints=' + maxDataPoints + '&callback=JSON_CALLBACK') - .success(function(graphiteData) { - deferred.resolve( - createChartSeries(graphiteData) - ) - - }).error(function(msg, code) { - deferred.reject(msg); - $log.error(msg, code); - }); - - return promise; + }); + flags.data = flagsData; + series.push(flags); + return series; + } + function addEvents(series, from, until, productName, dashboardName, testRunId) { + var deferred = $q.defer(); + var promise = deferred.promise; + var convertedFrom = convertTime(from); + var convertedUntil = convertTime(until); + Events.listEventsForTestRun(productName, dashboardName, convertedFrom, convertedUntil).success(function (events) { + deferred.resolve(addFlagData(series, events, productName, dashboardName, testRunId)); + }).error(function (msg, code) { + deferred.reject(msg); + $log.error(msg, code); + }); + return promise; + } + function createChartSeries(graphiteData) { + var series = []; + for (var j = 0; j < graphiteData.length; j++) { + var data = []; + for (var i = 0; i < graphiteData[j].datapoints.length; i++) { + if (graphiteData[j].datapoints[i][0] !== null) { + data.push([ + graphiteData[j].datapoints[i][1] * 1000, + graphiteData[j].datapoints[i][0] + ]); + } } - - - - function convertTime(inputTime){ - - var outputTime; - var inputTimePattern = new RegExp(/-([0-9]+)(h|d|w|mon|min|y|2)/); - var numberOf = (inputTimePattern.test(inputTime)) ? inputTime.match(inputTimePattern)[1] : ""; - var timeUnit = (inputTimePattern.test(inputTime)) ? inputTime.match(inputTimePattern)[2] : ""; - if (inputTime == "now"){ - - outputTime = new Date().getTime(); - }else { - - switch (timeUnit) { - - - case "s": - - outputTime = new Date() - numberOf - break; - - case "min": - - outputTime = new Date() - (numberOf * 60 * 1000) - break; - - case "h": - - outputTime = new Date() - (numberOf * 3600 * 1000) - break; - - - case "d": - - outputTime = new Date() - (numberOf * 3600 * 24 * 1000) - break; - - case "w": - - outputTime = new Date() - (numberOf * 3600 * 24 * 7 * 1000) - break; - - case "mon": - - outputTime = new Date() - (numberOf * 3600 * 24 * 7 * 30 * 1000) - break; - - default: - - outputTime = inputTime;//Math.round(inputTime / 1000); - break; - } + if (data.length > 0) { + series.push({ + name: graphiteData[j].target, + data: data, + tooltip: { yDecimals: 0 } + }); } - - return outputTime; - + } + return series; + } + function getData(from, until, targets, maxDataPoints) { + var urlEncodedTargetUrl = ''; + var queryFrom = /^\d+$/.test(from) ? Math.round(from / 1000) : from; + var queryUntil = /^\d+$/.test(until) ? Math.round(until / 1000) : until; + _.each(targets, function (target) { + urlEncodedTargetUrl = urlEncodedTargetUrl + '&target=' + encodeURI(target); + }); + var deferred = $q.defer(); + var promise = deferred.promise; + $http.jsonp('/graphite?' + urlEncodedTargetUrl + '&from=' + queryFrom + '&until=' + queryUntil + '&maxDataPoints=' + maxDataPoints + '&callback=JSON_CALLBACK').success(function (graphiteData) { + deferred.resolve(createChartSeries(graphiteData)); + }).error(function (msg, code) { + deferred.reject(msg); + $log.error(msg, code); + }); + return promise; } - + function convertTime(inputTime) { + var outputTime; + var inputTimePattern = new RegExp(/-([0-9]+)(h|d|w|mon|min|y|2)/); + var numberOf = inputTimePattern.test(inputTime) ? inputTime.match(inputTimePattern)[1] : ''; + var timeUnit = inputTimePattern.test(inputTime) ? inputTime.match(inputTimePattern)[2] : ''; + if (inputTime == 'now') { + outputTime = new Date().getTime(); + } else { + switch (timeUnit) { + case 's': + outputTime = new Date() - numberOf; + break; + case 'min': + outputTime = new Date() - numberOf * 60 * 1000; + break; + case 'h': + outputTime = new Date() - numberOf * 3600 * 1000; + break; + case 'd': + outputTime = new Date() - numberOf * 3600 * 24 * 1000; + break; + case 'w': + outputTime = new Date() - numberOf * 3600 * 24 * 7 * 1000; + break; + case 'mon': + outputTime = new Date() - numberOf * 3600 * 24 * 7 * 30 * 1000; + break; + default: + outputTime = inputTime; + //Math.round(inputTime / 1000); + break; + } + } + return outputTime; } -]); + } +]); \ No newline at end of file diff --git a/public/modules/graphs/services/interval.client.service.js b/public/modules/graphs/services/interval.client.service.js index e22274c..22ae2d8 100644 --- a/public/modules/graphs/services/interval.client.service.js +++ b/public/modules/graphs/services/interval.client.service.js @@ -1,41 +1,24 @@ 'use strict'; - -angular.module('graphs').factory('Interval', [ - function() { - - var Interval = { - clearAll: clearAll, - active: [], - clearIntervalForMetric: clearIntervalForMetric - - }; - - return Interval; - - - function clearIntervalForMetric (metricId){ - - _.each(Interval.active, function(intervalObject, i){ - - if(intervalObject.metricId === metricId){ - clearInterval(intervalObject.intervalId); - - } - }) - - Interval.active =_.reject(Interval.active, function(intervalObject ){ - - return intervalObject.metricId === metricId; - }) +angular.module('graphs').factory('Interval', [function () { + var Interval = { + clearAll: clearAll, + active: [], + clearIntervalForMetric: clearIntervalForMetric + }; + return Interval; + function clearIntervalForMetric(metricId) { + _.each(Interval.active, function (intervalObject, i) { + if (intervalObject.metricId === metricId) { + clearInterval(intervalObject.intervalId); } - - function clearAll(){ - - _.each(Interval.active, function(intervalObject){ - - clearInterval(intervalObject.intervalId); - }) - } - + }); + Interval.active = _.reject(Interval.active, function (intervalObject) { + return intervalObject.metricId === metricId; + }); + } + function clearAll() { + _.each(Interval.active, function (intervalObject) { + clearInterval(intervalObject.intervalId); + }); } -]); + }]); \ No newline at end of file diff --git a/public/modules/graphs/services/tags.client.service.js b/public/modules/graphs/services/tags.client.service.js index b02ae81..a6b1832 100644 --- a/public/modules/graphs/services/tags.client.service.js +++ b/public/modules/graphs/services/tags.client.service.js @@ -1,87 +1,80 @@ 'use strict'; - -angular.module('graphs').factory('Tags', ['Utils', 'TestRuns', - function(Utils, TestRuns) { - - var Tags = { - setTags: setTags, - getTagIndex: getTagIndex - //createHighstockSeries: createHighstockSeries - - }; - - return Tags; - - function getTagIndex(tag, tags){ - - var index; - - _.each(tags, function(tagObj, i){ - - if (tagObj.text === tag) return index = i; - - }) - - return index; +angular.module('graphs').factory('Tags', [ + 'Utils', + 'TestRuns', + function (Utils, TestRuns) { + var Tags = { + setTags: setTags, + getTagIndex: getTagIndex //createHighstockSeries: createHighstockSeries + }; + return Tags; + function getTagIndex(tag, tags) { + var index; + _.each(tags, function (tagObj, i) { + if (tagObj.text === tag) + return index = i; + }); + return index; + } + function setTags(metrics, productName, dashBoardName, testRunId, dashboardTags) { + var tags = []; + tags.push({ + text: 'All', + route: { + productName: productName, + dashboardName: dashBoardName, + tag: 'All' } - - function setTags (metrics, productName, dashBoardName, testRunId, dashboardTags){ - - var tags = []; - - - tags.push({text: 'All', route: {productName: productName, dashboardName: dashBoardName, tag: 'All'}}); - - _.each(metrics, function(metric){ - - _.each(metric.tags, function(tag){ - - if(tagExists(tags, tag)) tags.push({text: tag.text, route: {productName: productName, dashboardName: dashBoardName, tag: tag.text, testRunId: testRunId}}); - - }) - + }); + _.each(metrics, function (metric) { + _.each(metric.tags, function (tag) { + if (tagExists(tags, tag)) + tags.push({ + text: tag.text, + route: { + productName: productName, + dashboardName: dashBoardName, + tag: tag.text, + testRunId: testRunId + } }); - - /* add filter tags */ - _.each(dashboardTags, function(dashboardTag){ - - if(dashboardTag.text.indexOf(" AND ") > -1 || dashboardTag.text.indexOf(" OR ") > -1 ) { - - tags.push({text: dashboardTag.text, - route: { - productName: productName, - dashboardName: dashBoardName, - tag: dashboardTag.text, - testRunId: testRunId - } - }); - } - }); - - - tags.sort(Utils.dynamicSort('text')); - - //if available, add Gatling-details tab - if(TestRuns.selected && TestRuns.selected.buildResultKey){ - tags.unshift({text: 'Gatling', route: {productName: productName, dashboardName: dashBoardName, tag: 'Gatling'}}); - + }); + }); + /* add filter tags */ + _.each(dashboardTags, function (dashboardTag) { + if (dashboardTag.text.indexOf(' AND ') > -1 || dashboardTag.text.indexOf(' OR ') > -1) { + tags.push({ + text: dashboardTag.text, + route: { + productName: productName, + dashboardName: dashBoardName, + tag: dashboardTag.text, + testRunId: testRunId } - - - - return tags; - } - - function tagExists(existingTags, newTag){ - - var isNew = true; - - _.each(existingTags, function(existingTag){ - - if(existingTag.text === newTag.text) isNew = false; - }) - - return isNew; + }); } - } -]); + }); + tags.sort(Utils.dynamicSort('text')); + //if available, add Gatling-details tab + if (TestRuns.selected && TestRuns.selected.buildResultKey) { + tags.unshift({ + text: 'Gatling', + route: { + productName: productName, + dashboardName: dashBoardName, + tag: 'Gatling' + } + }); + } + return tags; + } + function tagExists(existingTags, newTag) { + var isNew = true; + _.each(existingTags, function (existingTag) { + if (existingTag.text === newTag.text) + isNew = false; + }); + return isNew; + } + } +]); \ No newline at end of file diff --git a/public/modules/graphs/services/utils.client.service.js b/public/modules/graphs/services/utils.client.service.js index 2930bff..704a32d 100644 --- a/public/modules/graphs/services/utils.client.service.js +++ b/public/modules/graphs/services/utils.client.service.js @@ -1,55 +1,40 @@ 'use strict'; - // service used for Utilty functions -angular.module('graphs').service('Utils', [ - - function() { - - - var Utils = { - dynamicSort: dynamicSort, - dynamicSortMultiple: dynamicSortMultiple, - selectedIndex : '' - +angular.module('graphs').service('Utils', [function () { + var Utils = { + dynamicSort: dynamicSort, + dynamicSortMultiple: dynamicSortMultiple, + selectedIndex: '' + }; + return Utils; + function dynamicSort(property) { + var sortOrder = 1; + if (property[0] === '-') { + sortOrder = -1; + property = property.substr(1); + } + return function (a, b) { + var result = a[property] < b[property] ? -1 : a[property] > b[property] ? 1 : 0; + return result * sortOrder; + }; } - - return Utils; - - function dynamicSort(property) { - - - - var sortOrder = 1; - if(property[0] === "-") { - sortOrder = -1; - property = property.substr(1); - } - return function (a,b) { - var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; - - - return result * sortOrder; - } - } - - function dynamicSortMultiple() { - /* - * save the arguments object as it will be overwritten - * note that arguments object is an array-like object - * consisting of the names of the properties to sort by - */ - var props = arguments; - return function (obj1, obj2) { - var i = 0, result = 0, numberOfProperties = props.length; - /* try getting a different result from 0 (equal) - * as long as we have extra properties to compare - */ - while(result === 0 && i < numberOfProperties) { - result = dynamicSort(props[i])(obj1, obj2); - i++; - } - return result; - } - } - } -]); + function dynamicSortMultiple() { + /* + * save the arguments object as it will be overwritten + * note that arguments object is an array-like object + * consisting of the names of the properties to sort by + */ + var props = arguments; + return function (obj1, obj2) { + var i = 0, result = 0, numberOfProperties = props.length; + /* try getting a different result from 0 (equal) + * as long as we have extra properties to compare + */ + while (result === 0 && i < numberOfProperties) { + result = dynamicSort(props[i])(obj1, obj2); + i++; + } + return result; + }; + } + }]); \ No newline at end of file diff --git a/public/modules/graphs/views/gatling-details.client.view.html b/public/modules/graphs/views/gatling-details.client.view.html index 1c80d21..87244e8 100644 --- a/public/modules/graphs/views/gatling-details.client.view.html +++ b/public/modules/graphs/views/gatling-details.client.view.html @@ -1,11 +1,11 @@
-
+
@@ -25,7 +25,7 @@
-
+
diff --git a/public/modules/graphs/views/graphs-live.client.view.html b/public/modules/graphs/views/graphs-live.client.view.html index a27ec76..58ab2ea 100644 --- a/public/modules/graphs/views/graphs-live.client.view.html +++ b/public/modules/graphs/views/graphs-live.client.view.html @@ -1,4 +1,4 @@ -
+
@@ -24,52 +24,64 @@ - - - - - - - - + + + + + + + + - + {{tag.text}} - - + + -
+
-
+
-
{{metric.alias}}
-
+ +
{{metric.alias}}
+
+
- - - + + +
- + -
+
- +
- -
-
+ +
+
diff --git a/public/modules/graphs/views/graphs.client.view.html b/public/modules/graphs/views/graphs.client.view.html index adbcc79..83cde22 100644 --- a/public/modules/graphs/views/graphs.client.view.html +++ b/public/modules/graphs/views/graphs.client.view.html @@ -11,7 +11,7 @@ Tag filter
- + @@ -22,10 +22,12 @@ - + {{tag.text}} - + + @@ -35,27 +37,40 @@
-
{{metric.alias}}
+ +
{{metric.alias}}
+
- - - + + +
- + -
+
- +
+
diff --git a/public/modules/graphs/views/tag-filter-modal.client.view.html b/public/modules/graphs/views/tag-filter-modal.client.view.html index c50a3ef..4fefdb8 100644 --- a/public/modules/graphs/views/tag-filter-modal.client.view.html +++ b/public/modules/graphs/views/tag-filter-modal.client.view.html @@ -3,7 +3,7 @@
- +
@@ -16,10 +16,11 @@

New Metric

- +
-
+
Add target
@@ -45,7 +46,7 @@

New Metric

- + @@ -67,7 +68,7 @@

New Metric

- + @@ -82,81 +83,81 @@

New Metric

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/public/modules/metrics/views/edit-metric.client.view.html b/public/modules/metrics/views/edit-metric.client.view.html index 722742f..3035672 100644 --- a/public/modules/metrics/views/edit-metric.client.view.html +++ b/public/modules/metrics/views/edit-metric.client.view.html @@ -3,7 +3,7 @@

Edit Metric

- +
@@ -16,7 +16,8 @@

Edit Metric

- +
@@ -45,7 +46,7 @@

Edit Metric

- + @@ -67,7 +68,7 @@

Edit Metric

- + @@ -83,91 +84,91 @@

Edit Metric

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/modules/products/config/products.client.config.js b/public/modules/products/config/products.client.config.js index 24c1eb2..5334d38 100644 --- a/public/modules/products/config/products.client.config.js +++ b/public/modules/products/config/products.client.config.js @@ -1,11 +1,11 @@ 'use strict'; - // Configuring the Articles module -angular.module('products').run(['Menus', - function(Menus) { - // Set top bar menu items - Menus.addMenuItem('topbar', 'Products', 'products', 'dropdown', '/products(/create)?'); - Menus.addSubMenuItem('topbar', 'products', 'List Products', 'products'); - Menus.addSubMenuItem('topbar', 'products', 'New Product', 'products/create'); - } +angular.module('products').run([ + 'Menus', + function (Menus) { + // Set top bar menu items + Menus.addMenuItem('topbar', 'Products', 'products', 'dropdown', '/products(/create)?'); + Menus.addSubMenuItem('topbar', 'products', 'List Products', 'products'); + Menus.addSubMenuItem('topbar', 'products', 'New Product', 'products/create'); + } ]); \ No newline at end of file diff --git a/public/modules/products/config/products.client.routes.js b/public/modules/products/config/products.client.routes.js index 6455dcb..c48b599 100644 --- a/public/modules/products/config/products.client.routes.js +++ b/public/modules/products/config/products.client.routes.js @@ -1,25 +1,21 @@ 'use strict'; - //Setting up route -angular.module('products').config(['$stateProvider', - function($stateProvider) { - // Products state routing - $stateProvider. - state('listProducts', { - url: '/products', - templateUrl: 'modules/products/views/list-products.client.view.html' - }). - state('createProduct', { - url: '/add/product', - templateUrl: 'modules/products/views/create-product.client.view.html' - }). - state('viewProduct', { - url: '/browse/:productName', - templateUrl: 'modules/products/views/view-product.client.view.html' - }). - state('editProduct', { - url: '/edit/product/:productName', - templateUrl: 'modules/products/views/edit-product.client.view.html' - }); - } -]); +angular.module('products').config([ + '$stateProvider', + function ($stateProvider) { + // Products state routing + $stateProvider.state('listProducts', { + url: '/products', + templateUrl: 'modules/products/views/list-products.client.view.html' + }).state('createProduct', { + url: '/add/product', + templateUrl: 'modules/products/views/create-product.client.view.html' + }).state('viewProduct', { + url: '/browse/:productName', + templateUrl: 'modules/products/views/view-product.client.view.html' + }).state('editProduct', { + url: '/edit/product/:productName', + templateUrl: 'modules/products/views/edit-product.client.view.html' + }); + } +]); \ No newline at end of file diff --git a/public/modules/products/controllers/products.client.controller.js b/public/modules/products/controllers/products.client.controller.js index 441dfdb..3128631 100644 --- a/public/modules/products/controllers/products.client.controller.js +++ b/public/modules/products/controllers/products.client.controller.js @@ -1,146 +1,102 @@ 'use strict'; - // Products controller -angular.module('products').controller('ProductsController', ['$scope', '$rootScope', '$stateParams', '$state', '$location', '$modal', 'Products', 'ConfirmModal','SideMenu', - function($scope, $rootScope, $stateParams, $state, $location, $modal, Products, ConfirmModal, SideMenu) { - - - $scope.initCreateForm = function(){ - - /* reset form */ - $scope.product = {}; - } +angular.module('products').controller('ProductsController', [ + '$scope', + '$rootScope', + '$stateParams', + '$state', + '$location', + '$modal', + 'Products', + 'ConfirmModal', + 'SideMenu', + function ($scope, $rootScope, $stateParams, $state, $location, $modal, Products, ConfirmModal, SideMenu) { + $scope.initCreateForm = function () { + /* reset form */ + $scope.product = {}; + }; + $scope.product = Products.selected; + // Create new Product + $scope.create = function () { + // Create new Product object + var product = {}; + product.name = this.product.name; + product.description = this.product.description; + Products.create(product).then(function (response) { + Products.fetch().success(function (products) { + SideMenu.addProducts(products); + $scope.products = Products.items; + $state.go('viewProduct', { productName: response.data.name }); + $scope.productForm.$setPristine(); + }); + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; + // Edit Product + $scope.edit = function (productName) { + $state.go('editProduct', { productName: productName }); + }; + $scope.update = function () { + Products.update($scope.product).then(function (product) { + /* Refresh sidebar */ + Products.fetch().success(function (product) { + $scope.products = Products.items; + SideMenu.addProducts($scope.products); + }); + if ($rootScope.previousStateParams) + $state.go($rootScope.previousState, $rootScope.previousStateParams); + else + $state.go($rootScope.previousState); + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; + // Find a list of Products + $scope.find = function () { + $scope.products = Products.query(); + }; + // Find existing Product + $scope.findOne = function () { + Products.get($stateParams.productName).success(function (product) { + Products.selected = product; $scope.product = Products.selected; - - // Create new Product - $scope.create = function() { - // Create new Product object - var product = {}; - product.name = this.product.name; - product.description = this.product.description; - - - Products.create(product).then(function(response){ - - Products.fetch().success(function(products){ - - SideMenu.addProducts(products); - $scope.products = Products.items; - $state.go('viewProduct', {productName: response.data.name}); - $scope.productForm.$setPristine(); - - }); - - }, function(errorResponse) { - $scope.error = errorResponse.data.message; - }); - }; - - - // Edit Product - $scope.edit = function(productName) { - - $state.go('editProduct', {productName: productName}) - }; - - $scope.update = function() { - - Products.update($scope.product).then(function (product) { - - /* Refresh sidebar */ - Products.fetch().success(function(product){ - $scope.products = Products.items; - SideMenu.addProducts($scope.products); - - }); - - if ($rootScope.previousStateParams) - $state.go($rootScope.previousState, $rootScope.previousStateParams); - else - $state.go($rootScope.previousState); - - - }, function(errorResponse) { - $scope.error = errorResponse.data.message; - }); - - }; - - // Find a list of Products - $scope.find = function() { - $scope.products = Products.query(); - }; - - // Find existing Product - $scope.findOne = function() { - - Products.get($stateParams.productName).success(function(product){ - - Products.selected = product; - $scope.product = Products.selected; - - }); - - }; - - // Add dashboard to Product - $scope.addDashboard = function(product) { - - $location.path('/dashboards/create/' + product._id); - }; - - $scope.cancel = function () { - - Products.selected = {}; - - /* reset form*/ - $scope.productForm.$setPristine(); - - - if ($rootScope.previousStateParams) - $state.go($rootScope.previousState, $rootScope.previousStateParams); - else - $state.go($rootScope.previousState); - - - } - - - $scope.openDeleteProductModal = function (size) { - - - ConfirmModal.itemType = 'Delete product '; - ConfirmModal.selectedItemId = Products.selected._id; - ConfirmModal.selectedItemDescription = Products.selected.name; - - var modalInstance = $modal.open({ - templateUrl: 'ConfirmDelete.html', - controller: 'ModalInstanceController', - size: size//, - }); - - modalInstance.result.then(function (productName) { - - Products.delete(productName).success(function(product){ - - /* reset slected Product*/ - - Products.selected = {}; - - /* Refresh sidebar */ - Products.fetch().success(function(products){ - $scope.products = Products.items; - - }); - - $state.go('home'); - - }); - - }, function () { - //$log.info('Modal dismissed at: ' + new Date()); + }); + }; + // Add dashboard to Product + $scope.addDashboard = function (product) { + $location.path('/dashboards/create/' + product._id); + }; + $scope.cancel = function () { + Products.selected = {}; + /* reset form*/ + $scope.productForm.$setPristine(); + if ($rootScope.previousStateParams) + $state.go($rootScope.previousState, $rootScope.previousStateParams); + else + $state.go($rootScope.previousState); + }; + $scope.openDeleteProductModal = function (size) { + ConfirmModal.itemType = 'Delete product '; + ConfirmModal.selectedItemId = Products.selected._id; + ConfirmModal.selectedItemDescription = Products.selected.name; + var modalInstance = $modal.open({ + templateUrl: 'ConfirmDelete.html', + controller: 'ModalInstanceController', + size: size //, + }); + modalInstance.result.then(function (productName) { + Products.delete(productName).success(function (product) { + /* reset slected Product*/ + Products.selected = {}; + /* Refresh sidebar */ + Products.fetch().success(function (products) { + $scope.products = Products.items; + }); + $state.go('home'); }); + }, function () { + }); }; - -} -]); + } +]); \ No newline at end of file diff --git a/public/modules/products/css/ngTables.css b/public/modules/products/css/ngTables.css index 08d6e36..2bca15e 100644 --- a/public/modules/products/css/ngTables.css +++ b/public/modules/products/css/ngTables.css @@ -1 +1,3 @@ -.ng-table-pager { display: none; } \ No newline at end of file +.ng-table-pager { + display: none; +} diff --git a/public/modules/products/products.client.module.js b/public/modules/products/products.client.module.js index 1c22696..7cae0a6 100644 --- a/public/modules/products/products.client.module.js +++ b/public/modules/products/products.client.module.js @@ -1,4 +1,3 @@ 'use strict'; - // Use applicaion configuration module to register a new module ApplicationConfiguration.registerModule('products'); \ No newline at end of file diff --git a/public/modules/products/services/products.client.service.js b/public/modules/products/services/products.client.service.js index fa13691..5fb4d5d 100644 --- a/public/modules/products/services/products.client.service.js +++ b/public/modules/products/services/products.client.service.js @@ -1,56 +1,40 @@ 'use strict'; - //Products service used to communicate Products REST endpoints -angular.module('products').factory('Products', ['$resource', '$http', 'SideMenu', - function($resource, $http, SideMenu) { - - - var Products = { - items : [], - 'get' : getFn, - query : query, - fetch : fetch, - create: create, - delete: deleteFn, - update: update, - selected: {} - - }; - - return Products; - - - function create(product){ - return $http.post('/products', product); - } - - function update(product){ - return $http.put('/product-by-id/' + product._id, product); - } - - function deleteFn(productId){ - return $http.delete('/product-by-id/' + productId); - } - - function fetch(){ - return $http.get('/products').success(function(products){ - - - }); - } - - function getFn(productName){ - return $http.get('/products/' + productName); - } - - function query (a1, a2, a3, a4){ - var resource = $resource('products/:productId', { productName: '@_id' - }, { - update: { - method: 'PUT' - } - }); - return resource.query(a1, a2, a3, a4); - } - } -]); +angular.module('products').factory('Products', [ + '$resource', + '$http', + 'SideMenu', + function ($resource, $http, SideMenu) { + var Products = { + items: [], + 'get': getFn, + query: query, + fetch: fetch, + create: create, + delete: deleteFn, + update: update, + selected: {} + }; + return Products; + function create(product) { + return $http.post('/products', product); + } + function update(product) { + return $http.put('/product-by-id/' + product._id, product); + } + function deleteFn(productId) { + return $http.delete('/product-by-id/' + productId); + } + function fetch() { + return $http.get('/products').success(function (products) { + }); + } + function getFn(productName) { + return $http.get('/products/' + productName); + } + function query(a1, a2, a3, a4) { + var resource = $resource('products/:productId', { productName: '@_id' }, { update: { method: 'PUT' } }); + return resource.query(a1, a2, a3, a4); + } + } +]); \ No newline at end of file diff --git a/public/modules/products/tests/products.client.controller.test.js b/public/modules/products/tests/products.client.controller.test.js index 0007381..ddb95d1 100644 --- a/public/modules/products/tests/products.client.controller.test.js +++ b/public/modules/products/tests/products.client.controller.test.js @@ -1,163 +1,114 @@ 'use strict'; - -(function() { - // Products Controller Spec - describe('Products Controller Tests', function() { - // Initialize global variables - var ProductsController, - scope, - $httpBackend, - $stateParams, - $location; - - // The $resource service augments the response object with methods for updating and deleting the resource. - // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match - // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. - // When the toEqualData matcher compares two objects, it takes only object properties into - // account and ignores methods. - beforeEach(function() { - jasmine.addMatchers({ - toEqualData: function(util, customEqualityTesters) { - return { - compare: function(actual, expected) { - return { - pass: angular.equals(actual, expected) - }; - } - }; - } - }); - }); - - // Then we can start by loading the main application module - beforeEach(module(ApplicationConfiguration.applicationModuleName)); - - // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). - // This allows us to inject a service but then attach it to a variable - // with the same name as the service. - beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { - // Set a new global scope - scope = $rootScope.$new(); - - // Point global variables to injected services - $stateParams = _$stateParams_; - $httpBackend = _$httpBackend_; - $location = _$location_; - - // Initialize the Products controller. - ProductsController = $controller('ProductsController', { - $scope: scope - }); - })); - - it('$scope.find() should create an array with at least one Product object fetched from XHR', inject(function(Products) { - // Create sample Product using the Products service - var sampleProduct = new Products({ - name: 'New Product' - }); - - // Create a sample Products array that includes the new Product - var sampleProducts = [sampleProduct]; - - // Set GET response - $httpBackend.expectGET('products').respond(sampleProducts); - - // Run controller functionality - scope.find(); - $httpBackend.flush(); - - // Test scope value - expect(scope.products).toEqualData(sampleProducts); - })); - - it('$scope.findOne() should create an array with one Product object fetched from XHR using a productId URL parameter', inject(function(Products) { - // Define a sample Product object - var sampleProduct = new Products({ - name: 'New Product' - }); - - // Set the URL parameter - $stateParams.productId = '525a8422f6d0f87f0e407a33'; - - // Set GET response - $httpBackend.expectGET(/products\/([0-9a-fA-F]{24})$/).respond(sampleProduct); - - // Run controller functionality - scope.findOne(); - $httpBackend.flush(); - - // Test scope value - expect(scope.product).toEqualData(sampleProduct); - })); - - it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function(Products) { - // Create a sample Product object - var sampleProductPostData = new Products({ - name: 'New Product' - }); - - // Create a sample Product response - var sampleProductResponse = new Products({ - _id: '525cf20451979dea2c000001', - name: 'New Product' - }); - - // Fixture mock form input values - scope.name = 'New Product'; - - // Set POST response - $httpBackend.expectPOST('products', sampleProductPostData).respond(sampleProductResponse); - - // Run controller functionality - scope.create(); - $httpBackend.flush(); - - // Test form inputs are reset - expect(scope.name).toEqual(''); - - // Test URL redirection after the Product was created - expect($location.path()).toBe('/products/' + sampleProductResponse._id); - })); - - it('$scope.update() should update a valid Product', inject(function(Products) { - // Define a sample Product put data - var sampleProductPutData = new Products({ - _id: '525cf20451979dea2c000001', - name: 'New Product' - }); - - // Mock Product in scope - scope.product = sampleProductPutData; - - // Set PUT response - $httpBackend.expectPUT(/products\/([0-9a-fA-F]{24})$/).respond(); - - // Run controller functionality - scope.update(); - $httpBackend.flush(); - - // Test URL location to new object - expect($location.path()).toBe('/products/' + sampleProductPutData._id); - })); - - it('$scope.remove() should send a DELETE request with a valid productId and remove the Product from the scope', inject(function(Products) { - // Create new Product object - var sampleProduct = new Products({ - _id: '525a8422f6d0f87f0e407a33' - }); - - // Create new Products array and include the Product - scope.products = [sampleProduct]; - - // Set expected DELETE response - $httpBackend.expectDELETE(/products\/([0-9a-fA-F]{24})$/).respond(204); - - // Run controller functionality - scope.remove(sampleProduct); - $httpBackend.flush(); - - // Test array after successful delete - expect(scope.products.length).toBe(0); - })); - }); +(function () { + // Products Controller Spec + describe('Products Controller Tests', function () { + // Initialize global variables + var ProductsController, scope, $httpBackend, $stateParams, $location; + // The $resource service augments the response object with methods for updating and deleting the resource. + // If we were to use the standard toEqual matcher, our tests would fail because the test values would not match + // the responses exactly. To solve the problem, we define a new toEqualData Jasmine matcher. + // When the toEqualData matcher compares two objects, it takes only object properties into + // account and ignores methods. + beforeEach(function () { + jasmine.addMatchers({ + toEqualData: function (util, customEqualityTesters) { + return { + compare: function (actual, expected) { + return { pass: angular.equals(actual, expected) }; + } + }; + } + }); + }); + // Then we can start by loading the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); + // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). + // This allows us to inject a service but then attach it to a variable + // with the same name as the service. + beforeEach(inject(function ($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { + // Set a new global scope + scope = $rootScope.$new(); + // Point global variables to injected services + $stateParams = _$stateParams_; + $httpBackend = _$httpBackend_; + $location = _$location_; + // Initialize the Products controller. + ProductsController = $controller('ProductsController', { $scope: scope }); + })); + it('$scope.find() should create an array with at least one Product object fetched from XHR', inject(function (Products) { + // Create sample Product using the Products service + var sampleProduct = new Products({ name: 'New Product' }); + // Create a sample Products array that includes the new Product + var sampleProducts = [sampleProduct]; + // Set GET response + $httpBackend.expectGET('products').respond(sampleProducts); + // Run controller functionality + scope.find(); + $httpBackend.flush(); + // Test scope value + expect(scope.products).toEqualData(sampleProducts); + })); + it('$scope.findOne() should create an array with one Product object fetched from XHR using a productId URL parameter', inject(function (Products) { + // Define a sample Product object + var sampleProduct = new Products({ name: 'New Product' }); + // Set the URL parameter + $stateParams.productId = '525a8422f6d0f87f0e407a33'; + // Set GET response + $httpBackend.expectGET(/products\/([0-9a-fA-F]{24})$/).respond(sampleProduct); + // Run controller functionality + scope.findOne(); + $httpBackend.flush(); + // Test scope value + expect(scope.product).toEqualData(sampleProduct); + })); + it('$scope.create() with valid form data should send a POST request with the form input values and then locate to new object URL', inject(function (Products) { + // Create a sample Product object + var sampleProductPostData = new Products({ name: 'New Product' }); + // Create a sample Product response + var sampleProductResponse = new Products({ + _id: '525cf20451979dea2c000001', + name: 'New Product' + }); + // Fixture mock form input values + scope.name = 'New Product'; + // Set POST response + $httpBackend.expectPOST('products', sampleProductPostData).respond(sampleProductResponse); + // Run controller functionality + scope.create(); + $httpBackend.flush(); + // Test form inputs are reset + expect(scope.name).toEqual(''); + // Test URL redirection after the Product was created + expect($location.path()).toBe('/products/' + sampleProductResponse._id); + })); + it('$scope.update() should update a valid Product', inject(function (Products) { + // Define a sample Product put data + var sampleProductPutData = new Products({ + _id: '525cf20451979dea2c000001', + name: 'New Product' + }); + // Mock Product in scope + scope.product = sampleProductPutData; + // Set PUT response + $httpBackend.expectPUT(/products\/([0-9a-fA-F]{24})$/).respond(); + // Run controller functionality + scope.update(); + $httpBackend.flush(); + // Test URL location to new object + expect($location.path()).toBe('/products/' + sampleProductPutData._id); + })); + it('$scope.remove() should send a DELETE request with a valid productId and remove the Product from the scope', inject(function (Products) { + // Create new Product object + var sampleProduct = new Products({ _id: '525a8422f6d0f87f0e407a33' }); + // Create new Products array and include the Product + scope.products = [sampleProduct]; + // Set expected DELETE response + $httpBackend.expectDELETE(/products\/([0-9a-fA-F]{24})$/).respond(204); + // Run controller functionality + scope.remove(sampleProduct); + $httpBackend.flush(); + // Test array after successful delete + expect(scope.products.length).toBe(0); + })); + }); }()); \ No newline at end of file diff --git a/public/modules/products/views/create-product.client.view.html b/public/modules/products/views/create-product.client.view.html index 4156930..7695afd 100644 --- a/public/modules/products/views/create-product.client.view.html +++ b/public/modules/products/views/create-product.client.view.html @@ -6,26 +6,35 @@

New Product

- + - -
+ + +
Product name is required.
Checking database...
The product name already exists
- + -
+ +
Product description is required.
- Submit - Cancel + Submit + Cancel
diff --git a/public/modules/products/views/edit-product.client.view.html b/public/modules/products/views/edit-product.client.view.html index 0e3d967..f7aefa4 100644 --- a/public/modules/products/views/edit-product.client.view.html +++ b/public/modules/products/views/edit-product.client.view.html @@ -6,26 +6,35 @@

Edit Product

- + - -
+ + +
Product name is required.
Checking database...
The product name already exists
- + -
+ +
Product description is required.
- Submit - Cancel + Submit + Cancel
diff --git a/public/modules/products/views/view-product.client.view.html b/public/modules/products/views/view-product.client.view.html index 361950c..a439d1c 100644 --- a/public/modules/products/views/view-product.client.view.html +++ b/public/modules/products/views/view-product.client.view.html @@ -1,18 +1,20 @@
-
- +
diff --git a/public/modules/testruns/config/testruns.client.routes.js b/public/modules/testruns/config/testruns.client.routes.js index c9f6dfe..824f92e 100644 --- a/public/modules/testruns/config/testruns.client.routes.js +++ b/public/modules/testruns/config/testruns.client.routes.js @@ -1,25 +1,21 @@ 'use strict'; - //Setting up route -angular.module('testruns').config(['$stateProvider', - function($stateProvider) { - // Testruns state routing - $stateProvider. - state('viewTestruns', { - url: '/testruns/:productName/:dashboardName', - templateUrl: 'modules/testruns/views/testruns.client.view.html' - }). - state('requirementsTestRun', { - url: '/requirements/:productName/:dashboardName/:testRunId/:requirementsResult', - templateUrl: 'modules/testruns/views/requirements.client.view.html' - }). - state('benchmarkPreviousBuildTestRun', { - url: '/benchmark-previous-build/:productName/:dashboardName/:testRunId/:benchmarkResult', - templateUrl: 'modules/testruns/views/benchmark-previous-build.client.view.html' - }). - state('benchmarkFixedBaselineTestRun', { - url: '/benchmark-fixed-baseline/:productName/:dashboardName/:testRunId/:benchmarkResult', - templateUrl: 'modules/testruns/views/benchmark-fixed-baseline.client.view.html' - }); - } -]); +angular.module('testruns').config([ + '$stateProvider', + function ($stateProvider) { + // Testruns state routing + $stateProvider.state('viewTestruns', { + url: '/testruns/:productName/:dashboardName', + templateUrl: 'modules/testruns/views/testruns.client.view.html' + }).state('requirementsTestRun', { + url: '/requirements/:productName/:dashboardName/:testRunId/:requirementsResult', + templateUrl: 'modules/testruns/views/requirements.client.view.html' + }).state('benchmarkPreviousBuildTestRun', { + url: '/benchmark-previous-build/:productName/:dashboardName/:testRunId/:benchmarkResult', + templateUrl: 'modules/testruns/views/benchmark-previous-build.client.view.html' + }).state('benchmarkFixedBaselineTestRun', { + url: '/benchmark-fixed-baseline/:productName/:dashboardName/:testRunId/:benchmarkResult', + templateUrl: 'modules/testruns/views/benchmark-fixed-baseline.client.view.html' + }); + } +]); \ No newline at end of file diff --git a/public/modules/testruns/controllers/testruns.client.controller.js b/public/modules/testruns/controllers/testruns.client.controller.js index e7e38ac..4110e9d 100644 --- a/public/modules/testruns/controllers/testruns.client.controller.js +++ b/public/modules/testruns/controllers/testruns.client.controller.js @@ -1,241 +1,184 @@ 'use strict'; - -angular.module('testruns').controller('TestrunsController', ['$scope', '$stateParams', '$state', 'TestRuns', 'Dashboards', 'Events', '$modal', '$q', 'ConfirmModal', - function($scope, $stateParams, $state, TestRuns, Dashboards, Events, $modal, $q, ConfirmModal) { - - - $scope.productName = $stateParams.productName; - - $scope.dashboardName = $stateParams.dashboardName; - - - - - $scope.$watch(function (scope) { - return Dashboards.selected._id; - }, - function (newVal, oldVal) { - - if (newVal !== oldVal) { - - $scope.showBenchmarks = Dashboards.selected.useInBenchmark; - $scope.dashboard = Dashboards.selected; - $scope.loading = true; - $scope.getTestRuns = TestRuns.listTestRunsForDashboard($scope.productName, $scope.dashboardName, Dashboards.selected.useInBenchmark).success(function (testRuns){ - - - TestRuns.list = testRuns; - $scope.loading = false; - $scope.testRuns = TestRuns.list; - - }, function(errorResponse) { - $scope.error = errorResponse.data.message; - }); - - } - } - ); - - $scope.$watch(function (scope) { - return TestRuns.list; - }, - function (newVal, oldVal) { - - if (newVal !== oldVal) { - - $scope.testRuns = TestRuns.list; - - - } - } - ); - - /* List test runs for dashboard */ - - -// $scope.listTestRunsForDashboard = function() { -// -// $scope.loading = true; -// -// TestRuns.listTestRunsForDashboard($scope.productName, $scope.dashboardName).success(function (testRuns) { -// -// TestRuns.list = testRuns; -// $scope.testRuns = TestRuns.list; -// $scope.loading = false; -// -// }, function (errorResponse) { -// $scope.error = errorResponse.data.message; -// }); -// -// -// }; - - - - $scope.testRunDetails = function(index){ - - TestRuns.selected = $scope.testRuns[index]; - $state.go('viewGraphs',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : $scope.testRuns[index].testRunId, tag: Dashboards.getDefaultTag(Dashboards.selected.tags) }); - } - - - - $scope.testRunFixedBaselineBenchmark = function(index){ - - TestRuns.selected = $scope.testRuns[index]; - - var benchmarkFixedResult = $scope.testRuns[index].benchmarkResultFixedOK ? "passed" : "failed"; - - $state.go('benchmarkFixedBaselineTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : $scope.testRuns[index].testRunId, "benchmarkResult" : benchmarkFixedResult }); - - - } - - $scope.testRunPreviousBuildBenchmark = function(index){ - - TestRuns.selected = $scope.testRuns[index]; - - var benchmarkPreviousResult = $scope.testRuns[index].benchmarkResultPreviousOK ? "passed" : "failed"; - - $state.go('benchmarkPreviousBuildTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : $scope.testRuns[index].testRunId, "benchmarkResult" : benchmarkPreviousResult }); - - - } - - - $scope.testRunRequirements = function(index){ - - TestRuns.selected = $scope.testRuns[index]; - - var requirementsResult = $scope.testRuns[index].meetsRequirement ? "passed" : "failed"; - - $state.go('requirementsTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : $scope.testRuns[index].testRunId, "requirementsResult" : requirementsResult }); - - - } - - $scope.setTestRunAsBaseline = function(baseline) { - - var arrayOfPromises = []; - - Dashboards.selected.baseline = baseline; - - Dashboards.update().success(function (dashboard) { - - - Dashboards.selected = dashboard; - - $scope.dashboard = dashboard; - - var baselineSet = false; - - _.each($scope.testRuns, function(testRun, index){ - - /* Only update test runs more recent than baseline */ - if(testRun.testRunId === baseline) baselineSet = true; - - if(testRun.testRunId !== baseline && baselineSet == false) { - - testRun.baseline = baseline; - - arrayOfPromises.push(TestRuns.updateFixedBaseline(testRun).then(function(testRun){})); - - - //.success(function (updatedTestRun) { - -// $scope.testRuns[index] = updatedTestRun; -// $scope.testRuns[index].busy = false; -// -// -// }, function(errorResponse) { -// $scope.error = errorResponse.data.message; -// }); - } - }) - - - $q.all(arrayOfPromises).then(function(results){ - - /* refresh test runs*/ - setTimeout(function () { - TestRuns.listTestRunsForDashboard($scope.productName, $scope.dashboardName, Dashboards.selected.useInBenchmark).success(function (testRuns){ - - TestRuns.list = testRuns; - - }, function(errorResponse) { - $scope.error = errorResponse.data.message; - }); - }, 100); - - }); - }); - - } - - $scope.refreshTestrun = function(index){ - - $scope.testRuns[index].meetsRequirement = "pending"; - $scope.testRuns[index].benchmarkResultPreviousOK = "pending"; - $scope.testRuns[index].benchmarkResultFixedOK = "pending"; - $scope.testRuns[index].busy = true; - - - TestRuns.refreshTestrun($stateParams.productName,$stateParams.dashboardName, $scope.testRuns[index].testRunId).success(function (testRun){ - - $scope.testRuns[index] = testRun; - - $scope.testRuns[index].busy = false; - ///* refresh screen*/ - //setTimeout(function(){ - // $state.go($state.current, {}, {reload: true}); - //},1); - - }, function(errorResponse) { - $scope.error = errorResponse.data.message; - }); - - - } - - - $scope.openDeleteTestRunModal = function (size, index) { - - - ConfirmModal.itemType = 'Delete test run '; - ConfirmModal.selectedItemId = index; - ConfirmModal.selectedItemDescription = $scope.testRuns[index].testRunId; - - var modalInstance = $modal.open({ - templateUrl: 'ConfirmDelete.html', - controller: 'ModalInstanceController', - size: size//, +angular.module('testruns').controller('TestrunsController', [ + '$scope', + '$stateParams', + '$state', + 'TestRuns', + 'Dashboards', + 'Events', + '$modal', + '$q', + 'ConfirmModal', + '$window', + function ($scope, $stateParams, $state, TestRuns, Dashboards, Events, $modal, $q, ConfirmModal, $window) { + + $scope.productName = $stateParams.productName; + $scope.dashboardName = $stateParams.dashboardName; + + var originatorEv; + $scope.openMenu = function ($mdOpenMenu, ev) { + originatorEv = ev; + $mdOpenMenu(ev); + }; + + $scope.go = function (url) { + $window.location.href = url; + }; + + $scope.$watch(function (scope) { + return Dashboards.selected._id; + }, function (newVal, oldVal) { + if (newVal !== oldVal) { + $scope.showBenchmarks = Dashboards.selected.useInBenchmark; + $scope.dashboard = Dashboards.selected; + $scope.loading = true; + $scope.getTestRuns = TestRuns.listTestRunsForDashboard($scope.productName, $scope.dashboardName, Dashboards.selected.useInBenchmark).success(function (testRuns) { + TestRuns.list = testRuns; + $scope.loading = false; + $scope.testRuns = TestRuns.list; + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + } + }); + $scope.$watch(function (scope) { + return TestRuns.list; + }, function (newVal, oldVal) { + if (newVal !== oldVal) { + $scope.testRuns = TestRuns.list; + } + }); + /* List test runs for dashboard */ + // $scope.listTestRunsForDashboard = function() { + // + // $scope.loading = true; + // + // TestRuns.listTestRunsForDashboard($scope.productName, $scope.dashboardName).success(function (testRuns) { + // + // TestRuns.list = testRuns; + // $scope.testRuns = TestRuns.list; + // $scope.loading = false; + // + // }, function (errorResponse) { + // $scope.error = errorResponse.data.message; + // }); + // + // + // }; + $scope.testRunDetails = function (index) { + TestRuns.selected = $scope.testRuns[index]; + $state.go('viewGraphs', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': $scope.testRuns[index].testRunId, + tag: Dashboards.getDefaultTag(Dashboards.selected.tags) + }); + }; + $scope.testRunFixedBaselineBenchmark = function (index) { + TestRuns.selected = $scope.testRuns[index]; + var benchmarkFixedResult = $scope.testRuns[index].benchmarkResultFixedOK ? 'passed' : 'failed'; + $state.go('benchmarkFixedBaselineTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': $scope.testRuns[index].testRunId, + 'benchmarkResult': benchmarkFixedResult + }); + }; + $scope.testRunPreviousBuildBenchmark = function (index) { + TestRuns.selected = $scope.testRuns[index]; + var benchmarkPreviousResult = $scope.testRuns[index].benchmarkResultPreviousOK ? 'passed' : 'failed'; + $state.go('benchmarkPreviousBuildTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': $scope.testRuns[index].testRunId, + 'benchmarkResult': benchmarkPreviousResult + }); + }; + $scope.testRunRequirements = function (index) { + TestRuns.selected = $scope.testRuns[index]; + var requirementsResult = $scope.testRuns[index].meetsRequirement ? 'passed' : 'failed'; + $state.go('requirementsTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': $scope.testRuns[index].testRunId, + 'requirementsResult': requirementsResult + }); + }; + $scope.setTestRunAsBaseline = function (baseline) { + var arrayOfPromises = []; + Dashboards.selected.baseline = baseline; + Dashboards.update().success(function (dashboard) { + Dashboards.selected = dashboard; + $scope.dashboard = dashboard; + var baselineSet = false; + _.each($scope.testRuns, function (testRun, index) { + /* Only update test runs more recent than baseline */ + if (testRun.testRunId === baseline) + baselineSet = true; + if (testRun.testRunId !== baseline && baselineSet == false) { + testRun.baseline = baseline; + arrayOfPromises.push(TestRuns.updateFixedBaseline(testRun).then(function (testRun) { + })); //.success(function (updatedTestRun) { + // $scope.testRuns[index] = updatedTestRun; + // $scope.testRuns[index].busy = false; + // + // + // }, function(errorResponse) { + // $scope.error = errorResponse.data.message; + // }); + } + }); + $q.all(arrayOfPromises).then(function (results) { + /* refresh test runs*/ + setTimeout(function () { + TestRuns.listTestRunsForDashboard($scope.productName, $scope.dashboardName, Dashboards.selected.useInBenchmark).success(function (testRuns) { + TestRuns.list = testRuns; + }, function (errorResponse) { + $scope.error = errorResponse.data.message; }); - - modalInstance.result.then(function (selectedIndex) { - - $q.all([Events.delete($scope.testRuns[selectedIndex].eventIds[0]), Events.delete($scope.testRuns[selectedIndex].eventIds[1])]) - .then(TestRuns.delete($scope.productName, $scope.dashboardName, $scope.testRuns[selectedIndex].testRunId)) - .then(function(results){ - - /* refresh test runs*/ - TestRuns.listTestRunsForDashboard($scope.productName, $scope.dashboardName, Dashboards.selected.useInBenchmark).success(function (testRuns){ - - $scope.testRuns = testRuns; - - }, function(errorResponse) { - $scope.error = errorResponse.data.message; - }); - - - }); - - }, function () { - //$log.info('Modal dismissed at: ' + new Date()); - }); - - - - }; - - } + }, 100); + }); + }); + }; + $scope.refreshTestrun = function (index) { + $scope.testRuns[index].meetsRequirement = 'pending'; + $scope.testRuns[index].benchmarkResultPreviousOK = 'pending'; + $scope.testRuns[index].benchmarkResultFixedOK = 'pending'; + $scope.testRuns[index].busy = true; + TestRuns.refreshTestrun($stateParams.productName, $stateParams.dashboardName, $scope.testRuns[index].testRunId).success(function (testRun) { + $scope.testRuns[index] = testRun; + $scope.testRuns[index].busy = false; ///* refresh screen*/ + //setTimeout(function(){ + // $state.go($state.current, {}, {reload: true}); + //},1); + }, function (errorResponse) { + $scope.error = errorResponse.data.message; + }); + }; + $scope.openDeleteTestRunModal = function (size, index) { + ConfirmModal.itemType = 'Delete test run '; + ConfirmModal.selectedItemId = index; + ConfirmModal.selectedItemDescription = $scope.testRuns[index].testRunId; + var modalInstance = $modal.open({ + templateUrl: 'ConfirmDelete.html', + controller: 'ModalInstanceController', + size: size //, + }); + modalInstance.result.then(function (selectedIndex) { + $q.all([ + Events.delete($scope.testRuns[selectedIndex].eventIds[0]), + Events.delete($scope.testRuns[selectedIndex].eventIds[1]) + ]).then(TestRuns.delete($scope.productName, $scope.dashboardName, $scope.testRuns[selectedIndex].testRunId)).then(function (results) { + /* refresh test runs*/ + $scope.testRuns.splice(selectedIndex,1); + //TestRuns.listTestRunsForDashboard($scope.productName, $scope.dashboardName, Dashboards.selected.useInBenchmark).success(function (testRuns) { + // $scope.testRuns = testRuns; + //}, function (errorResponse) { + // $scope.error = errorResponse.data.message; + //}); + }); + }, function () { + }); + }; + } ]); diff --git a/public/modules/testruns/directives/benchmark-fixed-baseline.client.directive.js b/public/modules/testruns/directives/benchmark-fixed-baseline.client.directive.js index 1ebf50a..68cae3a 100644 --- a/public/modules/testruns/directives/benchmark-fixed-baseline.client.directive.js +++ b/public/modules/testruns/directives/benchmark-fixed-baseline.client.directive.js @@ -1,170 +1,120 @@ -(function() { - 'use strict'; - - - /** +(function () { + 'use strict'; + /** * @desc * @example
*/ - angular - .module('testruns') - .directive( - 'benchmarkFixedBaseline', BenchmarkFixedBaselineDirective) - - function BenchmarkFixedBaselineDirective() { - var directive = { - restrict: 'EA', - templateUrl: 'modules/testruns/views/benchmark-fixed-baseline-directive.client.view.html', - controller: BenchmarkFixedBaselineController, - controllerAs: 'vm' - }; - - return directive; - - /* @ngInject */ - function BenchmarkFixedBaselineController ( - $scope, - $timeout, - $filter, - $state, - $stateParams, - TestRuns, - ngTableParams - - ) { - - - $scope.showPassed = $stateParams.benchmarkResult === "passed" ? true : false; - $scope.productName = $stateParams.productName; - $scope.dashboardName = $stateParams.dashboardName; - - /* set tab number based on url */ - - $scope.tabNumber = $stateParams.benchmarkResult === "passed" ? 0 : 1; - - $scope.setTab = function(newValue){ - $scope.tabNumber = newValue; - switch (newValue) { - case 0: - $state.go('benchmarkFixedBaselineTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : TestRuns.selected.testRunId, "benchmarkResult" : "passed" }); - break; - case 1: - $state.go('benchmarkFixedBaselineTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : TestRuns.selected.testRunId, "benchmarkResult" : "failed" }); - break; + angular.module('testruns').directive('benchmarkFixedBaseline', BenchmarkFixedBaselineDirective); + function BenchmarkFixedBaselineDirective() { + var directive = { + restrict: 'EA', + templateUrl: 'modules/testruns/views/benchmark-fixed-baseline-directive.client.view.html', + controller: BenchmarkFixedBaselineController, + controllerAs: 'vm' + }; + return directive; + /* @ngInject */ + function BenchmarkFixedBaselineController($scope, $timeout, $filter, $state, $stateParams, TestRuns, ngTableParams) { + $scope.showPassed = $stateParams.benchmarkResult === 'passed' ? true : false; + $scope.productName = $stateParams.productName; + $scope.dashboardName = $stateParams.dashboardName; + /* set tab number based on url */ + $scope.tabNumber = $stateParams.benchmarkResult === 'passed' ? 0 : 1; + $scope.setTab = function (newValue) { + $scope.tabNumber = newValue; + switch (newValue) { + case 0: + $state.go('benchmarkFixedBaselineTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': TestRuns.selected.testRunId, + 'benchmarkResult': 'passed' + }); + break; + case 1: + $state.go('benchmarkFixedBaselineTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': TestRuns.selected.testRunId, + 'benchmarkResult': 'failed' + }); + break; + } + $scope.tableParams.filter({}); + $scope.tableParams.reload(); + }; + $scope.isSet = function (tabNumber) { + return $scope.tabNumber === tabNumber; + }; + // $scope.$watch('showPassed', function (newVal, oldVal) { + // if (newVal !== oldVal) { + $scope.tableParams = new ngTableParams({ + page: 1, + // show first page + count: 50 // count per page + }, { + groupBy: 'metric', + total: 0, + //data.length, + getData: function ($defer, params) { + TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { + $timeout(function () { + TestRuns.selected = testRun; + $scope.testRun = testRun; + var data = []; + _.each(testRun.metrics, function (metric) { + /* only show metrics failed / passed requirements */ + if (metric.benchmarkResultFixedOK === $scope.showPassed) { + var tag = metric.tags ? metric.tags[0].text : 'All'; + _.each(metric.targets, function (target) { + if (target.benchmarkResultFixedOK === $scope.showPassed) { + var humanReadableBenchmarkOperator = metric.benchmarkOperator === '>' ? '+' : '-'; + data.push({ + target: target.target, + value: target.value, + benchmarkResultPreviousOK: target.benchmarkResultPreviousOK, + benchmarkResultFixedOK: target.benchmarkResultFixedOK, + benchmarkPreviousValue: target.benchmarkPreviousValue, + benchmarkFixedValue: target.benchmarkFixedValue, + meetsRequirement: target.meetsRequirement, + metric: metric.alias, + metricId: metric._id, + requirementOperator: metric.requirementOperator, + requirementValue: metric.requirementValue, + benchmarkOperator: humanReadableBenchmarkOperator, + benchmarkValue: metric.benchmarkValue, + testRunId: testRun.testRunId, + productName: $stateParams.productName, + dashboardName: $stateParams.dashboardName, + tag: tag + }); + } + }); } - - $scope.tableParams.filter({}); - $scope.tableParams.reload(); - - - }; - - $scope.isSet = function(tabNumber){ - return $scope.tabNumber === tabNumber; - }; - - -// $scope.$watch('showPassed', function (newVal, oldVal) { - -// if (newVal !== oldVal) { - - - - $scope.tableParams = new ngTableParams({ - page: 1, // show first page - count: 50 // count per page - - }, { - groupBy: 'metric', - total: 0, //data.length, - getData: function($defer, params) { - - TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { - - $timeout(function () { - - TestRuns.selected = testRun; - $scope.testRun = testRun; - - - var data = []; - - - _.each(testRun.metrics, function (metric) { - - /* only show metrics failed / passed requirements */ - if (metric.benchmarkResultFixedOK === $scope.showPassed) { - - var tag = (metric.tags) ? metric.tags[0].text : 'All'; - - _.each(metric.targets, function (target) { - - if(target.benchmarkResultFixedOK === $scope.showPassed) { - - var humanReadableBenchmarkOperator = (metric.benchmarkOperator === '>') ? '+' : '-'; - - data.push({ - - target: target.target, - value: target.value, - benchmarkResultPreviousOK: target.benchmarkResultPreviousOK, - benchmarkResultFixedOK: target.benchmarkResultFixedOK, - benchmarkPreviousValue: target.benchmarkPreviousValue, - benchmarkFixedValue: target.benchmarkFixedValue, - meetsRequirement: target.meetsRequirement, - metric: metric.alias, - metricId: metric._id, - requirementOperator: metric.requirementOperator, - requirementValue: metric.requirementValue, - benchmarkOperator: humanReadableBenchmarkOperator, - benchmarkValue: metric.benchmarkValue, - testRunId: testRun.testRunId, - productName: $stateParams.productName, - dashboardName: $stateParams.dashboardName, - tag: tag - - - }); - } - }); - } - }); - var orderedData = params.sorting() ? - $filter('orderBy')(data, $scope.tableParams.orderBy()) : data; - // update table params - params.total(orderedData.length); - $defer.resolve(orderedData); - - }, 500); - }); - } - }); - - -// }); - + }); + var orderedData = params.sorting() ? $filter('orderBy')(data, $scope.tableParams.orderBy()) : data; + // update table params + params.total(orderedData.length); + $defer.resolve(orderedData); + }, 500); + }); } - - } - - - - function LoadingContainerDirective (){ - - var directive = { - restrict: 'A', - scope: false, - link: function (scope, element, attrs) { - var loadingLayer = angular.element('
'); - element.append(loadingLayer); - element.addClass('loading-container'); - scope.$watch(attrs.loadingContainer, function (value) { - loadingLayer.toggleClass('ng-hide', !value); - }); - } - }; - - return directive; - + }); // }); } -}()); + } + function LoadingContainerDirective() { + var directive = { + restrict: 'A', + scope: false, + link: function (scope, element, attrs) { + var loadingLayer = angular.element('
'); + element.append(loadingLayer); + element.addClass('loading-container'); + scope.$watch(attrs.loadingContainer, function (value) { + loadingLayer.toggleClass('ng-hide', !value); + }); + } + }; + return directive; + } +}()); \ No newline at end of file diff --git a/public/modules/testruns/directives/benchmark-previous-build.client.directive.js b/public/modules/testruns/directives/benchmark-previous-build.client.directive.js index 6bbaf95..e98c490 100644 --- a/public/modules/testruns/directives/benchmark-previous-build.client.directive.js +++ b/public/modules/testruns/directives/benchmark-previous-build.client.directive.js @@ -1,169 +1,120 @@ -(function() { - 'use strict'; - - - /** +(function () { + 'use strict'; + /** * @desc * @example
*/ - angular - .module('testruns') - .directive( - 'benchmarkPreviousBuild', BenchmarkPreviousBuildDirective) - - function BenchmarkPreviousBuildDirective() { - var directive = { - restrict: 'EA', - templateUrl: 'modules/testruns/views/benchmark-previous-build-directive.client.view.html', - controller: BenchmarkPreviousBuildController, - controllerAs: 'vm' - }; - - return directive; - - /* @ngInject */ - function BenchmarkPreviousBuildController ( - $scope, - $timeout, - $filter, - $state, - $stateParams, - TestRuns, - ngTableParams - - ) { - - - $scope.showPassed = $stateParams.benchmarkResult === "passed" ? true : false; - $scope.productName = $stateParams.productName; - $scope.dashboardName = $stateParams.dashboardName; - - - /* set tab number based on url */ - - $scope.tabNumber = $stateParams.benchmarkResult === "passed" ? 0 : 1; - - $scope.setTab = function(newValue){ - $scope.tabNumber = newValue; - switch (newValue) { - case 0: - $state.go('benchmarkPreviousBuildTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : TestRuns.selected.testRunId, "benchmarkResult" : "passed" }); - break; - case 1: - $state.go('benchmarkPreviousBuildTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : TestRuns.selected.testRunId, "benchmarkResult" : "failed" }); - break; + angular.module('testruns').directive('benchmarkPreviousBuild', BenchmarkPreviousBuildDirective); + function BenchmarkPreviousBuildDirective() { + var directive = { + restrict: 'EA', + templateUrl: 'modules/testruns/views/benchmark-previous-build-directive.client.view.html', + controller: BenchmarkPreviousBuildController, + controllerAs: 'vm' + }; + return directive; + /* @ngInject */ + function BenchmarkPreviousBuildController($scope, $timeout, $filter, $state, $stateParams, TestRuns, ngTableParams) { + $scope.showPassed = $stateParams.benchmarkResult === 'passed' ? true : false; + $scope.productName = $stateParams.productName; + $scope.dashboardName = $stateParams.dashboardName; + /* set tab number based on url */ + $scope.tabNumber = $stateParams.benchmarkResult === 'passed' ? 0 : 1; + $scope.setTab = function (newValue) { + $scope.tabNumber = newValue; + switch (newValue) { + case 0: + $state.go('benchmarkPreviousBuildTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': TestRuns.selected.testRunId, + 'benchmarkResult': 'passed' + }); + break; + case 1: + $state.go('benchmarkPreviousBuildTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': TestRuns.selected.testRunId, + 'benchmarkResult': 'failed' + }); + break; + } + $scope.tableParams.filter({}); + $scope.tableParams.reload(); + }; + $scope.isSet = function (tabNumber) { + return $scope.tabNumber === tabNumber; + }; + // $scope.$watch('showPassed', function (newVal, oldVal) { + // if (newVal !== oldVal) { + $scope.tableParams = new ngTableParams({ + page: 1, + // show first page + count: 50 // count per page + }, { + groupBy: 'metric', + total: 0, + //data.length, + getData: function ($defer, params) { + TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { + $timeout(function () { + TestRuns.selected = testRun; + $scope.testRun = testRun; + var data = []; + _.each(testRun.metrics, function (metric) { + /* only show metrics failed / passed requirements */ + if (metric.benchmarkResultPreviousOK === $scope.showPassed) { + var tag = metric.tags ? metric.tags[0].text : 'All'; + _.each(metric.targets, function (target) { + if (target.benchmarkResultPreviousOK === $scope.showPassed) { + var humanReadableBenchmarkOperator = metric.benchmarkOperator === '>' ? '+' : '-'; + data.push({ + target: target.target, + value: target.value, + benchmarkResultPreviousOK: target.benchmarkResultPreviousOK, + benchmarkResultFixedOK: target.benchmarkResultFixedOK, + benchmarkPreviousValue: target.benchmarkPreviousValue, + benchmarkFixedValue: target.benchmarkFixedValue, + meetsRequirement: target.meetsRequirement, + metric: metric.alias, + metricId: metric._id, + requirementOperator: metric.requirementOperator, + requirementValue: metric.requirementValue, + benchmarkOperator: humanReadableBenchmarkOperator, + benchmarkValue: metric.benchmarkValue, + testRunId: testRun.testRunId, + productName: $stateParams.productName, + dashboardName: $stateParams.dashboardName, + tag: tag + }); + } + }); } - - $scope.tableParams.filter({}); - $scope.tableParams.reload(); - - - }; - - $scope.isSet = function(tabNumber){ - return $scope.tabNumber === tabNumber; - }; - - -// $scope.$watch('showPassed', function (newVal, oldVal) { - -// if (newVal !== oldVal) { - - - - $scope.tableParams = new ngTableParams({ - page: 1, // show first page - count: 50 // count per page - - }, { - groupBy: 'metric', - total: 0, //data.length, - getData: function($defer, params) { - - TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { - - $timeout(function () { - - TestRuns.selected = testRun; - $scope.testRun = testRun; - - var data = []; - - - _.each(testRun.metrics, function (metric) { - - /* only show metrics failed / passed requirements */ - if (metric.benchmarkResultPreviousOK === $scope.showPassed) { - - var tag = (metric.tags) ? metric.tags[0].text : 'All'; - - _.each(metric.targets, function (target) { - - if(target.benchmarkResultPreviousOK === $scope.showPassed) { - - var humanReadableBenchmarkOperator = (metric.benchmarkOperator === '>') ? '+' : '-'; - - data.push({ - - target: target.target, - value: target.value, - benchmarkResultPreviousOK: target.benchmarkResultPreviousOK, - benchmarkResultFixedOK: target.benchmarkResultFixedOK, - benchmarkPreviousValue: target.benchmarkPreviousValue, - benchmarkFixedValue: target.benchmarkFixedValue, - meetsRequirement: target.meetsRequirement, - metric: metric.alias, - metricId: metric._id, - requirementOperator: metric.requirementOperator, - requirementValue: metric.requirementValue, - benchmarkOperator: humanReadableBenchmarkOperator, - benchmarkValue: metric.benchmarkValue, - testRunId: testRun.testRunId, - productName: $stateParams.productName, - dashboardName: $stateParams.dashboardName, - tag: tag - - }); - } - }); - } - }); - var orderedData = params.sorting() ? - $filter('orderBy')(data, $scope.tableParams.orderBy()) : data; - // update table params - params.total(orderedData.length); - $defer.resolve(orderedData); - - }, 500); - }); - } - }); - - -// }); - + }); + var orderedData = params.sorting() ? $filter('orderBy')(data, $scope.tableParams.orderBy()) : data; + // update table params + params.total(orderedData.length); + $defer.resolve(orderedData); + }, 500); + }); } - - } - - - - function LoadingContainerDirective (){ - - var directive = { - restrict: 'A', - scope: false, - link: function (scope, element, attrs) { - var loadingLayer = angular.element('
'); - element.append(loadingLayer); - element.addClass('loading-container'); - scope.$watch(attrs.loadingContainer, function (value) { - loadingLayer.toggleClass('ng-hide', !value); - }); - } - }; - - return directive; - + }); // }); } -}()); + } + function LoadingContainerDirective() { + var directive = { + restrict: 'A', + scope: false, + link: function (scope, element, attrs) { + var loadingLayer = angular.element('
'); + element.append(loadingLayer); + element.addClass('loading-container'); + scope.$watch(attrs.loadingContainer, function (value) { + loadingLayer.toggleClass('ng-hide', !value); + }); + } + }; + return directive; + } +}()); \ No newline at end of file diff --git a/public/modules/testruns/directives/requirements.client.directive.js b/public/modules/testruns/directives/requirements.client.directive.js index 5cc8a22..75ec712 100644 --- a/public/modules/testruns/directives/requirements.client.directive.js +++ b/public/modules/testruns/directives/requirements.client.directive.js @@ -1,161 +1,112 @@ -(function() { - 'use strict'; - - /* public/modules/graphs/directives/gatling-details.client.directive.js */ - - /** +(function () { + 'use strict'; + /* public/modules/graphs/directives/gatling-details.client.directive.js */ + /** * @desc * @example
*/ - angular - .module('testruns') - .directive( - 'requirements', RequirementsDirective) - - function RequirementsDirective() { - var directive = { - restrict: 'EA', - templateUrl: 'modules/testruns/views/requirements-directive.client.view.html', - controller: RequirementsController, - controllerAs: 'vm' - }; - - return directive; - - /* @ngInject */ - function RequirementsController ( - $scope, - $timeout, - $filter, - $state, - $stateParams, - TestRuns, - ngTableParams - - ) { - - - $scope.showPassedRequirements = $stateParams.requirementsResult === "passed" ? true : false; - $scope.productName = $stateParams.productName; - $scope.dashboardName = $stateParams.dashboardName; - - - /* set tab number based on url */ - - $scope.tabNumber = $stateParams.requirementsResult === "passed" ? 0 : 1; - - $scope.setTab = function(newValue){ - $scope.tabNumber = newValue; - switch (newValue) { - case 0: - $state.go('requirementsTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : TestRuns.selected.testRunId, "requirementsResult" : "passed" }); - break; - case 1: - $state.go('requirementsTestRun',{"productName":$stateParams.productName, "dashboardName":$stateParams.dashboardName, "testRunId" : TestRuns.selected.testRunId, "requirementsResult" : "failed" }); - break; + angular.module('testruns').directive('requirements', RequirementsDirective); + function RequirementsDirective() { + var directive = { + restrict: 'EA', + templateUrl: 'modules/testruns/views/requirements-directive.client.view.html', + controller: RequirementsController, + controllerAs: 'vm' + }; + return directive; + /* @ngInject */ + function RequirementsController($scope, $timeout, $filter, $state, $stateParams, TestRuns, ngTableParams) { + $scope.showPassedRequirements = $stateParams.requirementsResult === 'passed' ? true : false; + $scope.productName = $stateParams.productName; + $scope.dashboardName = $stateParams.dashboardName; + /* set tab number based on url */ + $scope.tabNumber = $stateParams.requirementsResult === 'passed' ? 0 : 1; + $scope.setTab = function (newValue) { + $scope.tabNumber = newValue; + switch (newValue) { + case 0: + $state.go('requirementsTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': TestRuns.selected.testRunId, + 'requirementsResult': 'passed' + }); + break; + case 1: + $state.go('requirementsTestRun', { + 'productName': $stateParams.productName, + 'dashboardName': $stateParams.dashboardName, + 'testRunId': TestRuns.selected.testRunId, + 'requirementsResult': 'failed' + }); + break; + } + $scope.tableParams.filter({}); + $scope.tableParams.reload(); + }; + $scope.isSet = function (tabNumber) { + return $scope.tabNumber === tabNumber; + }; + // $scope.$watch('showPassedRequirements', function (newVal, oldVal) { + // if (newVal !== oldVal) { + $scope.tableParams = new ngTableParams({ + page: 1, + // show first page + count: 50 // count per page + }, { + groupBy: 'metric', + total: 0, + //data.length, + getData: function ($defer, params) { + TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { + $timeout(function () { + TestRuns.selected = testRun; + $scope.testRun = testRun; + var data = []; + _.each(testRun.metrics, function (metric) { + /* only show metrics failed / passed requirements */ + if (metric.meetsRequirement === $scope.showPassedRequirements) { + var tag = metric.tags ? metric.tags[0].text : 'All'; + _.each(metric.targets, function (target) { + data.push({ + target: target.target, + value: target.value, + meetsRequirement: target.meetsRequirement, + metric: metric.alias, + metricId: metric._id, + requirementOperator: metric.requirementOperator, + requirementValue: metric.requirementValue, + testRunId: testRun.testRunId, + productName: $stateParams.productName, + dashboardName: $stateParams.dashboardName, + tag: tag + }); + }); } - - $scope.tableParams.filter({}); - $scope.tableParams.reload(); - - - }; - - $scope.isSet = function(tabNumber){ - return $scope.tabNumber === tabNumber; - }; - - -// $scope.$watch('showPassedRequirements', function (newVal, oldVal) { - -// if (newVal !== oldVal) { - - - - $scope.tableParams = new ngTableParams({ - page: 1, // show first page - count: 50 // count per page - - }, { - groupBy: 'metric', - total: 0, //data.length, - getData: function($defer, params) { - - TestRuns.getTestRunById($stateParams.productName, $stateParams.dashboardName, $stateParams.testRunId).success(function (testRun) { - - $timeout(function () { - - TestRuns.selected = testRun; - $scope.testRun = testRun; - - - var data = []; - - - _.each(testRun.metrics, function (metric) { - - /* only show metrics failed / passed requirements */ - if (metric.meetsRequirement === $scope.showPassedRequirements) { - - var tag = (metric.tags) ? metric.tags[0].text : 'All'; - - _.each(metric.targets, function (target) { - - - data.push({ - - target: target.target, - value: target.value, - meetsRequirement: target.meetsRequirement, - metric: metric.alias, - metricId: metric._id, - requirementOperator: metric.requirementOperator, - requirementValue: metric.requirementValue, - testRunId: testRun.testRunId, - productName: $stateParams.productName, - dashboardName: $stateParams.dashboardName, - tag: tag - - }); - }); - } - }); - var orderedData = params.sorting() ? - $filter('orderBy')(data, $scope.tableParams.orderBy()) : data; - // update table params - params.total(orderedData.length); - $defer.resolve(orderedData); - - }, 500); - }); - } - }); - - -// }); - + }); + var orderedData = params.sorting() ? $filter('orderBy')(data, $scope.tableParams.orderBy()) : data; + // update table params + params.total(orderedData.length); + $defer.resolve(orderedData); + }, 500); + }); } - - } - - - - function LoadingContainerDirective (){ - - var directive = { - restrict: 'A', - scope: false, - link: function (scope, element, attrs) { - var loadingLayer = angular.element('
'); - element.append(loadingLayer); - element.addClass('loading-container'); - scope.$watch(attrs.loadingContainer, function (value) { - loadingLayer.toggleClass('ng-hide', !value); - }); - } - }; - - return directive; - + }); // }); } -}()); + } + function LoadingContainerDirective() { + var directive = { + restrict: 'A', + scope: false, + link: function (scope, element, attrs) { + var loadingLayer = angular.element('
'); + element.append(loadingLayer); + element.addClass('loading-container'); + scope.$watch(attrs.loadingContainer, function (value) { + loadingLayer.toggleClass('ng-hide', !value); + }); + } + }; + return directive; + } +}()); \ No newline at end of file diff --git a/public/modules/testruns/directives/running-test.client.directive.js b/public/modules/testruns/directives/running-test.client.directive.js index 3ba6d0f..bfd5090 100644 --- a/public/modules/testruns/directives/running-test.client.directive.js +++ b/public/modules/testruns/directives/running-test.client.directive.js @@ -1,127 +1,78 @@ -(function() { - 'use strict'; - - /* public/modules/testruns/directives/running-test.client.directive.js */ - - /** +(function () { + 'use strict'; + /* public/modules/testruns/directives/running-test.client.directive.js */ + /** * @desc * @example
*/ - angular - .module('testruns') - .directive( - 'runningTest', RunningTestDirective) - - function RunningTestDirective() { - var directive = { - restrict: 'EA', - templateUrl: 'modules/testruns/views/running-test-directive.client.view.html', - controller: RunningTestController, - controllerAs: 'vm' - }; - - return directive; - - /* @ngInject */ - function RunningTestController ( - $scope, - $modal, - $stateParams, - $state, - TestRuns, - Events, - ConfirmModal - ) { - - $scope.showDialog = false; - - TestRuns.getRunningTest($stateParams.productName, $stateParams.dashboardName).success(function (runningTest) { - - if(Object.keys(runningTest).length !== 0){ - - $scope.runningTest = runningTest; - $scope.showDialog = true; - - } - - - - }); - - $scope.openDeleteEventModal = function (size) { - - ConfirmModal.itemType = 'Delete event'; - ConfirmModal.selectedItemId = $scope.runningTest._id; - ConfirmModal.selectedItemDescription = $scope.runningTest.eventDescription; - - var modalInstance = $modal.open({ - templateUrl: 'ConfirmDelete.html', - controller: 'ModalInstanceController', - size: size//, - }); - - modalInstance.result.then(function (eventId) { - - Events.delete(eventId).success(function(event){ - - //TestRuns.getRunningTest($stateParams.productName, $stateParams.dashboardName).success(function (runningTest) { - // - // $scope.runningTest = runningTest; - $scope.showDialog = false; - $state.go($state.current, {}, {reload: true}); - - //}); - - }); - - }, function () { - $log.info('Modal dismissed at: ' + new Date()); - }); - }; - - $scope.openSendEndEventModal = function (size) { - - ConfirmModal.itemType = 'Send end event for test run ID '; - ConfirmModal.selectedItemId = $scope.runningTest.testRunId; - ConfirmModal.selectedItemDescription = $scope.runningTest.testRunId; - - var modalInstance = $modal.open({ - templateUrl: 'ConfirmDelete.html', - controller: 'ModalInstanceController', - size: size//, - }); - - modalInstance.result.then(function (eventId) { - - var endEvent = { - productName: $scope.runningTest.productName, - dashboardName: $scope.runningTest.dashboardName, - testRunId: $scope.runningTest.testRunId, - eventDescription: 'end', - baseline: $scope.runningTest.baseline, - buildResultKey: $scope.runningTest.buildResultKey - }; - - Events.create(endEvent).success(function(event){ - - //TestRuns.getRunningTest($stateParams.productName, $stateParams.dashboardName).success(function (runningTest) { - // - // $scope.runningTest = runningTest; - $scope.showDialog = false; - $state.go($state.current, {}, {reload: true}); - - //}); - - }); - - }, function () { - $log.info('Modal dismissed at: ' + new Date()); - }); - }; - + angular.module('testruns').directive('runningTest', RunningTestDirective); + function RunningTestDirective() { + var directive = { + restrict: 'EA', + templateUrl: 'modules/testruns/views/running-test-directive.client.view.html', + controller: RunningTestController, + controllerAs: 'vm' + }; + return directive; + /* @ngInject */ + function RunningTestController($scope, $modal, $stateParams, $state, TestRuns, Events, ConfirmModal) { + $scope.showDialog = false; + TestRuns.getRunningTest($stateParams.productName, $stateParams.dashboardName).success(function (runningTest) { + if (Object.keys(runningTest).length !== 0) { + $scope.runningTest = runningTest; + $scope.showDialog = true; } - - + }); + $scope.openDeleteEventModal = function (size) { + ConfirmModal.itemType = 'Delete event'; + ConfirmModal.selectedItemId = $scope.runningTest._id; + ConfirmModal.selectedItemDescription = $scope.runningTest.eventDescription; + var modalInstance = $modal.open({ + templateUrl: 'ConfirmDelete.html', + controller: 'ModalInstanceController', + size: size //, + }); + modalInstance.result.then(function (eventId) { + Events.delete(eventId).success(function (event) { + //TestRuns.getRunningTest($stateParams.productName, $stateParams.dashboardName).success(function (runningTest) { + // + // $scope.runningTest = runningTest; + $scope.showDialog = false; + $state.go($state.current, {}, { reload: true }); //}); + }); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + }; + $scope.openSendEndEventModal = function (size) { + ConfirmModal.itemType = 'Send end event for test run ID '; + ConfirmModal.selectedItemId = $scope.runningTest.testRunId; + ConfirmModal.selectedItemDescription = $scope.runningTest.testRunId; + var modalInstance = $modal.open({ + templateUrl: 'ConfirmDelete.html', + controller: 'ModalInstanceController', + size: size //, + }); + modalInstance.result.then(function (eventId) { + var endEvent = { + productName: $scope.runningTest.productName, + dashboardName: $scope.runningTest.dashboardName, + testRunId: $scope.runningTest.testRunId, + eventDescription: 'end', + baseline: $scope.runningTest.baseline, + buildResultKey: $scope.runningTest.buildResultKey + }; + Events.create(endEvent).success(function (event) { + //TestRuns.getRunningTest($stateParams.productName, $stateParams.dashboardName).success(function (runningTest) { + // + // $scope.runningTest = runningTest; + $scope.showDialog = false; + $state.go($state.current, {}, { reload: true }); //}); + }); + }, function () { + $log.info('Modal dismissed at: ' + new Date()); + }); + }; } - -}()); + } +}()); \ No newline at end of file diff --git a/public/modules/testruns/services/testruns.client.service.js b/public/modules/testruns/services/testruns.client.service.js index 0c5b875..3f4e9bb 100644 --- a/public/modules/testruns/services/testruns.client.service.js +++ b/public/modules/testruns/services/testruns.client.service.js @@ -1,70 +1,51 @@ 'use strict'; - //Events service used to communicate Events REST endpoints -angular.module('events').factory('TestRuns', ['$http', 'Products', 'Dashboards','Events', - function($http, Products, Dashboards, Events) { - - var TestRuns = { -// 'get' : getFn, - list:[], - selected: {}, - listTestRunsForDashboard: listTestRunsForDashboard, - zoomFrom: '', - zoomUntil: '', - zoomRange: '', - getTestRunById: getTestRunById, - getRunningTest: getRunningTest, - refreshTestrun: refreshTestrun, - delete: deleteFn, - updateFixedBaseline: updateFixedBaseline, - updateTestruns:updateTestruns - - }; - - return TestRuns; - - function updateTestruns(productName, dashboardName, metricId, updateRequirements, updateBenchmarks){ - - return $http.get('/update-testruns-results/' + productName + '/' + dashboardName + '/' + metricId + '/' + updateRequirements + '/' + updateBenchmarks ); - - } - - - function updateFixedBaseline(testRun) { - - return $http.post('/update-fixed-baseline-benchmark', testRun); - } - - function getRunningTest(productName, dashboardName){ - - return $http.get('/running-test/' + productName + '/' + dashboardName); - } - - function getTestRunById(productName, dashboardName, testRunId){ - - return $http.get('/testrun/' + productName + '/' + dashboardName + '/' + testRunId);//.success(function(testRun){ - // - // TestRuns.selected = testRun; - // - //}); - - } - - function listTestRunsForDashboard(productName, dashboardName, useInBenchmark){ - - return $http.get('/testruns-dashboard/' + productName + '/' + dashboardName + '/' + useInBenchmark ); - - }; - - function refreshTestrun(productName, dashboardName , testRunId){ - - return $http.get('/refresh-testrun/' + productName + '/' + dashboardName + '/' + testRunId ); - - }; - - function deleteFn(productName, dashboardName, testRunId){ - return $http.delete('/testrun/' + productName + '/' + dashboardName + '/' + testRunId); - } - +angular.module('events').factory('TestRuns', [ + '$http', + 'Products', + 'Dashboards', + 'Events', + function ($http, Products, Dashboards, Events) { + var TestRuns = { + // 'get' : getFn, + list: [], + selected: {}, + listTestRunsForDashboard: listTestRunsForDashboard, + zoomFrom: '', + zoomUntil: '', + zoomRange: '', + getTestRunById: getTestRunById, + getRunningTest: getRunningTest, + refreshTestrun: refreshTestrun, + delete: deleteFn, + updateFixedBaseline: updateFixedBaseline, + updateTestruns: updateTestruns + }; + return TestRuns; + function updateTestruns(productName, dashboardName, metricId, updateRequirements, updateBenchmarks) { + return $http.get('/update-testruns-results/' + productName + '/' + dashboardName + '/' + metricId + '/' + updateRequirements + '/' + updateBenchmarks); } -]); + function updateFixedBaseline(testRun) { + return $http.post('/update-fixed-baseline-benchmark', testRun); + } + function getRunningTest(productName, dashboardName) { + return $http.get('/running-test/' + productName + '/' + dashboardName); + } + function getTestRunById(productName, dashboardName, testRunId) { + return $http.get('/testrun/' + productName + '/' + dashboardName + '/' + testRunId); //.success(function(testRun){ + // + // TestRuns.selected = testRun; + // + //}); + } + function listTestRunsForDashboard(productName, dashboardName, useInBenchmark) { + return $http.get('/testruns-dashboard/' + productName + '/' + dashboardName + '/' + useInBenchmark); + } + function refreshTestrun(productName, dashboardName, testRunId) { + return $http.get('/refresh-testrun/' + productName + '/' + dashboardName + '/' + testRunId); + } + function deleteFn(productName, dashboardName, testRunId) { + return $http.delete('/testrun/' + productName + '/' + dashboardName + '/' + testRunId); + } + } +]); \ No newline at end of file diff --git a/public/modules/testruns/testruns.client.module.js b/public/modules/testruns/testruns.client.module.js index fcdaea1..da32fd5 100644 --- a/public/modules/testruns/testruns.client.module.js +++ b/public/modules/testruns/testruns.client.module.js @@ -1,4 +1,3 @@ 'use strict'; - // Use application configuration module to register a new module -ApplicationConfiguration.registerModule('testruns'); +ApplicationConfiguration.registerModule('testruns'); \ No newline at end of file diff --git a/public/modules/testruns/views/benchmark-fixed-baseline-directive.client.view.html b/public/modules/testruns/views/benchmark-fixed-baseline-directive.client.view.html index 3e278f2..e5bb84e 100644 --- a/public/modules/testruns/views/benchmark-fixed-baseline-directive.client.view.html +++ b/public/modules/testruns/views/benchmark-fixed-baseline-directive.client.view.html @@ -1,22 +1,24 @@
@@ -29,10 +31,16 @@
Baseline: {{testRun.baseline}}
{{target.benchmarkFixedValue}} - + diff --git a/public/modules/testruns/views/benchmark-previous-build-directive.client.view.html b/public/modules/testruns/views/benchmark-previous-build-directive.client.view.html index c710b6d..981d63c 100644 --- a/public/modules/testruns/views/benchmark-previous-build-directive.client.view.html +++ b/public/modules/testruns/views/benchmark-previous-build-directive.client.view.html @@ -1,22 +1,24 @@
- + {{ group.value }} {{target.value}}{{target.benchmarkOperator}} {{target.benchmarkValue}}{{target.benchmarkOperator}} + {{target.benchmarkValue}} + - - + +
@@ -29,10 +31,16 @@
Baseline: {{testRun.previousBuild}}
{{target.benchmarkPreviousValue}} - + diff --git a/public/modules/testruns/views/requirements-directive.client.view.html b/public/modules/testruns/views/requirements-directive.client.view.html index ff0ee52..f5e91b9 100644 --- a/public/modules/testruns/views/requirements-directive.client.view.html +++ b/public/modules/testruns/views/requirements-directive.client.view.html @@ -1,24 +1,26 @@ -
- + {{ group.value }} {{target.value}}{{target.benchmarkOperator}} {{target.benchmarkValue}}{{target.benchmarkOperator}} + {{target.benchmarkValue}} + - - + +
+ - + diff --git a/public/modules/testruns/views/running-test-directive.client.view.html b/public/modules/testruns/views/running-test-directive.client.view.html index 009e8db..99787f5 100644 --- a/public/modules/testruns/views/running-test-directive.client.view.html +++ b/public/modules/testruns/views/running-test-directive.client.view.html @@ -2,63 +2,64 @@
- - + +
- + View live graphs -

RUNNING TEST (since: {{runningTest.eventTimestamp | date:'EEEE, dd-M-yyyy H:mm:ss'}})

+

RUNNING TEST (since: {{runningTest.eventTimestamp | date:'EEEE, dd-M-yyyy + H:mm:ss'}})

-
+
Send end event - Delete start event + Delete start event +
- - - - - - - - - - - - - + + + + + + + + + + + +
- - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/public/modules/testruns/views/testruns.client.view.html b/public/modules/testruns/views/testruns.client.view.html index c9d08c7..58b4957 100644 --- a/public/modules/testruns/views/testruns.client.view.html +++ b/public/modules/testruns/views/testruns.client.view.html @@ -11,23 +11,85 @@
- - + - - - - - - - - - - - + + + + + + + + + + + + + + + + + +
- + {{ group.value }} -
@@ -27,10 +29,16 @@ {{target.value}} {{target.requirementOperator}} {{target.requirementValue}}{{target.requirementOperator}} + {{target.requirementValue}} + - - + +
Requirements Previous Build Fixed Baseline + +
{{testRun.testRunId}}{{testRun.start | date:'EEEE, dd-M-yyyy H:mm:ss'}}{{testRun.end | date:'EEEE, dd-M-yyyy H:mm:ss'}}
{{testRun.testRunId}}{{testRun.start | date:'EEEE, dd-M-yyyy + H:mm:ss'}} + {{testRun.end | date:'EEEE, dd-M-yyyy + H:mm:ss'}} + + + + + + + + + + + Test run menu + + + + + + + Refresh test run + + + + + + Set as baseline + + + + + + View in CI server + + + + + + + Delete test run + + + + +
diff --git a/public/modules/users/config/users.client.config.js b/public/modules/users/config/users.client.config.js index 0bfc8b6..313649c 100644 --- a/public/modules/users/config/users.client.config.js +++ b/public/modules/users/config/users.client.config.js @@ -1,30 +1,31 @@ 'use strict'; - // Config HTTP Error Handling -angular.module('users').config(['$httpProvider', - function($httpProvider) { - // Set the httpProvider "not authorized" interceptor - $httpProvider.interceptors.push(['$q', '$location', 'Authentication', - function($q, $location, Authentication) { - return { - responseError: function(rejection) { - switch (rejection.status) { - case 401: - // Deauthenticate the global user - Authentication.user = null; - - // Redirect to signin page - $location.path('signin'); - break; - case 403: - // Add unauthorized behaviour - break; - } - - return $q.reject(rejection); - } - }; - } - ]); - } +angular.module('users').config([ + '$httpProvider', + function ($httpProvider) { + // Set the httpProvider "not authorized" interceptor + $httpProvider.interceptors.push([ + '$q', + '$location', + 'Authentication', + function ($q, $location, Authentication) { + return { + responseError: function (rejection) { + switch (rejection.status) { + case 401: + // Deauthenticate the global user + Authentication.user = null; + // Redirect to signin page + $location.path('signin'); + break; + case 403: + // Add unauthorized behaviour + break; + } + return $q.reject(rejection); + } + }; + } + ]); + } ]); \ No newline at end of file diff --git a/public/modules/users/config/users.client.routes.js b/public/modules/users/config/users.client.routes.js index 879c2c4..07fff64 100644 --- a/public/modules/users/config/users.client.routes.js +++ b/public/modules/users/config/users.client.routes.js @@ -1,45 +1,36 @@ 'use strict'; - // Setting up route -angular.module('users').config(['$stateProvider', - function($stateProvider) { - // Users state routing - $stateProvider. - state('profile', { - url: '/settings/profile', - templateUrl: 'modules/users/views/settings/edit-profile.client.view.html' - }). - state('password', { - url: '/settings/password', - templateUrl: 'modules/users/views/settings/change-password.client.view.html' - }). - state('accounts', { - url: '/settings/accounts', - templateUrl: 'modules/users/views/settings/social-accounts.client.view.html' - }). - state('signup', { - url: '/signup', - templateUrl: 'modules/users/views/authentication/signup.client.view.html' - }). - state('signin', { - url: '/signin', - templateUrl: 'modules/users/views/authentication/signin.client.view.html' - }). - state('forgot', { - url: '/password/forgot', - templateUrl: 'modules/users/views/password/forgot-password.client.view.html' - }). - state('reset-invalid', { - url: '/password/reset/invalid', - templateUrl: 'modules/users/views/password/reset-password-invalid.client.view.html' - }). - state('reset-success', { - url: '/password/reset/success', - templateUrl: 'modules/users/views/password/reset-password-success.client.view.html' - }). - state('reset', { - url: '/password/reset/:token', - templateUrl: 'modules/users/views/password/reset-password.client.view.html' - }); - } +angular.module('users').config([ + '$stateProvider', + function ($stateProvider) { + // Users state routing + $stateProvider.state('profile', { + url: '/settings/profile', + templateUrl: 'modules/users/views/settings/edit-profile.client.view.html' + }).state('password', { + url: '/settings/password', + templateUrl: 'modules/users/views/settings/change-password.client.view.html' + }).state('accounts', { + url: '/settings/accounts', + templateUrl: 'modules/users/views/settings/social-accounts.client.view.html' + }).state('signup', { + url: '/signup', + templateUrl: 'modules/users/views/authentication/signup.client.view.html' + }).state('signin', { + url: '/signin', + templateUrl: 'modules/users/views/authentication/signin.client.view.html' + }).state('forgot', { + url: '/password/forgot', + templateUrl: 'modules/users/views/password/forgot-password.client.view.html' + }).state('reset-invalid', { + url: '/password/reset/invalid', + templateUrl: 'modules/users/views/password/reset-password-invalid.client.view.html' + }).state('reset-success', { + url: '/password/reset/success', + templateUrl: 'modules/users/views/password/reset-password-success.client.view.html' + }).state('reset', { + url: '/password/reset/:token', + templateUrl: 'modules/users/views/password/reset-password.client.view.html' + }); + } ]); \ No newline at end of file diff --git a/public/modules/users/controllers/authentication.client.controller.js b/public/modules/users/controllers/authentication.client.controller.js index 3e27cc3..d0c62c2 100644 --- a/public/modules/users/controllers/authentication.client.controller.js +++ b/public/modules/users/controllers/authentication.client.controller.js @@ -1,34 +1,33 @@ 'use strict'; - -angular.module('users').controller('AuthenticationController', ['$scope', '$http', '$location', 'Authentication', - function($scope, $http, $location, Authentication) { - $scope.authentication = Authentication; - - // If user is signed in then redirect back home - if ($scope.authentication.user) $location.path('/'); - - $scope.signup = function() { - $http.post('/auth/signup', $scope.credentials).success(function(response) { - // If successful we assign the response to the global user model - $scope.authentication.user = response; - - // And redirect to the index page - $location.path('/'); - }).error(function(response) { - $scope.error = response.message; - }); - }; - - $scope.signin = function() { - $http.post('/auth/signin', $scope.credentials).success(function(response) { - // If successful we assign the response to the global user model - $scope.authentication.user = response; - - // And redirect to the index page - $location.path('/'); - }).error(function(response) { - $scope.error = response.message; - }); - }; - } +angular.module('users').controller('AuthenticationController', [ + '$scope', + '$http', + '$location', + 'Authentication', + function ($scope, $http, $location, Authentication) { + $scope.authentication = Authentication; + // If user is signed in then redirect back home + if ($scope.authentication.user) + $location.path('/'); + $scope.signup = function () { + $http.post('/auth/signup', $scope.credentials).success(function (response) { + // If successful we assign the response to the global user model + $scope.authentication.user = response; + // And redirect to the index page + $location.path('/'); + }).error(function (response) { + $scope.error = response.message; + }); + }; + $scope.signin = function () { + $http.post('/auth/signin', $scope.credentials).success(function (response) { + // If successful we assign the response to the global user model + $scope.authentication.user = response; + // And redirect to the index page + $location.path('/'); + }).error(function (response) { + $scope.error = response.message; + }); + }; + } ]); \ No newline at end of file diff --git a/public/modules/users/controllers/password.client.controller.js b/public/modules/users/controllers/password.client.controller.js index dbc9e92..92663ce 100644 --- a/public/modules/users/controllers/password.client.controller.js +++ b/public/modules/users/controllers/password.client.controller.js @@ -1,44 +1,41 @@ 'use strict'; - -angular.module('users').controller('PasswordController', ['$scope', '$stateParams', '$http', '$location', 'Authentication', - function($scope, $stateParams, $http, $location, Authentication) { - $scope.authentication = Authentication; - - //If user is signed in then redirect back home - if ($scope.authentication.user) $location.path('/'); - - // Submit forgotten password account id - $scope.askForPasswordReset = function() { - $scope.success = $scope.error = null; - - $http.post('/auth/forgot', $scope.credentials).success(function(response) { - // Show user success message and clear form - $scope.credentials = null; - $scope.success = response.message; - - }).error(function(response) { - // Show user error message and clear form - $scope.credentials = null; - $scope.error = response.message; - }); - }; - - // Change user password - $scope.resetUserPassword = function() { - $scope.success = $scope.error = null; - - $http.post('/auth/reset/' + $stateParams.token, $scope.passwordDetails).success(function(response) { - // If successful show success message and clear form - $scope.passwordDetails = null; - - // Attach user profile - Authentication.user = response; - - // And redirect to the index page - $location.path('/password/reset/success'); - }).error(function(response) { - $scope.error = response.message; - }); - }; - } +angular.module('users').controller('PasswordController', [ + '$scope', + '$stateParams', + '$http', + '$location', + 'Authentication', + function ($scope, $stateParams, $http, $location, Authentication) { + $scope.authentication = Authentication; + //If user is signed in then redirect back home + if ($scope.authentication.user) + $location.path('/'); + // Submit forgotten password account id + $scope.askForPasswordReset = function () { + $scope.success = $scope.error = null; + $http.post('/auth/forgot', $scope.credentials).success(function (response) { + // Show user success message and clear form + $scope.credentials = null; + $scope.success = response.message; + }).error(function (response) { + // Show user error message and clear form + $scope.credentials = null; + $scope.error = response.message; + }); + }; + // Change user password + $scope.resetUserPassword = function () { + $scope.success = $scope.error = null; + $http.post('/auth/reset/' + $stateParams.token, $scope.passwordDetails).success(function (response) { + // If successful show success message and clear form + $scope.passwordDetails = null; + // Attach user profile + Authentication.user = response; + // And redirect to the index page + $location.path('/password/reset/success'); + }).error(function (response) { + $scope.error = response.message; + }); + }; + } ]); \ No newline at end of file diff --git a/public/modules/users/controllers/settings.client.controller.js b/public/modules/users/controllers/settings.client.controller.js index 8616fc9..e1a60df 100644 --- a/public/modules/users/controllers/settings.client.controller.js +++ b/public/modules/users/controllers/settings.client.controller.js @@ -1,71 +1,62 @@ 'use strict'; - -angular.module('users').controller('SettingsController', ['$scope', '$http', '$location', 'Users', 'Authentication', - function($scope, $http, $location, Users, Authentication) { - $scope.user = Authentication.user; - - // If user is not signed in then redirect back home - if (!$scope.user) $location.path('/'); - - // Check if there are additional accounts - $scope.hasConnectedAdditionalSocialAccounts = function(provider) { - for (var i in $scope.user.additionalProvidersData) { - return true; - } - - return false; - }; - - // Check if provider is already in use with current user - $scope.isConnectedSocialAccount = function(provider) { - return $scope.user.provider === provider || ($scope.user.additionalProvidersData && $scope.user.additionalProvidersData[provider]); - }; - - // Remove a user social account - $scope.removeUserSocialAccount = function(provider) { - $scope.success = $scope.error = null; - - $http.delete('/users/accounts', { - params: { - provider: provider - } - }).success(function(response) { - // If successful show success message and clear form - $scope.success = true; - $scope.user = Authentication.user = response; - }).error(function(response) { - $scope.error = response.message; - }); - }; - - // Update a user profile - $scope.updateUserProfile = function(isValid) { - if (isValid) { - $scope.success = $scope.error = null; - var user = new Users($scope.user); - - user.$update(function(response) { - $scope.success = true; - Authentication.user = response; - }, function(response) { - $scope.error = response.data.message; - }); - } else { - $scope.submitted = true; - } - }; - - // Change user password - $scope.changeUserPassword = function() { - $scope.success = $scope.error = null; - - $http.post('/users/password', $scope.passwordDetails).success(function(response) { - // If successful show success message and clear form - $scope.success = true; - $scope.passwordDetails = null; - }).error(function(response) { - $scope.error = response.message; - }); - }; - } +angular.module('users').controller('SettingsController', [ + '$scope', + '$http', + '$location', + 'Users', + 'Authentication', + function ($scope, $http, $location, Users, Authentication) { + $scope.user = Authentication.user; + // If user is not signed in then redirect back home + if (!$scope.user) + $location.path('/'); + // Check if there are additional accounts + $scope.hasConnectedAdditionalSocialAccounts = function (provider) { + for (var i in $scope.user.additionalProvidersData) { + return true; + } + return false; + }; + // Check if provider is already in use with current user + $scope.isConnectedSocialAccount = function (provider) { + return $scope.user.provider === provider || $scope.user.additionalProvidersData && $scope.user.additionalProvidersData[provider]; + }; + // Remove a user social account + $scope.removeUserSocialAccount = function (provider) { + $scope.success = $scope.error = null; + $http.delete('/users/accounts', { params: { provider: provider } }).success(function (response) { + // If successful show success message and clear form + $scope.success = true; + $scope.user = Authentication.user = response; + }).error(function (response) { + $scope.error = response.message; + }); + }; + // Update a user profile + $scope.updateUserProfile = function (isValid) { + if (isValid) { + $scope.success = $scope.error = null; + var user = new Users($scope.user); + user.$update(function (response) { + $scope.success = true; + Authentication.user = response; + }, function (response) { + $scope.error = response.data.message; + }); + } else { + $scope.submitted = true; + } + }; + // Change user password + $scope.changeUserPassword = function () { + $scope.success = $scope.error = null; + $http.post('/users/password', $scope.passwordDetails).success(function (response) { + // If successful show success message and clear form + $scope.success = true; + $scope.passwordDetails = null; + }).error(function (response) { + $scope.error = response.message; + }); + }; + } ]); \ No newline at end of file diff --git a/public/modules/users/css/users.css b/public/modules/users/css/users.css index de67bf9..3407fc1 100644 --- a/public/modules/users/css/users.css +++ b/public/modules/users/css/users.css @@ -1,14 +1,16 @@ @media (min-width: 992px) { - .nav-users { - position: fixed; - } + .nav-users { + position: fixed; + } } + .remove-account-container { - display: inline-block; - position: relative; + display: inline-block; + position: relative; } + .btn-remove-account { - top: 10px; - right: 10px; - position: absolute; -} \ No newline at end of file + top: 10px; + right: 10px; + position: absolute; +} diff --git a/public/modules/users/services/authentication.client.service.js b/public/modules/users/services/authentication.client.service.js index 4418b2d..0bd9da3 100644 --- a/public/modules/users/services/authentication.client.service.js +++ b/public/modules/users/services/authentication.client.service.js @@ -1,14 +1,7 @@ 'use strict'; - // Authentication service for user variables -angular.module('users').factory('Authentication', [ - function() { - var _this = this; - - _this._data = { - user: window.user - }; - - return _this._data; - } -]); \ No newline at end of file +angular.module('users').factory('Authentication', [function () { + var _this = this; + _this._data = { user: window.user }; + return _this._data; + }]); \ No newline at end of file diff --git a/public/modules/users/services/users.client.service.js b/public/modules/users/services/users.client.service.js index 664828f..0ad515b 100644 --- a/public/modules/users/services/users.client.service.js +++ b/public/modules/users/services/users.client.service.js @@ -1,12 +1,8 @@ 'use strict'; - // Users service used for communicating with the users REST endpoint -angular.module('users').factory('Users', ['$resource', - function($resource) { - return $resource('users', {}, { - update: { - method: 'PUT' - } - }); - } +angular.module('users').factory('Users', [ + '$resource', + function ($resource) { + return $resource('users', {}, { update: { method: 'PUT' } }); + } ]); \ No newline at end of file diff --git a/public/modules/users/tests/authentication.client.controller.test.js b/public/modules/users/tests/authentication.client.controller.test.js index 4c95d68..2d7e5b6 100644 --- a/public/modules/users/tests/authentication.client.controller.test.js +++ b/public/modules/users/tests/authentication.client.controller.test.js @@ -1,118 +1,81 @@ 'use strict'; - -(function() { - // Authentication controller Spec - describe('AuthenticationController', function() { - // Initialize global variables - var AuthenticationController, - scope, - $httpBackend, - $stateParams, - $location; - - beforeEach(function() { - jasmine.addMatchers({ - toEqualData: function(util, customEqualityTesters) { - return { - compare: function(actual, expected) { - return { - pass: angular.equals(actual, expected) - }; - } - }; - } - }); - }); - - // Load the main application module - beforeEach(module(ApplicationConfiguration.applicationModuleName)); - - // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). - // This allows us to inject a service but then attach it to a variable - // with the same name as the service. - beforeEach(inject(function($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { - // Set a new global scope - scope = $rootScope.$new(); - - // Point global variables to injected services - $stateParams = _$stateParams_; - $httpBackend = _$httpBackend_; - $location = _$location_; - - // Initialize the Authentication controller - AuthenticationController = $controller('AuthenticationController', { - $scope: scope - }); - })); - - - it('$scope.signin() should login with a correct user and password', function() { - // Test expected GET request - $httpBackend.when('POST', '/auth/signin').respond(200, 'Fred'); - - scope.signin(); - $httpBackend.flush(); - - // Test scope value - expect(scope.authentication.user).toEqual('Fred'); - expect($location.url()).toEqual('/'); - }); - - it('$scope.signin() should fail to log in with nothing', function() { - // Test expected POST request - $httpBackend.expectPOST('/auth/signin').respond(400, { - 'message': 'Missing credentials' - }); - - scope.signin(); - $httpBackend.flush(); - - // Test scope value - expect(scope.error).toEqual('Missing credentials'); - }); - - it('$scope.signin() should fail to log in with wrong credentials', function() { - // Foo/Bar combo assumed to not exist - scope.authentication.user = 'Foo'; - scope.credentials = 'Bar'; - - // Test expected POST request - $httpBackend.expectPOST('/auth/signin').respond(400, { - 'message': 'Unknown user' - }); - - scope.signin(); - $httpBackend.flush(); - - // Test scope value - expect(scope.error).toEqual('Unknown user'); - }); - - it('$scope.signup() should register with correct data', function() { - // Test expected GET request - scope.authentication.user = 'Fred'; - $httpBackend.when('POST', '/auth/signup').respond(200, 'Fred'); - - scope.signup(); - $httpBackend.flush(); - - // test scope value - expect(scope.authentication.user).toBe('Fred'); - expect(scope.error).toEqual(undefined); - expect($location.url()).toBe('/'); - }); - - it('$scope.signup() should fail to register with duplicate Username', function() { - // Test expected POST request - $httpBackend.when('POST', '/auth/signup').respond(400, { - 'message': 'Username already exists' - }); - - scope.signup(); - $httpBackend.flush(); - - // Test scope value - expect(scope.error).toBe('Username already exists'); - }); - }); +(function () { + // Authentication controller Spec + describe('AuthenticationController', function () { + // Initialize global variables + var AuthenticationController, scope, $httpBackend, $stateParams, $location; + beforeEach(function () { + jasmine.addMatchers({ + toEqualData: function (util, customEqualityTesters) { + return { + compare: function (actual, expected) { + return { pass: angular.equals(actual, expected) }; + } + }; + } + }); + }); + // Load the main application module + beforeEach(module(ApplicationConfiguration.applicationModuleName)); + // The injector ignores leading and trailing underscores here (i.e. _$httpBackend_). + // This allows us to inject a service but then attach it to a variable + // with the same name as the service. + beforeEach(inject(function ($controller, $rootScope, _$location_, _$stateParams_, _$httpBackend_) { + // Set a new global scope + scope = $rootScope.$new(); + // Point global variables to injected services + $stateParams = _$stateParams_; + $httpBackend = _$httpBackend_; + $location = _$location_; + // Initialize the Authentication controller + AuthenticationController = $controller('AuthenticationController', { $scope: scope }); + })); + it('$scope.signin() should login with a correct user and password', function () { + // Test expected GET request + $httpBackend.when('POST', '/auth/signin').respond(200, 'Fred'); + scope.signin(); + $httpBackend.flush(); + // Test scope value + expect(scope.authentication.user).toEqual('Fred'); + expect($location.url()).toEqual('/'); + }); + it('$scope.signin() should fail to log in with nothing', function () { + // Test expected POST request + $httpBackend.expectPOST('/auth/signin').respond(400, { 'message': 'Missing credentials' }); + scope.signin(); + $httpBackend.flush(); + // Test scope value + expect(scope.error).toEqual('Missing credentials'); + }); + it('$scope.signin() should fail to log in with wrong credentials', function () { + // Foo/Bar combo assumed to not exist + scope.authentication.user = 'Foo'; + scope.credentials = 'Bar'; + // Test expected POST request + $httpBackend.expectPOST('/auth/signin').respond(400, { 'message': 'Unknown user' }); + scope.signin(); + $httpBackend.flush(); + // Test scope value + expect(scope.error).toEqual('Unknown user'); + }); + it('$scope.signup() should register with correct data', function () { + // Test expected GET request + scope.authentication.user = 'Fred'; + $httpBackend.when('POST', '/auth/signup').respond(200, 'Fred'); + scope.signup(); + $httpBackend.flush(); + // test scope value + expect(scope.authentication.user).toBe('Fred'); + expect(scope.error).toEqual(undefined); + expect($location.url()).toBe('/'); + }); + it('$scope.signup() should fail to register with duplicate Username', function () { + // Test expected POST request + $httpBackend.when('POST', '/auth/signup').respond(400, { 'message': 'Username already exists' }); + scope.signup(); + $httpBackend.flush(); + // Test scope value + expect(scope.error).toBe('Username already exists'); + }); + }); }()); \ No newline at end of file diff --git a/public/modules/users/users.client.module.js b/public/modules/users/users.client.module.js index b119986..c03bb3d 100644 --- a/public/modules/users/users.client.module.js +++ b/public/modules/users/users.client.module.js @@ -1,4 +1,3 @@ 'use strict'; - // Use Applicaion configuration module to register a new module ApplicationConfiguration.registerModule('users'); \ No newline at end of file diff --git a/public/modules/users/views/authentication/signin.client.view.html b/public/modules/users/views/authentication/signin.client.view.html index 91e256e..4b8bafc 100644 --- a/public/modules/users/views/authentication/signin.client.view.html +++ b/public/modules/users/views/authentication/signin.client.view.html @@ -1,45 +1,50 @@
-

Sign in using your social accounts

- -

Or with your account

-
- -
-
- - -
-
- - -
-
-   or  - Sign up -
- -
- -
-
- -
-
\ No newline at end of file +

Sign in using your social accounts

+ + +

Or with your account

+ +
+ +
+
diff --git a/public/modules/users/views/authentication/signup.client.view.html b/public/modules/users/views/authentication/signup.client.view.html index e205176..fc09ad1 100644 --- a/public/modules/users/views/authentication/signup.client.view.html +++ b/public/modules/users/views/authentication/signup.client.view.html @@ -1,54 +1,62 @@
-

Sign up using your social accounts

- -

Or with your email

-
- -
-
\ No newline at end of file +

Sign up using your social accounts

+ + +

Or with your email

+ +
+ +
+ diff --git a/public/modules/users/views/password/forgot-password.client.view.html b/public/modules/users/views/password/forgot-password.client.view.html index e6275f9..ec26c63 100644 --- a/public/modules/users/views/password/forgot-password.client.view.html +++ b/public/modules/users/views/password/forgot-password.client.view.html @@ -1,22 +1,25 @@
-

Restore your password

-

Enter your account username.

-
- -
-
\ No newline at end of file +

Restore your password

+ +

Enter your account username.

+ +
+ +
+ diff --git a/public/modules/users/views/password/reset-password-invalid.client.view.html b/public/modules/users/views/password/reset-password-invalid.client.view.html index d5fc237..ffa154a 100644 --- a/public/modules/users/views/password/reset-password-invalid.client.view.html +++ b/public/modules/users/views/password/reset-password-invalid.client.view.html @@ -1,4 +1,4 @@
-

Password reset is invalid

- Ask for a new password reset -
\ No newline at end of file +

Password reset is invalid

+ Ask for a new password reset + diff --git a/public/modules/users/views/password/reset-password-success.client.view.html b/public/modules/users/views/password/reset-password-success.client.view.html index 4de46c4..a39d333 100644 --- a/public/modules/users/views/password/reset-password-success.client.view.html +++ b/public/modules/users/views/password/reset-password-success.client.view.html @@ -1,4 +1,4 @@
-

Password successfully reset

- Continue to home page -
\ No newline at end of file +

Password successfully reset

+ Continue to home page + diff --git a/public/modules/users/views/password/reset-password.client.view.html b/public/modules/users/views/password/reset-password.client.view.html index dc8b2ea..eb7eb63 100644 --- a/public/modules/users/views/password/reset-password.client.view.html +++ b/public/modules/users/views/password/reset-password.client.view.html @@ -1,26 +1,29 @@
-

Reset your password

-
- -
-
\ No newline at end of file +

Reset your password

+ +
+ +
+ diff --git a/public/modules/users/views/settings/change-password.client.view.html b/public/modules/users/views/settings/change-password.client.view.html index 9811011..763c91f 100644 --- a/public/modules/users/views/settings/change-password.client.view.html +++ b/public/modules/users/views/settings/change-password.client.view.html @@ -1,30 +1,34 @@
-

Change your password

-
- -
-
\ No newline at end of file +

Change your password

+ +
+ +
+ diff --git a/public/modules/users/views/settings/edit-profile.client.view.html b/public/modules/users/views/settings/edit-profile.client.view.html index a4be680..fd3e2b5 100644 --- a/public/modules/users/views/settings/edit-profile.client.view.html +++ b/public/modules/users/views/settings/edit-profile.client.view.html @@ -1,34 +1,40 @@
-

Edit your profile

-
- -
-
\ No newline at end of file +

Edit your profile

+ +
+ +
+ diff --git a/public/modules/users/views/settings/social-accounts.client.view.html b/public/modules/users/views/settings/social-accounts.client.view.html index 4712ee0..ce5474f 100644 --- a/public/modules/users/views/settings/social-accounts.client.view.html +++ b/public/modules/users/views/settings/social-accounts.client.view.html @@ -1,29 +1,33 @@
-

Connected social accounts:

-
- -
-

Connect other social accounts:

- -
\ No newline at end of file +

Connected social + accounts:

+ +
+ +
+

Connect other social accounts:

+ + +