activity.spec.jsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import React from 'react';
  2. import {mount} from 'enzyme';
  3. import {initializeOrg} from 'app-test/helpers/initializeOrg';
  4. import IncidentActivity from 'app/views/incidents/details/activity';
  5. import changeReactMentionsInput from 'app-test/helpers/changeReactMentionsInput';
  6. describe('IncidentDetails -> Activity', function() {
  7. const incident = TestStubs.Incident();
  8. const {organization, routerContext} = initializeOrg();
  9. const activity = TestStubs.IncidentActivity();
  10. let activitiesList;
  11. beforeAll(function() {
  12. activitiesList = MockApiClient.addMockResponse({
  13. url: `/organizations/${organization.slug}/incidents/${
  14. incident.identifier
  15. }/activity/`,
  16. body: [activity],
  17. });
  18. });
  19. afterAll(function() {
  20. MockApiClient.clearMockResponses();
  21. });
  22. const createWrapper = props =>
  23. mount(
  24. <IncidentActivity
  25. params={{incidentId: incident.identifier, orgId: organization.slug}}
  26. {...props}
  27. />,
  28. routerContext
  29. );
  30. it('fetches and renders activities', async function() {
  31. const wrapper = createWrapper();
  32. expect(activitiesList).toHaveBeenCalled();
  33. // loading
  34. expect(wrapper.find('Placeholder').length).toBeGreaterThan(0);
  35. await tick();
  36. wrapper.update();
  37. expect(wrapper.find('Placeholder')).toHaveLength(0);
  38. expect(
  39. wrapper
  40. .find('NoteBody')
  41. .text()
  42. .trim()
  43. ).toEqual('incident activity comment');
  44. });
  45. it('creates a new note', async function() {
  46. const createComment = MockApiClient.addMockResponse({
  47. url: `/organizations/${organization.slug}/incidents/${
  48. incident.identifier
  49. }/comments/`,
  50. method: 'POST',
  51. body: TestStubs.IncidentActivity({
  52. id: '234',
  53. comment: 'new incident comment',
  54. }),
  55. });
  56. const wrapper = createWrapper();
  57. changeReactMentionsInput(wrapper, 'new incident comment');
  58. wrapper.find('textarea').simulate('keyDown', {key: 'Enter', ctrlKey: true});
  59. await tick();
  60. expect(createComment).toHaveBeenCalledWith(
  61. `/organizations/${organization.slug}/incidents/${incident.identifier}/comments/`,
  62. expect.objectContaining({data: {comment: 'new incident comment', mentions: []}})
  63. );
  64. });
  65. it.todo('fails to create a new note');
  66. it('updates an existing note', async function() {
  67. const newComment = 'edited comment';
  68. const updateComment = MockApiClient.addMockResponse({
  69. url: `/organizations/${organization.slug}/incidents/${
  70. incident.identifier
  71. }/comments/${activity.id}/`,
  72. method: 'PUT',
  73. body: {
  74. ...activity,
  75. comment: newComment,
  76. },
  77. });
  78. const wrapper = createWrapper();
  79. await tick();
  80. // unfortunately edit/delete items are hidden until hover (using emotion)
  81. // so we can't simulate this in jest?
  82. wrapper.find('Activity').prop('onUpdateNote')(
  83. {
  84. text: newComment,
  85. },
  86. activity
  87. );
  88. await tick();
  89. expect(updateComment).toHaveBeenCalledWith(
  90. expect.anything(),
  91. expect.objectContaining({
  92. data: {
  93. comment: newComment,
  94. },
  95. })
  96. );
  97. await tick();
  98. wrapper.update();
  99. expect(
  100. wrapper
  101. .find('NoteBody')
  102. .text()
  103. .trim()
  104. ).toEqual(newComment);
  105. });
  106. it('fails to update an existing note', async function() {
  107. const newComment = 'edited comment';
  108. const updateComment = MockApiClient.addMockResponse({
  109. url: `/organizations/${organization.slug}/incidents/${
  110. incident.identifier
  111. }/comments/${activity.id}/`,
  112. method: 'PUT',
  113. statusCode: 400,
  114. });
  115. const wrapper = createWrapper();
  116. await tick();
  117. // unfortunately edit/delete items are hidden until hover (using emotion)
  118. // so we can't simulate this in jest?
  119. wrapper.find('Activity').prop('onUpdateNote')(
  120. {
  121. text: newComment,
  122. },
  123. activity
  124. );
  125. await tick();
  126. expect(updateComment).toHaveBeenCalled();
  127. await tick();
  128. wrapper.update();
  129. expect(
  130. wrapper
  131. .find('NoteBody')
  132. .text()
  133. .trim()
  134. ).toEqual('incident activity comment');
  135. });
  136. it('deletes a note', async function() {
  137. const deleteComment = MockApiClient.addMockResponse({
  138. url: `/organizations/${organization.slug}/incidents/${
  139. incident.identifier
  140. }/comments/${activity.id}/`,
  141. method: 'DELETE',
  142. body: {},
  143. });
  144. const wrapper = createWrapper();
  145. await tick();
  146. // unfortunately edit/delete items are hidden until hover (using emotion)
  147. // so we can't simulate this in jest?
  148. wrapper.find('Activity').prop('onDeleteNote')(activity);
  149. await tick();
  150. expect(deleteComment).toHaveBeenCalled();
  151. await tick();
  152. wrapper.update();
  153. expect(wrapper.find('NoteBody')).toHaveLength(0);
  154. });
  155. it('fails to delete a note', async function() {
  156. const deleteComment = MockApiClient.addMockResponse({
  157. url: `/organizations/${organization.slug}/incidents/${
  158. incident.identifier
  159. }/comments/${activity.id}/`,
  160. method: 'DELETE',
  161. statusCode: 400,
  162. });
  163. const wrapper = createWrapper();
  164. await tick();
  165. // unfortunately edit/delete items are hidden until hover (using emotion)
  166. // so we can't simulate this in jest?
  167. wrapper.find('Activity').prop('onDeleteNote')(activity);
  168. await tick();
  169. expect(deleteComment).toHaveBeenCalled();
  170. await tick();
  171. wrapper.update();
  172. // old note is displayed
  173. expect(
  174. wrapper
  175. .find('NoteBody')
  176. .text()
  177. .trim()
  178. ).toEqual('incident activity comment');
  179. });
  180. });