diff --git a/.jscsrc b/.jscsrc index 459ec7e..36dce16 100644 --- a/.jscsrc +++ b/.jscsrc @@ -2,6 +2,7 @@ "disallowEmptyBlocks": true, "disallowImplicitTypeConversion": [ "binary", + "boolean", "numeric", "string" ], @@ -13,8 +14,13 @@ "disallowMultipleSpaces": true, "disallowMultipleVarDecl": true, "disallowNewlineBeforeBlockStatements": true, + "disallowParenthesesAroundArrowParam": true, "disallowQuotedKeysInObjects": true, - "disallowSpaceAfterObjectKeys": true, + "disallowSpaceAfterObjectKeys": { + "allExcept": [ + "method" + ] + }, "disallowSpaceAfterPrefixUnaryOperators": true, "disallowSpaceBeforeComma": true, "disallowSpaceBeforeSemicolon": true, @@ -26,24 +32,22 @@ "disallowSpacesInsideBrackets": true, "disallowSpacesInsideObjectBrackets": true, "disallowSpacesInsideParentheses": true, + "disallowSpacesInsideTemplateStringPlaceholders": true, "disallowTrailingComma": true, "disallowTrailingWhitespace": true, + "disallowVar": true, "disallowYodaConditions": true, - "maximumLineLength": 200, + + "maximumLineLength": 100, + + "requireArrowFunctions": true, "requireBlocksOnNewline": true, + "requireCamelCaseOrUpperCaseIdentifiers": true, "requireCapitalizedConstructors": true, "requireCommaBeforeLineBreak": true, - "requireCurlyBraces": [ - "if", - "else", - "for", - "while", - "do", - "switch", - "try", - "catch" - ], + "requireCurlyBraces": true, "requireDotNotation": true, + "requireFunctionDeclarations": true, "requireLineBreakAfterVariableAssignment": true, "requireLineFeedAtFileEnd": true, "requireObjectKeysOnNewLine": true, @@ -74,6 +78,8 @@ "requireSpacesInFunction": { "beforeOpeningCurlyBrace": true }, + "requireTemplateStrings": true, + "validateIndentation": "\t", "validateLineBreaks": "LF", "validateNewlineAfterArrayElements": true, diff --git a/.jshintrc b/.jshintrc index d5df1f0..4379be2 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,7 +1,7 @@ { - "browser": true, "curly": true, "eqeqeq": true, + "esversion": 6, "forin": true, "globals": { "after": true, @@ -19,11 +19,8 @@ "node": true, "nonew": true, "nonstandard": true, - "regexp": true, - "shadow": true, + "shadow": false, "strict": true, - "sub": true, - "trailing": true, "undef": true, "unused": true } diff --git a/app.js b/app.js index f16efe2..31a3965 100644 --- a/app.js +++ b/app.js @@ -15,14 +15,14 @@ 'use strict'; -var bodyParser = require('body-parser'); -var compression = require('compression'); -var createClient = require('pa11y-webservice-client-node'); -var EventEmitter = require('events').EventEmitter; -var express = require('express'); -var hbs = require('express-hbs'); -var http = require('http'); -var pkg = require('./package.json'); +const bodyParser = require('body-parser'); +const compression = require('compression'); +const createClient = require('pa11y-webservice-client-node'); +const EventEmitter = require('events').EventEmitter; +const express = require('express'); +const hbs = require('express-hbs'); +const http = require('http'); +const pkg = require('./package.json'); module.exports = initApp; @@ -30,12 +30,12 @@ module.exports = initApp; function initApp(config, callback) { config = defaultConfig(config); - var webserviceUrl = config.webservice; + let webserviceUrl = config.webservice; if (typeof webserviceUrl === 'object') { - webserviceUrl = 'http://' + webserviceUrl.host + ':' + webserviceUrl.port + '/'; + webserviceUrl = `http://${webserviceUrl.host}:${webserviceUrl.port}/`; } - var app = new EventEmitter(); + const app = new EventEmitter(); app.address = null; app.express = express(); app.server = http.createServer(app.express); @@ -45,7 +45,7 @@ function initApp(config, callback) { app.express.use(compression()); // Public files - app.express.use(express.static(__dirname + '/public', { + app.express.use(express.static(`${__dirname}/public`, { maxAge: (process.env.NODE_ENV === 'production' ? 604800000 : 0) })); @@ -59,11 +59,11 @@ function initApp(config, callback) { app.express.engine('html', hbs.express4({ extname: '.html', contentHelperName: 'content', - layoutsDir: __dirname + '/view/layout', - partialsDir: __dirname + '/view/partial', - defaultLayout: __dirname + '/view/layout/default' + layoutsDir: `${__dirname}/view/layout`, + partialsDir: `${__dirname}/view/partial`, + defaultLayout: `${__dirname}/view/layout/default` })); - app.express.set('views', __dirname + '/view'); + app.express.set('views', `${__dirname}/view`); app.express.set('view engine', 'html'); // View helpers @@ -84,7 +84,7 @@ function initApp(config, callback) { settings: {} }; - app.express.use(function(req, res, next) { + app.express.use((req, res, next) => { res.locals.isHomePage = (req.path === '/'); res.locals.host = req.hostname; next(); @@ -105,11 +105,11 @@ function initApp(config, callback) { } // Error handling - app.express.get('*', function(req, res) { + app.express.get('*', (req, res) => { res.status(404); res.render('404'); }); - app.express.use(function(err, req, res, next) { + app.express.use((err, req, res, next) => { /* jshint unused: false */ if (err.code === 'ECONNREFUSED') { err = new Error('Could not connect to Pa11y Webservice'); @@ -122,9 +122,9 @@ function initApp(config, callback) { res.render('500'); }); - app.server.listen(config.port, function(err) { - var address = app.server.address(); - app.address = 'http://' + address.address + ':' + address.port; + app.server.listen(config.port, err => { + const address = app.server.address(); + app.address = `http://${address.address}:${address.port}`; callback(err, app); }); diff --git a/config.js b/config.js index fcd3039..f9e8744 100644 --- a/config.js +++ b/config.js @@ -15,8 +15,9 @@ 'use strict'; -var fs = require('fs'); -var jsonPath = './config/' + (process.env.NODE_ENV || 'development') + '.json'; +const fs = require('fs'); +const environment = (process.env.NODE_ENV || 'development'); +const jsonPath = `./config/${environment}.json`; if (fs.existsSync(jsonPath)) { module.exports = require(jsonPath); @@ -36,6 +37,6 @@ if (fs.existsSync(jsonPath)) { } function env(name, defaultValue) { - var value = process.env[name]; + const value = process.env[name]; return typeof value === 'string' ? value : defaultValue; } diff --git a/index.js b/index.js index caeb586..8b00f03 100644 --- a/index.js +++ b/index.js @@ -15,24 +15,24 @@ 'use strict'; -var chalk = require('chalk'); -var config = require('./config'); +const chalk = require('chalk'); +const config = require('./config'); -process.on('SIGINT', function() { +process.on('SIGINT', () => { console.log('\nGracefully shutting down from SIGINT (Ctrl-C)'); process.exit(); }); -require('./app')(config, function(err, app) { +require('./app')(config, (err, app) => { console.log(''); console.log(chalk.underline.magenta('Pa11y Dashboard started')); console.log(chalk.grey('mode: %s'), process.env.NODE_ENV); console.log(chalk.grey('uri: %s'), app.address); - app.on('route-error', function(err) { - var stack = (err.stack ? err.stack.split('\n') : [err.message]); - var msg = chalk.red(stack.shift()); + app.on('route-error', err => { + const stack = (err.stack ? err.stack.split('\n') : [err.message]); + const msg = chalk.red(stack.shift()); console.error(''); console.error(msg); console.error(chalk.grey(stack.join('\n'))); @@ -40,7 +40,7 @@ require('./app')(config, function(err, app) { // Start the webservice if required if (typeof config.webservice === 'object') { - require('pa11y-webservice')(config.webservice, function(err, webservice) { + require('pa11y-webservice')(config.webservice, (err, webservice) => { console.log(''); console.log(chalk.underline.cyan('Pa11y Webservice started')); console.log(chalk.grey('mode: %s'), process.env.NODE_ENV); diff --git a/route/index.js b/route/index.js index e1ff56c..dfd031e 100644 --- a/route/index.js +++ b/route/index.js @@ -15,14 +15,14 @@ 'use strict'; -var presentTask = require('../view/presenter/task'); +const presentTask = require('../view/presenter/task'); module.exports = route; // Route definition function route(app) { - app.express.get('/', function(req, res, next) { - app.webservice.tasks.get({lastres: true}, function(err, tasks) { + app.express.get('/', (req, res, next) => { + app.webservice.tasks.get({lastres: true}, (err, tasks) => { if (err) { return next(err); } diff --git a/route/new.js b/route/new.js index ccc6f35..492ec04 100644 --- a/route/new.js +++ b/route/new.js @@ -15,15 +15,15 @@ 'use strict'; -var getStandards = require('../data/standards'); +const getStandards = require('../data/standards'); module.exports = route; // Route definition function route(app) { - app.express.get('/new', function(req, res) { - var standards = getStandards().map(function(standard) { + app.express.get('/new', (req, res) => { + const standards = getStandards().map(standard => { if (standard.title === 'WCAG2AA') { standard.selected = true; } @@ -35,8 +35,8 @@ function route(app) { }); }); - app.express.post('/new', function(req, res) { - var newTask = { + app.express.post('/new', (req, res) => { + const newTask = { name: req.body.name, url: req.body.url, standard: req.body.standard, @@ -46,13 +46,13 @@ function route(app) { username: req.body.username, password: req.body.password }; - app.webservice.tasks.create(newTask, function(err, task) { + app.webservice.tasks.create(newTask, (err, task) => { if (err) { - var standards = getStandards().map(function(standard) { + const standards = getStandards().map(standard => { if (standard.title === newTask.standard) { standard.selected = true; } - standard.rules = standard.rules.map(function(rule) { + standard.rules = standard.rules.map(rule => { if (newTask.ignore.indexOf(rule.name) !== -1) { rule.ignored = true; } @@ -66,7 +66,7 @@ function route(app) { task: newTask }); } - res.redirect('/' + task.id + '?added'); + res.redirect(`/${task.id}?added`); }); }); diff --git a/route/result/download.js b/route/result/download.js index 43c1a09..e232ae3 100644 --- a/route/result/download.js +++ b/route/result/download.js @@ -15,7 +15,7 @@ 'use strict'; -var moment = require('moment'); +const moment = require('moment'); module.exports = route; @@ -23,14 +23,14 @@ module.exports = route; function route(app) { function getTaskAndResult(req, res, next) { - app.webservice.task(req.params.id).get({}, function(err, task) { + app.webservice.task(req.params.id).get({}, (err, task) => { if (err) { return next('route'); } app.webservice .task(req.params.id) .result(req.params.rid) - .get({full: true}, function(err, result) { + .get({full: true}, (err, result) => { if (err) { return next('route'); } @@ -58,11 +58,11 @@ function route(app) { ].join(''); } - app.express.get('/:id/:rid.csv', getTaskAndResult, function(req, res) { - var task = res.locals.task; - var result = res.locals.result; - var rows = ['"code","message","type","context","selector"']; - result.results.forEach(function(msg) { + app.express.get('/:id/:rid.csv', getTaskAndResult, (req, res) => { + const task = res.locals.task; + const result = res.locals.result; + const rows = ['"code","message","type","context","selector"']; + result.results.forEach(msg => { rows.push([ JSON.stringify(msg.code), JSON.stringify(msg.message), @@ -75,9 +75,9 @@ function route(app) { res.send(rows.join('\n')); }); - app.express.get('/:id/:rid.json', getTaskAndResult, function(req, res) { - var task = res.locals.task; - var result = res.locals.result; + app.express.get('/:id/:rid.json', getTaskAndResult, (req, res) => { + const task = res.locals.task; + const result = res.locals.result; res.attachment(getDownloadFileName(task, result, 'json')); delete task.id; delete result.id; diff --git a/route/result/index.js b/route/result/index.js index 0db177f..296fb61 100644 --- a/route/result/index.js +++ b/route/result/index.js @@ -15,23 +15,23 @@ 'use strict'; -var presentTask = require('../../view/presenter/task'); -var presentResult = require('../../view/presenter/result'); +const presentTask = require('../../view/presenter/task'); +const presentResult = require('../../view/presenter/result'); module.exports = route; // Route definition function route(app) { - app.express.get('/:id/:rid', function(req, res, next) { - app.webservice.task(req.params.id).get({}, function(err, task) { + app.express.get('/:id/:rid', (req, res, next) => { + app.webservice.task(req.params.id).get({}, (err, task) => { if (err) { return next(); } app.webservice .task(req.params.id) .result(req.params.rid) - .get({full: true}, function(err, result) { + .get({full: true}, (err, result) => { if (err) { return next(); } diff --git a/route/task/delete.js b/route/task/delete.js index fb41331..b7aebc3 100644 --- a/route/task/delete.js +++ b/route/task/delete.js @@ -15,15 +15,15 @@ 'use strict'; -var presentTask = require('../../view/presenter/task'); +const presentTask = require('../../view/presenter/task'); module.exports = route; // Route definition function route(app) { - app.express.get('/:id/delete', function(req, res, next) { - app.webservice.task(req.params.id).get({}, function(err, task) { + app.express.get('/:id/delete', (req, res, next) => { + app.webservice.task(req.params.id).get({}, (err, task) => { if (err) { return next(); } @@ -34,8 +34,8 @@ function route(app) { }); }); - app.express.post('/:id/delete', function(req, res, next) { - app.webservice.task(req.params.id).remove(function(err) { + app.express.post('/:id/delete', (req, res, next) => { + app.webservice.task(req.params.id).remove(err => { if (err) { return next(); } diff --git a/route/task/edit.js b/route/task/edit.js index 43c1d09..90d5127 100644 --- a/route/task/edit.js +++ b/route/task/edit.js @@ -15,24 +15,24 @@ 'use strict'; -var presentTask = require('../../view/presenter/task'); -var getStandards = require('../../data/standards'); +const presentTask = require('../../view/presenter/task'); +const getStandards = require('../../data/standards'); module.exports = route; // Route definition function route(app) { - app.express.get('/:id/edit', function(req, res, next) { - app.webservice.task(req.params.id).get({}, function(err, task) { + app.express.get('/:id/edit', (req, res, next) => { + app.webservice.task(req.params.id).get({}, (err, task) => { if (err) { return next(); } - var standards = getStandards().map(function(standard) { + const standards = getStandards().map(standard => { if (standard.title === task.standard) { standard.selected = true; } - standard.rules = standard.rules.map(function(rule) { + standard.rules = standard.rules.map(rule => { if (task.ignore.indexOf(rule.name) !== -1) { rule.ignored = true; } @@ -49,13 +49,13 @@ function route(app) { }); }); - app.express.post('/:id/edit', function(req, res, next) { - app.webservice.task(req.params.id).get({}, function(err, task) { + app.express.post('/:id/edit', (req, res, next) => { + app.webservice.task(req.params.id).get({}, (err, task) => { if (err) { return next(); } req.body.ignore = req.body.ignore || []; - app.webservice.task(req.params.id).edit(req.body, function(err) { + app.webservice.task(req.params.id).edit(req.body, err => { if (err) { task.name = req.body.name; task.ignore = req.body.ignore; @@ -63,11 +63,11 @@ function route(app) { task.wait = req.body.wait; task.username = req.body.username; task.password = req.body.password; - var standards = getStandards().map(function(standard) { + const standards = getStandards().map(standard => { if (standard.title === task.standard) { standard.selected = true; } - standard.rules = standard.rules.map(function(rule) { + standard.rules = standard.rules.map(rule => { if (task.ignore.indexOf(rule.name) !== -1) { rule.ignored = true; } @@ -82,7 +82,7 @@ function route(app) { isTaskSubPage: true }); } - res.redirect('/' + req.params.id + '/edit?edited'); + res.redirect(`/${req.params.id}/edit?edited`); }); }); }); diff --git a/route/task/ignore.js b/route/task/ignore.js index 3b2c398..18b8c8b 100644 --- a/route/task/ignore.js +++ b/route/task/ignore.js @@ -5,20 +5,20 @@ module.exports = route; // Route definition function route(app) { - app.express.post('/:id/ignore', function(req, res, next) { - app.webservice.task(req.params.id).get({}, function(err, task) { + app.express.post('/:id/ignore', (req, res, next) => { + app.webservice.task(req.params.id).get({}, (err, task) => { if (err) { return next(); } - var edit = { + const edit = { name: task.name, ignore: task.ignore }; if (typeof req.body.rule === 'string') { edit.ignore.push(req.body.rule); } - app.webservice.task(req.params.id).edit(edit, function() { - res.redirect('/' + req.params.id + '?rule-ignored'); + app.webservice.task(req.params.id).edit(edit, () => { + res.redirect(`/${req.params.id}?rule-ignored`); }); }); }); diff --git a/route/task/index.js b/route/task/index.js index c6ad4bd..234e3e1 100644 --- a/route/task/index.js +++ b/route/task/index.js @@ -15,25 +15,25 @@ 'use strict'; -var presentTask = require('../../view/presenter/task'); -var presentResult = require('../../view/presenter/result'); -var presentResultList = require('../../view/presenter/result-list'); +const presentTask = require('../../view/presenter/task'); +const presentResult = require('../../view/presenter/result'); +const presentResultList = require('../../view/presenter/result-list'); module.exports = route; // Route definition function route(app) { - app.express.get('/:id', function(req, res, next) { - app.webservice.task(req.params.id).get({lastres: true}, function(err, task) { + app.express.get('/:id', (req, res, next) => { + app.webservice.task(req.params.id).get({lastres: true}, (err, task) => { if (err) { return next(); } - app.webservice.task(req.params.id).results({}, function(err, results) { + app.webservice.task(req.params.id).results({}, (err, results) => { if (err) { return next(err); } - var presentedResults = presentResultList(results.map(presentResult)); + const presentedResults = presentResultList(results.map(presentResult)); res.render('task', { task: presentTask(task), results: presentedResults, diff --git a/route/task/run.js b/route/task/run.js index a509ffc..b5f85cb 100644 --- a/route/task/run.js +++ b/route/task/run.js @@ -20,12 +20,12 @@ module.exports = route; // Route definition function route(app) { - app.express.get('/:id/run', function(req, res, next) { - app.webservice.task(req.params.id).run(function(err) { + app.express.get('/:id/run', (req, res, next) => { + app.webservice.task(req.params.id).run(err => { if (err) { return next(); } - res.redirect('/' + req.params.id + '?running'); + res.redirect(`/${req.params.id}?running`); }); }); diff --git a/route/task/unignore.js b/route/task/unignore.js index eca0a2d..412d9e3 100644 --- a/route/task/unignore.js +++ b/route/task/unignore.js @@ -5,21 +5,21 @@ module.exports = route; // Route definition function route(app) { - app.express.post('/:id/unignore', function(req, res, next) { - app.webservice.task(req.params.id).get({}, function(err, task) { + app.express.post('/:id/unignore', (req, res, next) => { + app.webservice.task(req.params.id).get({}, (err, task) => { if (err) { return next(); } - var edit = { + const edit = { name: task.name, ignore: task.ignore }; - var indexOfRule = edit.ignore.indexOf(req.body.rule); + const indexOfRule = edit.ignore.indexOf(req.body.rule); if (typeof req.body.rule === 'string' && indexOfRule !== -1) { edit.ignore.splice(indexOfRule, 1); } - app.webservice.task(req.params.id).edit(edit, function() { - res.redirect('/' + req.params.id + '?rule-unignored'); + app.webservice.task(req.params.id).edit(edit, () => { + res.redirect(`/${req.params.id}?rule-unignored`); }); }); }); diff --git a/test/integration/helper/navigate.js b/test/integration/helper/navigate.js index 4ea7419..456a8ec 100644 --- a/test/integration/helper/navigate.js +++ b/test/integration/helper/navigate.js @@ -13,10 +13,11 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable requireArrowFunctions 'use strict'; -var cheerio = require('cheerio'); -var request = require('request'); +const cheerio = require('cheerio'); +const request = require('request'); module.exports = createNavigator; diff --git a/test/integration/helper/webservice.js b/test/integration/helper/webservice.js index 8d0306e..9001e95 100644 --- a/test/integration/helper/webservice.js +++ b/test/integration/helper/webservice.js @@ -13,17 +13,18 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable requireArrowFunctions 'use strict'; -var createClient = require('pa11y-webservice-client-node'); +const createClient = require('pa11y-webservice-client-node'); module.exports = createWebserviceClient; // Create a webservice client function createWebserviceClient(config) { - var webserviceUrl = config.webservice; + let webserviceUrl = config.webservice; if (typeof webserviceUrl === 'object') { - webserviceUrl = 'http://' + webserviceUrl.host + ':' + webserviceUrl.port + '/'; + webserviceUrl = `http://${webserviceUrl.host}:${webserviceUrl.port}/`; } return createClient(webserviceUrl); } diff --git a/test/integration/route/index.js b/test/integration/route/index.js index 39a57c6..18a259b 100644 --- a/test/integration/route/index.js +++ b/test/integration/route/index.js @@ -13,14 +13,15 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable maximumLineLength, requireArrowFunctions 'use strict'; -var assert = require('proclaim'); +const assert = require('proclaim'); describe.only('GET /', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/' }; @@ -32,13 +33,13 @@ describe.only('GET /', function() { }); it('should display an "Add new URL" button', function() { - var elem = this.last.dom('[data-test=add-task]'); + const elem = this.last.dom('[data-test=add-task]'); assert.strictEqual(elem.length, 1); assert.strictEqual(elem.eq(0).attr('href'), '/new'); }); it('should display all of the expected tasks', function() { - var tasks = this.last.dom('[data-test=task]'); + const tasks = this.last.dom('[data-test=task]'); assert.strictEqual(tasks.length, 3); assert.match(tasks.eq(0).text(), /npg home\s+\(wcag2aa\)/i); assert.match(tasks.eq(1).text(), /npg home\s+\(wcag2aaa\)/i); @@ -46,42 +47,42 @@ describe.only('GET /', function() { }); it('should have links to each task', function() { - var tasks = this.last.dom('[data-test=task]'); + const tasks = this.last.dom('[data-test=task]'); assert.strictEqual(tasks.eq(0).find('[href="/abc000000000000000000001"]').length, 1); assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002"]').length, 1); assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003"]').length, 1); }); it('should display an "Edit" button for each task', function() { - var tasks = this.last.dom('[data-test=task]'); + const tasks = this.last.dom('[data-test=task]'); assert.strictEqual(tasks.eq(0).find('[href="/abc000000000000000000001/edit"]').length, 1); assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/edit"]').length, 1); assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003/edit"]').length, 1); }); it('should display a "Delete" button for each task', function() { - var tasks = this.last.dom('[data-test=task]'); + const tasks = this.last.dom('[data-test=task]'); assert.strictEqual(tasks.eq(0).find('[href="/abc000000000000000000001/delete"]').length, 1); assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/delete"]').length, 1); assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003/delete"]').length, 1); }); it('should display a "Run" button for each task', function() { - var tasks = this.last.dom('[data-test=task]'); + const tasks = this.last.dom('[data-test=task]'); assert.strictEqual(tasks.eq(0).find('[href="/abc000000000000000000001/run"]').length, 1); assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/run"]').length, 1); assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003/run"]').length, 1); }); it('should display the task result counts if the task has been run', function() { - var tasks = this.last.dom('[data-test=task]'); + const tasks = this.last.dom('[data-test=task]'); assert.match(tasks.eq(0).text(), /1\s*errors/i); assert.match(tasks.eq(0).text(), /2\s*warnings/i); assert.match(tasks.eq(0).text(), /3\s*notices/i); }); it('should display a message indicating that there are no results if the task has not been run', function() { - var tasks = this.last.dom('[data-test=task]'); + const tasks = this.last.dom('[data-test=task]'); assert.match(tasks.eq(2).text(), /no results/i); }); diff --git a/test/integration/route/new.js b/test/integration/route/new.js index 02efd11..b9374b3 100644 --- a/test/integration/route/new.js +++ b/test/integration/route/new.js @@ -13,14 +13,15 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable maximumLineLength, requireArrowFunctions 'use strict'; -var assert = require('proclaim'); +const assert = require('proclaim'); describe('GET /new', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/new' }; @@ -36,7 +37,7 @@ describe('GET /new', function() { }); it('should have an "Add new URL" form', function() { - var form = this.last.dom('[data-test=new-url-form]').eq(0); + const form = this.last.dom('[data-test=new-url-form]').eq(0); assert.isDefined(form); assert.strictEqual(form.attr('action'), '/new'); assert.strictEqual(form.attr('method'), 'post'); @@ -49,48 +50,48 @@ describe('GET /new', function() { }); it('should have a "name" field', function() { - var field = this.form.find('input[name=name]').eq(0); + const field = this.form.find('input[name=name]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('value'), ''); }); it('should have a "url" field', function() { - var field = this.form.find('input[name=url]').eq(0); + const field = this.form.find('input[name=url]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'url'); assert.strictEqual(field.attr('value'), ''); }); it('should have a "wait" field', function() { - var field = this.form.find('input[name=wait]').eq(0); + const field = this.form.find('input[name=wait]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('value'), ''); }); it('should have a "username" field', function() { - var field = this.form.find('input[name=username]').eq(0); + const field = this.form.find('input[name=username]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('value'), ''); }); it('should have a "password" field', function() { - var field = this.form.find('input[name=password]').eq(0); + const field = this.form.find('input[name=password]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('value'), ''); }); it('should have a "standard" field', function() { - var field = this.form.find('select[name=standard]').eq(0); + const field = this.form.find('select[name=standard]').eq(0); assert.isDefined(field); assert.strictEqual(field.find('option').length, 4); }); it('should have "ignore" fields', function() { - var fields = this.form.find('input[name="ignore[]"]'); + const fields = this.form.find('input[name="ignore[]"]'); assert.isDefined(fields); assert.notStrictEqual(fields.length, 0); }); @@ -104,7 +105,7 @@ describe('POST /new', function() { describe('with invalid query', function() { beforeEach(function(done) { - var req = { + const req = { method: 'POST', endpoint: '/new', form: { @@ -128,7 +129,7 @@ describe('POST /new', function() { describe('with valid query', function() { beforeEach(function(done) { - var req = { + const req = { method: 'POST', endpoint: '/new', form: { @@ -160,7 +161,7 @@ describe('POST /new', function() { }); it('should display a success message', function() { - var alert = this.last.dom('[data-test=alert]').eq(0); + const alert = this.last.dom('[data-test=alert]').eq(0); assert.isDefined(alert); assert.match(alert.textContent, /url has been added/i); }); diff --git a/test/integration/route/result/download.js b/test/integration/route/result/download.js index 12c7fbc..be22d6c 100644 --- a/test/integration/route/result/download.js +++ b/test/integration/route/result/download.js @@ -13,14 +13,15 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable maximumLineLength, requireArrowFunctions 'use strict'; -var assert = require('proclaim'); +const assert = require('proclaim'); describe('GET //.csv', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/abc000000000000000000001/def000000000000000000001.csv', nonDom: true @@ -41,7 +42,7 @@ describe('GET //.csv', function() { describe('GET //.json', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/abc000000000000000000001/def000000000000000000001.json', nonDom: true, @@ -55,7 +56,7 @@ describe('GET //.json', function() { }); it('should output JSON results', function() { - var json = this.last.body; + const json = this.last.body; assert.strictEqual(json.task.name, 'NPG Home'); assert.strictEqual(json.task.url, 'nature.com'); assert.strictEqual(json.count.error, 1); diff --git a/test/integration/route/result/index.js b/test/integration/route/result/index.js index 26f2b71..3c759a8 100644 --- a/test/integration/route/result/index.js +++ b/test/integration/route/result/index.js @@ -13,14 +13,15 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable maximumLineLength, requireArrowFunctions 'use strict'; -var assert = require('proclaim'); +const assert = require('proclaim'); describe('GET //', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/abc000000000000000000001/def000000000000000000001' }; @@ -32,13 +33,13 @@ describe('GET //', function() { }); it('should display a "Download CSV" button', function() { - var elem = this.last.dom('[data-test=download-csv]'); + const elem = this.last.dom('[data-test=download-csv]'); assert.strictEqual(elem.length, 1); assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000001/def000000000000000000001.csv'); }); it('should display a "Download JSON" button', function() { - var elem = this.last.dom('[data-test=download-json]'); + const elem = this.last.dom('[data-test=download-json]'); assert.strictEqual(elem.length, 1); assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000001/def000000000000000000001.json'); }); @@ -48,19 +49,19 @@ describe('GET //', function() { }); it('should display errors', function() { - var elem = this.last.dom('[data-test=task-errors]').eq(0); + const elem = this.last.dom('[data-test=task-errors]').eq(0); assert.isDefined(elem); assert.match(elem.text(), /errors \( 1 \)/i); }); it('should display warnings', function() { - var elem = this.last.dom('[data-test=task-warnings]').eq(0); + const elem = this.last.dom('[data-test=task-warnings]').eq(0); assert.isDefined(elem); assert.match(elem.text(), /warnings \( 2 \)/i); }); it('should display notices', function() { - var elem = this.last.dom('[data-test=task-notices]').eq(0); + const elem = this.last.dom('[data-test=task-notices]').eq(0); assert.isDefined(elem); assert.match(elem.text(), /notices \( 3 \)/i); }); diff --git a/test/integration/route/task/delete.js b/test/integration/route/task/delete.js index 511f7a7..6298d9e 100644 --- a/test/integration/route/task/delete.js +++ b/test/integration/route/task/delete.js @@ -13,14 +13,15 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable maximumLineLength, requireArrowFunctions 'use strict'; -var assert = require('proclaim'); +const assert = require('proclaim'); describe('GET //delete', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/abc000000000000000000001/delete' }; @@ -32,7 +33,7 @@ describe('GET //delete', function() { }); it('should have a "Delete URL" form', function() { - var form = this.last.dom('[data-test=delete-url-form]').eq(0); + const form = this.last.dom('[data-test=delete-url-form]').eq(0); assert.isDefined(form); assert.strictEqual(form.attr('action'), '/abc000000000000000000001/delete'); assert.strictEqual(form.attr('method'), 'post'); @@ -47,7 +48,7 @@ describe('GET //delete', function() { describe('POST //delete', function() { beforeEach(function(done) { - var req = { + const req = { method: 'POST', endpoint: '/abc000000000000000000001/delete' }; @@ -70,7 +71,7 @@ describe('POST //delete', function() { }); it('should display a success message', function() { - var alert = this.last.dom('[data-test=alert]').eq(0); + const alert = this.last.dom('[data-test=alert]').eq(0); assert.isDefined(alert); assert.match(alert.text(), /been deleted/i); }); diff --git a/test/integration/route/task/edit.js b/test/integration/route/task/edit.js index b1d711b..4133681 100644 --- a/test/integration/route/task/edit.js +++ b/test/integration/route/task/edit.js @@ -13,14 +13,15 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable maximumLineLength, requireArrowFunctions 'use strict'; -var assert = require('proclaim'); +const assert = require('proclaim'); describe('GET //edit', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/abc000000000000000000001/edit' }; @@ -32,7 +33,7 @@ describe('GET //edit', function() { }); it('should have an "Edit URL" form', function() { - var form = this.last.dom('[data-test=edit-url-form]').eq(0); + const form = this.last.dom('[data-test=edit-url-form]').eq(0); assert.isDefined(form); assert.strictEqual(form.attr('action'), '/abc000000000000000000001/edit'); assert.strictEqual(form.attr('method'), 'post'); @@ -49,14 +50,14 @@ describe('GET //edit', function() { }); it('should have a "name" field', function() { - var field = this.form.find('input[name=name]').eq(0); + const field = this.form.find('input[name=name]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('value'), 'NPG Home'); }); it('should have a disabled "url" field', function() { - var field = this.form.find('input[name=url]').eq(0); + const field = this.form.find('input[name=url]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'url'); assert.strictEqual(field.attr('value'), 'nature.com'); @@ -64,34 +65,34 @@ describe('GET //edit', function() { }); it('should have a "wait" field', function() { - var field = this.form.find('input[name=wait]').eq(0); + const field = this.form.find('input[name=wait]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('value'), '0'); }); it('should have a disabled "standard" field', function() { - var field = this.form.find('select[name=standard]').eq(0); + const field = this.form.find('select[name=standard]').eq(0); assert.isDefined(field); assert.isDefined(field.attr('disabled')); }); it('should have a "username" field', function() { - var field = this.form.find('input[name=username]').eq(0); + const field = this.form.find('input[name=username]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('value'), 'user'); }); it('should have a "password" field', function() { - var field = this.form.find('input[name=password]').eq(0); + const field = this.form.find('input[name=password]').eq(0); assert.isDefined(field); assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('value'), 'access'); }); it('should have "ignore" fields', function() { - var fields = this.form.find('input[name="ignore[]"]'); + const fields = this.form.find('input[name="ignore[]"]'); assert.isDefined(fields); assert.notStrictEqual(fields.length, 0); }); @@ -103,7 +104,7 @@ describe('GET //edit', function() { describe('POST //edit', function() { beforeEach(function(done) { - var req = { + const req = { method: 'POST', endpoint: '/abc000000000000000000001/edit', form: { @@ -131,7 +132,7 @@ describe('POST //edit', function() { }); it('should display a success message', function() { - var alert = this.last.dom('[data-test=alert]').eq(0); + const alert = this.last.dom('[data-test=alert]').eq(0); assert.isDefined(alert); assert.match(alert.text(), /been saved/i); }); diff --git a/test/integration/route/task/index.js b/test/integration/route/task/index.js index bd2ca1e..e69eb08 100644 --- a/test/integration/route/task/index.js +++ b/test/integration/route/task/index.js @@ -13,16 +13,17 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable maximumLineLength, requireArrowFunctions 'use strict'; -var assert = require('proclaim'); +const assert = require('proclaim'); describe('GET /', function() { describe('when task has results', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/abc000000000000000000001' }; @@ -59,19 +60,19 @@ describe('GET /', function() { }); it('should display errors', function() { - var elem = this.last.dom('[data-test=task-errors]').eq(0); + const elem = this.last.dom('[data-test=task-errors]').eq(0); assert.isDefined(elem); assert.match(elem.text(), /errors \( 1 \)/i); }); it('should display warnings', function() { - var elem = this.last.dom('[data-test=task-warnings]').eq(0); + const elem = this.last.dom('[data-test=task-warnings]').eq(0); assert.isDefined(elem); assert.match(elem.text(), /warnings \( 2 \)/i); }); it('should display notices', function() { - var elem = this.last.dom('[data-test=task-notices]').eq(0); + const elem = this.last.dom('[data-test=task-notices]').eq(0); assert.isDefined(elem); assert.match(elem.text(), /notices \( 3 \)/i); }); @@ -81,7 +82,7 @@ describe('GET /', function() { describe('when task has no results', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/abc000000000000000000003' }; @@ -93,13 +94,13 @@ describe('GET /', function() { }); it('should display a "Run" button', function() { - var elem = this.last.dom('[data-test=run-task]'); + const elem = this.last.dom('[data-test=run-task]'); assert.strictEqual(elem.length, 1); assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000003/run'); }); it('should display a message indicating that there are no results', function() { - var alert = this.last.dom('[data-test=alert]').eq(0); + const alert = this.last.dom('[data-test=alert]').eq(0); assert.isDefined(alert); assert.match(alert.text(), /there are no results to show/i); }); diff --git a/test/integration/route/task/run.js b/test/integration/route/task/run.js index 41fd9eb..5059183 100644 --- a/test/integration/route/task/run.js +++ b/test/integration/route/task/run.js @@ -13,14 +13,15 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable maximumLineLength, requireArrowFunctions 'use strict'; -var assert = require('proclaim'); +const assert = require('proclaim'); describe('GET //run', function() { beforeEach(function(done) { - var req = { + const req = { method: 'GET', endpoint: '/abc000000000000000000001/run' }; @@ -36,7 +37,7 @@ describe('GET //run', function() { }); it('should display a success message', function() { - var alert = this.last.dom('[data-test=alert]').eq(0); + const alert = this.last.dom('[data-test=alert]').eq(0); assert.isDefined(alert); assert.match(alert.text(), /new results are being generated/i); }); diff --git a/test/integration/setup.js b/test/integration/setup.js index b1f07f4..5abfd63 100644 --- a/test/integration/setup.js +++ b/test/integration/setup.js @@ -13,21 +13,22 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable requireArrowFunctions 'use strict'; -var config = require('../../config/test.json'); -var createNavigator = require('./helper/navigate'); -var createWebserviceClient = require('./helper/webservice'); -var loadFixtures = require('pa11y-webservice/data/fixture/load'); -var request = require('request'); +const config = require('../../config/test.json'); +const createNavigator = require('./helper/navigate'); +const createWebserviceClient = require('./helper/webservice'); +const loadFixtures = require('pa11y-webservice/data/fixture/load'); +const request = require('request'); // Run before all tests before(function(done) { - this.baseUrl = 'http://localhost:' + config.port; + this.baseUrl = `http://localhost:${config.port}`; this.last = {}; this.navigate = createNavigator(this.baseUrl, this.last); this.webservice = createWebserviceClient(config); - assertTestAppIsRunning(this.baseUrl, function() { + assertTestAppIsRunning(this.baseUrl, () => { loadFixtures('test', config.webservice, done); }); }); @@ -39,7 +40,7 @@ afterEach(function(done) { // Check that the test application is running, and exit if not function assertTestAppIsRunning(url, done) { - request(url, function(err) { + request(url, err => { if (err) { console.error('Error: Test app not started; run with `NODE_ENV=test node index.js`'); process.exit(1); diff --git a/view/helper/date.js b/view/helper/date.js index 4d5c1b5..a542422 100644 --- a/view/helper/date.js +++ b/view/helper/date.js @@ -15,26 +15,21 @@ 'use strict'; -var moment = require('moment'); +const moment = require('moment'); module.exports = helper; function helper(hbs) { // Format a date with Moment - hbs.registerHelper('date-format', function(context, block) { - var format = block.hash.format || 'YYYY-MM-DD HH:mm:ss'; + hbs.registerHelper('date-format', (context, block) => { + const format = block.hash.format || 'YYYY-MM-DD HH:mm:ss'; return moment(context).format(format); }); // Get a relative date - hbs.registerHelper('date-relative', function(context) { - return moment(context).fromNow(); - }); - - hbs.registerHelper('date-timestamp', function(context) { - return moment(context).valueOf(); - }); + hbs.registerHelper('date-relative', context => moment(context).fromNow()); + hbs.registerHelper('date-timestamp', context => moment(context).valueOf()); } diff --git a/view/helper/string.js b/view/helper/string.js index 5f4cd42..6dffeec 100644 --- a/view/helper/string.js +++ b/view/helper/string.js @@ -5,8 +5,6 @@ module.exports = helper; function helper(hbs) { // Convert a string to lower-case - hbs.registerHelper('lowercase', function(context) { - return context.toLowerCase(); - }); + hbs.registerHelper('lowercase', context => context.toLowerCase()); } diff --git a/view/helper/url.js b/view/helper/url.js index d8f739c..b823b1e 100644 --- a/view/helper/url.js +++ b/view/helper/url.js @@ -20,7 +20,7 @@ module.exports = helper; function helper(hbs) { // Simplify url by removing (eg http://, https://, trailing slashes) from url - hbs.registerHelper('simplify-url', function(context) { + hbs.registerHelper('simplify-url', context => { return context.replace(/^https?:\/\//i, '').replace(/\/$/, '').toLowerCase(); }); diff --git a/view/presenter/ignore.js b/view/presenter/ignore.js index f54dbfc..72f2a16 100644 --- a/view/presenter/ignore.js +++ b/view/presenter/ignore.js @@ -15,13 +15,13 @@ 'use strict'; -var standardsArray = require('../../data/standards')(); -var rules = createStandardDescriptionMap(standardsArray); +const standardsArray = require('../../data/standards')(); +const rules = createStandardDescriptionMap(standardsArray); module.exports = presentIgnoreRules; function presentIgnoreRules(ignore) { - return ignore.map(function(name) { + return ignore.map(name => { return { name: name, description: rules[name] @@ -30,9 +30,9 @@ function presentIgnoreRules(ignore) { } function createStandardDescriptionMap(standards) { - var map = {}; - standards.forEach(function(standard) { - standard.rules.forEach(function(rule) { + const map = {}; + standards.forEach(standard => { + standard.rules.forEach(rule => { map[rule.name] = rule.description; }); }); diff --git a/view/presenter/result-list.js b/view/presenter/result-list.js index dc511f9..10b340b 100644 --- a/view/presenter/result-list.js +++ b/view/presenter/result-list.js @@ -15,17 +15,17 @@ 'use strict'; -var _ = require('underscore'); -var moment = require('moment'); +const _ = require('underscore'); +const moment = require('moment'); module.exports = presentResultList; function presentResultList(results) { - var resultsByDay = _.groupBy(results, function(result) { + const resultsByDay = _.groupBy(results, result => { return moment(result.date).format('YYYY-MM-DD'); }); - var uniqueDayResults = []; - _.keys(resultsByDay).forEach(function(day) { + const uniqueDayResults = []; + _.keys(resultsByDay).forEach(day => { uniqueDayResults.push(resultsByDay[day][0]); }); return uniqueDayResults; diff --git a/view/presenter/result.js b/view/presenter/result.js index d119822..a342805 100644 --- a/view/presenter/result.js +++ b/view/presenter/result.js @@ -15,17 +15,17 @@ 'use strict'; -var _ = require('underscore'); -var presentIgnoreRules = require('./ignore'); +const _ = require('underscore'); +const presentIgnoreRules = require('./ignore'); module.exports = presentResult; function presentResult(result) { // Add additional info - result.href = '/' + result.task + '/' + result.id; - result.hrefCsv = '/' + result.task + '/' + result.id + '.csv'; - result.hrefJson = '/' + result.task + '/' + result.id + '.json'; + result.href = `/${result.task}/${result.id}`; + result.hrefCsv = `/${result.task}/${result.id}.csv`; + result.hrefJson = `/${result.task}/${result.id}.json`; // Parse date result.date = new Date(result.date); @@ -35,13 +35,13 @@ function presentResult(result) { // Split out message types if (result.results) { - var groupedByType = _.groupBy(result.results, 'type'); - ['error', 'warning', 'notice'].forEach(function(type) { - var pluralType = type + 's'; - var results = groupedByType[type] || []; - var groupedByCode = _.groupBy(results, 'code'); - result[pluralType] = _.keys(groupedByCode).map(function(group) { - var firstMessage = groupedByCode[group][0]; + const groupedByType = _.groupBy(result.results, 'type'); + ['error', 'warning', 'notice'].forEach(type => { + const pluralType = `${type}s`; + const results = groupedByType[type] || []; + const groupedByCode = _.groupBy(results, 'code'); + result[pluralType] = _.keys(groupedByCode).map(group => { + const firstMessage = groupedByCode[group][0]; firstMessage.count = groupedByCode[group].length; return firstMessage; }); diff --git a/view/presenter/task.js b/view/presenter/task.js index c6c1f24..c4f9e3f 100644 --- a/view/presenter/task.js +++ b/view/presenter/task.js @@ -13,23 +13,24 @@ // You should have received a copy of the GNU General Public License // along with Pa11y Dashboard. If not, see . +// jscs:disable requireCamelCaseOrUpperCaseIdentifiers 'use strict'; -var presentIgnoreRules = require('./ignore'); -var presentResult = require('./result'); +const presentIgnoreRules = require('./ignore'); +const presentResult = require('./result'); module.exports = presentTask; function presentTask(task) { // Add additional info - task.href = '/' + task.id; - task.hrefDelete = '/' + task.id + '/delete'; - task.hrefRun = '/' + task.id + '/run'; - task.hrefJson = '/' + task.id + '.json'; - task.hrefEdit = '/' + task.id + '/edit'; - task.hrefIgnore = '/' + task.id + '/ignore'; - task.hrefUnignore = '/' + task.id + '/unignore'; + task.href = `/${task.id}`; + task.hrefDelete = `/${task.id}/delete`; + task.hrefRun = `/${task.id}/run`; + task.hrefJson = `/${task.id}.json`; + task.hrefEdit = `/${task.id}/edit`; + task.hrefIgnore = `/${task.id}/ignore`; + task.hrefUnignore = `/${task.id}/unignore`; // Enhance the ignored rules task.ignore = presentIgnoreRules(task.ignore);