PasteStatus.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. 'use strict';
  2. var common = require('../common');
  3. function urlStrings(schema, longUrl, shortUrl) {
  4. longUrl.schema = schema;
  5. shortUrl.schema = schema;
  6. let longUrlString = common.urlToString(longUrl),
  7. shortUrlString = common.urlToString(shortUrl);
  8. // ensure the two random URLs actually are sorted as expected
  9. if (longUrlString.length <= shortUrlString.length) {
  10. if (longUrlString.length === shortUrlString.length) {
  11. longUrl.address.unshift('a');
  12. longUrlString = common.urlToString(longUrl);
  13. } else {
  14. [longUrlString, shortUrlString] = [shortUrlString, longUrlString];
  15. }
  16. }
  17. return [longUrlString, shortUrlString];
  18. }
  19. describe('PasteStatus', function () {
  20. describe('createPasteNotification', function () {
  21. this.timeout(30000);
  22. it('creates a notification after a successful document upload', function () {
  23. cleanup();
  24. document.body.innerHTML = '<a href="#" id="deletelink"><span></span></a><div id="pastelink"></div><div id="pastesuccess"></div>';
  25. PrivateBin.PasteStatus.init();
  26. const expected1 = 'https://example.com/long';
  27. const expected2 = 'https://example.com/short';
  28. PrivateBin.PasteStatus.createPasteNotification(expected1, expected2);
  29. assert.strictEqual(document.getElementById('pasteurl').href, expected1);
  30. assert.strictEqual(document.getElementById('deletelink').href, expected2);
  31. assert.ok(!document.getElementById('pastesuccess').classList.contains('hidden'));
  32. });
  33. jsc.property(
  34. 'creates a notification after a successful document upload (jsc)',
  35. common.jscUrl(),
  36. common.jscUrl(false),
  37. function (url1, url2) {
  38. // sometimes the generator returns incomplete objects, bail out
  39. if (!url1 || !url1.address || !url2 || !url2.address) {
  40. return true;
  41. }
  42. const expected1 = common.urlToString(url1).replace(/&(gt|lt)$/, '&$1a'),
  43. expected2 = common.urlToString(url2).replace(/&(gt|lt)$/, '&$1a');
  44. cleanup();
  45. document.body.innerHTML = '<a href="#" id="deletelink"><span></span></a><div id="pastelink"></div><div id="pastesuccess"></div>';
  46. PrivateBin.PasteStatus.init();
  47. PrivateBin.PasteStatus.createPasteNotification(expected1, expected2);
  48. assert.ok(!document.getElementById('pastesuccess').classList.contains('hidden'));
  49. const result2 = document.getElementById('deletelink').href;
  50. return document.getElementById('pasteurl').href === expected1 && result2 === expected2;
  51. }
  52. );
  53. });
  54. describe('extractUrl', function () {
  55. this.timeout(30000);
  56. jsc.property(
  57. 'extracts and updates IDN URLs found in given response',
  58. common.jscSchemas(false),
  59. 'nestring',
  60. common.jscUrl(),
  61. function (schema, domain, url) {
  62. domain = domain.replace(/\P{Letter}|[\u{AA}-\u{BA}]/gu, '').toLowerCase();
  63. if (domain.length === 0) {
  64. domain = 'a';
  65. }
  66. url.schema = schema;
  67. url.address.unshift('.');
  68. url.address = domain.split('').concat(url.address);
  69. const urlString = common.urlToString(url),
  70. expected = urlString.substring((schema + '://' + domain).length),
  71. clean = globalThis.cleanup();
  72. document.body.innerHTML = '<div><div id="pastelink"></div></div>';
  73. PrivateBin.PasteStatus.init();
  74. PrivateBin.PasteStatus.createPasteNotification('', '');
  75. PrivateBin.PasteStatus.extractUrl(urlString);
  76. const result = document.getElementById('pasteurl').href;
  77. clean();
  78. return result.endsWith(expected) && (
  79. result.startsWith(schema + '://xn--') ||
  80. result.startsWith(schema + '://' + domain)
  81. );
  82. }
  83. );
  84. // YOURLS API samples from: https://yourls.org/readme.html#API;apireturn
  85. jsc.property(
  86. 'extracts and updates URLs found in YOURLS API JSON response',
  87. common.jscSchemas(false),
  88. common.jscUrl(),
  89. common.jscUrl(false),
  90. function (schema, longUrl, shortUrl) {
  91. const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
  92. yourlsResponse = {
  93. url: {
  94. keyword: longUrl.address.join(''),
  95. url: longUrlString,
  96. title: 'example title',
  97. date: '2014-10-24 16:01:39',
  98. ip: '127.0.0.1'
  99. },
  100. status: 'success',
  101. message: longUrlString + ' added to database',
  102. title: 'example title',
  103. shorturl: shortUrlString,
  104. statusCode: 200
  105. },
  106. clean = globalThis.cleanup();
  107. document.body.innerHTML = '<div><div id="pastelink"></div></div>';
  108. PrivateBin.PasteStatus.init();
  109. PrivateBin.PasteStatus.createPasteNotification('', '');
  110. PrivateBin.PasteStatus.extractUrl(JSON.stringify(yourlsResponse, undefined, 4));
  111. const result = document.getElementById('pasteurl').href;
  112. clean();
  113. return result === shortUrlString;
  114. }
  115. );
  116. jsc.property(
  117. 'extracts and updates URLs found in YOURLS API XML response',
  118. common.jscSchemas(false),
  119. common.jscUrl(),
  120. common.jscUrl(false),
  121. function (schema, longUrl, shortUrl) {
  122. const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
  123. yourlsResponse = '<result>\n' +
  124. ' <keyword>' + longUrl.address.join('') + '</keyword>\n' +
  125. ' <shorturl>' + shortUrlString + '</shorturl>\n' +
  126. ' <longurl>' + longUrlString + '</longurl>\n' +
  127. ' <message>success</message>\n' +
  128. ' <statusCode>200</statusCode>\n' +
  129. '</result>',
  130. clean = globalThis.cleanup();
  131. document.body.innerHTML = '<div><div id="pastelink"></div></div>';
  132. PrivateBin.PasteStatus.init();
  133. PrivateBin.PasteStatus.createPasteNotification('', '');
  134. PrivateBin.PasteStatus.extractUrl(yourlsResponse);
  135. const result = document.getElementById('pasteurl').href;
  136. clean();
  137. return result === shortUrlString;
  138. }
  139. );
  140. jsc.property(
  141. 'extracts and updates URLs found in YOURLS proxy HTML response',
  142. common.jscSchemas(false),
  143. common.jscUrl(),
  144. common.jscUrl(false),
  145. function (schema, longUrl, shortUrl) {
  146. const [_, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
  147. yourlsResponse = '<!DOCTYPE html>\n' +
  148. '<html lang="en">\n' +
  149. '\t<head>\n' +
  150. '\t\t<meta charset="utf-8" />\n' +
  151. '\t\t<meta name="robots" content="noindex" />\n' +
  152. '\t\t<meta name="google" content="notranslate">\n' +
  153. '\t\t<title>PrivateBin</title>\n' +
  154. '\t</head>\n' +
  155. '\t<body>\n' +
  156. '\t\t<p>Your document is <a id="pasteurl" href="' + shortUrlString + '">' + shortUrlString + '</a> <span id="copyhint">(Hit <kbd>Ctrl</kbd>+<kbd>c</kbd> to copy)</span></p>\n' +
  157. '\t</body>\n' +
  158. '</html>',
  159. clean = globalThis.cleanup();
  160. document.body.innerHTML = '<div><div id="pastelink"></div></div>';
  161. PrivateBin.PasteStatus.init();
  162. PrivateBin.PasteStatus.createPasteNotification('', '');
  163. PrivateBin.PasteStatus.extractUrl(yourlsResponse);
  164. const result = document.getElementById('pasteurl').href;
  165. clean();
  166. return result === shortUrlString;
  167. }
  168. );
  169. });
  170. describe('showRemainingTime', function () {
  171. this.timeout(30000);
  172. jsc.property(
  173. 'shows burn after reading message or remaining time',
  174. 'bool',
  175. 'nat',
  176. common.jscUrl(),
  177. function (burnafterreading, remainingTime, url) {
  178. let clean = globalThis.cleanup('', {url: common.urlToString(url)}),
  179. result;
  180. document.body.innerHTML = '<div id="remainingtime" class="hidden"></div>';
  181. PrivateBin.PasteStatus.init();
  182. PrivateBin.PasteStatus.showRemainingTime(PrivateBin.Helper.PasteFactory({
  183. 'adata': [null, null, null, burnafterreading],
  184. 'v': 2,
  185. 'meta': {
  186. 'time_to_live': remainingTime
  187. }
  188. }));
  189. if (burnafterreading) {
  190. result = document.getElementById('remainingtime').classList.contains('foryoureyesonly') &&
  191. !document.getElementById('remainingtime').classList.contains('hidden');
  192. } else if (remainingTime) {
  193. result =!document.getElementById('remainingtime').classList.contains('foryoureyesonly') &&
  194. !document.getElementById('remainingtime').classList.contains('hidden');
  195. } else {
  196. result = document.getElementById('remainingtime').classList.contains('hidden') &&
  197. !document.getElementById('remainingtime').classList.contains('foryoureyesonly');
  198. }
  199. clean();
  200. return result;
  201. }
  202. );
  203. });
  204. describe('hideMessages', function () {
  205. it(
  206. 'hides all messages',
  207. function() {
  208. document.body.innerHTML = (
  209. '<div id="remainingtime"></div><div id="pastesuccess"></div>'
  210. );
  211. PrivateBin.PasteStatus.init();
  212. PrivateBin.PasteStatus.hideMessages();
  213. assert.ok(document.getElementById('remainingtime').classList.contains('hidden'));
  214. assert.ok(document.getElementById('pastesuccess').classList.contains('hidden'));
  215. }
  216. );
  217. });
  218. });