1
0

PasteStatus.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  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. jsc.property(
  23. 'creates a notification after a successful document upload',
  24. common.jscUrl(),
  25. common.jscUrl(false),
  26. function (url1, url2) {
  27. const expected1 = common.urlToString(url1).replace(/&(gt|lt)$/, '&$1a'),
  28. expected2 = common.urlToString(url2).replace(/&(gt|lt)$/, '&$1a'),
  29. clean = jsdom();
  30. $('body').html('<a href="#" id="deletelink"><span></span></a><div id="pastelink"></div>');
  31. $.PrivateBin.PasteStatus.init();
  32. $.PrivateBin.PasteStatus.createPasteNotification(expected1, expected2);
  33. const result1 = $('#pasteurl')[0].href,
  34. result2 = $('#deletelink')[0].href;
  35. clean();
  36. return result1 === expected1 && result2 === expected2;
  37. }
  38. );
  39. it(
  40. 'shows Cmd hotkey hint on macOS',
  41. function () {
  42. const clean = jsdom();
  43. Object.defineProperty(navigator, 'userAgent', {
  44. value: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
  45. configurable: true
  46. });
  47. $('body').html('<a href="#" id="deletelink"><span></span></a><div id="pastelink"></div>');
  48. $.PrivateBin.PasteStatus.init();
  49. $.PrivateBin.PasteStatus.createPasteNotification('https://example.com/', 'https://example.com/delete');
  50. const hotkey = $('#copyhint kbd').first().text();
  51. clean();
  52. assert.strictEqual(hotkey, 'Cmd');
  53. }
  54. );
  55. it(
  56. 'shows Ctrl hotkey hint on non-Mac platforms',
  57. function () {
  58. const clean = jsdom();
  59. Object.defineProperty(navigator, 'userAgent', {
  60. value: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
  61. configurable: true
  62. });
  63. $('body').html('<a href="#" id="deletelink"><span></span></a><div id="pastelink"></div>');
  64. $.PrivateBin.PasteStatus.init();
  65. $.PrivateBin.PasteStatus.createPasteNotification('https://example.com/', 'https://example.com/delete');
  66. const hotkey = $('#copyhint kbd').first().text();
  67. clean();
  68. assert.strictEqual(hotkey, 'Ctrl');
  69. }
  70. );
  71. });
  72. describe('extractUrl', function () {
  73. this.timeout(30000);
  74. jsc.property(
  75. 'extracts and updates IDN URLs found in given response',
  76. common.jscSchemas(false),
  77. 'nestring',
  78. common.jscUrl(),
  79. function (schema, domain, url) {
  80. domain = domain.replace(/\P{Letter}|[\u{AA}-\u{BA}]/gu, '').toLowerCase();
  81. if (domain.length === 0) {
  82. domain = 'a';
  83. }
  84. url.schema = schema;
  85. url.address.unshift('.');
  86. url.address = domain.split('').concat(url.address);
  87. const urlString = common.urlToString(url),
  88. expected = urlString.substring((schema + '://' + domain).length),
  89. clean = jsdom();
  90. $('body').html('<div><div id="pastelink"></div></div>');
  91. $.PrivateBin.PasteStatus.init();
  92. $.PrivateBin.PasteStatus.createPasteNotification('', '');
  93. $.PrivateBin.PasteStatus.extractUrl(urlString);
  94. const result = $('#pasteurl')[0].href;
  95. clean();
  96. return result.endsWith(expected) && (
  97. result.startsWith(schema + '://xn--') ||
  98. result.startsWith(schema + '://' + domain)
  99. );
  100. }
  101. );
  102. // YOURLS API samples from: https://yourls.org/readme.html#API;apireturn
  103. jsc.property(
  104. 'extracts and updates URLs found in YOURLS API JSON response',
  105. common.jscSchemas(false),
  106. common.jscUrl(),
  107. common.jscUrl(false),
  108. function (schema, longUrl, shortUrl) {
  109. const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
  110. yourlsResponse = {
  111. url: {
  112. keyword: longUrl.address.join(''),
  113. url: longUrlString,
  114. title: 'example title',
  115. date: '2014-10-24 16:01:39',
  116. ip: '127.0.0.1'
  117. },
  118. status: 'success',
  119. message: longUrlString + ' added to database',
  120. title: 'example title',
  121. shorturl: shortUrlString,
  122. statusCode: 200
  123. },
  124. clean = jsdom();
  125. $('body').html('<div><div id="pastelink"></div></div>');
  126. $.PrivateBin.PasteStatus.init();
  127. $.PrivateBin.PasteStatus.createPasteNotification('', '');
  128. $.PrivateBin.PasteStatus.extractUrl(JSON.stringify(yourlsResponse, undefined, 4));
  129. const result = $('#pasteurl')[0].href;
  130. clean();
  131. return result === shortUrlString;
  132. }
  133. );
  134. jsc.property(
  135. 'extracts and updates URLs found in YOURLS API XML response',
  136. common.jscSchemas(false),
  137. common.jscUrl(),
  138. common.jscUrl(false),
  139. function (schema, longUrl, shortUrl) {
  140. const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
  141. yourlsResponse = '<result>\n' +
  142. ' <keyword>' + longUrl.address.join('') + '</keyword>\n' +
  143. ' <shorturl>' + shortUrlString + '</shorturl>\n' +
  144. ' <longurl>' + longUrlString + '</longurl>\n' +
  145. ' <message>success</message>\n' +
  146. ' <statusCode>200</statusCode>\n' +
  147. '</result>',
  148. clean = jsdom();
  149. $('body').html('<div><div id="pastelink"></div></div>');
  150. $.PrivateBin.PasteStatus.init();
  151. $.PrivateBin.PasteStatus.createPasteNotification('', '');
  152. $.PrivateBin.PasteStatus.extractUrl(yourlsResponse);
  153. const result = $('#pasteurl')[0].href;
  154. clean();
  155. return result === shortUrlString;
  156. }
  157. );
  158. jsc.property(
  159. 'extracts and updates URLs found in YOURLS proxy HTML response',
  160. common.jscSchemas(false),
  161. common.jscUrl(),
  162. common.jscUrl(false),
  163. function (schema, longUrl, shortUrl) {
  164. const [_, shortUrlString] = urlStrings(schema, longUrl, shortUrl),
  165. yourlsResponse = '<!DOCTYPE html>\n' +
  166. '<html lang="en">\n' +
  167. '\t<head>\n' +
  168. '\t\t<meta charset="utf-8" />\n' +
  169. '\t\t<meta name="robots" content="noindex" />\n' +
  170. '\t\t<meta name="google" content="notranslate">\n' +
  171. '\t\t<title>PrivateBin</title>\n' +
  172. '\t</head>\n' +
  173. '\t<body>\n' +
  174. '\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' +
  175. '\t</body>\n' +
  176. '</html>',
  177. clean = jsdom();
  178. $('body').html('<div><div id="pastelink"></div></div>');
  179. $.PrivateBin.PasteStatus.init();
  180. $.PrivateBin.PasteStatus.createPasteNotification('', '');
  181. $.PrivateBin.PasteStatus.extractUrl(yourlsResponse);
  182. const result = $('#pasteurl')[0].href;
  183. clean();
  184. return result === shortUrlString;
  185. }
  186. );
  187. });
  188. describe('showRemainingTime', function () {
  189. this.timeout(30000);
  190. jsc.property(
  191. 'shows burn after reading message or remaining time',
  192. 'bool',
  193. 'nat',
  194. common.jscUrl(),
  195. function (burnafterreading, remainingTime, url) {
  196. let clean = jsdom('', {url: common.urlToString(url)}),
  197. result;
  198. $('body').html('<div id="remainingtime" class="hidden"></div>');
  199. $.PrivateBin.PasteStatus.init();
  200. $.PrivateBin.PasteStatus.showRemainingTime($.PrivateBin.Helper.PasteFactory({
  201. 'adata': [null, null, null, burnafterreading],
  202. 'v': 2,
  203. 'meta': {
  204. 'time_to_live': remainingTime
  205. }
  206. }));
  207. if (burnafterreading) {
  208. result = $('#remainingtime').hasClass('foryoureyesonly') &&
  209. !$('#remainingtime').hasClass('hidden');
  210. } else if (remainingTime) {
  211. result =!$('#remainingtime').hasClass('foryoureyesonly') &&
  212. !$('#remainingtime').hasClass('hidden');
  213. } else {
  214. result = $('#remainingtime').hasClass('hidden') &&
  215. !$('#remainingtime').hasClass('foryoureyesonly');
  216. }
  217. clean();
  218. return result;
  219. }
  220. );
  221. });
  222. describe('hideMessages', function () {
  223. it(
  224. 'hides all messages',
  225. function() {
  226. $('body').html(
  227. '<div id="remainingtime"></div><div id="pastesuccess"></div>'
  228. );
  229. $.PrivateBin.PasteStatus.init();
  230. $.PrivateBin.PasteStatus.hideMessages();
  231. assert.ok($('#remainingtime').hasClass('hidden'));
  232. assert.ok($('#pastesuccess').hasClass('hidden'));
  233. }
  234. );
  235. });
  236. });