integrations/editors/vscode/panel.test.js
1
'use strict';
3
const assert = require('node:assert');
4
const { test } = require('node:test');
5
const { escape, panelHTML, paragraphs } = require('./panel');
7
const render = (items) => panelHTML({ items, file: 'internal/store/ulid.go', nonce: 'n1', styleNonce: 's1' });
9
test('an entry carries its title above its body', () => {
10
const html = render([
11
{ kind: 'why', status: 'ok', line: 4, title: 'Retry once before giving up', body: 'The upstream closes idle connections.' }
12
]);
13
assert.ok(html.includes('Retry once before giving up'));
14
assert.ok(html.includes('The upstream closes idle connections.'));
15
assert.ok(html.indexOf('Retry once') < html.indexOf('The upstream'), 'the title should precede the body');
16
});
18
test('a title cannot inject markup either', () => {
19
const html = render([{ kind: 'why', status: 'ok', line: 1, title: '<img src=x onerror=y>', body: 'fine' }]);
20
assert.ok(!html.includes('<img src=x'));
21
assert.ok(html.includes('<img src=x'));
22
});
24
test('a body cannot inject markup or script', () => {
25
const html = render([
26
{ kind: 'why', status: 'ok', line: 3, body: '<script>alert(1)</script> & "quoted" <img src=x onerror=y>' }
27
]);
28
assert.ok(!html.includes('<script>alert(1)</script>'), 'script tag survived escaping');
29
assert.ok(!html.includes('<img src=x'), 'img tag survived escaping');
30
assert.ok(html.includes('<script>alert(1)</script>'));
31
assert.ok(html.includes('&'));
32
});
34
test('a kind or status cannot inject either', () => {
35
const html = render([{ kind: '<b>why</b>', status: '"ok', line: 1, body: 'fine' }]);
36
assert.ok(!html.includes('<b>why</b>'));
37
assert.ok(html.includes('<b>why</b>'));
38
});
40
test('the whole body is rendered, however long', () => {
41
const body = 'word '.repeat(400).trim();
42
const html = render([{ kind: 'invariant', status: 'ok', line: 9, body }]);
43
assert.ok(html.includes(body), 'the body was shortened somewhere');
44
});
46
test('blank lines become separate paragraphs and single newlines stay inside one', () => {
47
const html = paragraphs('first line\nstill first\n\nsecond block');
48
assert.strictEqual(html, '<p>first line<br>still first</p><p>second block</p>');
49
});
51
test('an empty body renders nothing rather than an empty paragraph', () => {
52
assert.strictEqual(paragraphs(''), '');
53
assert.strictEqual(paragraphs(null), '');
54
assert.strictEqual(paragraphs(' \n\n '), '');
55
});
57
test('every entry can be revealed and carries its line', () => {
58
const html = render([
59
{ kind: 'why', status: 'ok', line: 12, body: 'one' },
60
{ kind: 'gotcha', status: 'drifted', line: 40, body: 'two', warning: 'the excerpt is gone' }
61
]);
62
assert.ok(html.includes('data-reveal="0"'));
63
assert.ok(html.includes('data-reveal="1"'));
64
assert.ok(html.includes('L12') && html.includes('L40'));
65
assert.ok(html.includes('the excerpt is gone'));
66
});
68
test('a failing status is toned apart from a healthy one', () => {
69
const html = render([
70
{ kind: 'why', status: 'ok', line: 1, body: 'a' },
71
{ kind: 'why', status: 'orphaned', line: 3, body: 'c' }
72
]);
73
assert.ok(html.includes('status ok'));
74
assert.ok(html.includes('status failing'));
75
});
77
test('the document restricts itself to its own nonces', () => {
78
const html = render([{ kind: 'why', status: 'ok', line: 1, body: 'a' }]);
79
assert.ok(html.includes("default-src 'none'"));
80
assert.ok(html.includes("script-src 'nonce-n1'"));
81
assert.ok(html.includes("style-src 'nonce-s1'"));
82
assert.ok(!/<script(?![^>]*nonce=)/.test(html), 'a script tag carries no nonce');
83
});
85
test('an empty file says so instead of rendering an empty list', () => {
86
const html = render([]);
87
assert.ok(html.includes('No annotations in this file.'));
88
assert.ok(!html.includes('<ul>'));
89
});
91
test('escape leaves ordinary prose alone', () => {
92
assert.strictEqual(escape('plain prose, with punctuation.'), 'plain prose, with punctuation.');
93
});