comments.e2e.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. 'use strict';
  2. describe('Comments', function () {
  3. var id = 'testContainer';
  4. beforeEach(function () {
  5. this.$container = $('<div id="' + id + '"></div>').appendTo('body');
  6. });
  7. afterEach(function () {
  8. if (this.$container) {
  9. destroy();
  10. this.$container.remove();
  11. }
  12. });
  13. describe('Enabling the plugin', function () {
  14. it('should enable the plugin in the initial config', function () {
  15. var hot = handsontable({
  16. data: Handsontable.helper.createSpreadsheetData(4, 4),
  17. comments: true
  18. });
  19. expect(hot.getPlugin('comments').isEnabled()).toBe(true);
  20. });
  21. it('should enable the plugin using updateSettings', function () {
  22. var hot = handsontable({
  23. data: Handsontable.helper.createSpreadsheetData(4, 4)
  24. });
  25. expect(hot.getPlugin('comments').isEnabled()).toBe(false);
  26. updateSettings({
  27. comments: true
  28. });
  29. expect(hot.getPlugin('comments').isEnabled()).toBe(true);
  30. });
  31. });
  32. describe('Styling', function () {
  33. it('should display comment indicators in the appropriate cells', function () {
  34. var hot = handsontable({
  35. data: Handsontable.helper.createSpreadsheetData(4, 4),
  36. comments: true,
  37. cell: [{ row: 1, col: 1, comment: { value: 'test' } }, { row: 2, col: 2, comment: { value: 'test' } }]
  38. });
  39. expect(getCell(1, 1).className.indexOf('htCommentCell')).toBeGreaterThan(-1);
  40. expect(getCell(2, 2).className.indexOf('htCommentCell')).toBeGreaterThan(-1);
  41. });
  42. });
  43. describe('API', function () {
  44. it('should return the comment from a proper cell, when using the getCommentAtCell method', function () {
  45. var hot = handsontable({
  46. data: Handsontable.helper.createSpreadsheetData(4, 4),
  47. comments: true,
  48. cell: [{ row: 1, col: 1, comment: { value: 'test' } }, { row: 2, col: 2, comment: { value: 'another test' } }]
  49. });
  50. var plugin = hot.getPlugin('comments');
  51. expect(plugin.getCommentAtCell(1, 1)).toEqual('test');
  52. expect(plugin.getCommentAtCell(2, 2)).toEqual('another test');
  53. });
  54. it('should return the comment from a proper cell, when using the setRange and getComment methods', function () {
  55. var hot = handsontable({
  56. data: Handsontable.helper.createSpreadsheetData(4, 4),
  57. comments: true,
  58. cell: [{ row: 1, col: 1, comment: { value: 'test' } }, { row: 2, col: 2, comment: { value: 'another test' } }]
  59. });
  60. var plugin = hot.getPlugin('comments');
  61. plugin.setRange({ from: { row: 1, col: 1 } });
  62. expect(plugin.getComment()).toEqual('test');
  63. plugin.setRange({ from: { row: 2, col: 2 } });
  64. expect(plugin.getComment()).toEqual('another test');
  65. });
  66. it('should allow inserting comments using the `setCommentAtCell` method', function () {
  67. var hot = handsontable({
  68. data: Handsontable.helper.createSpreadsheetData(4, 4),
  69. comments: true
  70. });
  71. var plugin = hot.getPlugin('comments');
  72. expect(getCellMeta(1, 1).comment).toEqual(void 0);
  73. plugin.setCommentAtCell(1, 1, 'test comment');
  74. expect(getCellMeta(1, 1).comment.value).toEqual('test comment');
  75. });
  76. it('should trigger `afterSetCellMeta` callback when `setCommentAtCell` function is invoked', function () {
  77. var afterSetCellMetaCallback = jasmine.createSpy('afterSetCellMetaCallback');
  78. var hot = handsontable({
  79. data: Handsontable.helper.createSpreadsheetData(4, 4),
  80. comments: true,
  81. afterSetCellMeta: afterSetCellMetaCallback
  82. });
  83. var plugin = hot.getPlugin('comments');
  84. plugin.setCommentAtCell(1, 1, 'Added comment');
  85. expect(afterSetCellMetaCallback).toHaveBeenCalledWith(1, 1, 'comment', { value: 'Added comment' }, undefined, undefined);
  86. });
  87. it('should allow removing comments using the `removeCommentAtCell` method', function () {
  88. var hot = handsontable({
  89. data: Handsontable.helper.createSpreadsheetData(4, 4),
  90. comments: true,
  91. cell: [{ row: 1, col: 1, comment: { value: 'test' } }]
  92. });
  93. var plugin = hot.getPlugin('comments');
  94. expect(getCellMeta(1, 1).comment.value).toEqual('test');
  95. plugin.removeCommentAtCell(1, 1);
  96. expect(getCellMeta(1, 1).comment).toEqual(void 0);
  97. });
  98. it('should trigger `afterSetCellMeta` callback when `removeCommentAtCell` function is invoked', function () {
  99. var afterSetCellMetaCallback = jasmine.createSpy('afterSetCellMetaCallback');
  100. var hot = handsontable({
  101. data: Handsontable.helper.createSpreadsheetData(4, 4),
  102. comments: true,
  103. cell: [{ row: 1, col: 1, comment: { value: 'test' } }],
  104. afterSetCellMeta: afterSetCellMetaCallback
  105. });
  106. var plugin = hot.getPlugin('comments');
  107. plugin.removeCommentAtCell(1, 1);
  108. expect(afterSetCellMetaCallback).toHaveBeenCalledWith(1, 1, 'comment', undefined, undefined, undefined);
  109. });
  110. it('should allow opening the comment editor using the `showAtCell` method', function () {
  111. var hot = handsontable({
  112. data: Handsontable.helper.createSpreadsheetData(4, 4),
  113. comments: true
  114. });
  115. var plugin = hot.getPlugin('comments');
  116. var editor = plugin.editor.getInputElement();
  117. expect(editor.parentNode.style.display).toEqual('none');
  118. plugin.showAtCell(1, 1);
  119. expect(editor.parentNode.style.display).toEqual('block');
  120. });
  121. it('should allow closing the comment editor using the `hide` method', function () {
  122. var hot = handsontable({
  123. data: Handsontable.helper.createSpreadsheetData(4, 4),
  124. comments: true
  125. });
  126. var plugin = hot.getPlugin('comments');
  127. var editor = plugin.editor.getInputElement();
  128. plugin.showAtCell(1, 1);
  129. expect(editor.parentNode.style.display).toEqual('block');
  130. plugin.hide();
  131. expect(editor.parentNode.style.display).toEqual('none');
  132. });
  133. });
  134. it('`updateCommentMeta` & `setComment` functions should extend cellMetaObject properly', function () {
  135. var comment, readOnly;
  136. var hot = handsontable({
  137. data: Handsontable.helper.createSpreadsheetData(4, 4),
  138. comments: true
  139. });
  140. var plugin = hot.getPlugin('comments');
  141. setCellMeta(0, 0, 'comment', { readOnly: true });
  142. plugin.updateCommentMeta(0, 0, { value: 'Test' });
  143. comment = getCellMeta(0, 0).comment;
  144. readOnly = comment && comment.readOnly;
  145. expect(readOnly).toEqual(true);
  146. plugin.setRange({ from: { row: 0, col: 0 }, to: { row: 0, col: 0 } });
  147. plugin.setComment('Test2');
  148. comment = getCellMeta(0, 0).comment;
  149. readOnly = comment && comment.readOnly;
  150. expect(readOnly).toEqual(true);
  151. });
  152. describe('Using the Context Menu', function () {
  153. it('should open the comment editor when clicking the "Add comment" entry', function () {
  154. var hot = handsontable({
  155. data: Handsontable.helper.createSpreadsheetData(4, 4),
  156. contextMenu: true,
  157. comments: true
  158. });
  159. selectCell(1, 1);
  160. contextMenu();
  161. var addCommentButton = $('.htItemWrapper').filter(function () {
  162. return $(this).text() === 'Add comment';
  163. })[0];
  164. $(addCommentButton).simulate('mousedown');
  165. var editor = hot.getPlugin('comments').editor.getInputElement();
  166. expect($(editor).parents('.htComments')[0].style.display).toEqual('block');
  167. });
  168. it('should remove the comment from a cell after clicking the "Delete comment" entry', function () {
  169. var hot = handsontable({
  170. data: Handsontable.helper.createSpreadsheetData(4, 4),
  171. contextMenu: true,
  172. comments: true,
  173. cell: [{ row: 1, col: 1, comment: { value: 'Test comment' } }]
  174. });
  175. expect(getCellMeta(1, 1).comment.value).toEqual('Test comment');
  176. selectCell(1, 1);
  177. contextMenu();
  178. var deleteCommentButton = $('.htItemWrapper').filter(function () {
  179. return $(this).text() === 'Delete comment';
  180. })[0];
  181. $(deleteCommentButton).simulate('mousedown');
  182. expect(getCellMeta(1, 1).comment).toEqual(void 0);
  183. });
  184. it('should remove comments from a selected group of cells after clicking the "Delete comment" entry', function () {
  185. var hot = handsontable({
  186. data: Handsontable.helper.createSpreadsheetData(4, 4),
  187. contextMenu: true,
  188. comments: true,
  189. cell: [{ row: 1, col: 1, comment: { value: 'Test comment' } }, { row: 2, col: 2, comment: { value: 'Test comment 2' } }]
  190. });
  191. expect(getCellMeta(1, 1).comment.value).toEqual('Test comment');
  192. expect(getCellMeta(2, 2).comment.value).toEqual('Test comment 2');
  193. selectCell(1, 1, 2, 2);
  194. contextMenu();
  195. var deleteCommentButton = $('.htItemWrapper').filter(function () {
  196. return $(this).text() === 'Delete comment';
  197. })[0];
  198. $(deleteCommentButton).simulate('mousedown');
  199. expect(getCellMeta(1, 1).comment).toEqual(void 0);
  200. expect(getCellMeta(2, 2).comment).toEqual(void 0);
  201. });
  202. it('should make the comment editor\'s textarea read-only after clicking the "Read only comment" entry', function (done) {
  203. var hot = handsontable({
  204. data: Handsontable.helper.createSpreadsheetData(4, 4),
  205. contextMenu: true,
  206. comments: true,
  207. cell: [{ row: 1, col: 1, comment: { value: 'Test comment' } }]
  208. });
  209. selectCell(1, 1);
  210. contextMenu();
  211. var editor = hot.getPlugin('comments').editor.getInputElement();
  212. expect($(editor)[0].readOnly).toBe(false);
  213. var readOnlyComment = $('.htItemWrapper').filter(function () {
  214. return $(this).text() === 'Read only comment';
  215. })[0];
  216. $(readOnlyComment).simulate('mousedown');
  217. $(document).simulate('mouseup');
  218. $(getCell(1, 1)).simulate('mouseover', {
  219. clientX: Handsontable.dom.offset(getCell(1, 1)).left + 5,
  220. clientY: Handsontable.dom.offset(getCell(1, 1)).top + 5
  221. });
  222. setTimeout(function () {
  223. expect($(editor)[0].readOnly).toBe(true);
  224. done();
  225. }, 550);
  226. });
  227. });
  228. describe('Hooks invoked after changing cell meta', function () {
  229. it('should trigger `afterSetCellMeta` callback after deleting comment by context menu', function () {
  230. var afterSetCellMetaCallback = jasmine.createSpy('afterSetCellMetaCallback');
  231. var rows = 10,
  232. columns = 10;
  233. handsontable({
  234. data: Handsontable.helper.createSpreadsheetData(rows, columns),
  235. rowHeaders: true,
  236. colHeaders: true,
  237. contextMenu: true,
  238. comments: true,
  239. columns: function columns() {
  240. return {
  241. comment: {
  242. value: 'test'
  243. }
  244. };
  245. },
  246. afterSetCellMeta: afterSetCellMetaCallback
  247. });
  248. expect(afterSetCellMetaCallback).not.toHaveBeenCalled();
  249. selectCell(1, 1);
  250. contextMenu();
  251. var deleteCommentButton = $('.htItemWrapper').filter(function () {
  252. return $(this).text() === 'Delete comment';
  253. })[0];
  254. $(deleteCommentButton).simulate('mousedown');
  255. expect(afterSetCellMetaCallback).toHaveBeenCalledWith(1, 1, 'comment', undefined, undefined, undefined);
  256. });
  257. // Don't work in PhantomJS
  258. // It will work probably when #3961 will be fixed
  259. xit('should trigger `afterSetCellMeta` callback after editing comment by context menu', function (done) {
  260. var afterSetCellMetaCallback = jasmine.createSpy('afterSetCellMetaCallback');
  261. var rows = 10,
  262. columns = 10;
  263. handsontable({
  264. data: Handsontable.helper.createSpreadsheetData(rows, columns),
  265. rowHeaders: true,
  266. colHeaders: true,
  267. contextMenu: true,
  268. comments: true,
  269. columns: function columns() {
  270. return {
  271. comment: {
  272. value: 'test'
  273. }
  274. };
  275. },
  276. afterSetCellMeta: afterSetCellMetaCallback
  277. });
  278. selectCell(0, 0);
  279. contextMenu();
  280. var editCommentButton = $('.htItemWrapper').filter(function () {
  281. return $(this).text() === 'Edit comment';
  282. })[0];
  283. $(editCommentButton).simulate('mousedown');
  284. setTimeout(function () {
  285. $('.htCommentTextArea').val('Edited comment');
  286. // changing focus
  287. $('body').simulate('mousedown');
  288. setTimeout(function () {
  289. expect(afterSetCellMetaCallback).toHaveBeenCalledWith(0, 0, 'comment', { value: 'Edited comment' }, undefined, undefined);
  290. done();
  291. }, 100);
  292. }, 100);
  293. });
  294. });
  295. });