'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('showViewButtons & hideViewButtons', function () { before(function () { cleanup(); }); it( 'displays & hides navigation elements for viewing an existing document', function () { let results = []; document.documentElement.innerHTML = ``; 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 = ''; 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); } ); }); describe('showNewPasteButton', function () { before(function () { cleanup(); }); it( 'displays the button for creating a document', function () { let results = []; document.documentElement.innerHTML = ''; 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 = ''; 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 = ''; 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 = ''; 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 = ''; 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 = ''; 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 = ''; 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 = ''; 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 = ''; 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); } ); }); describe('getExpiration', function () { before(function () { cleanup(); }); it( 'returns the currently selected expiration date', function () { document.documentElement.innerHTML = ''; 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 = ''; 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 = ''; 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 = ''; 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 = ''; 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 = ''; 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 = ''; 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('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 = ` `; 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(); } ); }); });