9a44cc1e4d3190c1afdcdf1301bfe5e9ec0293780bcd47a21636860f862d05cb8e5a9a3b2388dfd5a965f83a19fe894551721997bbac1a7c17524e719dc449 12 KB

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