diff --git a/js/common.js b/js/common.js index 093428c2..39f52056 100644 --- a/js/common.js +++ b/js/common.js @@ -125,6 +125,11 @@ exports.jscQueryString = function() { return jsc.elements(queryString); } +// provides random characters allowed in base64 encoded strings +exports.jscBase64String = function() { + return jsc.elements(base64String); +} + // provides a random URL schema supported by the whatwg-url library exports.jscSchemas = function() { return jsc.elements(schemas); diff --git a/js/test/Model.js b/js/test/Model.js new file mode 100644 index 00000000..3763d931 --- /dev/null +++ b/js/test/Model.js @@ -0,0 +1,263 @@ +'use strict'; +var common = require('../common'); + +describe('Model', function () { + describe('getExpirationDefault', function () { + before(function () { + $.PrivateBin.Model.reset(); + cleanup(); + }); + + jsc.property( + 'returns the contents of the element with id "pasteExpiration"', + 'array 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'), + contents = ''; + $('body').html(contents); + var result = common.htmlEntities( + $.PrivateBin.Model.getExpirationDefault() + ); + $.PrivateBin.Model.reset(); + return content === result; + } + ); + }); + + describe('getFormatDefault', function () { + before(function () { + $.PrivateBin.Model.reset(); + cleanup(); + }); + + jsc.property( + 'returns the contents of the element with id "pasteFormatter"', + 'array 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'), + contents = ''; + $('body').html(contents); + var result = common.htmlEntities( + $.PrivateBin.Model.getFormatDefault() + ); + $.PrivateBin.Model.reset(); + return content === result; + } + ); + }); + + describe('hasCipherData', function () { + before(function () { + $.PrivateBin.Model.reset(); + cleanup(); + }); + + jsc.property( + 'checks if the element with id "cipherdata" contains any data', + 'asciistring', + function (value) { + value = common.htmlEntities(value).trim(); + $('body').html('
' + value + '
'); + $.PrivateBin.Model.init(); + var result = $.PrivateBin.Model.hasCipherData(); + $.PrivateBin.Model.reset(); + return (value.length > 0) === result; + } + ); + }); + + describe('getCipherData', function () { + before(function () { + $.PrivateBin.Model.reset(); + cleanup(); + }); + + jsc.property( + 'returns the contents of the element with id "cipherdata"', + 'asciistring', + function (value) { + value = common.htmlEntities(value).trim(); + $('body').html('
' + value + '
'); + $.PrivateBin.Model.init(); + var result = common.htmlEntities( + $.PrivateBin.Model.getCipherData() + ); + $.PrivateBin.Model.reset(); + return value === result; + } + ); + }); + + describe('getPasteId', function () { + this.timeout(30000); + before(function () { + $.PrivateBin.Model.reset(); + cleanup(); + }); + + jsc.property( + 'returns the query string without separator, if any', + jsc.nearray(common.jscA2zString()), + jsc.nearray(common.jscA2zString()), + jsc.nearray(common.jscQueryString()), + 'string', + function (schema, address, query, fragment) { + var queryString = query.join(''), + clean = jsdom('', { + url: schema.join('') + '://' + address.join('') + + '/?' + queryString + '#' + fragment + }), + result = $.PrivateBin.Model.getPasteId(); + $.PrivateBin.Model.reset(); + clean(); + return queryString === result; + } + ); + jsc.property( + 'throws exception on empty query string', + jsc.nearray(common.jscA2zString()), + jsc.nearray(common.jscA2zString()), + 'string', + function (schema, address, fragment) { + var clean = jsdom('', { + url: schema.join('') + '://' + address.join('') + + '/#' + fragment + }), + result = false; + try { + $.PrivateBin.Model.getPasteId(); + } + catch(err) { + result = true; + } + $.PrivateBin.Model.reset(); + clean(); + return result; + } + ); + }); + + describe('getPasteKey', function () { + this.timeout(30000); + jsc.property( + 'returns the fragment of the URL', + jsc.nearray(common.jscA2zString()), + jsc.nearray(common.jscA2zString()), + jsc.array(common.jscQueryString()), + jsc.nearray(common.jscBase64String()), + function (schema, address, query, fragment) { + var fragmentString = fragment.join(''), + clean = jsdom('', { + url: schema.join('') + '://' + address.join('') + + '/?' + query.join('') + '#' + fragmentString + }), + result = $.PrivateBin.Model.getPasteKey(); + $.PrivateBin.Model.reset(); + clean(); + return fragmentString === result; + } + ); + jsc.property( + 'returns the fragment stripped of trailing query parts', + jsc.nearray(common.jscA2zString()), + jsc.nearray(common.jscA2zString()), + jsc.array(common.jscQueryString()), + jsc.nearray(common.jscBase64String()), + jsc.array(common.jscQueryString()), + function (schema, address, query, fragment, trail) { + var fragmentString = fragment.join(''), + clean = jsdom('', { + url: schema.join('') + '://' + address.join('') + '/?' + + query.join('') + '#' + fragmentString + '&' + trail.join('') + }), + result = $.PrivateBin.Model.getPasteKey(); + $.PrivateBin.Model.reset(); + clean(); + return fragmentString === result; + } + ); + jsc.property( + 'throws exception on empty fragment of the URL', + jsc.nearray(common.jscA2zString()), + jsc.nearray(common.jscA2zString()), + jsc.array(common.jscQueryString()), + function (schema, address, query) { + var clean = jsdom('', { + url: schema.join('') + '://' + address.join('') + + '/?' + query.join('') + }), + result = false; + try { + $.PrivateBin.Model.getPasteKey(); + } + catch(err) { + result = true; + } + $.PrivateBin.Model.reset(); + clean(); + return result; + } + ); + }); + + describe('getTemplate', function () { + before(function () { + $.PrivateBin.Model.reset(); + cleanup(); + }); + + jsc.property( + 'returns the contents of the element with id "[name]template"', + jsc.nearray(common.jscAlnumString()), + jsc.nearray(common.jscA2zString()), + jsc.nearray(common.jscAlnumString()), + function (id, element, value) { + id = id.join(''); + element = element.join(''); + value = value.join('').trim(); + + //
,
, and tags can't contain strings, + // table tags can't be alone, so test with a

instead + if (['br', 'col', 'hr', 'img', 'tr', 'td', 'th', 'wbr'].indexOf(element) >= 0) { + element = 'p'; + } + + $('body').html( + '

<' + element + ' id="' + id + + 'template">' + value + '
' + ); + $.PrivateBin.Model.init(); + var template = '<' + element + ' id="' + id + '">' + value + + '', + result = $.PrivateBin.Model.getTemplate(id).wrap('

').parent().html(); + $.PrivateBin.Model.reset(); + return template === result; + } + ); + }); +}); +