more general solution addressing #554, kudos @rugk for the suggestions

This commit is contained in:
El RIDO
2020-01-04 11:34:16 +01:00
parent 6a3a8a395a
commit 2caddf985f
14 changed files with 241 additions and 151 deletions

View File

@@ -3,21 +3,56 @@ var common = require('../common');
describe('Alert', function () {
describe('showStatus', function () {
before(function () {
cleanup();
});
jsc.property(
'shows a status message',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
function (icon, message) {
icon = icon.join('');
message = message.join('');
var expected = '<div id="status">' + message + '</div>';
$('body').html(
'<div id="status"></div>'
);
$.PrivateBin.Alert.init();
$.PrivateBin.Alert.showStatus(message, icon);
var result = $('body').html();
return expected === result;
}
);
jsc.property(
'shows a status message (bootstrap)',
jsc.array(common.jscAlnumString()),
function (message) {
message = message.join('');
var expected = '<div id="status" role="alert" ' +
'class="statusmessage alert alert-info"><span ' +
'class="glyphicon glyphicon-info-sign" ' +
'aria-hidden="true"></span> <span>' + message + '</span></div>';
$('body').html(
'<div id="status" role="alert" class="statusmessage ' +
'alert alert-info hidden"><span class="glyphicon ' +
'glyphicon-info-sign" aria-hidden="true"></span> </div>'
);
$.PrivateBin.Alert.init();
$.PrivateBin.Alert.showStatus(message);
var result = $('body').html();
return expected === result;
}
);
jsc.property(
'shows a status message (bootstrap, custom icon)',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
function (icon, message) {
icon = icon.join('');
message = message.join('');
var expected = '<div id="status" role="alert" ' +
'class="statusmessage alert alert-info"><span ' +
'class="glyphicon glyphicon-' + icon +
'" aria-hidden="true"></span> ' + message + '</div>';
'" aria-hidden="true"></span> <span>' + message + '</span></div>';
$('body').html(
'<div id="status" role="alert" class="statusmessage ' +
'alert alert-info hidden"><span class="glyphicon ' +
@@ -32,12 +67,48 @@ describe('Alert', function () {
});
describe('showError', function () {
before(function () {
cleanup();
});
jsc.property(
'shows an error message (basic)',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
function (icon, message) {
icon = icon.join('');
message = message.join('');
var expected = '<div id="errormessage">' + message + '</div>';
$('body').html(
'<div id="errormessage"></div>'
);
$.PrivateBin.Alert.init();
$.PrivateBin.Alert.showError(message, icon);
var result = $('body').html();
return expected === result;
}
);
jsc.property(
'shows an error message',
'shows an error message (bootstrap)',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
function (icon, message) {
message = message.join('');
var expected = '<div id="errormessage" role="alert" ' +
'class="statusmessage alert alert-danger"><span ' +
'class="glyphicon glyphicon-alert" ' +
'aria-hidden="true"></span> <span>' + message + '</span></div>';
$('body').html(
'<div id="errormessage" role="alert" class="statusmessage ' +
'alert alert-danger hidden"><span class="glyphicon ' +
'glyphicon-alert" aria-hidden="true"></span> </div>'
);
$.PrivateBin.Alert.init();
$.PrivateBin.Alert.showError(message);
var result = $('body').html();
return expected === result;
}
);
jsc.property(
'shows an error message (bootstrap, custom icon)',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
function (icon, message) {
@@ -46,7 +117,7 @@ describe('Alert', function () {
var expected = '<div id="errormessage" role="alert" ' +
'class="statusmessage alert alert-danger"><span ' +
'class="glyphicon glyphicon-' + icon +
'" aria-hidden="true"></span> ' + message + '</div>';
'" aria-hidden="true"></span> <span>' + message + '</span></div>';
$('body').html(
'<div id="errormessage" role="alert" class="statusmessage ' +
'alert alert-danger hidden"><span class="glyphicon ' +
@@ -61,12 +132,27 @@ describe('Alert', function () {
});
describe('showRemaining', function () {
before(function () {
cleanup();
});
jsc.property(
'shows remaining time (basic)',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
'integer',
function (message, string, number) {
message = message.join('');
string = string.join('');
var expected = '<div id="remainingtime" class="">' + string + message + number + '</div>';
$('body').html(
'<div id="remainingtime" class="hidden"></div>'
);
$.PrivateBin.Alert.init();
$.PrivateBin.Alert.showRemaining(['%s' + message + '%d', string, number]);
var result = $('body').html();
return expected === result;
}
);
jsc.property(
'shows remaining time',
'shows remaining time (bootstrap)',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
'integer',
@@ -76,7 +162,7 @@ describe('Alert', function () {
var expected = '<div id="remainingtime" role="alert" ' +
'class="alert alert-info"><span ' +
'class="glyphicon glyphicon-fire" aria-hidden="true">' +
'</span> ' + string + message + number + '</div>';
'</span> <span>' + string + message + number + '</span></div>';
$('body').html(
'<div id="remainingtime" role="alert" class="hidden ' +
'alert alert-info"><span class="glyphicon ' +
@@ -91,12 +177,30 @@ describe('Alert', function () {
});
describe('showLoading', function () {
before(function () {
cleanup();
});
jsc.property(
'shows a loading message (basic)',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
function (message, icon) {
message = message.join('');
icon = icon.join('');
var defaultMessage = 'Loading…';
if (message.length === 0) {
message = defaultMessage;
}
var expected = '<div id="loadingindicator" class="">' + message + '</div>';
$('body').html(
'<div id="loadingindicator" class="hidden">' + defaultMessage + '</div>'
);
$.PrivateBin.Alert.init();
$.PrivateBin.Alert.showLoading(message, icon);
var result = $('body').html();
return expected === result;
}
);
jsc.property(
'shows a loading message',
'shows a loading message (bootstrap)',
jsc.array(common.jscAlnumString()),
jsc.array(common.jscAlnumString()),
function (message, icon) {
@@ -109,7 +213,7 @@ describe('Alert', function () {
var expected = '<ul class="nav navbar-nav"><li ' +
'id="loadingindicator" class="navbar-text"><span ' +
'class="glyphicon glyphicon-' + icon +
'" aria-hidden="true"></span> ' + message + '</li></ul>';
'" aria-hidden="true"></span> <span>' + message + '</span></li></ul>';
$('body').html(
'<ul class="nav navbar-nav"><li id="loadingindicator" ' +
'class="navbar-text hidden"><span class="glyphicon ' +
@@ -125,10 +229,6 @@ describe('Alert', function () {
});
describe('hideLoading', function () {
before(function () {
cleanup();
});
it(
'hides the loading message',
function() {
@@ -150,10 +250,6 @@ describe('Alert', function () {
});
describe('hideMessages', function () {
before(function () {
cleanup();
});
it(
'hides all messages',
function() {
@@ -176,10 +272,6 @@ describe('Alert', function () {
});
describe('setCustomHandler', function () {
before(function () {
cleanup();
});
jsc.property(
'calls a given handler function',
'nat 3',

View File

@@ -4,9 +4,6 @@ var common = require('../common');
describe('AttachmentViewer', function () {
describe('setAttachment, showAttachment, removeAttachment, hideAttachment, hideAttachmentPreview, hasAttachment, getAttachment & moveAttachmentTo', function () {
this.timeout(30000);
before(function () {
cleanup();
});
jsc.property(
'displays & hides data as requested',
@@ -24,7 +21,8 @@ describe('AttachmentViewer', function () {
mimeType.substring(0, 6) === 'video/' ||
mimeType.match(/\/pdf/i)
),
results = [];
results = [],
result = '';
prefix = prefix.replace(/%(s|d)/g, '%%');
postfix = postfix.replace(/%(s|d)/g, '%%');
$('body').html(
@@ -72,13 +70,19 @@ describe('AttachmentViewer', function () {
!$('#attachment').hasClass('hidden') &&
(previewSupported ? !$('#attachmentPreview').hasClass('hidden') : $('#attachmentPreview').hasClass('hidden'))
);
var element = $('<div></div>');
let element = $('<div>');
$.PrivateBin.AttachmentViewer.moveAttachmentTo(element, prefix + '%s' + postfix);
// messageIDs with links get a relaxed treatment
if (prefix.indexOf('<a') === -1 && postfix.indexOf('<a') === -1) {
result = $.PrivateBin.Helper.htmlEntities(prefix + filename + postfix);
} else {
result = $('<div>').html(prefix + $.PrivateBin.Helper.htmlEntities(filename) + postfix).html();
}
if (filename.length) {
results.push(
element.children()[0].href === data &&
element.children()[0].getAttribute('download') === filename &&
element.children()[0].text === prefix + filename + postfix
element.children()[0].text === result
);
} else {
results.push(element.children()[0].href === data);

View File

@@ -4,9 +4,6 @@ var common = require('../common');
describe('DiscussionViewer', function () {
describe('handleNotification, prepareNewDiscussion, addComment, finishDiscussion, getReplyMessage, getReplyNickname, getReplyCommentId & highlightComment', function () {
this.timeout(30000);
before(function () {
cleanup();
});
jsc.property(
'displays & hides comments as requested',

View File

@@ -4,9 +4,6 @@ require('../common');
describe('Editor', function () {
describe('show, hide, getText, setText & isPreview', function () {
this.timeout(30000);
before(function () {
cleanup();
});
jsc.property(
'returns text fed into the textarea, handles editor tabs',

View File

@@ -3,10 +3,6 @@ var common = require('../common');
describe('Helper', function () {
describe('secondsToHuman', function () {
after(function () {
cleanup();
});
jsc.property('returns an array with a number and a word', 'integer', function (number) {
var result = $.PrivateBin.Helper.secondsToHuman(number);
return Array.isArray(result) &&
@@ -57,11 +53,11 @@ describe('Helper', function () {
'nearray string',
function (ids, contents) {
var html = '',
result = true;
result = true,
clean = jsdom(html);
ids.forEach(function(item, i) {
html += '<div id="' + item.join('') + '">' + common.htmlEntities(contents[i] || contents[0]) + '</div>';
html += '<div id="' + item.join('') + '">' + $.PrivateBin.Helper.htmlEntities(contents[i] || contents[0]) + '</div>';
});
var clean = jsdom(html);
// TODO: As per https://github.com/tmpvar/jsdom/issues/321 there is no getSelection in jsdom, yet.
// Once there is one, uncomment the block below to actually check the result.
/*
@@ -77,8 +73,8 @@ describe('Helper', function () {
});
describe('urls2links', function () {
after(function () {
cleanup();
before(function () {
cleanup = jsdom();
});
jsc.property(
@@ -97,11 +93,11 @@ describe('Helper', function () {
jsc.array(common.jscHashString()),
'string',
function (prefix, schema, address, query, fragment, postfix) {
var query = query.join(''),
var query = query.join(''),
fragment = fragment.join(''),
url = schema + '://' + address.join('') + '/?' + query + '#' + fragment,
prefix = common.htmlEntities(prefix),
postfix = ' ' + common.htmlEntities(postfix);
url = schema + '://' + address.join('') + '/?' + query + '#' + fragment,
prefix = $.PrivateBin.Helper.htmlEntities(prefix),
postfix = ' ' + $.PrivateBin.Helper.htmlEntities(postfix);
// special cases: When the query string and fragment imply the beginning of an HTML entity, eg. &#0 or &#x
if (
@@ -122,19 +118,15 @@ describe('Helper', function () {
jsc.array(common.jscQueryString()),
'string',
function (prefix, query, postfix) {
var url = 'magnet:?' + query.join('').replace(/^&+|&+$/gm,''),
prefix = common.htmlEntities(prefix),
postfix = common.htmlEntities(postfix);
var url = 'magnet:?' + query.join('').replace(/^&+|&+$/gm,''),
prefix = $.PrivateBin.Helper.htmlEntities(prefix),
postfix = $.PrivateBin.Helper.htmlEntities(postfix);
return prefix + '<a href="' + url + '" rel="nofollow">' + url + '</a> ' + postfix === $.PrivateBin.Helper.urls2links(prefix + url + ' ' + postfix);
}
);
});
describe('sprintf', function () {
after(function () {
cleanup();
});
jsc.property(
'replaces %s in strings with first given parameter',
'string',
@@ -211,6 +203,10 @@ describe('Helper', function () {
describe('getCookie', function () {
this.timeout(30000);
before(function () {
cleanup();
});
jsc.property(
'returns the requested cookie',
'nearray asciinestring',
@@ -261,16 +257,16 @@ describe('Helper', function () {
});
describe('htmlEntities', function () {
after(function () {
cleanup();
before(function () {
cleanup = jsdom();
});
jsc.property(
'removes all HTML entities from any given string',
'string',
function (string) {
var result = common.htmlEntities(string);
return !(/[<>"'`=\/]/.test(result)) && !(string.indexOf('&') > -1 && !(/&amp;/.test(result)));
var result = $.PrivateBin.Helper.htmlEntities(string);
return !(/[<>]/.test(result)) && !(string.indexOf('&') > -1 && !(/&amp;/.test(result)));
}
);
});

View File

@@ -32,6 +32,7 @@ describe('I18n', function () {
var fakeAlias = $.PrivateBin.I18n._(fake);
$.PrivateBin.I18n.reset();
messageId = $.PrivateBin.Helper.htmlEntities(messageId);
return messageId === result && messageId === alias &&
messageId === pluralResult && messageId === pluralAlias &&
messageId === fakeResult && messageId === fakeAlias;
@@ -46,7 +47,7 @@ describe('I18n', function () {
prefix = prefix.replace(/%(s|d)/g, '%%');
params[0] = params[0].replace(/%(s|d)/g, '%%');
postfix = postfix.replace(/%(s|d)/g, '%%');
var translation = prefix + params[0] + postfix;
var translation = $.PrivateBin.Helper.htmlEntities(prefix + params[0] + postfix);
params.unshift(prefix + '%s' + postfix);
var result = $.PrivateBin.I18n.translate.apply(this, params);
$.PrivateBin.I18n.reset();

View File

@@ -5,18 +5,18 @@ describe('Model', function () {
describe('getExpirationDefault', function () {
before(function () {
$.PrivateBin.Model.reset();
cleanup();
cleanup = jsdom();
});
jsc.property(
'returns the contents of the element with id "pasteExpiration"',
'array asciinestring',
'nearray asciinestring',
'string',
'small nat',
function (keys, value, key) {
keys = keys.map(common.htmlEntities);
value = common.htmlEntities(value);
var content = keys.length > key ? keys[key] : (keys.length > 0 ? keys[0] : 'null'),
keys = keys.map($.PrivateBin.Helper.htmlEntities);
value = $.PrivateBin.Helper.htmlEntities(value);
var content = keys.length > key ? keys[key] : keys[0],
contents = '<select id="pasteExpiration" name="pasteExpiration">';
keys.forEach(function(item) {
contents += '<option value="' + item + '"';
@@ -27,7 +27,7 @@ describe('Model', function () {
});
contents += '</select>';
$('body').html(contents);
var result = common.htmlEntities(
var result = $.PrivateBin.Helper.htmlEntities(
$.PrivateBin.Model.getExpirationDefault()
);
$.PrivateBin.Model.reset();
@@ -39,18 +39,20 @@ describe('Model', function () {
describe('getFormatDefault', function () {
before(function () {
$.PrivateBin.Model.reset();
});
after(function () {
cleanup();
});
jsc.property(
'returns the contents of the element with id "pasteFormatter"',
'array asciinestring',
'nearray asciinestring',
'string',
'small nat',
function (keys, value, key) {
keys = keys.map(common.htmlEntities);
value = common.htmlEntities(value);
var content = keys.length > key ? keys[key] : (keys.length > 0 ? keys[0] : 'null'),
keys = keys.map($.PrivateBin.Helper.htmlEntities);
value = $.PrivateBin.Helper.htmlEntities(value);
var content = keys.length > key ? keys[key] : keys[0],
contents = '<select id="pasteFormatter" name="pasteFormatter">';
keys.forEach(function(item) {
contents += '<option value="' + item + '"';
@@ -61,7 +63,7 @@ describe('Model', function () {
});
contents += '</select>';
$('body').html(contents);
var result = common.htmlEntities(
var result = $.PrivateBin.Helper.htmlEntities(
$.PrivateBin.Model.getFormatDefault()
);
$.PrivateBin.Model.reset();
@@ -74,7 +76,6 @@ describe('Model', function () {
this.timeout(30000);
before(function () {
$.PrivateBin.Model.reset();
cleanup();
});
jsc.property(
@@ -185,7 +186,6 @@ describe('Model', function () {
describe('getTemplate', function () {
before(function () {
$.PrivateBin.Model.reset();
cleanup();
});
jsc.property(

View File

@@ -39,9 +39,6 @@ describe('PasteStatus', function () {
describe('showRemainingTime', function () {
this.timeout(30000);
before(function () {
cleanup();
});
jsc.property(
'shows burn after reading message or remaining time',
@@ -84,10 +81,6 @@ describe('PasteStatus', function () {
});
describe('hideMessages', function () {
before(function () {
cleanup();
});
it(
'hides all messages',
function() {

View File

@@ -4,9 +4,6 @@ var common = require('../common');
describe('PasteViewer', function () {
describe('run, hide, getText, setText, getFormat, setFormat & isPrettyPrinted', function () {
this.timeout(30000);
before(function () {
cleanup();
});
jsc.property(
'displays text according to format',

View File

@@ -6,10 +6,6 @@ describe('Prompt', function () {
// in nodejs -> replace the prompt in the "page" template with a modal
describe('requestPassword & getPassword', function () {
this.timeout(30000);
before(function () {
$.PrivateBin.Model.reset();
cleanup();
});
jsc.property(
'returns the password fed into the dialog',
@@ -26,6 +22,7 @@ describe('Prompt', function () {
'password"></div><button type="submit">Decrypt</button>' +
'</form></div></div></div></div>'
);
$.PrivateBin.Model.reset();
$.PrivateBin.Model.init();
$.PrivateBin.Prompt.init();
$.PrivateBin.Prompt.requestPassword();