TopNav.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. 'use strict';
  2. require('../common');
  3. function query(selector) {
  4. if (selector.startsWith('#')) {
  5. return document.getElementById(selector.slice(1));
  6. }
  7. return document.querySelector(selector);
  8. }
  9. describe('TopNav', function () {
  10. describe('showViewButtons & hideViewButtons', function () {
  11. before(function () {
  12. cleanup();
  13. });
  14. it(
  15. 'displays & hides navigation elements for viewing an existing document',
  16. function () {
  17. let results = [];
  18. document.documentElement.innerHTML =
  19. `<nav class="navbar navbar-inverse navbar-static-top">
  20. <div id="navbar" class="navbar-collapse collapse">
  21. <ul class="nav navbar-nav"><li><button id="newbutton" type="button" class="hidden btn btn-warning navbar-btn">
  22. <span class="glyphicon glyphicon-file" aria-hidden="true">
  23. </span> New</button><button id="clonebutton" type="button" class="hidden btn btn-warning navbar-btn">
  24. <span class="glyphicon glyphicon-duplicate" aria-hidden="true"></span> Clone</button>
  25. <button id="rawtextbutton" type="button" class="hidden btn btn-warning navbar-btn">
  26. <span class="glyphicon glyphicon-text-background" aria-hidden="true"></span> Raw text</button>
  27. <button id="downloadtextbutton" type="button" class="hidden btn btn-<?php echo $isDark ? 'warning' : 'default'; ?> navbar-btn"></button>
  28. <button id="qrcodelink" type="button" data-toggle="modal" data-target="#qrcodemodal" class="hidden btn btn-warning navbar-btn"/>
  29. <span class="glyphicon glyphicon-qrcode" aria-hidden="true"></span> QR code</button></li></ul></div>
  30. </nav>`;
  31. PrivateBin.TopNav.init();
  32. results.push(
  33. query('#newbutton').classList.contains('hidden') &&
  34. query('#clonebutton').classList.contains('hidden') &&
  35. query('#rawtextbutton').classList.contains('hidden') &&
  36. query('#qrcodelink').classList.contains('hidden')
  37. );
  38. PrivateBin.TopNav.showViewButtons();
  39. results.push(
  40. !query('#newbutton').classList.contains('hidden') &&
  41. !query('#clonebutton').classList.contains('hidden') &&
  42. !query('#rawtextbutton').classList.contains('hidden') &&
  43. !query('#qrcodelink').classList.contains('hidden')
  44. );
  45. PrivateBin.TopNav.hideViewButtons();
  46. results.push(
  47. query('#newbutton').classList.contains('hidden') &&
  48. query('#clonebutton').classList.contains('hidden') &&
  49. query('#rawtextbutton').classList.contains('hidden') &&
  50. query('#qrcodelink').classList.contains('hidden')
  51. );
  52. cleanup();
  53. const result = results.every(element => element);
  54. if (!result) {
  55. console.log(results);
  56. }
  57. assert.ok(result);
  58. }
  59. );
  60. });
  61. describe('showCreateButtons & hideCreateButtons', function () {
  62. before(function () {
  63. cleanup();
  64. });
  65. it(
  66. 'displays & hides navigation elements for creating a document',
  67. function () { // eslint-disable-line complexity
  68. let results = [];
  69. document.documentElement.innerHTML =
  70. '<nav><div id="navbar"><ul><li><button id="newbutton" ' +
  71. 'type="button" class="hidden">New</button></li><li><a ' +
  72. 'id="expiration" href="#" class="hidden">Expiration</a>' +
  73. '</li><li><div id="burnafterreadingoption" class="hidden">' +
  74. 'Burn after reading</div></li><li><div id="opendiscussion' +
  75. 'option" class="hidden">Open discussion</div></li><li>' +
  76. '<div id="password" class="hidden">Password</div></li>' +
  77. '<li id="attach" class="hidden">Attach a file</li><li>' +
  78. '<a id="formatter" href="#" class="hidden">Format</a>' +
  79. '</li><li><button id="sendbutton" type="button" ' +
  80. 'class="hidden">Create</button></li></ul></div></nav>';
  81. PrivateBin.TopNav.init();
  82. results.push(
  83. query('#sendbutton').classList.contains('hidden') &&
  84. query('#expiration').classList.contains('hidden') &&
  85. query('#formatter').classList.contains('hidden') &&
  86. query('#burnafterreadingoption').classList.contains('hidden') &&
  87. query('#opendiscussionoption').classList.contains('hidden') &&
  88. query('#newbutton').classList.contains('hidden') &&
  89. query('#password').classList.contains('hidden') &&
  90. query('#attach').classList.contains('hidden')
  91. );
  92. PrivateBin.TopNav.showCreateButtons();
  93. results.push(
  94. !query('#sendbutton').classList.contains('hidden') &&
  95. !query('#expiration').classList.contains('hidden') &&
  96. !query('#formatter').classList.contains('hidden') &&
  97. !query('#burnafterreadingoption').classList.contains('hidden') &&
  98. !query('#opendiscussionoption').classList.contains('hidden') &&
  99. !query('#newbutton').classList.contains('hidden') &&
  100. !query('#password').classList.contains('hidden') &&
  101. !query('#attach').classList.contains('hidden')
  102. );
  103. PrivateBin.TopNav.hideCreateButtons();
  104. results.push(
  105. query('#sendbutton').classList.contains('hidden') &&
  106. query('#expiration').classList.contains('hidden') &&
  107. query('#formatter').classList.contains('hidden') &&
  108. query('#burnafterreadingoption').classList.contains('hidden') &&
  109. query('#opendiscussionoption').classList.contains('hidden') &&
  110. query('#newbutton').classList.contains('hidden') &&
  111. query('#password').classList.contains('hidden') &&
  112. query('#attach').classList.contains('hidden')
  113. );
  114. cleanup();
  115. const result = results.every(element => element);
  116. if (!result) {
  117. console.log(results);
  118. }
  119. assert.ok(result);
  120. }
  121. );
  122. });
  123. describe('showNewPasteButton', function () {
  124. before(function () {
  125. cleanup();
  126. });
  127. it(
  128. 'displays the button for creating a document',
  129. function () {
  130. let results = [];
  131. document.documentElement.innerHTML =
  132. '<nav><div id="navbar"><ul><li><button id="newbutton" type=' +
  133. '"button" class="hidden">New</button></li></ul></div></nav>';
  134. PrivateBin.TopNav.init();
  135. results.push(
  136. query('#newbutton').classList.contains('hidden')
  137. );
  138. PrivateBin.TopNav.showNewPasteButton();
  139. results.push(
  140. !query('#newbutton').classList.contains('hidden')
  141. );
  142. cleanup();
  143. const result = results.every(element => element);
  144. if (!result) {
  145. console.log(results);
  146. }
  147. assert.ok(result);
  148. }
  149. );
  150. });
  151. describe('hideCloneButton', function () {
  152. before(function () {
  153. cleanup();
  154. });
  155. it(
  156. 'hides the button for cloning a document',
  157. function () {
  158. let results = [];
  159. document.documentElement.innerHTML =
  160. '<nav><div id="navbar"><ul><li><button id="clonebutton" ' +
  161. 'type="button" class="btn btn-warning navbar-btn">' +
  162. '<span class="glyphicon glyphicon-duplicate" aria-hidden=' +
  163. '"true"></span> Clone</button></li></ul></div></nav>';
  164. PrivateBin.TopNav.init();
  165. results.push(
  166. !query('#clonebutton').classList.contains('hidden')
  167. );
  168. PrivateBin.TopNav.hideCloneButton();
  169. results.push(
  170. query('#clonebutton').classList.contains('hidden')
  171. );
  172. cleanup();
  173. const result = results.every(element => element);
  174. if (!result) {
  175. console.log(results);
  176. }
  177. assert.ok(result);
  178. }
  179. );
  180. });
  181. describe('hideRawButton', function () {
  182. before(function () {
  183. cleanup();
  184. });
  185. it(
  186. 'hides the raw text button',
  187. function () {
  188. let results = [];
  189. document.documentElement.innerHTML =
  190. '<nav><div id="navbar"><ul><li><button ' +
  191. 'id="rawtextbutton" type="button" class="btn ' +
  192. 'btn-warning navbar-btn"><span class="glyphicon ' +
  193. 'glyphicon-text-background" aria-hidden="true"></span> ' +
  194. 'Raw text</button></li></ul></div></nav>';
  195. PrivateBin.TopNav.init();
  196. results.push(
  197. !query('#rawtextbutton').classList.contains('hidden')
  198. );
  199. PrivateBin.TopNav.hideRawButton();
  200. results.push(
  201. query('#rawtextbutton').classList.contains('hidden')
  202. );
  203. cleanup();
  204. const result = results.every(element => element);
  205. if (!result) {
  206. console.log(results);
  207. }
  208. assert.ok(result);
  209. }
  210. );
  211. });
  212. describe('hideFileSelector', function () {
  213. before(function () {
  214. cleanup();
  215. });
  216. it(
  217. 'hides the file attachment selection button',
  218. function () {
  219. let results = [];
  220. document.documentElement.innerHTML =
  221. '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
  222. 'dropdown"><a href="#" class="dropdown-toggle" data-' +
  223. 'toggle="dropdown" role="button" aria-haspopup="true" ' +
  224. 'aria-expanded="false">Attach a file <span class="caret">' +
  225. '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
  226. '<div><input type="file" id="file" name="file" /></div>' +
  227. '</li><li id="customattachment" class="hidden"></li><li>' +
  228. '<a id="fileremovebutton" href="#">Remove attachment</a>' +
  229. '</li></ul></li></ul></div></nav>';
  230. PrivateBin.TopNav.init();
  231. results.push(
  232. !query('#filewrap').classList.contains('hidden')
  233. );
  234. PrivateBin.TopNav.hideFileSelector();
  235. results.push(
  236. query('#filewrap').classList.contains('hidden')
  237. );
  238. cleanup();
  239. const result = results.every(element => element);
  240. if (!result) {
  241. console.log(results);
  242. }
  243. assert.ok(result);
  244. }
  245. );
  246. });
  247. describe('showCustomAttachment', function () {
  248. before(function () {
  249. cleanup();
  250. });
  251. it(
  252. 'display the custom file attachment',
  253. function () {
  254. let results = [];
  255. document.documentElement.innerHTML =
  256. '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
  257. 'dropdown"><a href="#" class="dropdown-toggle" data-' +
  258. 'toggle="dropdown" role="button" aria-haspopup="true" ' +
  259. 'aria-expanded="false">Attach a file <span class="caret">' +
  260. '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
  261. '<div><input type="file" id="file" name="file" /></div>' +
  262. '</li><li id="customattachment" class="hidden"></li><li>' +
  263. '<a id="fileremovebutton" href="#">Remove attachment</a>' +
  264. '</li></ul></li></ul></div></nav>';
  265. PrivateBin.TopNav.init();
  266. results.push(
  267. query('#customattachment').classList.contains('hidden')
  268. );
  269. PrivateBin.TopNav.showCustomAttachment();
  270. results.push(
  271. !query('#customattachment').classList.contains('hidden')
  272. );
  273. cleanup();
  274. const result = results.every(element => element);
  275. if (!result) {
  276. console.log(results);
  277. }
  278. assert.ok(result);
  279. }
  280. );
  281. });
  282. describe('collapseBar', function () {
  283. before(function () {
  284. cleanup();
  285. });
  286. it(
  287. 'collapses the navigation when displayed on a small screen',
  288. function () {
  289. let results = [];
  290. document.documentElement.innerHTML =
  291. '<nav><div class="navbar-header"><button type="button" ' +
  292. 'class="navbar-toggle collapsed" data-toggle="collapse" ' +
  293. 'data-target="#navbar" aria-expanded="false" aria-controls' +
  294. '="navbar">Toggle navigation</button><a class="reloadlink ' +
  295. 'navbar-brand" href=""><img alt="PrivateBin" ' +
  296. 'src="img/icon.svg" width="38" /></a></div><div ' +
  297. 'id="navbar"><ul><li><button id="newbutton" type=' +
  298. '"button" class="hidden">New</button></li></ul></div></nav>';
  299. PrivateBin.TopNav.init();
  300. results.push(
  301. query('.navbar-toggle').classList.contains('collapsed') &&
  302. query('#navbar').getAttribute('aria-expanded') !== 'true'
  303. );
  304. PrivateBin.TopNav.collapseBar();
  305. results.push(
  306. query('.navbar-toggle').classList.contains('collapsed') &&
  307. query('#navbar').getAttribute('aria-expanded') !== 'true'
  308. );
  309. /*
  310. with the upgrade for bootstrap-3.3.7.js to bootstrap-3.4.1.js
  311. the mobile interface detection changed to check if the
  312. ontouchstart event exists, which broke this section of the test
  313. const toggleBtn = document.querySelector('.navbar-toggle');
  314. toggleBtn.dispatchEvent(new MouseEvent('click'));
  315. results.push(
  316. !toggleBtn.classList.contains('collapsed') &&
  317. document.getElementById('navbar').getAttribute('aria-expanded') == 'true'
  318. );
  319. PrivateBin.TopNav.collapseBar();
  320. results.push(
  321. document.querySelector('.navbar-toggle').classList.contains('collapsed') &&
  322. document.getElementById('navbar').getAttribute('aria-expanded') == 'false'
  323. );
  324. */
  325. const result = results.every(element => element);
  326. if (!result) {
  327. console.log(results);
  328. }
  329. assert.ok(result);
  330. }
  331. );
  332. });
  333. describe('resetInput', function () {
  334. before(function () {
  335. cleanup();
  336. });
  337. it(
  338. 'reset inputs to defaults (options off)',
  339. function () {
  340. let results = [];
  341. document.documentElement.innerHTML =
  342. '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
  343. 'class="hidden"><label><input type="checkbox" ' +
  344. 'id="burnafterreading" name="burnafterreading" /> ' +
  345. 'Burn after reading</label></li><li id="opendiscussionoption" ' +
  346. 'class="hidden"><label><input type="checkbox" ' +
  347. 'id="opendiscussion" name="opendiscussion" /> ' +
  348. 'Open discussion</label></li></ul></div></nav>';
  349. PrivateBin.TopNav.init();
  350. results.push(
  351. !PrivateBin.TopNav.getBurnAfterReading()
  352. );
  353. results.push(
  354. !PrivateBin.TopNav.getOpenDiscussion()
  355. );
  356. query('#burnafterreading').checked = true;
  357. query('#opendiscussion').checked = true;
  358. results.push(
  359. PrivateBin.TopNav.getBurnAfterReading()
  360. );
  361. results.push(
  362. PrivateBin.TopNav.getOpenDiscussion()
  363. );
  364. PrivateBin.TopNav.resetInput();
  365. results.push(
  366. !PrivateBin.TopNav.getBurnAfterReading()
  367. );
  368. results.push(
  369. !PrivateBin.TopNav.getOpenDiscussion()
  370. );
  371. cleanup();
  372. const result = results.every(element => element);
  373. if (!result) {
  374. console.log(results);
  375. }
  376. assert.ok(result);
  377. }
  378. );
  379. it(
  380. 'reset inputs to defaults (burnafterreading on)',
  381. function () {
  382. let results = [];
  383. document.documentElement.innerHTML =
  384. '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
  385. 'class="hidden"><label><input type="checkbox" ' +
  386. 'id="burnafterreading" name="burnafterreading" checked="checked" /> ' +
  387. 'Burn after reading</label></li><li id="opendiscussionoption" ' +
  388. 'class="hidden"><label><input type="checkbox" ' +
  389. 'id="opendiscussion" name="opendiscussion" checked="checked" /> ' +
  390. 'Open discussion</label></li></ul></div></nav>';
  391. PrivateBin.TopNav.init();
  392. results.push(
  393. PrivateBin.TopNav.getBurnAfterReading()
  394. );
  395. results.push(
  396. !PrivateBin.TopNav.getOpenDiscussion()
  397. );
  398. query('#burnafterreading').checked = false;
  399. query('#burnafterreading').removeAttribute('checked');
  400. results.push(
  401. !PrivateBin.TopNav.getBurnAfterReading()
  402. );
  403. results.push(
  404. !PrivateBin.TopNav.getOpenDiscussion()
  405. );
  406. PrivateBin.TopNav.resetInput();
  407. results.push(
  408. PrivateBin.TopNav.getBurnAfterReading()
  409. );
  410. results.push(
  411. !PrivateBin.TopNav.getOpenDiscussion()
  412. );
  413. cleanup();
  414. const result = results.every(element => element);
  415. if (!result) {
  416. console.log(results);
  417. }
  418. assert.ok(result);
  419. }
  420. );
  421. it(
  422. 'reset inputs to defaults (opendiscussion on)',
  423. function () {
  424. let results = [];
  425. document.documentElement.innerHTML =
  426. '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
  427. 'class="hidden"><label><input type="checkbox" ' +
  428. 'id="burnafterreading" name="burnafterreading" /> ' +
  429. 'Burn after reading</label></li><li id="opendiscussionoption" ' +
  430. 'class="hidden"><label><input type="checkbox" ' +
  431. 'id="opendiscussion" name="opendiscussion" checked="checked" /> ' +
  432. 'Open discussion</label></li></ul></div></nav>';
  433. PrivateBin.TopNav.init();
  434. results.push(
  435. !PrivateBin.TopNav.getBurnAfterReading()
  436. );
  437. results.push(
  438. PrivateBin.TopNav.getOpenDiscussion()
  439. );
  440. query('#opendiscussion').checked = false;
  441. query('#opendiscussion').removeAttribute('checked');
  442. query('#burnafterreading').checked = true;
  443. query('#burnafterreading').setAttribute('checked', 'checked');
  444. results.push(
  445. PrivateBin.TopNav.getBurnAfterReading()
  446. );
  447. results.push(
  448. !PrivateBin.TopNav.getOpenDiscussion()
  449. );
  450. PrivateBin.TopNav.resetInput();
  451. results.push(
  452. !PrivateBin.TopNav.getBurnAfterReading()
  453. );
  454. results.push(
  455. PrivateBin.TopNav.getOpenDiscussion()
  456. );
  457. cleanup();
  458. const result = results.every(element => element);
  459. if (!result) {
  460. console.log(results);
  461. }
  462. assert.ok(result);
  463. }
  464. );
  465. });
  466. describe('getExpiration', function () {
  467. before(function () {
  468. cleanup();
  469. });
  470. it(
  471. 'returns the currently selected expiration date',
  472. function () {
  473. document.documentElement.innerHTML =
  474. '<select id="pasteExpiration" name="pasteExpiration">' +
  475. '<option value="1day">1 day</option>' +
  476. '<option value="never">Never</option></select>';
  477. PrivateBin.TopNav.init();
  478. assert.strictEqual(PrivateBin.TopNav.getExpiration(), '1day');
  479. cleanup();
  480. }
  481. );
  482. });
  483. describe('getFileList', function () {
  484. before(function () {
  485. cleanup();
  486. });
  487. const File = window.File,
  488. FileList = window.FileList,
  489. path = require('path'), // eslint-disable-line global-require
  490. mime = require('mime-types'); // eslint-disable-line global-require
  491. // mocking file input as per https://github.com/jsdom/jsdom/issues/1272
  492. function createFile(file_path) {
  493. const lastModified = fs.statSync(file_path).mtimeMs;
  494. return new File(
  495. [new fs.readFileSync(file_path)],
  496. path.basename(file_path),
  497. {
  498. lastModified,
  499. type: mime.lookup(file_path) || ''
  500. }
  501. );
  502. }
  503. function addFileList(input, file_paths) {
  504. if (typeof file_paths === 'string') {
  505. file_paths = [file_paths];
  506. } else if (!Array.isArray(file_paths)) {
  507. throw new Error('file_paths needs to be a file path string or an Array of file path strings');
  508. }
  509. const file_list = file_paths.map(fp => createFile(fp));
  510. Object.setPrototypeOf(file_list, Object.create(FileList.prototype));
  511. Object.defineProperty(input, 'files', {
  512. value: file_list,
  513. writeable: false
  514. });
  515. return input;
  516. }
  517. it(
  518. 'returns the selected files',
  519. function () {
  520. let results = [];
  521. document.documentElement.innerHTML =
  522. '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
  523. 'dropdown"><a href="#" class="dropdown-toggle" data-' +
  524. 'toggle="dropdown" role="button" aria-haspopup="true" ' +
  525. 'aria-expanded="false">Attach a file <span class="caret">' +
  526. '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
  527. '<div><input type="file" id="file" name="file" /></div>' +
  528. '</li><li id="customattachment" class="hidden"></li><li>' +
  529. '<a id="fileremovebutton" href="#">Remove attachment</a>' +
  530. '</li></ul></li></ul></div></nav>';
  531. PrivateBin.TopNav.init();
  532. results.push(
  533. PrivateBin.TopNav.getFileList() === null
  534. );
  535. addFileList(query('#file'), [
  536. '../img/logo.svg',
  537. '../img/busy.gif'
  538. ]);
  539. const files = PrivateBin.TopNav.getFileList();
  540. results.push(
  541. files[0].name === 'logo.svg' &&
  542. files[1].name === 'busy.gif'
  543. );
  544. cleanup();
  545. const result = results.every(element => element);
  546. if (!result) {
  547. console.log(results);
  548. }
  549. assert.ok(result);
  550. }
  551. );
  552. });
  553. describe('getBurnAfterReading', function () {
  554. before(function () {
  555. cleanup();
  556. });
  557. it(
  558. 'returns if the burn-after-reading checkbox was ticked',
  559. function () {
  560. let results = [];
  561. document.documentElement.innerHTML =
  562. '<nav><div id="navbar"><ul><li id="burnafterreadingoption" ' +
  563. 'class="hidden"><label><input type="checkbox" ' +
  564. 'id="burnafterreading" name="burnafterreading" /> ' +
  565. 'Burn after reading</label></li></ul></div></nav>';
  566. PrivateBin.TopNav.init();
  567. results.push(
  568. !PrivateBin.TopNav.getBurnAfterReading()
  569. );
  570. query('#burnafterreading').checked = true;
  571. results.push(
  572. PrivateBin.TopNav.getBurnAfterReading()
  573. );
  574. query('#burnafterreading').checked = false;
  575. query('#burnafterreading').removeAttribute('checked');
  576. results.push(
  577. !PrivateBin.TopNav.getBurnAfterReading()
  578. );
  579. cleanup();
  580. const result = results.every(element => element);
  581. if (!result) {
  582. console.log(results);
  583. }
  584. assert.ok(result);
  585. }
  586. );
  587. });
  588. describe('getOpenDiscussion', function () {
  589. before(function () {
  590. cleanup();
  591. });
  592. it(
  593. 'returns if the open-discussion checkbox was ticked',
  594. function () {
  595. let results = [];
  596. document.documentElement.innerHTML =
  597. '<nav><div id="navbar"><ul><li id="opendiscussionoption" ' +
  598. 'class="hidden"><label><input type="checkbox" ' +
  599. 'id="opendiscussion" name="opendiscussion" /> ' +
  600. 'Open discussion</label></li></ul></div></nav>';
  601. PrivateBin.TopNav.init();
  602. results.push(
  603. !PrivateBin.TopNav.getOpenDiscussion()
  604. );
  605. query('#opendiscussion').checked = true;
  606. results.push(
  607. PrivateBin.TopNav.getOpenDiscussion()
  608. );
  609. query('#opendiscussion').checked = false;
  610. query('#opendiscussion').removeAttribute('checked');
  611. results.push(
  612. !PrivateBin.TopNav.getOpenDiscussion()
  613. );
  614. cleanup();
  615. const result = results.every(element => element);
  616. if (!result) {
  617. console.log(results);
  618. }
  619. assert.ok(result);
  620. }
  621. );
  622. });
  623. describe('getPassword', function () {
  624. before(function () {
  625. cleanup();
  626. });
  627. jsc.property(
  628. 'returns the contents of the password input',
  629. 'string',
  630. function (password) {
  631. password = password.replace(/\r+|\n+/g, '');
  632. let results = [];
  633. document.documentElement.innerHTML =
  634. '<nav><div id="navbar"><ul><li><div id="password" ' +
  635. 'class="navbar-form hidden"><input type="password" ' +
  636. 'id="passwordinput" placeholder="Password (recommended)" ' +
  637. 'class="form-control" size="23" /></div></li></ul></div></nav>';
  638. PrivateBin.TopNav.init();
  639. results.push(
  640. PrivateBin.TopNav.getPassword() === ''
  641. );
  642. query('#passwordinput').value = password;
  643. results.push(
  644. PrivateBin.TopNav.getPassword() === password
  645. );
  646. query('#passwordinput').value = '';
  647. results.push(
  648. PrivateBin.TopNav.getPassword() === ''
  649. );
  650. cleanup();
  651. const result = results.every(element => element);
  652. if (!result) {
  653. console.log(results);
  654. }
  655. return result;
  656. }
  657. );
  658. });
  659. describe('getCustomAttachment', function () {
  660. before(function () {
  661. cleanup();
  662. });
  663. it(
  664. 'returns the custom attachment element',
  665. function () {
  666. let results = [];
  667. document.documentElement.innerHTML =
  668. '<nav><div id="navbar"><ul><li id="attach" class="hidden ' +
  669. 'dropdown"><a href="#" class="dropdown-toggle" data-' +
  670. 'toggle="dropdown" role="button" aria-haspopup="true" ' +
  671. 'aria-expanded="false">Attach a file <span class="caret">' +
  672. '</span></a><ul class="dropdown-menu"><li id="filewrap">' +
  673. '<div><input type="file" id="file" name="file" /></div>' +
  674. '</li><li id="customattachment" class="hidden"></li><li>' +
  675. '<a id="fileremovebutton" href="#">Remove attachment</a>' +
  676. '</li></ul></li></ul></div></nav>';
  677. PrivateBin.TopNav.init();
  678. results.push(
  679. !PrivateBin.TopNav.getCustomAttachment().classList.contains('test')
  680. );
  681. query('#customattachment').classList.add('test');
  682. results.push(
  683. PrivateBin.TopNav.getCustomAttachment().classList.contains('test')
  684. );
  685. cleanup();
  686. const result = results.every(element => element);
  687. if (!result) {
  688. console.log(results);
  689. }
  690. assert.ok(result);
  691. }
  692. );
  693. });
  694. describe('hideAllButtons', function () {
  695. before(function () {
  696. cleanup();
  697. });
  698. it(
  699. 'hides all buttons correctly',
  700. function () {
  701. // Insert any setup code needed for the hideAllButtons function
  702. // Example: Initialize the DOM elements required for testing
  703. document.body.innerHTML =
  704. '<nav class="navbar navbar-inverse navbar-static-top">' +
  705. '<div id="navbar" class="navbar-collapse collapse"><ul ' +
  706. 'class="nav navbar-nav"><li><button id="newbutton" ' +
  707. 'type="button" class="hidden btn btn-warning navbar-btn">' +
  708. '<span class="glyphicon glyphicon-file" aria-hidden="true">' +
  709. '</span> New</button><button id="clonebutton" type="button"' +
  710. ' class="hidden btn btn-warning navbar-btn">' +
  711. '<span class="glyphicon glyphicon-duplicate" ' +
  712. 'aria-hidden="true"></span> Clone</button><button ' +
  713. 'id="rawtextbutton" type="button" class="hidden btn ' +
  714. 'btn-warning navbar-btn"><span class="glyphicon ' +
  715. 'glyphicon-text-background" aria-hidden="true"></span> ' +
  716. 'Raw text</button><button id="qrcodelink" type="button" ' +
  717. 'data-toggle="modal" data-target="#qrcodemodal" ' +
  718. 'class="hidden btn btn-warning navbar-btn"><span ' +
  719. 'class="glyphicon glyphicon-qrcode" aria-hidden="true">' +
  720. '</span> QR code</button></li></ul></div></nav>';
  721. PrivateBin.TopNav.init();
  722. PrivateBin.TopNav.hideAllButtons();
  723. assert.ok(query('#newbutton').classList.contains('hidden'));
  724. assert.ok(query('#clonebutton').classList.contains('hidden'));
  725. assert.ok(query('#rawtextbutton').classList.contains('hidden'));
  726. assert.ok(query('#qrcodelink').classList.contains('hidden'));
  727. cleanup();
  728. }
  729. );
  730. });
  731. describe('rawText', function () {
  732. before(function () {
  733. cleanup();
  734. });
  735. // TODO triggers error messages in jsDOM since version 12, but passes
  736. it(
  737. 'displays raw text view correctly',
  738. function () {
  739. const clean = globalThis.cleanup('', {url: 'https://privatebin.net/?0123456789abcdef#1'});
  740. document.documentElement.innerHTML = `
  741. <li id="loadingindicator" class="hidden"></li>
  742. <button id="rawtextbutton"></button>`;
  743. const sample = 'example';
  744. PrivateBin.Alert.init(); // required because of locading indiator being used
  745. PrivateBin.TopNav.init();
  746. PrivateBin.PasteViewer.setText(sample);
  747. PrivateBin.Helper.reset();
  748. query('#rawtextbutton').click();
  749. assert.strictEqual(document.querySelector('pre').textContent, sample);
  750. clean();
  751. }
  752. );
  753. });
  754. });