test: use cleanup function everywhere instead of jsdom manually

This commit is contained in:
rugk
2026-03-03 11:01:30 +00:00
parent 778df44b0b
commit 3de6dc9f68
15 changed files with 84 additions and 92 deletions

View File

@@ -14,7 +14,7 @@ describe('AttachmentViewer', function () {
'string',
// eslint-disable-next-line complexity
function (mimeType, rawdata, filename, prefix, postfix) {
let clean = jsdom(),
let clean = globalThis.cleanup(),
data = 'data:' + mimeType + ';base64,' + common.btoa(rawdata),
mimePrefix = mimeType.substring(0, 6),
previewSupported = (
@@ -133,7 +133,7 @@ describe('AttachmentViewer', function () {
it(
'sanitizes file names in attachments',
function() {
const clean = jsdom();
const clean = globalThis.cleanup();
$('body').html(
'<div id="attachmentPreview" class="col-md-12 text-center hidden"></div>' +
'<div id="attachment" class="hidden"></div>' +

View File

@@ -12,7 +12,7 @@ describe('Check', function () {
jsc.elements(['Bot', 'bot']),
'string',
function (prefix, botBit, suffix) {
const clean = jsdom(
const clean = globalThis.cleanup(
'<html><body><div id="errormessage" class="hidden"></div>' +
'</body></html>', {
'userAgent': prefix + botBit + suffix
@@ -36,7 +36,7 @@ describe('Check', function () {
function (secureProtocol, localhost, domain, tld) {
const isDomain = localhost === '',
isSecureContext = secureProtocol || !isDomain || tld.length > 0,
clean = jsdom(
clean = globalThis.cleanup(
'<html><body><div id="errormessage" class="hidden"></div>' +
'<div id="oldnotice" class="hidden"></div>' +
'<div id="insecurecontextnotice" class="hidden"></div></body></html>',
@@ -63,7 +63,7 @@ describe('Check', function () {
'bool',
jsc.nearray(common.jscA2zString()),
function (secureProtocol, domain) {
const clean = jsdom(
const clean = globalThis.cleanup(
'<html><body><div id="httpnotice" class="hidden"></div>' +
'</body></html>',
{

View File

@@ -9,7 +9,7 @@ describe('CopyToClipboard', function() {
common.jscFormats(),
'nestring',
async function (format, text) {
var clean = jsdom();
var clean = globalThis.cleanup();
common.enableClipboard();
$('body').html(
@@ -46,7 +46,7 @@ describe('CopyToClipboard', function() {
common.jscFormats(),
'nestring',
async function (format, text) {
var clean = jsdom();
var clean = globalThis.cleanup();
common.enableClipboard();
$('body').html(
@@ -80,7 +80,7 @@ describe('CopyToClipboard', function() {
jsc.property('Copy link to clipboard',
'nestring',
async function (text) {
var clean = jsdom();
var clean = globalThis.cleanup();
common.enableClipboard();
$('body').html('<button id="copyLink"></button>');
@@ -103,7 +103,7 @@ describe('CopyToClipboard', function() {
jsc.property('Show hint',
'nestring',
function (text) {
var clean = jsdom();
var clean = globalThis.cleanup();
$('body').html('<small id="copyShortcutHintText"></small>');
@@ -121,7 +121,7 @@ describe('CopyToClipboard', function() {
jsc.property('Hide hint',
'nestring',
function (text) {
var clean = jsdom();
var clean = globalThis.cleanup();
$('body').html('<small id="copyShortcutHintText">' + text + '</small>');
@@ -136,4 +136,4 @@ describe('CopyToClipboard', function() {
}
);
});
});
});

View File

@@ -15,7 +15,7 @@ describe('CryptTool', function () {
'string',
'string',
async function (key, password, message) {
const clean = jsdom();
const clean = globalThis.cleanup();
// ensure zlib is getting loaded
PrivateBin.Controller.initZ();
Object.defineProperty(window, 'crypto', {
@@ -42,7 +42,7 @@ describe('CryptTool', function () {
it('does not truncate messages', async function () {
const message = fs.readFileSync('test/compression-sample.txt', 'ascii').trim(),
clean = jsdom();
clean = globalThis.cleanup();
Object.defineProperty(window, 'crypto', {
value: new WebCrypto(),
writeable: false
@@ -91,7 +91,7 @@ isWhile : interp (while expr sBody) (MemElem mem) =
======================== ( 1 / 1 )
conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
`;
const clean = jsdom();
const clean = globalThis.cleanup();
// ensure zlib is getting loaded
PrivateBin.Controller.initZ();
Object.defineProperty(window, 'crypto', {
@@ -123,7 +123,7 @@ conseq_or_bottom inv (interp (nth_iterate sBody n) (MemElem mem))
jsc.assert(jsc.forall(
'integer',
function(counter) {
const clean = jsdom();
const clean = globalThis.cleanup();
Object.defineProperty(window, 'crypto', {
value: new WebCrypto(),
writeable: false

View File

@@ -26,7 +26,7 @@ describe('DiscussionViewer', function () {
jsc.elements(['loading', 'danger', 'other']),
'nestring',
function (comments, commentKey, fadeOut, nickname, message, alertType, alert) {
var clean = jsdom(),
var clean = globalThis.cleanup(),
results = [];
$('body').html(
'<div id="discussion"><h4>Discussion</h4>' +

View File

@@ -9,7 +9,7 @@ describe('Editor', function () {
'returns text fed into the textarea, handles editor tabs',
'string',
function (text) {
var clean = jsdom(),
var clean = globalThis.cleanup(),
results = [];
$('body').html(
'<ul id="editorTabs" class="nav nav-tabs hidden"><li ' +

View File

@@ -54,7 +54,7 @@ describe('Helper', function () {
function (ids, contents) {
var html = '',
result = true,
clean = jsdom(html);
clean = globalThis.cleanup(html);
ids.forEach(function(item, i) {
html += '<div id="' + item.join('') + '">' + PrivateBin.Helper.htmlEntities(contents[i] || contents[0]) + '</div>';
});
@@ -75,7 +75,7 @@ describe('Helper', function () {
describe('urls2links', function () {
this.timeout(30000);
before(function () {
cleanup = jsdom();
cleanup = globalThis.cleanup();
});
jsc.property(
@@ -84,7 +84,7 @@ describe('Helper', function () {
function (content) {
// eslint-disable-next-line no-control-regex
content = content.replace(/\r|\f/g, '\n').replace(/\u0000|\u000b/g, '');
let clean = jsdom();
let clean = globalThis.cleanup();
$('body').html('<div id="foo"></div>');
let e = $('#foo');
e.text(content);
@@ -107,7 +107,7 @@ describe('Helper', function () {
postfix = ' ' + postfix.replace(/\r/g, '\n').replace(/\u0000/g, '');
url.fragment = fragment.join('');
let urlString = common.urlToString(url),
clean = jsdom();
clean = globalThis.cleanup();
$('body').html('<div id="foo"></div>');
let e = $('#foo');
@@ -140,7 +140,7 @@ describe('Helper', function () {
// eslint-disable-next-line no-control-regex
postfix = ' ' + postfix.replace(/\r/g, '\n').replace(/\u0000/g, '');
let url = 'magnet:?' + query.join('').replace(/^&+|&+$/gm, ''),
clean = jsdom();
clean = globalThis.cleanup();
$('body').html('<div id="foo"></div>');
let e = $('#foo');
e.text(prefix + url + postfix);
@@ -241,7 +241,7 @@ describe('Helper', function () {
jsc.nearray(jsc.nearray(common.jscAlnumString())),
function (labels, values) {
let selectedKey = '', selectedValue = '';
const clean = jsdom();
const clean = globalThis.cleanup();
labels.forEach(function(item, i) {
const key = item.join(''),
value = (values[i] || values[0]).join('');
@@ -273,7 +273,7 @@ describe('Helper', function () {
delete(url.fragment);
PrivateBin.Helper.reset();
const expected = common.urlToString(url),
clean = jsdom('', {url: fullUrl}),
clean = globalThis.cleanup('', {url: fullUrl}),
result = PrivateBin.Helper.baseUri();
clean();
return expected === result;
@@ -283,7 +283,7 @@ describe('Helper', function () {
describe('htmlEntities', function () {
before(function () {
cleanup = jsdom();
cleanup = globalThis.cleanup();
});
jsc.property(

View File

@@ -102,14 +102,14 @@ describe('I18n', function () {
const translation = $('<textarea>').text((prefix + params[0] + postfix)).text();
let args = Array.prototype.slice.call(params);
args.unshift(prefix + '%s' + postfix);
let clean = jsdom();
let clean = globalThis.cleanup();
$('body').html('<div id="i18n"></div>');
args.unshift($('#i18n'));
PrivateBin.I18n.translate.apply(this, args);
const result = $('#i18n').text();
PrivateBin.I18n.reset();
clean();
clean = jsdom();
clean = globalThis.cleanup();
$('body').html('<div id="i18n"></div>');
args[0] = $('#i18n');
PrivateBin.I18n._.apply(this, args);
@@ -137,14 +137,14 @@ describe('I18n', function () {
);
let args = Array.prototype.slice.call(params);
args.unshift(prefix + '<a href="%s"></a>' + postfix);
let clean = jsdom();
let clean = globalThis.cleanup();
$('body').html('<div id="i18n"></div>');
args.unshift($('#i18n'));
PrivateBin.I18n.translate.apply(this, args);
const result = $('#i18n').html();
PrivateBin.I18n.reset();
clean();
clean = jsdom();
clean = globalThis.cleanup();
$('body').html('<div id="i18n"></div>');
args[0] = $('#i18n');
PrivateBin.I18n._.apply(this, args);
@@ -187,13 +187,13 @@ describe('I18n', function () {
common.jscSupportedLanguages(),
function(language) {
// cleanup
var clean = jsdom('', {cookie: ['lang=en']});
var clean = globalThis.cleanup('', {cookie: ['lang=en']});
PrivateBin.I18n.reset('en');
PrivateBin.I18n.loadTranslations();
clean();
// mock
clean = jsdom('', {cookie: ['lang=' + language]});
clean = globalThis.cleanup('', {cookie: ['lang=' + language]});
// eslint-disable-next-line global-require
PrivateBin.I18n.reset(language, require('../../i18n/' + language + '.json'));
var loadedLang = PrivateBin.I18n.getLanguage(),
@@ -207,7 +207,7 @@ describe('I18n', function () {
jsc.property(
'should default to en',
function() {
var clean = jsdom('', {url: 'https://privatebin.net/'});
var clean = globalThis.cleanup('', {url: 'https://privatebin.net/'});
// when navigator.userLanguage is undefined and no default language
// is specified, it would throw an error

View File

@@ -5,7 +5,7 @@ describe('Model', function () {
describe('getExpirationDefault', function () {
before(function () {
PrivateBin.Model.reset();
cleanup = jsdom();
cleanup = globalThis.cleanup();
});
jsc.property(
@@ -93,7 +93,7 @@ describe('Model', function () {
}
url.query = queryStart.concat(pasteId, queryEnd);
const pasteIdString = pasteId.join(''),
clean = jsdom('', {url: common.urlToString(url)});
clean = globalThis.cleanup('', {url: common.urlToString(url)});
const result = PrivateBin.Model.getPasteId();
PrivateBin.Model.reset();
clean();
@@ -104,7 +104,7 @@ describe('Model', function () {
'throws exception on empty query string',
common.jscUrl(true, false),
function (url) {
const clean = jsdom('', {url: common.urlToString(url)});
const clean = globalThis.cleanup('', {url: common.urlToString(url)});
let result = false;
try {
PrivateBin.Model.getPasteId();
@@ -130,7 +130,7 @@ describe('Model', function () {
common.jscUrl(),
function (url) {
url.fragment = '0OIl'; // any non-base58 string
const clean = jsdom('', {url: common.urlToString(url)});
const clean = globalThis.cleanup('', {url: common.urlToString(url)});
let result = false;
try {
PrivateBin.Model.getPasteId();
@@ -150,7 +150,7 @@ describe('Model', function () {
function (url, trail) {
const fragment = url.fragment.padStart(32, '\u0000');
url.fragment = PrivateBin.CryptTool.base58encode(fragment) + '&' + trail.join('');
const clean = jsdom('', {url: common.urlToString(url)}),
const clean = globalThis.cleanup('', {url: common.urlToString(url)}),
result = PrivateBin.Model.getPasteKey();
PrivateBin.Model.reset();
clean();
@@ -164,7 +164,7 @@ describe('Model', function () {
// base58 strips leading NULL bytes, so the string is padded with these if not found
const fragment = url.fragment.padStart(32, '\u0000');
url.fragment = PrivateBin.CryptTool.base58encode(fragment);
const clean = jsdom('', {url: common.urlToString(url)}),
const clean = globalThis.cleanup('', {url: common.urlToString(url)}),
result = PrivateBin.Model.getPasteKey();
PrivateBin.Model.reset();
clean();
@@ -179,7 +179,7 @@ describe('Model', function () {
// base58 strips leading NULL bytes, so the string is padded with these if not found
const fragment = url.fragment.padStart(32, '\u0000');
url.fragment = PrivateBin.CryptTool.base58encode(fragment) + '&' + trail.join('');
const clean = jsdom('', {url: common.urlToString(url)}),
const clean = globalThis.cleanup('', {url: common.urlToString(url)}),
result = PrivateBin.Model.getPasteKey();
PrivateBin.Model.reset();
clean();
@@ -190,7 +190,7 @@ describe('Model', function () {
'throws exception on empty fragment of the URL',
common.jscUrl(false),
function (url) {
let clean = jsdom('', {url: common.urlToString(url)}),
let clean = globalThis.cleanup('', {url: common.urlToString(url)}),
result = false;
try {
PrivateBin.Model.getPasteKey();

View File

@@ -23,7 +23,7 @@ describe('PasteStatus', function () {
this.timeout(30000);
it('creates a notification after a successful document upload', function () {
const clean = jsdom();
cleanup();
$('body').html('<a href="#" id="deletelink"><span></span></a><div id="pastelink"></div>');
PrivateBin.PasteStatus.init();
const expected1 = 'https://example.com/long';
@@ -31,30 +31,29 @@ describe('PasteStatus', function () {
PrivateBin.PasteStatus.createPasteNotification(expected1, expected2);
const result1 = $('#pasteurl')[0].href,
result2 = $('#deletelink')[0].href;
clean();
assert.strictEqual(result1, expected1);
assert.strictEqual(result2, expected2);
});
jsc.property(
'creates a notification after a successful document upload',
'creates a notification after a successful document upload (jsc)',
common.jscUrl(),
common.jscUrl(false),
function (url1, url2) {
// sometimes the generator returns incomplete objects, bail out
if (!url1 || !url1.address || !url2 || !url2.address) {
return true;
}
const expected1 = common.urlToString(url1).replace(/&(gt|lt)$/, '&$1a'),
expected2 = common.urlToString(url2).replace(/&(gt|lt)$/, '&$1a'),
clean = jsdom();
$('body').html('<a href="#" id="deletelink"><span></span></a><div id="pastelink"></div>');
PrivateBin.PasteStatus.init();
PrivateBin.PasteStatus.createPasteNotification(expected1, expected2);
const result1 = $('#pasteurl')[0].href,
result2 = $('#deletelink')[0].href;
clean();
return result1 === expected1 && result2 === expected2;
// sometimes the generator returns incomplete objects, bail out
if (!url1 || !url1.address || !url2 || !url2.address) {
return true;
}
const expected1 = common.urlToString(url1).replace(/&(gt|lt)$/, '&$1a'),
expected2 = common.urlToString(url2).replace(/&(gt|lt)$/, '&$1a');
cleanup();
$('body').html('<a href="#" id="deletelink"><span></span></a><div id="pastelink"></div>');
PrivateBin.PasteStatus.init();
PrivateBin.PasteStatus.createPasteNotification(expected1, expected2);
const result1 = $('#pasteurl')[0].href,
result2 = $('#deletelink')[0].href;
return result1 === expected1 && result2 === expected2;
}
);
});
@@ -77,7 +76,7 @@ describe('PasteStatus', function () {
url.address = domain.split('').concat(url.address);
const urlString = common.urlToString(url),
expected = urlString.substring((schema + '://' + domain).length),
clean = jsdom();
clean = globalThis.cleanup();
$('body').html('<div><div id="pastelink"></div></div>');
PrivateBin.PasteStatus.init();
@@ -116,7 +115,7 @@ describe('PasteStatus', function () {
shorturl: shortUrlString,
statusCode: 200
},
clean = jsdom();
clean = globalThis.cleanup();
$('body').html('<div><div id="pastelink"></div></div>');
PrivateBin.PasteStatus.init();
@@ -143,7 +142,7 @@ describe('PasteStatus', function () {
' <message>success</message>\n' +
' <statusCode>200</statusCode>\n' +
'</result>',
clean = jsdom();
clean = globalThis.cleanup();
$('body').html('<div><div id="pastelink"></div></div>');
PrivateBin.PasteStatus.init();
@@ -175,7 +174,7 @@ describe('PasteStatus', function () {
'\t\t<p>Your document is <a id="pasteurl" href="' + shortUrlString + '">' + shortUrlString + '</a> <span id="copyhint">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span></p>\n' +
'\t</body>\n' +
'</html>',
clean = jsdom();
clean = globalThis.cleanup();
$('body').html('<div><div id="pastelink"></div></div>');
PrivateBin.PasteStatus.init();
@@ -199,7 +198,7 @@ describe('PasteStatus', function () {
'nat',
common.jscUrl(),
function (burnafterreading, remainingTime, url) {
let clean = jsdom('', {url: common.urlToString(url)}),
let clean = globalThis.cleanup('', {url: common.urlToString(url)}),
result;
$('body').html('<div id="remainingtime" class="hidden"></div>');
PrivateBin.PasteStatus.init();

View File

@@ -6,7 +6,7 @@ describe('PasteViewer', function () {
this.timeout(30000);
it('basic plaintext display works', function () {
const clean = jsdom();
cleanup();
$('body').html(
'<div id="placeholder" class="hidden">+++ no document text +++</div>' +
'<div id="prettymessage" class="hidden"><pre id="prettyprint" class="prettyprint linenums:1"></pre></div>' +
@@ -18,7 +18,6 @@ describe('PasteViewer', function () {
PrivateBin.PasteViewer.run();
assert.strictEqual(PrivateBin.PasteViewer.getText(), 'hello');
assert.ok(!$('#plaintext').hasClass('hidden'));
clean();
});
jsc.property(
@@ -26,8 +25,8 @@ describe('PasteViewer', function () {
common.jscFormats(),
'nestring',
function (format, text) {
var clean = jsdom(),
results = [];
cleanup();
var results = [];
$('body').html(
'<div id="placeholder" class="hidden">+++ no document text ' +
'+++</div><div id="prettymessage" class="hidden"><pre ' +
@@ -113,7 +112,7 @@ describe('PasteViewer', function () {
]),
'string',
function (format, prefix, xss, suffix) {
var clean = jsdom(),
var clean = globalThis.cleanup(),
text = prefix + xss + suffix;
$('body').html(
'<div id="placeholder" class="hidden">+++ no document text ' +

View File

@@ -10,7 +10,7 @@ describe('Prompt', function () {
'string',
function (password) {
password = password.replace(/\r+|\n+/g, '');
const clean = jsdom('', {url: 'ftp://example.com/?0000000000000000'});
const clean = globalThis.cleanup('', {url: 'ftp://example.com/?0000000000000000'});
$('body').html(
'<div id="passwordmodal" class="modal fade" role="dialog">' +
'<div class="modal-dialog"><div class="modal-content">' +

View File

@@ -16,7 +16,7 @@ describe('ServerInteraction', function () {
async function (key, password, message) {
// pause to let async functions conclude
await new Promise(resolve => setTimeout(resolve, 300));
let clean = jsdom();
let clean = globalThis.cleanup();
window.crypto = new WebCrypto();
message = message.trim();

View File

@@ -12,23 +12,17 @@ describe('TopNav', function () {
function () {
let results = [];
$('body').html(
'<nav class="navbar navbar-inverse navbar-static-top">' +
'<div id="navbar" class="navbar-collapse collapse"><ul ' +
'class="nav navbar-nav"><li><button id="newbutton" ' +
'type="button" class="hidden btn btn-warning navbar-btn">' +
'<span class="glyphicon glyphicon-file" aria-hidden="true">' +
'</span> New</button><button id="clonebutton" type="button"' +
' class="hidden btn btn-warning navbar-btn">' +
'<span class="glyphicon glyphicon-duplicate" ' +
'aria-hidden="true"></span> Clone</button><button ' +
'id="rawtextbutton" type="button" class="hidden btn ' +
'btn-warning navbar-btn"><span class="glyphicon ' +
'glyphicon-text-background" aria-hidden="true"></span> ' +
'Raw text</button><button id="qrcodelink" type="button" ' +
'data-toggle="modal" data-target="#qrcodemodal" ' +
'class="hidden btn btn-warning navbar-btn"><span ' +
'class="glyphicon glyphicon-qrcode" aria-hidden="true">' +
'</span> QR code</button></li></ul></div></nav>'
`<nav class="navbar navbar-inverse navbar-static-top">
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav"><li><button id="newbutton" type="button" class="hidden btn btn-warning navbar-btn">
<span class="glyphicon glyphicon-file" aria-hidden="true">
</span> New</button><button id="clonebutton" type="button" class="hidden btn btn-warning navbar-btn">
<span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> Clone</button>
<button id="rawtextbutton" type="button" class="hidden btn btn-warning navbar-btn">
<span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> Raw text</button>
<button id="qrcodelink" type="button" data-toggle="modal" data-target="#qrcodemodal" class="hidden btn btn-warning navbar-btn">
<span class="glyphicon glyphicon-qrcode" aria-hidden="true"></span> QR code</button></li></ul></div>
</nav>`
);
PrivateBin.TopNav.init();
results.push(
@@ -308,7 +302,7 @@ describe('TopNav', function () {
it(
'collapses the navigation when displayed on a small screen',
function () {
const clean = jsdom();
const clean = globalThis.cleanup();
let results = [];
$('body').html(
'<nav><div class="navbar-header"><button type="button" ' +
@@ -793,7 +787,7 @@ describe('TopNav', function () {
it(
'displays raw text view correctly',
function () {
const clean = jsdom('', {url: 'https://privatebin.net/?0123456789abcdef#1'});
const clean = globalThis.cleanup('', {url: 'https://privatebin.net/?0123456789abcdef#1'});
$('body').html('<button id="rawtextbutton"></button>');
const sample = 'example';
PrivateBin.PasteViewer.setText(sample);

View File

@@ -16,7 +16,7 @@ describe('UiHelper', function () {
common.jscUrl(false, false),
function (url) {
const expected = common.urlToString(url),
clean = jsdom('', {url: expected});
clean = globalThis.cleanup('', {url: expected});
PrivateBin.UiHelper.mockHistoryChange();
PrivateBin.Helper.reset();
@@ -33,7 +33,7 @@ describe('UiHelper', function () {
function (url, fragment) {
url.fragment = fragment.join('');
const expected = common.urlToString(url),
clean = jsdom('', {url: expected});
clean = globalThis.cleanup('', {url: expected});
PrivateBin.UiHelper.mockHistoryChange([
{type: 'newpaste'}, '', expected
@@ -58,7 +58,7 @@ describe('UiHelper', function () {
'redirects to home',
common.jscUrl(),
function (url) {
const clean = jsdom('', {url: common.urlToString(url)});
const clean = globalThis.cleanup('', {url: common.urlToString(url)});
delete(url.query);
delete(url.fragment);
const expected = common.urlToString(url);
@@ -88,7 +88,7 @@ describe('UiHelper', function () {
function (id, element) {
id = id.join('');
element = element.join('');
var clean = jsdom(
var clean = globalThis.cleanup(
'<' + element + ' id="' + id + '"></' + element + '>'
);
var result = PrivateBin.UiHelper.isVisible($('#' + id));