@jrpool/kilotest 46.0.5 → 46.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api/getReport.test.js +62 -0
- package/api/listDiagnoses.test.js +88 -0
- package/api/listIssues.test.js +98 -0
- package/api/listReports.test.js +104 -0
- package/api/listViolators.test.js +73 -0
- package/api/requestFeature.test.js +54 -0
- package/api/requestRetest.test.js +76 -0
- package/api/requestTest.test.js +81 -0
- package/index.js +25 -19
- package/package.json +2 -2
- package/routing.test.js +77 -0
- package/util.js +5 -5
- package/web/listDiagnoses/listDiagnoses.test.js +74 -0
- package/web/listIssues/index.js +3 -3
- package/web/listIssues/listIssues.test.js +80 -0
- package/web/listReports/listReports.test.js +84 -0
- package/web/listViolators/listViolators.test.js +66 -0
- package/api/testSuite.js +0 -311
package/index.js
CHANGED
|
@@ -861,6 +861,10 @@ const requestHandler = async (request, response) => {
|
|
|
861
861
|
}
|
|
862
862
|
};
|
|
863
863
|
|
|
864
|
+
// EXPORTS
|
|
865
|
+
|
|
866
|
+
exports.requestHandler = requestHandler;
|
|
867
|
+
|
|
864
868
|
// SERVER
|
|
865
869
|
|
|
866
870
|
const serve = async (protocolModule, options) => {
|
|
@@ -879,23 +883,25 @@ const serve = async (protocolModule, options) => {
|
|
|
879
883
|
|
|
880
884
|
// EXECUTION
|
|
881
885
|
|
|
882
|
-
if (
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
886
|
+
if (require.main === module) {
|
|
887
|
+
if (protocol === 'http') {
|
|
888
|
+
console.log('Starting HTTP server');
|
|
889
|
+
serve(http, {});
|
|
890
|
+
}
|
|
891
|
+
else if (protocol === 'https') {
|
|
892
|
+
console.log('Starting HTTPS server');
|
|
893
|
+
fs.readFile(process.env.KEY, 'utf8')
|
|
894
|
+
.then(
|
|
895
|
+
key => {
|
|
896
|
+
fs.readFile(process.env.CERT, 'utf8')
|
|
897
|
+
.then(
|
|
898
|
+
cert => {
|
|
899
|
+
serve(https, {key, cert});
|
|
900
|
+
},
|
|
901
|
+
error => console.log(error.message)
|
|
902
|
+
);
|
|
903
|
+
},
|
|
904
|
+
error => console.log(error.message)
|
|
905
|
+
);
|
|
906
|
+
}
|
|
901
907
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jrpool/kilotest",
|
|
3
|
-
"version": "46.0.
|
|
3
|
+
"version": "46.0.7",
|
|
4
4
|
"description": "Ensemble testing for front-end web quality",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"engines": {
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
"start": "node index",
|
|
11
11
|
"lint": "npx eslint && npx markdownlint-cli2",
|
|
12
12
|
"test": "c8 node --test",
|
|
13
|
-
"test:api": "node api/testSuite",
|
|
14
13
|
"generate:openapi": "node scripts/generate-openapi"
|
|
15
14
|
},
|
|
16
15
|
"repository": {
|
|
@@ -49,6 +48,7 @@
|
|
|
49
48
|
"globals": "*",
|
|
50
49
|
"js-yaml": "*",
|
|
51
50
|
"markdownlint-cli2": "*",
|
|
51
|
+
"node-html-parser": "*",
|
|
52
52
|
"zod-openapi": "*"
|
|
53
53
|
},
|
|
54
54
|
"allowScripts": {
|
package/routing.test.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/*
|
|
2
|
+
routing.test.js
|
|
3
|
+
Integration tests for HTTP routing in index.js, verifying that POST-only API services reject GET requests.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// IMPORTS
|
|
7
|
+
|
|
8
|
+
const {test, before, after} = require('node:test');
|
|
9
|
+
const assert = require('node:assert/strict');
|
|
10
|
+
const path = require('node:path');
|
|
11
|
+
const http = require('node:http');
|
|
12
|
+
const {requestHandler} = require('./index');
|
|
13
|
+
|
|
14
|
+
// CONSTANTS
|
|
15
|
+
|
|
16
|
+
const port = 3999;
|
|
17
|
+
|
|
18
|
+
// SETUP AND TEARDOWN
|
|
19
|
+
|
|
20
|
+
const savedDBDir = process.env.DB_DIR;
|
|
21
|
+
let server;
|
|
22
|
+
|
|
23
|
+
before(async () => {
|
|
24
|
+
process.env.DB_DIR = path.join(__dirname, 'test', 'fixtures', 'db');
|
|
25
|
+
server = http.createServer(requestHandler);
|
|
26
|
+
await new Promise(resolve => server.listen(port, resolve));
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
after(async () => {
|
|
30
|
+
if (savedDBDir !== undefined) {
|
|
31
|
+
process.env.DB_DIR = savedDBDir;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
delete process.env.DB_DIR;
|
|
35
|
+
}
|
|
36
|
+
await new Promise(resolve => server.close(() => resolve()));
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// HELPERS
|
|
40
|
+
|
|
41
|
+
// Sends a GET request and returns the response body as a string.
|
|
42
|
+
const get = requestPath => new Promise((resolve, reject) => {
|
|
43
|
+
http.request({method: 'GET', host: 'localhost', port, path: requestPath}, response => {
|
|
44
|
+
const chunks = [];
|
|
45
|
+
response.on('data', chunk => chunks.push(chunk));
|
|
46
|
+
response.on('end', () => {
|
|
47
|
+
resolve({statusCode: response.statusCode, body: chunks.join('')});
|
|
48
|
+
});
|
|
49
|
+
})
|
|
50
|
+
.on('error', reject)
|
|
51
|
+
.end();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// TESTS
|
|
55
|
+
|
|
56
|
+
test('GET /api/requestTest returns an error, not a test-request response', async () => {
|
|
57
|
+
const result = await get('/api/requestTest');
|
|
58
|
+
assert.ok(result.body.includes('Invalid service request'));
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('GET /api/requestRetest returns an error, not a retest-request response', async () => {
|
|
62
|
+
const result = await get('/api/requestRetest/260101T0001/ct');
|
|
63
|
+
assert.ok(result.body.includes('Invalid service request'));
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('GET /api/requestFeature returns an error, not a feature-request response', async () => {
|
|
67
|
+
const result = await get('/api/requestFeature');
|
|
68
|
+
assert.ok(result.body.includes('Invalid service request'));
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('GET /api/listReports returns a valid JSON response', async () => {
|
|
72
|
+
const result = await get('/api/listReports');
|
|
73
|
+
const body = JSON.parse(result.body);
|
|
74
|
+
assert.equal(body['tool name'], 'listReports');
|
|
75
|
+
const reports = body['response content']['basics about all available reports'];
|
|
76
|
+
assert.equal(reports.length, 6);
|
|
77
|
+
});
|
package/util.js
CHANGED
|
@@ -641,11 +641,11 @@ exports.getPageDataStrings = async (timeStamp, jobID, pageData) => {
|
|
|
641
641
|
};
|
|
642
642
|
// Returns the creation time and size of a report.
|
|
643
643
|
const getReportStats = exports.getReportStats = async (timeStamp, jobID) => {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
{
|
|
647
|
-
|
|
648
|
-
|
|
644
|
+
let reportStat;
|
|
645
|
+
try {
|
|
646
|
+
reportStat = await fs.stat(path.join(reportsPath(), `${timeStamp}-${jobID}.json`));
|
|
647
|
+
}
|
|
648
|
+
catch {
|
|
649
649
|
return null;
|
|
650
650
|
}
|
|
651
651
|
const reportTime = reportStat.birthtime;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/*
|
|
2
|
+
listDiagnoses.test.js
|
|
3
|
+
UI tests for web/listDiagnoses/index.js using the fixture corpus.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// IMPORTS
|
|
7
|
+
|
|
8
|
+
const {test, before, after} = require('node:test');
|
|
9
|
+
const assert = require('node:assert/strict');
|
|
10
|
+
const path = require('node:path');
|
|
11
|
+
const {parse} = require('node-html-parser');
|
|
12
|
+
const {answer} = require('./index');
|
|
13
|
+
|
|
14
|
+
// SETUP AND TEARDOWN
|
|
15
|
+
|
|
16
|
+
const savedDBDir = process.env.DB_DIR;
|
|
17
|
+
|
|
18
|
+
before(() => {
|
|
19
|
+
process.env.DB_DIR = path.join(__dirname, '..', '..', 'test', 'fixtures', 'db');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
after(() => {
|
|
23
|
+
if (savedDBDir !== undefined) {
|
|
24
|
+
process.env.DB_DIR = savedDBDir;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
delete process.env.DB_DIR;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// TESTS
|
|
32
|
+
|
|
33
|
+
test('listDiagnoses returns an ok status with valid HTML for catalogIndex 0, linkNoText, in the mixed report', async () => {
|
|
34
|
+
const result = await answer('linkNoText/260101T0000/mix/0');
|
|
35
|
+
assert.equal(result.status, 'ok');
|
|
36
|
+
assert.ok(result.answerPage);
|
|
37
|
+
const html = parse(result.answerPage);
|
|
38
|
+
assert.ok(html.querySelector('title'));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('listDiagnoses includes the issue summary in the HTML', async () => {
|
|
42
|
+
const result = await answer('linkNoText/260101T0000/mix/0');
|
|
43
|
+
assert.ok(result.answerPage.includes('link not named'));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('listDiagnoses includes the element tag name and text from the catalog', async () => {
|
|
47
|
+
const result = await answer('linkNoText/260101T0000/mix/0');
|
|
48
|
+
assert.ok(result.answerPage.includes('About Us'));
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('listDiagnoses includes diagnosis descriptions from the rule engines', async () => {
|
|
52
|
+
const result = await answer('linkNoText/260101T0000/mix/0');
|
|
53
|
+
assert.ok(result.answerPage.includes('The link does not have an accessible name'));
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('listDiagnoses returns an error status for a hidden report', async () => {
|
|
57
|
+
const result = await answer('linkNoText/260101T0007/hid/0');
|
|
58
|
+
assert.equal(result.status, 'error');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('listDiagnoses returns an error status for a nonexistent report', async () => {
|
|
62
|
+
const result = await answer('linkNoText/999999T9999/xyz/0');
|
|
63
|
+
assert.equal(result.status, 'error');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('listDiagnoses returns ok with no diagnoses for a nonexistent catalog index', async () => {
|
|
67
|
+
const result = await answer('linkNoText/260101T0000/mix/999');
|
|
68
|
+
assert.equal(result.status, 'ok');
|
|
69
|
+
const html = parse(result.answerPage);
|
|
70
|
+
const diagnosisItems = html.querySelectorAll('li');
|
|
71
|
+
// The page may have other li elements, but none should contain diagnosis descriptions.
|
|
72
|
+
const diagnosisTexts = diagnosisItems.map(li => li.text);
|
|
73
|
+
assert.ok(!diagnosisTexts.some(t => t.includes('The link does not have an accessible name')));
|
|
74
|
+
});
|
package/web/listIssues/index.js
CHANGED
|
@@ -64,9 +64,9 @@ const getIssuesData = async (timeStamp, jobID) => {
|
|
|
64
64
|
const instances = result?.standardResult?.instances ?? [];
|
|
65
65
|
// For each of its standard instances:
|
|
66
66
|
instances.forEach(instance => {
|
|
67
|
-
const {catalogIndex, issueID} = instance;
|
|
68
|
-
// If the instance
|
|
69
|
-
if (issueID && issueID !== 'ignorable') {
|
|
67
|
+
const {catalogIndex, issueID, outcome} = instance;
|
|
68
|
+
// If the instance reports a violation and identifies a non-ignorable issue:
|
|
69
|
+
if (outcome !== 'cantTell' && issueID && issueID !== 'ignorable') {
|
|
70
70
|
const issueClassification = issueSpecs[issueID];
|
|
71
71
|
// If the issue has a current weighted classification:
|
|
72
72
|
if (issueClassification && [1, 2, 3, 4].includes(issueClassification.weight)) {
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/*
|
|
2
|
+
listIssues.test.js
|
|
3
|
+
UI tests for web/listIssues/index.js using the fixture corpus.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// IMPORTS
|
|
7
|
+
|
|
8
|
+
const {test, before, after} = require('node:test');
|
|
9
|
+
const assert = require('node:assert/strict');
|
|
10
|
+
const path = require('node:path');
|
|
11
|
+
const {parse} = require('node-html-parser');
|
|
12
|
+
const {answer} = require('./index');
|
|
13
|
+
|
|
14
|
+
// SETUP AND TEARDOWN
|
|
15
|
+
|
|
16
|
+
const savedDBDir = process.env.DB_DIR;
|
|
17
|
+
|
|
18
|
+
before(() => {
|
|
19
|
+
process.env.DB_DIR = path.join(__dirname, '..', '..', 'test', 'fixtures', 'db');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
after(() => {
|
|
23
|
+
if (savedDBDir !== undefined) {
|
|
24
|
+
process.env.DB_DIR = savedDBDir;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
delete process.env.DB_DIR;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// TESTS
|
|
32
|
+
|
|
33
|
+
test('listIssues returns an ok status with valid HTML for the mixed report', async () => {
|
|
34
|
+
const result = await answer('260101T0000/mix');
|
|
35
|
+
assert.equal(result.status, 'ok');
|
|
36
|
+
assert.ok(result.answerPage);
|
|
37
|
+
const html = parse(result.answerPage);
|
|
38
|
+
assert.ok(html.querySelector('title'));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('listIssues includes the page description in the HTML for the mixed report', async () => {
|
|
42
|
+
const result = await answer('260101T0000/mix');
|
|
43
|
+
assert.ok(result.answerPage.includes('Mixed Outcomes Page'));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('listIssues includes links to listViolators for issues in the mixed report', async () => {
|
|
47
|
+
const result = await answer('260101T0000/mix');
|
|
48
|
+
const html = parse(result.answerPage);
|
|
49
|
+
const violatorLinks = html.querySelectorAll('a[href*="listViolators.html"]');
|
|
50
|
+
assert.ok(violatorLinks.length >= 2);
|
|
51
|
+
const hrefs = violatorLinks.map(a => a.getAttribute('href'));
|
|
52
|
+
assert.ok(hrefs.some(href => href.includes('linkNoText')));
|
|
53
|
+
assert.ok(hrefs.some(href => href.includes('allCaps')));
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('listIssues returns an error status for a hidden report', async () => {
|
|
57
|
+
const result = await answer('260101T0007/hid');
|
|
58
|
+
assert.equal(result.status, 'error');
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('listIssues returns an error status for a nonexistent report', async () => {
|
|
62
|
+
const result = await answer('999999T9999/xyz');
|
|
63
|
+
assert.equal(result.status, 'error');
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test('listIssues for the all-cantTell report shows no issue links', async () => {
|
|
67
|
+
const result = await answer('260101T0001/ct');
|
|
68
|
+
assert.equal(result.status, 'ok');
|
|
69
|
+
const html = parse(result.answerPage);
|
|
70
|
+
const violatorLinks = html.querySelectorAll('a[href*="listViolators.html"]');
|
|
71
|
+
assert.equal(violatorLinks.length, 0);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('listIssues for the empty report shows no issue links', async () => {
|
|
75
|
+
const result = await answer('260101T0005/emp');
|
|
76
|
+
assert.equal(result.status, 'ok');
|
|
77
|
+
const html = parse(result.answerPage);
|
|
78
|
+
const violatorLinks = html.querySelectorAll('a[href*="listViolators.html"]');
|
|
79
|
+
assert.equal(violatorLinks.length, 0);
|
|
80
|
+
});
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/*
|
|
2
|
+
listReports.test.js
|
|
3
|
+
UI tests for web/listReports/index.js using the fixture corpus.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// IMPORTS
|
|
7
|
+
|
|
8
|
+
const {test, before, after} = require('node:test');
|
|
9
|
+
const assert = require('node:assert/strict');
|
|
10
|
+
const path = require('node:path');
|
|
11
|
+
const {parse} = require('node-html-parser');
|
|
12
|
+
const {answer} = require('./index');
|
|
13
|
+
|
|
14
|
+
// SETUP AND TEARDOWN
|
|
15
|
+
|
|
16
|
+
const savedDBDir = process.env.DB_DIR;
|
|
17
|
+
|
|
18
|
+
before(() => {
|
|
19
|
+
process.env.DB_DIR = path.join(__dirname, '..', '..', 'test', 'fixtures', 'db');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
after(() => {
|
|
23
|
+
if (savedDBDir !== undefined) {
|
|
24
|
+
process.env.DB_DIR = savedDBDir;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
delete process.env.DB_DIR;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// TESTS
|
|
32
|
+
|
|
33
|
+
test('listReports returns an ok status with valid HTML', async () => {
|
|
34
|
+
const result = await answer();
|
|
35
|
+
assert.equal(result.status, 'ok');
|
|
36
|
+
assert.ok(result.answerPage);
|
|
37
|
+
const html = parse(result.answerPage);
|
|
38
|
+
assert.equal(html.querySelector('title').text, 'Pages tested | Kilotest');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('listReports includes the 6 non-hidden fixture reports as details elements', async () => {
|
|
42
|
+
const result = await answer();
|
|
43
|
+
const html = parse(result.answerPage);
|
|
44
|
+
const details = html.querySelectorAll('details');
|
|
45
|
+
assert.equal(details.length, 6);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test('listReports includes the page descriptions in summary elements', async () => {
|
|
49
|
+
const result = await answer();
|
|
50
|
+
const html = parse(result.answerPage);
|
|
51
|
+
const summaries = html.querySelectorAll('details > summary').map(s => s.text);
|
|
52
|
+
assert.ok(summaries.some(s => s.startsWith('Mixed Outcomes Page')));
|
|
53
|
+
assert.ok(summaries.some(s => s.startsWith('All CantTell Page')));
|
|
54
|
+
assert.ok(summaries.some(s => s.startsWith('No Outcomes Page')));
|
|
55
|
+
assert.ok(summaries.some(s => s.startsWith('Empty Results Page')));
|
|
56
|
+
assert.ok(summaries.some(s => s.startsWith('Prevented Page')));
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('listReports does not include the hidden report', async () => {
|
|
60
|
+
const result = await answer();
|
|
61
|
+
assert.ok(!result.answerPage.includes('Hidden Page'));
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test('listReports includes links to listIssues for reports with issues', async () => {
|
|
65
|
+
const result = await answer();
|
|
66
|
+
const html = parse(result.answerPage);
|
|
67
|
+
const issueLinks = html.querySelectorAll('a[href*="listIssues.html"]');
|
|
68
|
+
assert.ok(issueLinks.length > 0);
|
|
69
|
+
const hrefs = issueLinks.map(a => a.getAttribute('href'));
|
|
70
|
+
assert.ok(hrefs.some(href => href.includes('260101T0000/mix')));
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test('listReports includes the page URLs in the report details', async () => {
|
|
74
|
+
const result = await answer();
|
|
75
|
+
assert.ok(result.answerPage.includes('https://example.com/mixed'));
|
|
76
|
+
assert.ok(result.answerPage.includes('https://example.com/canttell'));
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test('listReports includes a link to request testing a new page', async () => {
|
|
80
|
+
const result = await answer();
|
|
81
|
+
const html = parse(result.answerPage);
|
|
82
|
+
const testLink = html.querySelector('a[href="requestTestForm.html"]');
|
|
83
|
+
assert.ok(testLink);
|
|
84
|
+
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/*
|
|
2
|
+
listViolators.test.js
|
|
3
|
+
UI tests for web/listViolators/index.js using the fixture corpus.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// IMPORTS
|
|
7
|
+
|
|
8
|
+
const {test, before, after} = require('node:test');
|
|
9
|
+
const assert = require('node:assert/strict');
|
|
10
|
+
const path = require('node:path');
|
|
11
|
+
const {parse} = require('node-html-parser');
|
|
12
|
+
const {answer} = require('./index');
|
|
13
|
+
|
|
14
|
+
// SETUP AND TEARDOWN
|
|
15
|
+
|
|
16
|
+
const savedDBDir = process.env.DB_DIR;
|
|
17
|
+
|
|
18
|
+
before(() => {
|
|
19
|
+
process.env.DB_DIR = path.join(__dirname, '..', '..', 'test', 'fixtures', 'db');
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
after(() => {
|
|
23
|
+
if (savedDBDir !== undefined) {
|
|
24
|
+
process.env.DB_DIR = savedDBDir;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
delete process.env.DB_DIR;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// TESTS
|
|
32
|
+
|
|
33
|
+
test('listViolators returns an ok status with valid HTML for linkNoText in the mixed report', async () => {
|
|
34
|
+
const result = await answer('linkNoText/260101T0000/mix');
|
|
35
|
+
assert.equal(result.status, 'ok');
|
|
36
|
+
assert.ok(result.answerPage);
|
|
37
|
+
const html = parse(result.answerPage);
|
|
38
|
+
assert.ok(html.querySelector('title'));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('listViolators includes the issue summary in the HTML', async () => {
|
|
42
|
+
const result = await answer('linkNoText/260101T0000/mix');
|
|
43
|
+
assert.ok(result.answerPage.includes('link not named'));
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('listViolators includes links to listDiagnoses for violators', async () => {
|
|
47
|
+
const result = await answer('linkNoText/260101T0000/mix');
|
|
48
|
+
const html = parse(result.answerPage);
|
|
49
|
+
const diagnosisLinks = html.querySelectorAll('a[href*="listDiagnoses.html"]');
|
|
50
|
+
assert.ok(diagnosisLinks.length > 0);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test('listViolators returns an error status for a hidden report', async () => {
|
|
54
|
+
const result = await answer('linkNoText/260101T0007/hid');
|
|
55
|
+
assert.equal(result.status, 'error');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test('listViolators returns an error status for a nonexistent report', async () => {
|
|
59
|
+
const result = await answer('linkNoText/999999T9999/xyz');
|
|
60
|
+
assert.equal(result.status, 'error');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('listViolators returns an error status for an unknown issue', async () => {
|
|
64
|
+
const result = await answer('nonexistentIssue/260101T0000/mix');
|
|
65
|
+
assert.equal(result.status, 'error');
|
|
66
|
+
});
|