filters.js 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. describe('Filters', function() {
  2. let $filter;
  3. // Ignoring page reload request
  4. beforeAll(() => window.onbeforeunload = () => null);
  5. let webClientServiceMock = {
  6. me: {
  7. id: 'MEMEMEME',
  8. displayName: 'Er'
  9. },
  10. contacts: {
  11. get: function(id) {
  12. if (id === 'AAAAAAAA') {
  13. return {
  14. displayName: 'ContactA'
  15. }
  16. }
  17. else if (id === 'XXXXXXXX') {
  18. return {
  19. displayName: 'ContactX'
  20. }
  21. }
  22. else if (id === '*AAAAAAA') {
  23. return {
  24. displayName: 'GWContactA'
  25. }
  26. }
  27. else if (id === 'BAD0BAD1') {
  28. return {
  29. displayName: '<b>< script >foo&ndash;</b>< script>',
  30. }
  31. }
  32. return null;
  33. }
  34. }
  35. };
  36. let translationMock = {
  37. instant: function(label) {
  38. return label;
  39. }
  40. };
  41. beforeEach(function() {
  42. // Load 3ema.filters module
  43. module('3ema.filters');
  44. module(function ($provide) {
  45. $provide.value('WebClientService', webClientServiceMock);
  46. $provide.value('$translate', translationMock);
  47. });
  48. // Inject the $filter function
  49. inject(function(_$filter_) {
  50. $filter = _$filter_;
  51. });
  52. });
  53. function testPatterns(filterName, cases) {
  54. const filter = $filter(filterName);
  55. for (let testcase of cases) {
  56. const input = testcase[0];
  57. const expected = testcase[1];
  58. expect(filter(input)).toEqual(expected);
  59. };
  60. };
  61. describe('markify', function() {
  62. this.testPatterns = (cases) => testPatterns('markify', cases);
  63. it('detects bold text', () => {
  64. this.testPatterns([
  65. ['*bold text (not italic)*',
  66. '<span class="text-bold">bold text (not italic)</span>'],
  67. ]);
  68. });
  69. it('detects italic text', () => {
  70. this.testPatterns([
  71. ['This text is not italic.',
  72. 'This text is not italic.'],
  73. ['_This text is italic._',
  74. '<span class="text-italic">This text is italic.</span>'],
  75. ['This text is _partially_ italic',
  76. 'This text is <span class="text-italic">partially</span> italic'],
  77. ['This text has _two_ _italic_ bits',
  78. 'This text has <span class="text-italic">two</span> <span class="text-italic">italic</span> bits'],
  79. ]);
  80. });
  81. it('detects strikethrough text', () => {
  82. this.testPatterns([
  83. ['so ~strikethrough~', 'so <span class="text-strike">strikethrough</span>'],
  84. ]);
  85. });
  86. it('detects mixed markup', () => {
  87. this.testPatterns([
  88. ['*bold text with _italic_ *',
  89. '<span class="text-bold">bold text with <span class="text-italic">italic</span> </span>'],
  90. ['*part bold,* _part italic_',
  91. '<span class="text-bold">part bold,</span> <span class="text-italic">part italic</span>'],
  92. ['_italic text with *bold* _',
  93. '<span class="text-italic">italic text with <span class="text-bold">bold</span> </span>'],
  94. ]);
  95. });
  96. it('is only applied on word boundaries', () => {
  97. this.testPatterns([
  98. ['so not_really_italic',
  99. 'so not_really_italic'],
  100. ['invalid*bold*stuff',
  101. 'invalid*bold*stuff'],
  102. ['no~strike~through',
  103. 'no~strike~through'],
  104. ['*bold_but_no~strike~through*',
  105. '<span class="text-bold">bold_but_no~strike~through</span>'],
  106. ]);
  107. });
  108. it('does not break URLs', () => {
  109. this.testPatterns([
  110. ['https://en.wikipedia.org/wiki/Java_class_file *nice*',
  111. 'https://en.wikipedia.org/wiki/Java_class_file <span class="text-bold">nice</span>'],
  112. ['<a href="https://threema.ch/>_Threema_</a>',
  113. '<a href="https://threema.ch/><span class="text-italic">Threema</span></a>'],
  114. ]);
  115. });
  116. it('ignores invalid markup', () => {
  117. this.testPatterns([
  118. ['*invalid markup (do not parse)_', '*invalid markup (do not parse)_'],
  119. ['random *asterisk', 'random *asterisk'],
  120. ]);
  121. });
  122. it('ignores markup with \\n (newline)', () => {
  123. this.testPatterns([
  124. ['*First line\n and a new one. (do not parse)*', '*First line\n and a new one. (do not parse)*'],
  125. ['*\nbegins with linebreak. (do not parse)*', '*\nbegins with linebreak. (do not parse)*'],
  126. ['*Just some text. But it ends with newline (do not parse)\n*', '*Just some text. But it ends with newline (do not parse)\n*'],
  127. ]);
  128. });
  129. });
  130. describe('escapeHtml', function() {
  131. this.testPatterns = (cases) => testPatterns('escapeHtml', cases);
  132. it('escapes html tags', () => {
  133. this.testPatterns([
  134. ['<h1>heading</h1>', '&lt;h1&gt;heading&lt;/h1&gt;'],
  135. ['<b>< script >foo&ndash;</b>< script>', '&lt;b&gt;&lt; script &gt;foo&amp;ndash;&lt;/b&gt;&lt; script&gt;'],
  136. ['<a href="/">a</a>', '&lt;a href=&quot;/&quot;&gt;a&lt;/a&gt;'],
  137. ]);
  138. });
  139. });
  140. describe('mentionify', function() {
  141. this.testPatterns = (cases) => testPatterns('mentionify', cases);
  142. it('no mentions', () => {
  143. this.testPatterns([
  144. ['', ''],
  145. ['hello my friend', 'hello my friend'],
  146. ['@[AAAAAAA]', '@[AAAAAAA]'],
  147. ['this is not a valid @[AAAAAAA]', 'this is not a valid @[AAAAAAA]'],
  148. ['@[@@@@@@@]', '@[@@@@@@@]'],
  149. ['this is not a valid @[@@@@@@@]', 'this is not a valid @[@@@@@@@]'],
  150. ]);
  151. });
  152. it('mention - no contacts', () => {
  153. this.testPatterns([
  154. ['@[BBBBBBBB]', '@[BBBBBBBB]'],
  155. ['@[*BBBBBBB]', '@[*BBBBBBB]'],
  156. ]);
  157. });
  158. it('mention - contact', () => {
  159. this.testPatterns([
  160. ['@[AAAAAAAA]', '<span class="mention id AAAAAAAA" text="@[AAAAAAAA]">ContactA</span>'],
  161. ['hello @[AAAAAAAA]. @[AAAAAAAA] you are my friend', 'hello <span class="mention id AAAAAAAA" text="@[AAAAAAAA]">ContactA</span>. <span class="mention id AAAAAAAA" text="@[AAAAAAAA]">ContactA</span> you are my friend'],
  162. ['@[AAAAAAAA] @[AAAAAAAA] @[AAAAAAAA]', '<span class="mention id AAAAAAAA" text="@[AAAAAAAA]">ContactA</span> <span class="mention id AAAAAAAA" text="@[AAAAAAAA]">ContactA</span> <span class="mention id AAAAAAAA" text="@[AAAAAAAA]">ContactA</span>']
  163. ]);
  164. });
  165. it('mention - all', () => {
  166. this.testPatterns([
  167. ['@[@@@@@@@@]', '<span class="mention all" text="@[@@@@@@@@]">messenger.ALL</span>'],
  168. ['@[@@@@@@@@] your base are belong to us', '<span class="mention all" text="@[@@@@@@@@]">messenger.ALL</span> your base are belong to us'],
  169. ['@[@@@@@@@@] @[@@@@@@@@] @[@@@@@@@@]', '<span class="mention all" text="@[@@@@@@@@]">messenger.ALL</span> <span class="mention all" text="@[@@@@@@@@]">messenger.ALL</span> <span class="mention all" text="@[@@@@@@@@]">messenger.ALL</span>']
  170. ]);
  171. });
  172. it('mention - mixed', () => {
  173. this.testPatterns([
  174. ['@[@@@@@@@@] @[AAAAAAAA] @[BBBBBBBB]', '<span class="mention all" text="@[@@@@@@@@]">messenger.ALL</span> <span class="mention id AAAAAAAA" text="@[AAAAAAAA]">ContactA</span> @[BBBBBBBB]'],
  175. ]);
  176. });
  177. it('mention - me contact', () => {
  178. this.testPatterns([
  179. ['@[MEMEMEME]', '<span class="mention me" text="@[MEMEMEME]">Er</span>'],
  180. ['hello @[MEMEMEME]. @[MEMEMEME] you are my friend', 'hello <span class="mention me" text="@[MEMEMEME]">Er</span>. <span class="mention me" text="@[MEMEMEME]">Er</span> you are my friend'],
  181. ['@[MEMEMEME] @[MEMEMEME] @[MEMEMEME]', '<span class="mention me" text="@[MEMEMEME]">Er</span> <span class="mention me" text="@[MEMEMEME]">Er</span> <span class="mention me" text="@[MEMEMEME]">Er</span>']
  182. ]);
  183. });
  184. it('mention - escape html parameters', () => {
  185. this.testPatterns([
  186. ['@[BAD0BAD1]', '<span class="mention id BAD0BAD1" text="@[BAD0BAD1]">&lt;b&gt;&lt; script &gt;foo&amp;ndash;&lt;/b&gt;&lt; script&gt;</span>'],
  187. ]);
  188. });
  189. });
  190. describe('nlToBr', function() {
  191. this.testPatterns = (cases) => testPatterns('nlToBr', cases);
  192. it('converts newlines (enabled=true)', () => {
  193. const filter = $filter('nlToBr');
  194. expect(filter('abc \n def', true)).toEqual('abc <br> def');
  195. expect(filter('a\nb\nc\\n', true)).toEqual('a<br>b<br>c\\n');
  196. });
  197. it('does not converts newlines (enabled=false)', () => {
  198. const filter = $filter('nlToBr');
  199. expect(filter('abc\ndef', false)).toEqual('abc\ndef');
  200. });
  201. it('if enabled flag is not set, converts newlines', () => {
  202. const filter = $filter('nlToBr');
  203. expect(filter('abc\ndef')).toEqual('abc<br>def');
  204. });
  205. });
  206. });