| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057 |
- 'use strict';
- require('../common');
- const fc = require('fast-check');
- function query(selector) {
- if (selector.startsWith('#')) {
- return document.getElementById(selector.slice(1));
- }
- return document.querySelector(selector);
- }
- describe('TopNav', function () {
- describe('hideBurnAfterReadingButtons', function () {
- it(
- 'hides buttons when the QR code button is disabled',
- function () {
- document.documentElement.innerHTML =
- '<nav><button id="clonebutton"></button></nav>';
- PrivateBin.TopNav.init();
- assert.doesNotThrow(function () {
- PrivateBin.TopNav.hideBurnAfterReadingButtons();
- });
- assert.ok(query('#clonebutton').classList.contains('hidden'));
- cleanup();
- }
- );
- });
- describe('showViewButtons & hideViewButtons', function () {
- before(function () {
- cleanup();
- });
- it(
- 'shows and hides navigation elements when the QR code button is disabled',
- function () {
- document.documentElement.innerHTML =
- '<nav><button id="newbutton" class="hidden"></button>' +
- '<button id="clonebutton" class="hidden"></button>' +
- '<button id="rawtextbutton" class="hidden"></button>' +
- '<button id="downloadtextbutton" class="hidden"></button></nav>';
- PrivateBin.TopNav.init();
- assert.doesNotThrow(function () {
- PrivateBin.TopNav.showViewButtons();
- });
- assert.ok(!query('#newbutton').classList.contains('hidden'));
- assert.ok(!query('#clonebutton').classList.contains('hidden'));
- assert.ok(!query('#rawtextbutton').classList.contains('hidden'));
- assert.ok(!query('#downloadtextbutton').classList.contains('hidden'));
- assert.doesNotThrow(function () {
- PrivateBin.TopNav.hideViewButtons();
- });
- assert.ok(query('#newbutton').classList.contains('hidden'));
- assert.ok(query('#clonebutton').classList.contains('hidden'));
- assert.ok(query('#rawtextbutton').classList.contains('hidden'));
- assert.ok(query('#downloadtextbutton').classList.contains('hidden'));
- cleanup();
- }
- );
- it(
- 'displays & hides navigation elements for viewing an existing document',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- `<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="downloadtextbutton" type="button" class="hidden btn btn-default navbar-btn"></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(
- query('#newbutton').classList.contains('hidden') &&
- query('#clonebutton').classList.contains('hidden') &&
- query('#rawtextbutton').classList.contains('hidden') &&
- query('#qrcodelink').classList.contains('hidden')
- );
- PrivateBin.TopNav.showViewButtons();
- results.push(
- !query('#newbutton').classList.contains('hidden') &&
- !query('#clonebutton').classList.contains('hidden') &&
- !query('#rawtextbutton').classList.contains('hidden') &&
- !query('#qrcodelink').classList.contains('hidden')
- );
- PrivateBin.TopNav.hideViewButtons();
- results.push(
- query('#newbutton').classList.contains('hidden') &&
- query('#clonebutton').classList.contains('hidden') &&
- query('#rawtextbutton').classList.contains('hidden') &&
- query('#qrcodelink').classList.contains('hidden')
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('showCreateButtons & hideCreateButtons', function () {
- before(function () {
- cleanup();
- });
- it(
- 'displays & hides navigation elements for creating a document',
- function () { // eslint-disable-line complexity
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li><button id="newbutton" ' +
- 'type="button" class="hidden">New</button></li><li><a ' +
- 'id="expiration" href="#" class="hidden">Expiration</a>' +
- '</li><li><div id="burnafterreadingoption" class="hidden">' +
- 'Burn after reading</div></li><li><div id="opendiscussion' +
- 'option" class="hidden">Open discussion</div></li><li>' +
- '<div id="password" class="hidden">Password</div></li>' +
- '<li id="attach" class="hidden">Attach a file</li><li>' +
- '<a id="formatter" href="#" class="hidden">Format</a>' +
- '</li><li><button id="sendbutton" type="button" ' +
- 'class="hidden">Create</button></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- query('#sendbutton').classList.contains('hidden') &&
- query('#expiration').classList.contains('hidden') &&
- query('#formatter').classList.contains('hidden') &&
- query('#burnafterreadingoption').classList.contains('hidden') &&
- query('#opendiscussionoption').classList.contains('hidden') &&
- query('#newbutton').classList.contains('hidden') &&
- query('#password').classList.contains('hidden') &&
- query('#attach').classList.contains('hidden')
- );
- PrivateBin.TopNav.showCreateButtons();
- results.push(
- !query('#sendbutton').classList.contains('hidden') &&
- !query('#expiration').classList.contains('hidden') &&
- !query('#formatter').classList.contains('hidden') &&
- !query('#burnafterreadingoption').classList.contains('hidden') &&
- !query('#opendiscussionoption').classList.contains('hidden') &&
- !query('#newbutton').classList.contains('hidden') &&
- !query('#password').classList.contains('hidden') &&
- !query('#attach').classList.contains('hidden')
- );
- PrivateBin.TopNav.hideCreateButtons();
- results.push(
- query('#sendbutton').classList.contains('hidden') &&
- query('#expiration').classList.contains('hidden') &&
- query('#formatter').classList.contains('hidden') &&
- query('#burnafterreadingoption').classList.contains('hidden') &&
- query('#opendiscussionoption').classList.contains('hidden') &&
- query('#newbutton').classList.contains('hidden') &&
- query('#password').classList.contains('hidden') &&
- query('#attach').classList.contains('hidden')
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- it(
- 'tolerates missing optional elements (discussion & password disabled)',
- function () {
- // with discussion = false and password = false in the
- // configuration, the template omits these elements entirely
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li><button id="newbutton" ' +
- 'type="button" class="hidden">New</button></li><li><a ' +
- 'id="expiration" href="#" class="hidden">Expiration</a>' +
- '</li><li><div id="burnafterreadingoption" class="hidden">' +
- 'Burn after reading</div></li><li>' +
- '<a id="formatter" href="#" class="hidden">Format</a>' +
- '</li><li><button id="sendbutton" type="button" ' +
- 'class="hidden">Create</button></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- assert.doesNotThrow(() => PrivateBin.TopNav.showCreateButtons());
- assert.ok(!query('#sendbutton').classList.contains('hidden'));
- assert.ok(!query('#burnafterreadingoption').classList.contains('hidden'));
- assert.doesNotThrow(() => PrivateBin.TopNav.hideCreateButtons());
- assert.ok(query('#sendbutton').classList.contains('hidden'));
- assert.ok(query('#burnafterreadingoption').classList.contains('hidden'));
- cleanup();
- }
- );
- });
- describe('send shortcut', function () {
- let sendCount;
- // builds the create-document navbar and stubs the actual send, so no
- // server interaction happens
- function setUpCreateMode() {
- cleanup();
- sendCount = 0;
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li><button id="newbutton" ' +
- 'type="button" class="hidden">New</button></li><li><a ' +
- 'id="expiration" href="#" class="hidden">Expiration</a>' +
- '</li><li><div id="burnafterreadingoption" class="hidden">' +
- 'Burn after reading</div></li><li><div id="opendiscussion' +
- 'option" class="hidden">Open discussion</div></li><li>' +
- '<div id="password" class="hidden">Password</div></li>' +
- '<li id="attach" class="hidden">Attach a file</li><li>' +
- '<a id="formatter" href="#" class="hidden">Format</a>' +
- '</li><li><button id="sendbutton" type="button" ' +
- 'class="hidden">Create</button></li></ul></div></nav>';
- PrivateBin.PasteEncrypter.sendPaste = function () {
- sendCount++;
- };
- PrivateBin.TopNav.init();
- PrivateBin.TopNav.showCreateButtons();
- }
- // dispatches a keydown on the document, returns whether the default was prevented
- function pressKey(options) {
- const event = new window.KeyboardEvent('keydown', Object.assign(
- {bubbles: true, cancelable: true}, options
- ));
- document.dispatchEvent(event);
- return event.defaultPrevented;
- }
- afterEach(function () {
- cleanup();
- });
- it('sends the document on Ctrl+S and suppresses the browser save dialog', function () {
- setUpCreateMode();
- const prevented = pressKey({key: 's', code: 'KeyS', ctrlKey: true});
- assert.strictEqual(sendCount, 1);
- assert.ok(prevented);
- });
- it('sends the document on Cmd+S (macOS)', function () {
- setUpCreateMode();
- const prevented = pressKey({key: 's', code: 'KeyS', metaKey: true});
- assert.strictEqual(sendCount, 1);
- assert.ok(prevented);
- });
- it('sends on the physical S key of non-Latin keyboard layouts', function () {
- setUpCreateMode();
- // on a Russian layout the S key produces "ы"
- pressKey({key: 'ы', code: 'KeyS', ctrlKey: true});
- assert.strictEqual(sendCount, 1);
- });
- it('leaves Ctrl+S to the browser when viewing a document', function () {
- setUpCreateMode();
- PrivateBin.TopNav.hideCreateButtons();
- const prevented = pressKey({key: 's', code: 'KeyS', ctrlKey: true});
- assert.strictEqual(sendCount, 0);
- assert.ok(!prevented);
- });
- it('ignores S without Ctrl/Cmd, with AltGr (Ctrl+Alt), with Shift, or other keys', function () {
- setUpCreateMode();
- const prevented = [
- pressKey({key: 's', code: 'KeyS'}),
- pressKey({key: 's', code: 'KeyS', ctrlKey: true, altKey: true}),
- pressKey({key: 'S', code: 'KeyS', ctrlKey: true, shiftKey: true}),
- pressKey({key: 'd', code: 'KeyD', ctrlKey: true})
- ];
- assert.strictEqual(sendCount, 0);
- assert.deepStrictEqual(prevented, [false, false, false, false]);
- });
- });
- describe('showNewPasteButton', function () {
- before(function () {
- cleanup();
- });
- it(
- 'displays the button for creating a document',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li><button id="newbutton" type=' +
- '"button" class="hidden">New</button></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- query('#newbutton').classList.contains('hidden')
- );
- PrivateBin.TopNav.showNewPasteButton();
- results.push(
- !query('#newbutton').classList.contains('hidden')
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('hideCloneButton', function () {
- before(function () {
- cleanup();
- });
- it(
- 'hides the button for cloning a document',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li><button id="clonebutton" ' +
- 'type="button" class="btn btn-warning navbar-btn">' +
- '<span class="glyphicon glyphicon-duplicate" aria-hidden=' +
- '"true"></span> Clone</button></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- !query('#clonebutton').classList.contains('hidden')
- );
- PrivateBin.TopNav.hideCloneButton();
- results.push(
- query('#clonebutton').classList.contains('hidden')
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('hideRawButton', function () {
- before(function () {
- cleanup();
- });
- it(
- 'hides the raw text button',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li><button ' +
- 'id="rawtextbutton" type="button" class="btn ' +
- 'btn-warning navbar-btn"><span class="glyphicon ' +
- 'glyphicon-text-background" aria-hidden="true"></span> ' +
- 'Raw text</button></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- !query('#rawtextbutton').classList.contains('hidden')
- );
- PrivateBin.TopNav.hideRawButton();
- results.push(
- query('#rawtextbutton').classList.contains('hidden')
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('hideFileSelector', function () {
- before(function () {
- cleanup();
- });
- it(
- 'hides the file attachment selection button',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
- 'dropdown"><a href="#" class="dropdown-toggle" data-' +
- 'toggle="dropdown" role="button" aria-haspopup="true" ' +
- 'aria-expanded="false">Attach a file <span class="caret">' +
- '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
- '<div><input type="file" id="file" name="file" /></div>' +
- '</li><li id="customattachment" class="hidden"></li><li>' +
- '<a id="fileremovebutton" href="#">Remove attachment</a>' +
- '</li></ul></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- !query('#filewrap').classList.contains('hidden')
- );
- PrivateBin.TopNav.hideFileSelector();
- results.push(
- query('#filewrap').classList.contains('hidden')
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('showCustomAttachment', function () {
- before(function () {
- cleanup();
- });
- it(
- 'display the custom file attachment',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
- 'dropdown"><a href="#" class="dropdown-toggle" data-' +
- 'toggle="dropdown" role="button" aria-haspopup="true" ' +
- 'aria-expanded="false">Attach a file <span class="caret">' +
- '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
- '<div><input type="file" id="file" name="file" /></div>' +
- '</li><li id="customattachment" class="hidden"></li><li>' +
- '<a id="fileremovebutton" href="#">Remove attachment</a>' +
- '</li></ul></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- query('#customattachment').classList.contains('hidden')
- );
- PrivateBin.TopNav.showCustomAttachment();
- results.push(
- !query('#customattachment').classList.contains('hidden')
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('collapseBar', function () {
- before(function () {
- cleanup();
- });
- it(
- 'collapses the navigation when displayed on a small screen',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div class="navbar-header"><button type="button" ' +
- 'class="navbar-toggle collapsed" data-toggle="collapse" ' +
- 'data-target="#navbar" aria-expanded="false" aria-controls' +
- '="navbar">Toggle navigation</button><a class="reloadlink ' +
- 'navbar-brand" href=""><img alt="PrivateBin" ' +
- 'src="img/icon.svg" width="38" /></a></div><div ' +
- 'id="navbar"><ul><li><button id="newbutton" type=' +
- '"button" class="hidden">New</button></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- query('.navbar-toggle').classList.contains('collapsed') &&
- query('#navbar').getAttribute('aria-expanded') !== 'true'
- );
- PrivateBin.TopNav.collapseBar();
- results.push(
- query('.navbar-toggle').classList.contains('collapsed') &&
- query('#navbar').getAttribute('aria-expanded') !== 'true'
- );
- /*
- with the upgrade for bootstrap-3.3.7.js to bootstrap-3.4.1.js
- the mobile interface detection changed to check if the
- ontouchstart event exists, which broke this section of the test
- const toggleBtn = document.querySelector('.navbar-toggle');
- toggleBtn.dispatchEvent(new MouseEvent('click'));
- results.push(
- !toggleBtn.classList.contains('collapsed') &&
- document.getElementById('navbar').getAttribute('aria-expanded') == 'true'
- );
- PrivateBin.TopNav.collapseBar();
- results.push(
- document.querySelector('.navbar-toggle').classList.contains('collapsed') &&
- document.getElementById('navbar').getAttribute('aria-expanded') == 'false'
- );
- */
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('resetInput', function () {
- before(function () {
- cleanup();
- });
- it(
- 'reset inputs to defaults (options off)',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
- 'class="hidden"><label><input type="checkbox" ' +
- 'id="burnafterreading" name="burnafterreading" /> ' +
- 'Burn after reading</label></li><li id="opendiscussionoption" ' +
- 'class="hidden"><label><input type="checkbox" ' +
- 'id="opendiscussion" name="opendiscussion" /> ' +
- 'Open discussion</label></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- !PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- !PrivateBin.TopNav.getOpenDiscussion()
- );
- query('#burnafterreading').checked = true;
- query('#opendiscussion').checked = true;
- results.push(
- PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- PrivateBin.TopNav.getOpenDiscussion()
- );
- PrivateBin.TopNav.resetInput();
- results.push(
- !PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- !PrivateBin.TopNav.getOpenDiscussion()
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- it(
- 'reset inputs to defaults (burnafterreading on)',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
- 'class="hidden"><label><input type="checkbox" ' +
- 'id="burnafterreading" name="burnafterreading" checked="checked" /> ' +
- 'Burn after reading</label></li><li id="opendiscussionoption" ' +
- 'class="hidden"><label><input type="checkbox" ' +
- 'id="opendiscussion" name="opendiscussion" checked="checked" /> ' +
- 'Open discussion</label></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- !PrivateBin.TopNav.getOpenDiscussion()
- );
- query('#burnafterreading').checked = false;
- query('#burnafterreading').removeAttribute('checked');
- results.push(
- !PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- !PrivateBin.TopNav.getOpenDiscussion()
- );
- PrivateBin.TopNav.resetInput();
- results.push(
- PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- !PrivateBin.TopNav.getOpenDiscussion()
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- it(
- 'reset inputs to defaults (opendiscussion on)',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
- 'class="hidden"><label><input type="checkbox" ' +
- 'id="burnafterreading" name="burnafterreading" /> ' +
- 'Burn after reading</label></li><li id="opendiscussionoption" ' +
- 'class="hidden"><label><input type="checkbox" ' +
- 'id="opendiscussion" name="opendiscussion" checked="checked" /> ' +
- 'Open discussion</label></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- !PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- PrivateBin.TopNav.getOpenDiscussion()
- );
- query('#opendiscussion').checked = false;
- query('#opendiscussion').removeAttribute('checked');
- query('#burnafterreading').checked = true;
- query('#burnafterreading').setAttribute('checked', 'checked');
- results.push(
- PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- !PrivateBin.TopNav.getOpenDiscussion()
- );
- PrivateBin.TopNav.resetInput();
- results.push(
- !PrivateBin.TopNav.getBurnAfterReading()
- );
- results.push(
- PrivateBin.TopNav.getOpenDiscussion()
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- it(
- 'tolerates a missing discussion option (discussion disabled)',
- function () {
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
- 'class="buttondisabled"><label><input type="checkbox" ' +
- 'id="burnafterreading" name="burnafterreading" /> ' +
- 'Burn after reading</label></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- assert.doesNotThrow(() => PrivateBin.TopNav.resetInput());
- assert.ok(!query('#burnafterreadingoption').classList.contains('buttondisabled'));
- cleanup();
- }
- );
- });
- describe('getExpiration', function () {
- before(function () {
- cleanup();
- });
- it(
- 'returns the currently selected expiration date',
- function () {
- document.documentElement.innerHTML =
- '<select id="pasteExpiration" name="pasteExpiration">' +
- '<option value="1day">1 day</option>' +
- '<option value="never">Never</option></select>';
- PrivateBin.TopNav.init();
- assert.strictEqual(PrivateBin.TopNav.getExpiration(), '1day');
- cleanup();
- }
- );
- });
- describe('getFileList', function () {
- before(function () {
- cleanup();
- });
- const File = window.File,
- FileList = window.FileList,
- path = require('path'), // eslint-disable-line global-require
- mime = require('mime-types'); // eslint-disable-line global-require
- // mocking file input as per https://github.com/jsdom/jsdom/issues/1272
- function createFile(file_path) {
- const lastModified = fs.statSync(file_path).mtimeMs;
- return new File(
- [new fs.readFileSync(file_path)],
- path.basename(file_path),
- {
- lastModified,
- type: mime.lookup(file_path) || ''
- }
- );
- }
- function addFileList(input, file_paths) {
- if (typeof file_paths === 'string') {
- file_paths = [file_paths];
- } else if (!Array.isArray(file_paths)) {
- throw new Error('file_paths needs to be a file path string or an Array of file path strings');
- }
- const file_list = file_paths.map(fp => createFile(fp));
- Object.setPrototypeOf(file_list, Object.create(FileList.prototype));
- Object.defineProperty(input, 'files', {
- value: file_list,
- writeable: false
- });
- return input;
- }
- it(
- 'returns the selected files',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
- 'dropdown"><a href="#" class="dropdown-toggle" data-' +
- 'toggle="dropdown" role="button" aria-haspopup="true" ' +
- 'aria-expanded="false">Attach a file <span class="caret">' +
- '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
- '<div><input type="file" id="file" name="file" /></div>' +
- '</li><li id="customattachment" class="hidden"></li><li>' +
- '<a id="fileremovebutton" href="#">Remove attachment</a>' +
- '</li></ul></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- PrivateBin.TopNav.getFileList() === null
- );
- addFileList(query('#file'), [
- '../img/logo.svg',
- '../img/busy.gif'
- ]);
- const files = PrivateBin.TopNav.getFileList();
- results.push(
- files[0].name === 'logo.svg' &&
- files[1].name === 'busy.gif'
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('getBurnAfterReading', function () {
- before(function () {
- cleanup();
- });
- it(
- 'returns if the burn-after-reading checkbox was ticked',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
- 'class="hidden"><label><input type="checkbox" ' +
- 'id="burnafterreading" name="burnafterreading" /> ' +
- 'Burn after reading</label></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- !PrivateBin.TopNav.getBurnAfterReading()
- );
- query('#burnafterreading').checked = true;
- results.push(
- PrivateBin.TopNav.getBurnAfterReading()
- );
- query('#burnafterreading').checked = false;
- query('#burnafterreading').removeAttribute('checked');
- results.push(
- !PrivateBin.TopNav.getBurnAfterReading()
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('getOpenDiscussion', function () {
- before(function () {
- cleanup();
- });
- it(
- 'returns if the open-discussion checkbox was ticked',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="opendiscussionoption" ' +
- 'class="hidden"><label><input type="checkbox" ' +
- 'id="opendiscussion" name="opendiscussion" /> ' +
- 'Open discussion</label></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- !PrivateBin.TopNav.getOpenDiscussion()
- );
- query('#opendiscussion').checked = true;
- results.push(
- PrivateBin.TopNav.getOpenDiscussion()
- );
- query('#opendiscussion').checked = false;
- query('#opendiscussion').removeAttribute('checked');
- results.push(
- !PrivateBin.TopNav.getOpenDiscussion()
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('getPassword', function () {
- before(function () {
- globalThis.cleanup();
- });
- it('returns the contents of the password input', () => {
- fc.assert(fc.property(
- fc.string(),
- function (password) {
- password = password.replace(/\r+|\n+/g, '');
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li><div id="password" ' +
- 'class="navbar-form hidden"><input type="password" ' +
- 'id="passwordinput" placeholder="Password (recommended)" ' +
- 'class="form-control" size="23" /></div></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- PrivateBin.TopNav.getPassword() === ''
- );
- query('#passwordinput').value = password;
- results.push(
- PrivateBin.TopNav.getPassword() === password
- );
- query('#passwordinput').value = '';
- results.push(
- PrivateBin.TopNav.getPassword() === ''
- );
- globalThis.cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- return result;
- }
- ));
- });
- });
- describe('getCustomAttachment', function () {
- before(function () {
- cleanup();
- });
- it(
- 'returns the custom attachment element',
- function () {
- let results = [];
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
- 'dropdown"><a href="#" class="dropdown-toggle" data-' +
- 'toggle="dropdown" role="button" aria-haspopup="true" ' +
- 'aria-expanded="false">Attach a file <span class="caret">' +
- '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
- '<div><input type="file" id="file" name="file" /></div>' +
- '</li><li id="customattachment" class="hidden"></li><li>' +
- '<a id="fileremovebutton" href="#">Remove attachment</a>' +
- '</li></ul></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- results.push(
- !PrivateBin.TopNav.getCustomAttachment().classList.contains('test')
- );
- query('#customattachment').classList.add('test');
- results.push(
- PrivateBin.TopNav.getCustomAttachment().classList.contains('test')
- );
- cleanup();
- const result = results.every(element => element);
- if (!result) {
- console.log(results);
- }
- assert.ok(result);
- }
- );
- });
- describe('hideAllButtons', function () {
- before(function () {
- cleanup();
- });
- it(
- 'hides all buttons correctly',
- function () {
- // Insert any setup code needed for the hideAllButtons function
- // Example: Initialize the DOM elements required for testing
- document.body.innerHTML =
- '<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();
- PrivateBin.TopNav.hideAllButtons();
- assert.ok(query('#newbutton').classList.contains('hidden'));
- assert.ok(query('#clonebutton').classList.contains('hidden'));
- assert.ok(query('#rawtextbutton').classList.contains('hidden'));
- assert.ok(query('#qrcodelink').classList.contains('hidden'));
- cleanup();
- }
- );
- });
- describe('showRetryButton & hideRetryButton', function () {
- afterEach(function () {
- delete global.bootstrap;
- cleanup();
- });
- it(
- 'shows and hides the Bootstrap 5 retry button with its list item and runs the callback once',
- function () {
- cleanup();
- global.bootstrap = {};
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul class="navbar-nav">' +
- '<li class="nav-item hidden"><button id="retrybutton" ' +
- 'type="button" class="hidden">Retry</button></li>' +
- '<li><button id="newbutton" type="button">New</button>' +
- '</li></ul></div></nav>';
- PrivateBin.TopNav.init();
- let calls = 0;
- PrivateBin.TopNav.setRetryCallback(function () {
- calls++;
- });
- const retryItem = query('#retrybutton').parentElement;
- assert.ok(query('#retrybutton').classList.contains('hidden'));
- assert.ok(retryItem.classList.contains('hidden'));
- PrivateBin.TopNav.showRetryButton();
- assert.ok(!query('#retrybutton').classList.contains('hidden'));
- assert.ok(!retryItem.classList.contains('hidden'));
- query('#retrybutton').click();
- assert.strictEqual(calls, 1);
- PrivateBin.TopNav.hideRetryButton();
- assert.ok(query('#retrybutton').classList.contains('hidden'));
- assert.ok(retryItem.classList.contains('hidden'));
- PrivateBin.TopNav.showRetryButton();
- PrivateBin.TopNav.hideRetryButton();
- assert.ok(query('#retrybutton').classList.contains('hidden'));
- assert.ok(retryItem.classList.contains('hidden'));
- assert.ok(!query('#newbutton').classList.contains('hidden'));
- assert.strictEqual(calls, 1);
- }
- );
- it(
- 'toggles only the retry button on legacy Bootstrap 3 and page templates',
- function () {
- cleanup();
- delete global.bootstrap;
- document.documentElement.innerHTML =
- '<nav><div id="navbar"><ul class="nav navbar-nav"><li>' +
- '<button id="retrybutton" type="button" class="hidden">' +
- 'Retry</button><button id="newbutton" type="button">' +
- 'New</button></li></ul></div></nav>';
- PrivateBin.TopNav.init();
- let calls = 0;
- PrivateBin.TopNav.setRetryCallback(function () {
- calls++;
- });
- const retryItem = query('#retrybutton').parentElement;
- assert.ok(query('#retrybutton').classList.contains('hidden'));
- assert.ok(!retryItem.classList.contains('hidden'));
- PrivateBin.TopNav.showRetryButton();
- assert.ok(!query('#retrybutton').classList.contains('hidden'));
- assert.ok(!retryItem.classList.contains('hidden'));
- assert.ok(!query('#newbutton').classList.contains('hidden'));
- query('#retrybutton').click();
- assert.strictEqual(calls, 1);
- PrivateBin.TopNav.hideRetryButton();
- assert.ok(query('#retrybutton').classList.contains('hidden'));
- assert.ok(!retryItem.classList.contains('hidden'));
- assert.ok(!query('#newbutton').classList.contains('hidden'));
- PrivateBin.TopNav.showRetryButton();
- PrivateBin.TopNav.hideRetryButton();
- assert.ok(query('#retrybutton').classList.contains('hidden'));
- assert.strictEqual(calls, 1);
- }
- );
- });
- describe('rawText', function () {
- before(function () {
- cleanup();
- });
- // TODO triggers error messages in jsDOM since version 12, but passes
- it(
- 'displays raw text view correctly',
- function () {
- const clean = globalThis.cleanup('', {url: 'https://privatebin.net/?0123456789abcdef#1'});
- document.documentElement.innerHTML = `
- <li id="loadingindicator" class="hidden"></li>
- <button id="rawtextbutton"></button>`;
- const sample = 'example';
- PrivateBin.Alert.init(); // required because of locading indiator being used
- PrivateBin.TopNav.init();
- PrivateBin.PasteViewer.setText(sample);
- PrivateBin.Helper.reset();
- query('#rawtextbutton').click();
- assert.strictEqual(document.querySelector('pre').textContent, sample);
- clean();
- }
- );
- });
- });
|