Compare commits

..

12 Commits
2.0.0 ... 2.0.1

Author SHA1 Message Date
Jose Bolos
02ce731e83 Version 2.0.1 2016-09-12 14:09:38 +01:00
Jose Bolos
4f46351d68 Merge pull request #143 from pa11y/secfixes
Update several packages in order to fix several vulns
2016-09-12 13:58:30 +01:00
Jose Bolos
ee7795a7a9 Merge pull request #144 from pa11y/license
Add license field to package.json
2016-09-09 14:09:43 +01:00
Jose Bolos
3a3cca881a Add license field to package.json 2016-09-09 12:58:55 +01:00
Jose Bolos
fa0c523e3f Require webservice-client-node 1.2.1 or greater
Fixes https://nodesecurity.io/advisories/130
2016-09-09 12:52:11 +01:00
Jose Bolos
36a677948b Upgrade mocha to version 3 2016-09-09 12:27:42 +01:00
Jose Bolos
22aab6bee2 Require request 2.74 or greater
Fixes https://nodesecurity.io/advisories/130
2016-09-09 12:27:09 +01:00
Jose Bolos
a30e82d5be Require webservice 2.0.1 or greater
Addresses the following vulns present on 2.0.0:
* https://nodesecurity.io/advisories/45
* https://nodesecurity.io/advisories/63
* https://nodesecurity.io/advisories/65
* https://nodesecurity.io/advisories/121
2016-09-09 12:22:34 +01:00
Jose Bolos
71432a3063 Upgrade express to 4.14 or greater
Prevents https://nodesecurity.io/advisories/106
2016-09-09 12:19:28 +01:00
Rowan Manning
6cd7630049 Merge pull request #141 from pa11y/digitial
Fix a typo in link text
2016-08-15 09:09:32 +01:00
Jose Bolos
979f7f244b Fix a typo in link text 2016-08-15 08:02:48 +01:00
Rowan Manning
e431fefbd8 Use the ES6 linting rules from the website (#138) 2016-07-22 14:34:10 +01:00
36 changed files with 270 additions and 244 deletions

30
.jscsrc
View File

@@ -2,6 +2,7 @@
"disallowEmptyBlocks": true, "disallowEmptyBlocks": true,
"disallowImplicitTypeConversion": [ "disallowImplicitTypeConversion": [
"binary", "binary",
"boolean",
"numeric", "numeric",
"string" "string"
], ],
@@ -13,8 +14,13 @@
"disallowMultipleSpaces": true, "disallowMultipleSpaces": true,
"disallowMultipleVarDecl": true, "disallowMultipleVarDecl": true,
"disallowNewlineBeforeBlockStatements": true, "disallowNewlineBeforeBlockStatements": true,
"disallowParenthesesAroundArrowParam": true,
"disallowQuotedKeysInObjects": true, "disallowQuotedKeysInObjects": true,
"disallowSpaceAfterObjectKeys": true, "disallowSpaceAfterObjectKeys": {
"allExcept": [
"method"
]
},
"disallowSpaceAfterPrefixUnaryOperators": true, "disallowSpaceAfterPrefixUnaryOperators": true,
"disallowSpaceBeforeComma": true, "disallowSpaceBeforeComma": true,
"disallowSpaceBeforeSemicolon": true, "disallowSpaceBeforeSemicolon": true,
@@ -26,24 +32,22 @@
"disallowSpacesInsideBrackets": true, "disallowSpacesInsideBrackets": true,
"disallowSpacesInsideObjectBrackets": true, "disallowSpacesInsideObjectBrackets": true,
"disallowSpacesInsideParentheses": true, "disallowSpacesInsideParentheses": true,
"disallowSpacesInsideTemplateStringPlaceholders": true,
"disallowTrailingComma": true, "disallowTrailingComma": true,
"disallowTrailingWhitespace": true, "disallowTrailingWhitespace": true,
"disallowVar": true,
"disallowYodaConditions": true, "disallowYodaConditions": true,
"maximumLineLength": 200,
"maximumLineLength": 100,
"requireArrowFunctions": true,
"requireBlocksOnNewline": true, "requireBlocksOnNewline": true,
"requireCamelCaseOrUpperCaseIdentifiers": true,
"requireCapitalizedConstructors": true, "requireCapitalizedConstructors": true,
"requireCommaBeforeLineBreak": true, "requireCommaBeforeLineBreak": true,
"requireCurlyBraces": [ "requireCurlyBraces": true,
"if",
"else",
"for",
"while",
"do",
"switch",
"try",
"catch"
],
"requireDotNotation": true, "requireDotNotation": true,
"requireFunctionDeclarations": true,
"requireLineBreakAfterVariableAssignment": true, "requireLineBreakAfterVariableAssignment": true,
"requireLineFeedAtFileEnd": true, "requireLineFeedAtFileEnd": true,
"requireObjectKeysOnNewLine": true, "requireObjectKeysOnNewLine": true,
@@ -74,6 +78,8 @@
"requireSpacesInFunction": { "requireSpacesInFunction": {
"beforeOpeningCurlyBrace": true "beforeOpeningCurlyBrace": true
}, },
"requireTemplateStrings": true,
"validateIndentation": "\t", "validateIndentation": "\t",
"validateLineBreaks": "LF", "validateLineBreaks": "LF",
"validateNewlineAfterArrayElements": true, "validateNewlineAfterArrayElements": true,

View File

@@ -1,7 +1,7 @@
{ {
"browser": true,
"curly": true, "curly": true,
"eqeqeq": true, "eqeqeq": true,
"esversion": 6,
"forin": true, "forin": true,
"globals": { "globals": {
"after": true, "after": true,
@@ -19,11 +19,8 @@
"node": true, "node": true,
"nonew": true, "nonew": true,
"nonstandard": true, "nonstandard": true,
"regexp": true, "shadow": false,
"shadow": true,
"strict": true, "strict": true,
"sub": true,
"trailing": true,
"undef": true, "undef": true,
"unused": true "unused": true
} }

View File

@@ -1,6 +1,22 @@
# Changelog # Changelog
## 2.0.1 (2016-09-12)
* Update dependencies and devDependencies
* express: ~4.13 to ~4.14
* pa11y-webservice: ~2.0 to ^2.0.1
* request: ^2 to ^2.74
* mocha: ^2 to ^3
* pa11y-webservice-client-node: ~1.2 to ^1.2.1
This fixes the following vulnerabilities:
* https://nodesecurity.io/advisories/45
* https://nodesecurity.io/advisories/63
* https://nodesecurity.io/advisories/65
* https://nodesecurity.io/advisories/106
* https://nodesecurity.io/advisories/121
* https://nodesecurity.io/advisories/130
## 2.0.0 (2016-06-05) ## 2.0.0 (2016-06-05)
* Drop Node.js 0.100.12 support * Drop Node.js 0.100.12 support

View File

@@ -111,7 +111,7 @@ make uglify # Compile and uglify the client-side JavaScript
Useful Resources Useful Resources
------- -------
* [Setting up An Accessibility Dashboard from Scratch with Pa11y on DigitialOcean][resource-una-k] * [Setting up An Accessibility Dashboard from Scratch with Pa11y on DigitalOcean][resource-una-k]
Support and Migration Support and Migration

44
app.js
View File

@@ -15,14 +15,14 @@
'use strict'; 'use strict';
var bodyParser = require('body-parser'); const bodyParser = require('body-parser');
var compression = require('compression'); const compression = require('compression');
var createClient = require('pa11y-webservice-client-node'); const createClient = require('pa11y-webservice-client-node');
var EventEmitter = require('events').EventEmitter; const EventEmitter = require('events').EventEmitter;
var express = require('express'); const express = require('express');
var hbs = require('express-hbs'); const hbs = require('express-hbs');
var http = require('http'); const http = require('http');
var pkg = require('./package.json'); const pkg = require('./package.json');
module.exports = initApp; module.exports = initApp;
@@ -30,12 +30,12 @@ module.exports = initApp;
function initApp(config, callback) { function initApp(config, callback) {
config = defaultConfig(config); config = defaultConfig(config);
var webserviceUrl = config.webservice; let webserviceUrl = config.webservice;
if (typeof webserviceUrl === 'object') { 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.address = null;
app.express = express(); app.express = express();
app.server = http.createServer(app.express); app.server = http.createServer(app.express);
@@ -45,7 +45,7 @@ function initApp(config, callback) {
app.express.use(compression()); app.express.use(compression());
// Public files // Public files
app.express.use(express.static(__dirname + '/public', { app.express.use(express.static(`${__dirname}/public`, {
maxAge: (process.env.NODE_ENV === 'production' ? 604800000 : 0) maxAge: (process.env.NODE_ENV === 'production' ? 604800000 : 0)
})); }));
@@ -59,11 +59,11 @@ function initApp(config, callback) {
app.express.engine('html', hbs.express4({ app.express.engine('html', hbs.express4({
extname: '.html', extname: '.html',
contentHelperName: 'content', contentHelperName: 'content',
layoutsDir: __dirname + '/view/layout', layoutsDir: `${__dirname}/view/layout`,
partialsDir: __dirname + '/view/partial', partialsDir: `${__dirname}/view/partial`,
defaultLayout: __dirname + '/view/layout/default' defaultLayout: `${__dirname}/view/layout/default`
})); }));
app.express.set('views', __dirname + '/view'); app.express.set('views', `${__dirname}/view`);
app.express.set('view engine', 'html'); app.express.set('view engine', 'html');
// View helpers // View helpers
@@ -84,7 +84,7 @@ function initApp(config, callback) {
settings: {} settings: {}
}; };
app.express.use(function(req, res, next) { app.express.use((req, res, next) => {
res.locals.isHomePage = (req.path === '/'); res.locals.isHomePage = (req.path === '/');
res.locals.host = req.hostname; res.locals.host = req.hostname;
next(); next();
@@ -105,11 +105,11 @@ function initApp(config, callback) {
} }
// Error handling // Error handling
app.express.get('*', function(req, res) { app.express.get('*', (req, res) => {
res.status(404); res.status(404);
res.render('404'); res.render('404');
}); });
app.express.use(function(err, req, res, next) { app.express.use((err, req, res, next) => {
/* jshint unused: false */ /* jshint unused: false */
if (err.code === 'ECONNREFUSED') { if (err.code === 'ECONNREFUSED') {
err = new Error('Could not connect to Pa11y Webservice'); err = new Error('Could not connect to Pa11y Webservice');
@@ -122,9 +122,9 @@ function initApp(config, callback) {
res.render('500'); res.render('500');
}); });
app.server.listen(config.port, function(err) { app.server.listen(config.port, err => {
var address = app.server.address(); const address = app.server.address();
app.address = 'http://' + address.address + ':' + address.port; app.address = `http://${address.address}:${address.port}`;
callback(err, app); callback(err, app);
}); });

View File

@@ -15,8 +15,9 @@
'use strict'; 'use strict';
var fs = require('fs'); const fs = require('fs');
var jsonPath = './config/' + (process.env.NODE_ENV || 'development') + '.json'; const environment = (process.env.NODE_ENV || 'development');
const jsonPath = `./config/${environment}.json`;
if (fs.existsSync(jsonPath)) { if (fs.existsSync(jsonPath)) {
module.exports = require(jsonPath); module.exports = require(jsonPath);
@@ -36,6 +37,6 @@ if (fs.existsSync(jsonPath)) {
} }
function env(name, defaultValue) { function env(name, defaultValue) {
var value = process.env[name]; const value = process.env[name];
return typeof value === 'string' ? value : defaultValue; return typeof value === 'string' ? value : defaultValue;
} }

View File

@@ -15,24 +15,24 @@
'use strict'; 'use strict';
var chalk = require('chalk'); const chalk = require('chalk');
var config = require('./config'); const config = require('./config');
process.on('SIGINT', function() { process.on('SIGINT', () => {
console.log('\nGracefully shutting down from SIGINT (Ctrl-C)'); console.log('\nGracefully shutting down from SIGINT (Ctrl-C)');
process.exit(); process.exit();
}); });
require('./app')(config, function(err, app) { require('./app')(config, (err, app) => {
console.log(''); console.log('');
console.log(chalk.underline.magenta('Pa11y Dashboard started')); console.log(chalk.underline.magenta('Pa11y Dashboard started'));
console.log(chalk.grey('mode: %s'), process.env.NODE_ENV); console.log(chalk.grey('mode: %s'), process.env.NODE_ENV);
console.log(chalk.grey('uri: %s'), app.address); console.log(chalk.grey('uri: %s'), app.address);
app.on('route-error', function(err) { app.on('route-error', err => {
var stack = (err.stack ? err.stack.split('\n') : [err.message]); const stack = (err.stack ? err.stack.split('\n') : [err.message]);
var msg = chalk.red(stack.shift()); const msg = chalk.red(stack.shift());
console.error(''); console.error('');
console.error(msg); console.error(msg);
console.error(chalk.grey(stack.join('\n'))); console.error(chalk.grey(stack.join('\n')));
@@ -40,7 +40,7 @@ require('./app')(config, function(err, app) {
// Start the webservice if required // Start the webservice if required
if (typeof config.webservice === 'object') { if (typeof config.webservice === 'object') {
require('pa11y-webservice')(config.webservice, function(err, webservice) { require('pa11y-webservice')(config.webservice, (err, webservice) => {
console.log(''); console.log('');
console.log(chalk.underline.cyan('Pa11y Webservice started')); console.log(chalk.underline.cyan('Pa11y Webservice started'));
console.log(chalk.grey('mode: %s'), process.env.NODE_ENV); console.log(chalk.grey('mode: %s'), process.env.NODE_ENV);

View File

@@ -1,6 +1,6 @@
{ {
"name": "pa11y-dashboard", "name": "pa11y-dashboard",
"version": "2.0.0", "version": "2.0.1",
"private": true, "private": true,
"description": "Pa11y Dashboard is a visual web interface to the Pa11y accessibility reporter", "description": "Pa11y Dashboard is a visual web interface to the Pa11y accessibility reporter",
@@ -16,6 +16,7 @@
}, },
"homepage": "https://github.com/pa11y/dashboard", "homepage": "https://github.com/pa11y/dashboard",
"bugs": "https://github.com/pa11y/dashboard/issues", "bugs": "https://github.com/pa11y/dashboard/issues",
"license": "GPL-3.0",
"engines": { "engines": {
"node": ">=4" "node": ">=4"
@@ -24,11 +25,11 @@
"body-parser": "~1.15", "body-parser": "~1.15",
"chalk": "~1.1", "chalk": "~1.1",
"compression": "~1.6", "compression": "~1.6",
"express": "~4.13", "express": "~4.14",
"express-hbs": "~1.0", "express-hbs": "~1.0",
"moment": "~2.13", "moment": "~2.13",
"pa11y-webservice": "~2.0", "pa11y-webservice": "^2.0.1",
"pa11y-webservice-client-node": "~1.2", "pa11y-webservice-client-node": "^1.2.1",
"underscore": "~1.8" "underscore": "~1.8"
}, },
"devDependencies": { "devDependencies": {
@@ -37,9 +38,9 @@
"jscs": "^2", "jscs": "^2",
"jshint": "^2", "jshint": "^2",
"less": "~2.7", "less": "~2.7",
"mocha": "^2", "mocha": "^3",
"proclaim": "^3", "proclaim": "^3",
"request": "^2", "request": "^2.74",
"uglify-js": "~2.6" "uglify-js": "~2.6"
}, },

View File

@@ -15,14 +15,14 @@
'use strict'; 'use strict';
var presentTask = require('../view/presenter/task'); const presentTask = require('../view/presenter/task');
module.exports = route; module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.get('/', function(req, res, next) { app.express.get('/', (req, res, next) => {
app.webservice.tasks.get({lastres: true}, function(err, tasks) { app.webservice.tasks.get({lastres: true}, (err, tasks) => {
if (err) { if (err) {
return next(err); return next(err);
} }

View File

@@ -15,15 +15,15 @@
'use strict'; 'use strict';
var getStandards = require('../data/standards'); const getStandards = require('../data/standards');
module.exports = route; module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.get('/new', function(req, res) { app.express.get('/new', (req, res) => {
var standards = getStandards().map(function(standard) { const standards = getStandards().map(standard => {
if (standard.title === 'WCAG2AA') { if (standard.title === 'WCAG2AA') {
standard.selected = true; standard.selected = true;
} }
@@ -35,8 +35,8 @@ function route(app) {
}); });
}); });
app.express.post('/new', function(req, res) { app.express.post('/new', (req, res) => {
var newTask = { const newTask = {
name: req.body.name, name: req.body.name,
url: req.body.url, url: req.body.url,
standard: req.body.standard, standard: req.body.standard,
@@ -46,13 +46,13 @@ function route(app) {
username: req.body.username, username: req.body.username,
password: req.body.password password: req.body.password
}; };
app.webservice.tasks.create(newTask, function(err, task) { app.webservice.tasks.create(newTask, (err, task) => {
if (err) { if (err) {
var standards = getStandards().map(function(standard) { const standards = getStandards().map(standard => {
if (standard.title === newTask.standard) { if (standard.title === newTask.standard) {
standard.selected = true; standard.selected = true;
} }
standard.rules = standard.rules.map(function(rule) { standard.rules = standard.rules.map(rule => {
if (newTask.ignore.indexOf(rule.name) !== -1) { if (newTask.ignore.indexOf(rule.name) !== -1) {
rule.ignored = true; rule.ignored = true;
} }
@@ -66,7 +66,7 @@ function route(app) {
task: newTask task: newTask
}); });
} }
res.redirect('/' + task.id + '?added'); res.redirect(`/${task.id}?added`);
}); });
}); });

View File

@@ -15,7 +15,7 @@
'use strict'; 'use strict';
var moment = require('moment'); const moment = require('moment');
module.exports = route; module.exports = route;
@@ -23,14 +23,14 @@ module.exports = route;
function route(app) { function route(app) {
function getTaskAndResult(req, res, next) { 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) { if (err) {
return next('route'); return next('route');
} }
app.webservice app.webservice
.task(req.params.id) .task(req.params.id)
.result(req.params.rid) .result(req.params.rid)
.get({full: true}, function(err, result) { .get({full: true}, (err, result) => {
if (err) { if (err) {
return next('route'); return next('route');
} }
@@ -58,11 +58,11 @@ function route(app) {
].join(''); ].join('');
} }
app.express.get('/:id/:rid.csv', getTaskAndResult, function(req, res) { app.express.get('/:id/:rid.csv', getTaskAndResult, (req, res) => {
var task = res.locals.task; const task = res.locals.task;
var result = res.locals.result; const result = res.locals.result;
var rows = ['"code","message","type","context","selector"']; const rows = ['"code","message","type","context","selector"'];
result.results.forEach(function(msg) { result.results.forEach(msg => {
rows.push([ rows.push([
JSON.stringify(msg.code), JSON.stringify(msg.code),
JSON.stringify(msg.message), JSON.stringify(msg.message),
@@ -75,9 +75,9 @@ function route(app) {
res.send(rows.join('\n')); res.send(rows.join('\n'));
}); });
app.express.get('/:id/:rid.json', getTaskAndResult, function(req, res) { app.express.get('/:id/:rid.json', getTaskAndResult, (req, res) => {
var task = res.locals.task; const task = res.locals.task;
var result = res.locals.result; const result = res.locals.result;
res.attachment(getDownloadFileName(task, result, 'json')); res.attachment(getDownloadFileName(task, result, 'json'));
delete task.id; delete task.id;
delete result.id; delete result.id;

View File

@@ -15,23 +15,23 @@
'use strict'; 'use strict';
var presentTask = require('../../view/presenter/task'); const presentTask = require('../../view/presenter/task');
var presentResult = require('../../view/presenter/result'); const presentResult = require('../../view/presenter/result');
module.exports = route; module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.get('/:id/:rid', function(req, res, next) { app.express.get('/:id/:rid', (req, res, next) => {
app.webservice.task(req.params.id).get({}, function(err, task) { app.webservice.task(req.params.id).get({}, (err, task) => {
if (err) { if (err) {
return next(); return next();
} }
app.webservice app.webservice
.task(req.params.id) .task(req.params.id)
.result(req.params.rid) .result(req.params.rid)
.get({full: true}, function(err, result) { .get({full: true}, (err, result) => {
if (err) { if (err) {
return next(); return next();
} }

View File

@@ -15,15 +15,15 @@
'use strict'; 'use strict';
var presentTask = require('../../view/presenter/task'); const presentTask = require('../../view/presenter/task');
module.exports = route; module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.get('/:id/delete', function(req, res, next) { app.express.get('/:id/delete', (req, res, next) => {
app.webservice.task(req.params.id).get({}, function(err, task) { app.webservice.task(req.params.id).get({}, (err, task) => {
if (err) { if (err) {
return next(); return next();
} }
@@ -34,8 +34,8 @@ function route(app) {
}); });
}); });
app.express.post('/:id/delete', function(req, res, next) { app.express.post('/:id/delete', (req, res, next) => {
app.webservice.task(req.params.id).remove(function(err) { app.webservice.task(req.params.id).remove(err => {
if (err) { if (err) {
return next(); return next();
} }

View File

@@ -15,24 +15,24 @@
'use strict'; 'use strict';
var presentTask = require('../../view/presenter/task'); const presentTask = require('../../view/presenter/task');
var getStandards = require('../../data/standards'); const getStandards = require('../../data/standards');
module.exports = route; module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.get('/:id/edit', function(req, res, next) { app.express.get('/:id/edit', (req, res, next) => {
app.webservice.task(req.params.id).get({}, function(err, task) { app.webservice.task(req.params.id).get({}, (err, task) => {
if (err) { if (err) {
return next(); return next();
} }
var standards = getStandards().map(function(standard) { const standards = getStandards().map(standard => {
if (standard.title === task.standard) { if (standard.title === task.standard) {
standard.selected = true; standard.selected = true;
} }
standard.rules = standard.rules.map(function(rule) { standard.rules = standard.rules.map(rule => {
if (task.ignore.indexOf(rule.name) !== -1) { if (task.ignore.indexOf(rule.name) !== -1) {
rule.ignored = true; rule.ignored = true;
} }
@@ -49,13 +49,13 @@ function route(app) {
}); });
}); });
app.express.post('/:id/edit', function(req, res, next) { app.express.post('/:id/edit', (req, res, next) => {
app.webservice.task(req.params.id).get({}, function(err, task) { app.webservice.task(req.params.id).get({}, (err, task) => {
if (err) { if (err) {
return next(); return next();
} }
req.body.ignore = req.body.ignore || []; 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) { if (err) {
task.name = req.body.name; task.name = req.body.name;
task.ignore = req.body.ignore; task.ignore = req.body.ignore;
@@ -63,11 +63,11 @@ function route(app) {
task.wait = req.body.wait; task.wait = req.body.wait;
task.username = req.body.username; task.username = req.body.username;
task.password = req.body.password; task.password = req.body.password;
var standards = getStandards().map(function(standard) { const standards = getStandards().map(standard => {
if (standard.title === task.standard) { if (standard.title === task.standard) {
standard.selected = true; standard.selected = true;
} }
standard.rules = standard.rules.map(function(rule) { standard.rules = standard.rules.map(rule => {
if (task.ignore.indexOf(rule.name) !== -1) { if (task.ignore.indexOf(rule.name) !== -1) {
rule.ignored = true; rule.ignored = true;
} }
@@ -82,7 +82,7 @@ function route(app) {
isTaskSubPage: true isTaskSubPage: true
}); });
} }
res.redirect('/' + req.params.id + '/edit?edited'); res.redirect(`/${req.params.id}/edit?edited`);
}); });
}); });
}); });

View File

@@ -5,20 +5,20 @@ module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.post('/:id/ignore', function(req, res, next) { app.express.post('/:id/ignore', (req, res, next) => {
app.webservice.task(req.params.id).get({}, function(err, task) { app.webservice.task(req.params.id).get({}, (err, task) => {
if (err) { if (err) {
return next(); return next();
} }
var edit = { const edit = {
name: task.name, name: task.name,
ignore: task.ignore ignore: task.ignore
}; };
if (typeof req.body.rule === 'string') { if (typeof req.body.rule === 'string') {
edit.ignore.push(req.body.rule); edit.ignore.push(req.body.rule);
} }
app.webservice.task(req.params.id).edit(edit, function() { app.webservice.task(req.params.id).edit(edit, () => {
res.redirect('/' + req.params.id + '?rule-ignored'); res.redirect(`/${req.params.id}?rule-ignored`);
}); });
}); });
}); });

View File

@@ -15,25 +15,25 @@
'use strict'; 'use strict';
var presentTask = require('../../view/presenter/task'); const presentTask = require('../../view/presenter/task');
var presentResult = require('../../view/presenter/result'); const presentResult = require('../../view/presenter/result');
var presentResultList = require('../../view/presenter/result-list'); const presentResultList = require('../../view/presenter/result-list');
module.exports = route; module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.get('/:id', function(req, res, next) { app.express.get('/:id', (req, res, next) => {
app.webservice.task(req.params.id).get({lastres: true}, function(err, task) { app.webservice.task(req.params.id).get({lastres: true}, (err, task) => {
if (err) { if (err) {
return next(); return next();
} }
app.webservice.task(req.params.id).results({}, function(err, results) { app.webservice.task(req.params.id).results({}, (err, results) => {
if (err) { if (err) {
return next(err); return next(err);
} }
var presentedResults = presentResultList(results.map(presentResult)); const presentedResults = presentResultList(results.map(presentResult));
res.render('task', { res.render('task', {
task: presentTask(task), task: presentTask(task),
results: presentedResults, results: presentedResults,

View File

@@ -20,12 +20,12 @@ module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.get('/:id/run', function(req, res, next) { app.express.get('/:id/run', (req, res, next) => {
app.webservice.task(req.params.id).run(function(err) { app.webservice.task(req.params.id).run(err => {
if (err) { if (err) {
return next(); return next();
} }
res.redirect('/' + req.params.id + '?running'); res.redirect(`/${req.params.id}?running`);
}); });
}); });

View File

@@ -5,21 +5,21 @@ module.exports = route;
// Route definition // Route definition
function route(app) { function route(app) {
app.express.post('/:id/unignore', function(req, res, next) { app.express.post('/:id/unignore', (req, res, next) => {
app.webservice.task(req.params.id).get({}, function(err, task) { app.webservice.task(req.params.id).get({}, (err, task) => {
if (err) { if (err) {
return next(); return next();
} }
var edit = { const edit = {
name: task.name, name: task.name,
ignore: task.ignore 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) { if (typeof req.body.rule === 'string' && indexOfRule !== -1) {
edit.ignore.splice(indexOfRule, 1); edit.ignore.splice(indexOfRule, 1);
} }
app.webservice.task(req.params.id).edit(edit, function() { app.webservice.task(req.params.id).edit(edit, () => {
res.redirect('/' + req.params.id + '?rule-unignored'); res.redirect(`/${req.params.id}?rule-unignored`);
}); });
}); });
}); });

View File

@@ -13,10 +13,11 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable requireArrowFunctions
'use strict'; 'use strict';
var cheerio = require('cheerio'); const cheerio = require('cheerio');
var request = require('request'); const request = require('request');
module.exports = createNavigator; module.exports = createNavigator;

View File

@@ -13,17 +13,18 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable requireArrowFunctions
'use strict'; 'use strict';
var createClient = require('pa11y-webservice-client-node'); const createClient = require('pa11y-webservice-client-node');
module.exports = createWebserviceClient; module.exports = createWebserviceClient;
// Create a webservice client // Create a webservice client
function createWebserviceClient(config) { function createWebserviceClient(config) {
var webserviceUrl = config.webservice; let webserviceUrl = config.webservice;
if (typeof webserviceUrl === 'object') { if (typeof webserviceUrl === 'object') {
webserviceUrl = 'http://' + webserviceUrl.host + ':' + webserviceUrl.port + '/'; webserviceUrl = `http://${webserviceUrl.host}:${webserviceUrl.port}/`;
} }
return createClient(webserviceUrl); return createClient(webserviceUrl);
} }

View File

@@ -13,14 +13,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable maximumLineLength, requireArrowFunctions
'use strict'; 'use strict';
var assert = require('proclaim'); const assert = require('proclaim');
describe.only('GET /', function() { describe.only('GET /', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/' endpoint: '/'
}; };
@@ -32,13 +33,13 @@ describe.only('GET /', function() {
}); });
it('should display an "Add new URL" button', 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.length, 1);
assert.strictEqual(elem.eq(0).attr('href'), '/new'); assert.strictEqual(elem.eq(0).attr('href'), '/new');
}); });
it('should display all of the expected tasks', function() { 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.strictEqual(tasks.length, 3);
assert.match(tasks.eq(0).text(), /npg home\s+\(wcag2aa\)/i); assert.match(tasks.eq(0).text(), /npg home\s+\(wcag2aa\)/i);
assert.match(tasks.eq(1).text(), /npg home\s+\(wcag2aaa\)/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() { 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(0).find('[href="/abc000000000000000000001"]').length, 1);
assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002"]').length, 1); assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002"]').length, 1);
assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003"]').length, 1); assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003"]').length, 1);
}); });
it('should display an "Edit" button for each task', function() { 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(0).find('[href="/abc000000000000000000001/edit"]').length, 1);
assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/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); assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003/edit"]').length, 1);
}); });
it('should display a "Delete" button for each task', function() { 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(0).find('[href="/abc000000000000000000001/delete"]').length, 1);
assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/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); assert.strictEqual(tasks.eq(2).find('[href="/abc000000000000000000003/delete"]').length, 1);
}); });
it('should display a "Run" button for each task', function() { 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(0).find('[href="/abc000000000000000000001/run"]').length, 1);
assert.strictEqual(tasks.eq(1).find('[href="/abc000000000000000000002/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); 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() { 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(), /1\s*errors/i);
assert.match(tasks.eq(0).text(), /2\s*warnings/i); assert.match(tasks.eq(0).text(), /2\s*warnings/i);
assert.match(tasks.eq(0).text(), /3\s*notices/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() { 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); assert.match(tasks.eq(2).text(), /no results/i);
}); });

View File

@@ -13,14 +13,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable maximumLineLength, requireArrowFunctions
'use strict'; 'use strict';
var assert = require('proclaim'); const assert = require('proclaim');
describe('GET /new', function() { describe('GET /new', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/new' endpoint: '/new'
}; };
@@ -36,7 +37,7 @@ describe('GET /new', function() {
}); });
it('should have an "Add new URL" form', 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.isDefined(form);
assert.strictEqual(form.attr('action'), '/new'); assert.strictEqual(form.attr('action'), '/new');
assert.strictEqual(form.attr('method'), 'post'); assert.strictEqual(form.attr('method'), 'post');
@@ -49,48 +50,48 @@ describe('GET /new', function() {
}); });
it('should have a "name" field', 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('type'), 'text');
assert.strictEqual(field.attr('value'), ''); assert.strictEqual(field.attr('value'), '');
}); });
it('should have a "url" field', function() { 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'url'); assert.strictEqual(field.attr('type'), 'url');
assert.strictEqual(field.attr('value'), ''); assert.strictEqual(field.attr('value'), '');
}); });
it('should have a "wait" field', 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('type'), 'text');
assert.strictEqual(field.attr('value'), ''); assert.strictEqual(field.attr('value'), '');
}); });
it('should have a "username" field', function() { 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('type'), 'text');
assert.strictEqual(field.attr('value'), ''); assert.strictEqual(field.attr('value'), '');
}); });
it('should have a "password" field', function() { 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('type'), 'text');
assert.strictEqual(field.attr('value'), ''); assert.strictEqual(field.attr('value'), '');
}); });
it('should have a "standard" field', function() { 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.isDefined(field);
assert.strictEqual(field.find('option').length, 4); assert.strictEqual(field.find('option').length, 4);
}); });
it('should have "ignore" fields', function() { 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.isDefined(fields);
assert.notStrictEqual(fields.length, 0); assert.notStrictEqual(fields.length, 0);
}); });
@@ -104,7 +105,7 @@ describe('POST /new', function() {
describe('with invalid query', function() { describe('with invalid query', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'POST', method: 'POST',
endpoint: '/new', endpoint: '/new',
form: { form: {
@@ -128,7 +129,7 @@ describe('POST /new', function() {
describe('with valid query', function() { describe('with valid query', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'POST', method: 'POST',
endpoint: '/new', endpoint: '/new',
form: { form: {
@@ -160,7 +161,7 @@ describe('POST /new', function() {
}); });
it('should display a success message', 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.isDefined(alert);
assert.match(alert.textContent, /url has been added/i); assert.match(alert.textContent, /url has been added/i);
}); });

View File

@@ -13,14 +13,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable maximumLineLength, requireArrowFunctions
'use strict'; 'use strict';
var assert = require('proclaim'); const assert = require('proclaim');
describe('GET /<task-id>/<result-id>.csv', function() { describe('GET /<task-id>/<result-id>.csv', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/abc000000000000000000001/def000000000000000000001.csv', endpoint: '/abc000000000000000000001/def000000000000000000001.csv',
nonDom: true nonDom: true
@@ -41,7 +42,7 @@ describe('GET /<task-id>/<result-id>.csv', function() {
describe('GET /<task-id>/<result-id>.json', function() { describe('GET /<task-id>/<result-id>.json', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/abc000000000000000000001/def000000000000000000001.json', endpoint: '/abc000000000000000000001/def000000000000000000001.json',
nonDom: true, nonDom: true,
@@ -55,7 +56,7 @@ describe('GET /<task-id>/<result-id>.json', function() {
}); });
it('should output JSON results', 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.name, 'NPG Home');
assert.strictEqual(json.task.url, 'nature.com'); assert.strictEqual(json.task.url, 'nature.com');
assert.strictEqual(json.count.error, 1); assert.strictEqual(json.count.error, 1);

View File

@@ -13,14 +13,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable maximumLineLength, requireArrowFunctions
'use strict'; 'use strict';
var assert = require('proclaim'); const assert = require('proclaim');
describe('GET /<task-id>/<result-id>', function() { describe('GET /<task-id>/<result-id>', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/abc000000000000000000001/def000000000000000000001' endpoint: '/abc000000000000000000001/def000000000000000000001'
}; };
@@ -32,13 +33,13 @@ describe('GET /<task-id>/<result-id>', function() {
}); });
it('should display a "Download CSV" button', 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.length, 1);
assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000001/def000000000000000000001.csv'); assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000001/def000000000000000000001.csv');
}); });
it('should display a "Download JSON" button', function() { 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.length, 1);
assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000001/def000000000000000000001.json'); assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000001/def000000000000000000001.json');
}); });
@@ -48,19 +49,19 @@ describe('GET /<task-id>/<result-id>', function() {
}); });
it('should display errors', 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.isDefined(elem);
assert.match(elem.text(), /errors \( 1 \)/i); assert.match(elem.text(), /errors \( 1 \)/i);
}); });
it('should display warnings', function() { 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.isDefined(elem);
assert.match(elem.text(), /warnings \( 2 \)/i); assert.match(elem.text(), /warnings \( 2 \)/i);
}); });
it('should display notices', function() { 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.isDefined(elem);
assert.match(elem.text(), /notices \( 3 \)/i); assert.match(elem.text(), /notices \( 3 \)/i);
}); });

View File

@@ -13,14 +13,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable maximumLineLength, requireArrowFunctions
'use strict'; 'use strict';
var assert = require('proclaim'); const assert = require('proclaim');
describe('GET /<task-id>/delete', function() { describe('GET /<task-id>/delete', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/abc000000000000000000001/delete' endpoint: '/abc000000000000000000001/delete'
}; };
@@ -32,7 +33,7 @@ describe('GET /<task-id>/delete', function() {
}); });
it('should have a "Delete URL" form', 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.isDefined(form);
assert.strictEqual(form.attr('action'), '/abc000000000000000000001/delete'); assert.strictEqual(form.attr('action'), '/abc000000000000000000001/delete');
assert.strictEqual(form.attr('method'), 'post'); assert.strictEqual(form.attr('method'), 'post');
@@ -47,7 +48,7 @@ describe('GET /<task-id>/delete', function() {
describe('POST /<task-id>/delete', function() { describe('POST /<task-id>/delete', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'POST', method: 'POST',
endpoint: '/abc000000000000000000001/delete' endpoint: '/abc000000000000000000001/delete'
}; };
@@ -70,7 +71,7 @@ describe('POST /<task-id>/delete', function() {
}); });
it('should display a success message', 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.isDefined(alert);
assert.match(alert.text(), /been deleted/i); assert.match(alert.text(), /been deleted/i);
}); });

View File

@@ -13,14 +13,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable maximumLineLength, requireArrowFunctions
'use strict'; 'use strict';
var assert = require('proclaim'); const assert = require('proclaim');
describe('GET /<task-id>/edit', function() { describe('GET /<task-id>/edit', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/abc000000000000000000001/edit' endpoint: '/abc000000000000000000001/edit'
}; };
@@ -32,7 +33,7 @@ describe('GET /<task-id>/edit', function() {
}); });
it('should have an "Edit URL" form', 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.isDefined(form);
assert.strictEqual(form.attr('action'), '/abc000000000000000000001/edit'); assert.strictEqual(form.attr('action'), '/abc000000000000000000001/edit');
assert.strictEqual(form.attr('method'), 'post'); assert.strictEqual(form.attr('method'), 'post');
@@ -49,14 +50,14 @@ describe('GET /<task-id>/edit', function() {
}); });
it('should have a "name" field', 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('type'), 'text');
assert.strictEqual(field.attr('value'), 'NPG Home'); assert.strictEqual(field.attr('value'), 'NPG Home');
}); });
it('should have a disabled "url" field', function() { 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'url'); assert.strictEqual(field.attr('type'), 'url');
assert.strictEqual(field.attr('value'), 'nature.com'); assert.strictEqual(field.attr('value'), 'nature.com');
@@ -64,34 +65,34 @@ describe('GET /<task-id>/edit', function() {
}); });
it('should have a "wait" field', 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('type'), 'text');
assert.strictEqual(field.attr('value'), '0'); assert.strictEqual(field.attr('value'), '0');
}); });
it('should have a disabled "standard" field', function() { 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);
assert.isDefined(field.attr('disabled')); assert.isDefined(field.attr('disabled'));
}); });
it('should have a "username" field', function() { 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('type'), 'text');
assert.strictEqual(field.attr('value'), 'user'); assert.strictEqual(field.attr('value'), 'user');
}); });
it('should have a "password" field', function() { 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.isDefined(field);
assert.strictEqual(field.attr('type'), 'text'); assert.strictEqual(field.attr('type'), 'text');
assert.strictEqual(field.attr('value'), 'access'); assert.strictEqual(field.attr('value'), 'access');
}); });
it('should have "ignore" fields', function() { 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.isDefined(fields);
assert.notStrictEqual(fields.length, 0); assert.notStrictEqual(fields.length, 0);
}); });
@@ -103,7 +104,7 @@ describe('GET /<task-id>/edit', function() {
describe('POST /<task-id>/edit', function() { describe('POST /<task-id>/edit', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'POST', method: 'POST',
endpoint: '/abc000000000000000000001/edit', endpoint: '/abc000000000000000000001/edit',
form: { form: {
@@ -131,7 +132,7 @@ describe('POST /<task-id>/edit', function() {
}); });
it('should display a success message', 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.isDefined(alert);
assert.match(alert.text(), /been saved/i); assert.match(alert.text(), /been saved/i);
}); });

View File

@@ -13,16 +13,17 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable maximumLineLength, requireArrowFunctions
'use strict'; 'use strict';
var assert = require('proclaim'); const assert = require('proclaim');
describe('GET /<task-id>', function() { describe('GET /<task-id>', function() {
describe('when task has results', function() { describe('when task has results', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/abc000000000000000000001' endpoint: '/abc000000000000000000001'
}; };
@@ -59,19 +60,19 @@ describe('GET /<task-id>', function() {
}); });
it('should display errors', 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.isDefined(elem);
assert.match(elem.text(), /errors \( 1 \)/i); assert.match(elem.text(), /errors \( 1 \)/i);
}); });
it('should display warnings', function() { 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.isDefined(elem);
assert.match(elem.text(), /warnings \( 2 \)/i); assert.match(elem.text(), /warnings \( 2 \)/i);
}); });
it('should display notices', function() { 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.isDefined(elem);
assert.match(elem.text(), /notices \( 3 \)/i); assert.match(elem.text(), /notices \( 3 \)/i);
}); });
@@ -81,7 +82,7 @@ describe('GET /<task-id>', function() {
describe('when task has no results', function() { describe('when task has no results', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/abc000000000000000000003' endpoint: '/abc000000000000000000003'
}; };
@@ -93,13 +94,13 @@ describe('GET /<task-id>', function() {
}); });
it('should display a "Run" button', 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.length, 1);
assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000003/run'); assert.strictEqual(elem.eq(0).attr('href'), '/abc000000000000000000003/run');
}); });
it('should display a message indicating that there are no results', function() { 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.isDefined(alert);
assert.match(alert.text(), /there are no results to show/i); assert.match(alert.text(), /there are no results to show/i);
}); });

View File

@@ -13,14 +13,15 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable maximumLineLength, requireArrowFunctions
'use strict'; 'use strict';
var assert = require('proclaim'); const assert = require('proclaim');
describe('GET /<task-id>/run', function() { describe('GET /<task-id>/run', function() {
beforeEach(function(done) { beforeEach(function(done) {
var req = { const req = {
method: 'GET', method: 'GET',
endpoint: '/abc000000000000000000001/run' endpoint: '/abc000000000000000000001/run'
}; };
@@ -36,7 +37,7 @@ describe('GET /<task-id>/run', function() {
}); });
it('should display a success message', 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.isDefined(alert);
assert.match(alert.text(), /new results are being generated/i); assert.match(alert.text(), /new results are being generated/i);
}); });

View File

@@ -13,21 +13,22 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable requireArrowFunctions
'use strict'; 'use strict';
var config = require('../../config/test.json'); const config = require('../../config/test.json');
var createNavigator = require('./helper/navigate'); const createNavigator = require('./helper/navigate');
var createWebserviceClient = require('./helper/webservice'); const createWebserviceClient = require('./helper/webservice');
var loadFixtures = require('pa11y-webservice/data/fixture/load'); const loadFixtures = require('pa11y-webservice/data/fixture/load');
var request = require('request'); const request = require('request');
// Run before all tests // Run before all tests
before(function(done) { before(function(done) {
this.baseUrl = 'http://localhost:' + config.port; this.baseUrl = `http://localhost:${config.port}`;
this.last = {}; this.last = {};
this.navigate = createNavigator(this.baseUrl, this.last); this.navigate = createNavigator(this.baseUrl, this.last);
this.webservice = createWebserviceClient(config); this.webservice = createWebserviceClient(config);
assertTestAppIsRunning(this.baseUrl, function() { assertTestAppIsRunning(this.baseUrl, () => {
loadFixtures('test', config.webservice, done); loadFixtures('test', config.webservice, done);
}); });
}); });
@@ -39,7 +40,7 @@ afterEach(function(done) {
// Check that the test application is running, and exit if not // Check that the test application is running, and exit if not
function assertTestAppIsRunning(url, done) { function assertTestAppIsRunning(url, done) {
request(url, function(err) { request(url, err => {
if (err) { if (err) {
console.error('Error: Test app not started; run with `NODE_ENV=test node index.js`'); console.error('Error: Test app not started; run with `NODE_ENV=test node index.js`');
process.exit(1); process.exit(1);

View File

@@ -15,26 +15,21 @@
'use strict'; 'use strict';
var moment = require('moment'); const moment = require('moment');
module.exports = helper; module.exports = helper;
function helper(hbs) { function helper(hbs) {
// Format a date with Moment // Format a date with Moment
hbs.registerHelper('date-format', function(context, block) { hbs.registerHelper('date-format', (context, block) => {
var format = block.hash.format || 'YYYY-MM-DD HH:mm:ss'; const format = block.hash.format || 'YYYY-MM-DD HH:mm:ss';
return moment(context).format(format); return moment(context).format(format);
}); });
// Get a relative date // Get a relative date
hbs.registerHelper('date-relative', function(context) { hbs.registerHelper('date-relative', context => moment(context).fromNow());
return moment(context).fromNow();
});
hbs.registerHelper('date-timestamp', function(context) {
return moment(context).valueOf();
});
hbs.registerHelper('date-timestamp', context => moment(context).valueOf());
} }

View File

@@ -5,8 +5,6 @@ module.exports = helper;
function helper(hbs) { function helper(hbs) {
// Convert a string to lower-case // Convert a string to lower-case
hbs.registerHelper('lowercase', function(context) { hbs.registerHelper('lowercase', context => context.toLowerCase());
return context.toLowerCase();
});
} }

View File

@@ -20,7 +20,7 @@ module.exports = helper;
function helper(hbs) { function helper(hbs) {
// Simplify url by removing (eg http://, https://, trailing slashes) from url // 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(); return context.replace(/^https?:\/\//i, '').replace(/\/$/, '').toLowerCase();
}); });

View File

@@ -15,13 +15,13 @@
'use strict'; 'use strict';
var standardsArray = require('../../data/standards')(); const standardsArray = require('../../data/standards')();
var rules = createStandardDescriptionMap(standardsArray); const rules = createStandardDescriptionMap(standardsArray);
module.exports = presentIgnoreRules; module.exports = presentIgnoreRules;
function presentIgnoreRules(ignore) { function presentIgnoreRules(ignore) {
return ignore.map(function(name) { return ignore.map(name => {
return { return {
name: name, name: name,
description: rules[name] description: rules[name]
@@ -30,9 +30,9 @@ function presentIgnoreRules(ignore) {
} }
function createStandardDescriptionMap(standards) { function createStandardDescriptionMap(standards) {
var map = {}; const map = {};
standards.forEach(function(standard) { standards.forEach(standard => {
standard.rules.forEach(function(rule) { standard.rules.forEach(rule => {
map[rule.name] = rule.description; map[rule.name] = rule.description;
}); });
}); });

View File

@@ -15,17 +15,17 @@
'use strict'; 'use strict';
var _ = require('underscore'); const _ = require('underscore');
var moment = require('moment'); const moment = require('moment');
module.exports = presentResultList; module.exports = presentResultList;
function presentResultList(results) { function presentResultList(results) {
var resultsByDay = _.groupBy(results, function(result) { const resultsByDay = _.groupBy(results, result => {
return moment(result.date).format('YYYY-MM-DD'); return moment(result.date).format('YYYY-MM-DD');
}); });
var uniqueDayResults = []; const uniqueDayResults = [];
_.keys(resultsByDay).forEach(function(day) { _.keys(resultsByDay).forEach(day => {
uniqueDayResults.push(resultsByDay[day][0]); uniqueDayResults.push(resultsByDay[day][0]);
}); });
return uniqueDayResults; return uniqueDayResults;

View File

@@ -15,17 +15,17 @@
'use strict'; 'use strict';
var _ = require('underscore'); const _ = require('underscore');
var presentIgnoreRules = require('./ignore'); const presentIgnoreRules = require('./ignore');
module.exports = presentResult; module.exports = presentResult;
function presentResult(result) { function presentResult(result) {
// Add additional info // Add additional info
result.href = '/' + result.task + '/' + result.id; result.href = `/${result.task}/${result.id}`;
result.hrefCsv = '/' + result.task + '/' + result.id + '.csv'; result.hrefCsv = `/${result.task}/${result.id}.csv`;
result.hrefJson = '/' + result.task + '/' + result.id + '.json'; result.hrefJson = `/${result.task}/${result.id}.json`;
// Parse date // Parse date
result.date = new Date(result.date); result.date = new Date(result.date);
@@ -35,13 +35,13 @@ function presentResult(result) {
// Split out message types // Split out message types
if (result.results) { if (result.results) {
var groupedByType = _.groupBy(result.results, 'type'); const groupedByType = _.groupBy(result.results, 'type');
['error', 'warning', 'notice'].forEach(function(type) { ['error', 'warning', 'notice'].forEach(type => {
var pluralType = type + 's'; const pluralType = `${type}s`;
var results = groupedByType[type] || []; const results = groupedByType[type] || [];
var groupedByCode = _.groupBy(results, 'code'); const groupedByCode = _.groupBy(results, 'code');
result[pluralType] = _.keys(groupedByCode).map(function(group) { result[pluralType] = _.keys(groupedByCode).map(group => {
var firstMessage = groupedByCode[group][0]; const firstMessage = groupedByCode[group][0];
firstMessage.count = groupedByCode[group].length; firstMessage.count = groupedByCode[group].length;
return firstMessage; return firstMessage;
}); });

View File

@@ -13,23 +13,24 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>. // along with Pa11y Dashboard. If not, see <http://www.gnu.org/licenses/>.
// jscs:disable requireCamelCaseOrUpperCaseIdentifiers
'use strict'; 'use strict';
var presentIgnoreRules = require('./ignore'); const presentIgnoreRules = require('./ignore');
var presentResult = require('./result'); const presentResult = require('./result');
module.exports = presentTask; module.exports = presentTask;
function presentTask(task) { function presentTask(task) {
// Add additional info // Add additional info
task.href = '/' + task.id; task.href = `/${task.id}`;
task.hrefDelete = '/' + task.id + '/delete'; task.hrefDelete = `/${task.id}/delete`;
task.hrefRun = '/' + task.id + '/run'; task.hrefRun = `/${task.id}/run`;
task.hrefJson = '/' + task.id + '.json'; task.hrefJson = `/${task.id}.json`;
task.hrefEdit = '/' + task.id + '/edit'; task.hrefEdit = `/${task.id}/edit`;
task.hrefIgnore = '/' + task.id + '/ignore'; task.hrefIgnore = `/${task.id}/ignore`;
task.hrefUnignore = '/' + task.id + '/unignore'; task.hrefUnignore = `/${task.id}/unignore`;
// Enhance the ignored rules // Enhance the ignored rules
task.ignore = presentIgnoreRules(task.ignore); task.ignore = presentIgnoreRules(task.ignore);