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 + '' + element + '>
'
+ );
+ $.PrivateBin.Model.init();
+ var template = '<' + element + ' id="' + id + '">' + value +
+ '' + element + '>',
+ result = $.PrivateBin.Model.getTemplate(id).wrap('').parent().html();
+ $.PrivateBin.Model.reset();
+ return template === result;
+ }
+ );
+ });
+});
+