eventDetails.spec.jsx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. import React from 'react';
  2. import {mount} from 'enzyme';
  3. import {initializeOrg} from 'app-test/helpers/initializeOrg';
  4. import {browserHistory} from 'react-router';
  5. import EventDetails from 'app/views/eventsV2/eventDetails';
  6. import {ALL_VIEWS, DEFAULT_EVENT_VIEW_V1} from 'app/views/eventsV2/data';
  7. import EventView from 'app/views/eventsV2/eventView';
  8. describe('EventsV2 > EventDetails', function() {
  9. const allEventsView = EventView.fromEventViewv1(DEFAULT_EVENT_VIEW_V1);
  10. const errorsView = EventView.fromEventViewv1(
  11. ALL_VIEWS.find(view => view.name === 'Errors')
  12. );
  13. beforeEach(function() {
  14. MockApiClient.addMockResponse({
  15. url: '/organizations/org-slug/eventsv2/',
  16. body: {
  17. meta: {
  18. id: 'string',
  19. title: 'string',
  20. 'project.name': 'string',
  21. timestamp: 'date',
  22. },
  23. data: [
  24. {
  25. id: 'deadbeef',
  26. title: 'Oh no something bad',
  27. 'project.name': 'project-slug',
  28. timestamp: '2019-05-23T22:12:48+00:00',
  29. },
  30. ],
  31. },
  32. });
  33. MockApiClient.addMockResponse({
  34. url: '/organizations/org-slug/events/project-slug:deadbeef/',
  35. method: 'GET',
  36. body: {
  37. id: '1234',
  38. size: 1200,
  39. projectSlug: 'project-slug',
  40. eventID: 'deadbeef',
  41. groupID: '123',
  42. title: 'Oh no something bad',
  43. location: '/users/login',
  44. message: 'It was not good',
  45. dateCreated: '2019-05-23T22:12:48+00:00',
  46. entries: [
  47. {
  48. type: 'message',
  49. message: 'bad stuff',
  50. data: {},
  51. },
  52. ],
  53. tags: [{key: 'browser', value: 'Firefox'}],
  54. },
  55. });
  56. MockApiClient.addMockResponse({
  57. url: '/issues/123/',
  58. method: 'GET',
  59. body: TestStubs.Group({id: '123'}),
  60. });
  61. MockApiClient.addMockResponse({
  62. url: '/organizations/org-slug/events-stats/',
  63. method: 'GET',
  64. body: {
  65. data: [[1234561700, [1]], [1234561800, [1]]],
  66. },
  67. });
  68. // Missing event
  69. MockApiClient.addMockResponse({
  70. url: '/organizations/org-slug/events/project-slug:abad1/',
  71. method: 'GET',
  72. statusCode: 404,
  73. body: {},
  74. });
  75. // Error event
  76. MockApiClient.addMockResponse(
  77. {
  78. url: '/organizations/org-slug/events/latest/',
  79. method: 'GET',
  80. body: {
  81. id: '5678',
  82. size: 1200,
  83. projectSlug: 'project-slug',
  84. eventID: 'deadbeef',
  85. groupID: '123',
  86. type: 'error',
  87. title: 'Oh no something bad',
  88. message: 'It was not good',
  89. dateCreated: '2019-05-23T22:12:48+00:00',
  90. previousEventID: 'beefbeef',
  91. metadata: {
  92. type: 'Oh no something bad',
  93. },
  94. entries: [
  95. {
  96. type: 'message',
  97. message: 'bad stuff',
  98. data: {},
  99. },
  100. ],
  101. tags: [{key: 'browser', value: 'Firefox'}],
  102. },
  103. },
  104. {
  105. predicate: (_, options) => {
  106. const query = options.query.query;
  107. return (
  108. query && (query.includes('event.type:error') || query.includes('issue.id'))
  109. );
  110. },
  111. }
  112. );
  113. // Transaction event
  114. MockApiClient.addMockResponse(
  115. {
  116. url: '/organizations/org-slug/events/latest/',
  117. method: 'GET',
  118. body: {
  119. id: '5678',
  120. size: 1200,
  121. projectSlug: 'project-slug',
  122. eventID: 'deadbeef',
  123. type: 'transaction',
  124. title: 'Oh no something bad',
  125. location: '/users/login',
  126. message: 'It was not good',
  127. startTimestamp: 1564153693.2419,
  128. endTimestamp: 1564153694.4191,
  129. previousEventID: 'beefbeef',
  130. entries: [
  131. {
  132. type: 'spans',
  133. data: [],
  134. },
  135. ],
  136. tags: [{key: 'browser', value: 'Firefox'}],
  137. },
  138. },
  139. {
  140. predicate: (_, options) => {
  141. return options.query.query && options.query.query.includes('transaction');
  142. },
  143. }
  144. );
  145. });
  146. it('renders', function() {
  147. const wrapper = mount(
  148. <EventDetails
  149. organization={TestStubs.Organization({projects: [TestStubs.Project()]})}
  150. eventSlug="project-slug:deadbeef"
  151. location={{query: {eventSlug: 'project-slug:deadbeef'}}}
  152. eventView={allEventsView}
  153. />,
  154. TestStubs.routerContext()
  155. );
  156. const content = wrapper.find('EventHeader');
  157. expect(content.text()).toContain('Oh no something bad');
  158. const graph = wrapper.find('ModalLineGraph');
  159. expect(graph).toHaveLength(0);
  160. });
  161. it('renders a 404', function() {
  162. const wrapper = mount(
  163. <EventDetails
  164. organization={TestStubs.Organization({projects: [TestStubs.Project()]})}
  165. eventSlug="project-slug:abad1"
  166. location={{query: {eventSlug: 'project-slug:abad1'}}}
  167. eventView={allEventsView}
  168. />,
  169. TestStubs.routerContext()
  170. );
  171. const content = wrapper.find('NotFound');
  172. expect(content).toHaveLength(1);
  173. });
  174. it('renders a chart in grouped view', function() {
  175. const wrapper = mount(
  176. <EventDetails
  177. organization={TestStubs.Organization({projects: [TestStubs.Project()]})}
  178. eventSlug="project-slug:deadbeef"
  179. location={{query: {eventSlug: 'project-slug:deadbeef'}}}
  180. eventView={errorsView}
  181. />,
  182. TestStubs.routerContext()
  183. );
  184. const content = wrapper.find('EventHeader');
  185. expect(content.text()).toContain('Oh no something bad');
  186. const graph = wrapper.find('ModalLineGraph');
  187. expect(graph).toHaveLength(1);
  188. });
  189. it('removes eventSlug when close button is clicked', function() {
  190. const wrapper = mount(
  191. <EventDetails
  192. organization={TestStubs.Organization({projects: [TestStubs.Project()]})}
  193. eventSlug="project-slug:deadbeef"
  194. location={{
  195. pathname: '/organizations/org-slug/events/',
  196. query: {eventSlug: 'project-slug:deadbeef'},
  197. }}
  198. eventView={allEventsView}
  199. />,
  200. TestStubs.routerContext()
  201. );
  202. const button = wrapper.find('DismissButton');
  203. button.simulate('click');
  204. expect(browserHistory.push).toHaveBeenCalledWith({
  205. pathname: '/organizations/org-slug/events/',
  206. query: {},
  207. });
  208. });
  209. it('navigates when tag values are clicked', async function() {
  210. const {organization, routerContext} = initializeOrg({
  211. organization: TestStubs.Organization({projects: [TestStubs.Project()]}),
  212. router: {
  213. location: {
  214. pathname: '/organizations/org-slug/events/',
  215. query: {
  216. eventSlug: 'project-slug:deadbeef',
  217. },
  218. },
  219. },
  220. });
  221. const wrapper = mount(
  222. <EventDetails
  223. organization={organization}
  224. eventSlug="project-slug:deadbeef"
  225. location={{query: {eventSlug: 'project-slug:deadbeef'}}}
  226. eventView={allEventsView}
  227. />,
  228. routerContext
  229. );
  230. await tick();
  231. await wrapper.update();
  232. // Get the first link as we wrap react-router's link
  233. const tagLink = wrapper.find('EventDetails TagsTable TagValue Link').first();
  234. // Should remove eventSlug and append new tag value causing
  235. // the view to re-render
  236. expect(tagLink.props().to).toEqual({
  237. pathname: '/organizations/org-slug/events/',
  238. query: {query: 'browser:"Firefox"'},
  239. });
  240. });
  241. it('appends tag value to existing query when clicked', async function() {
  242. const {organization, routerContext} = initializeOrg({
  243. organization: TestStubs.Organization({projects: [TestStubs.Project()]}),
  244. router: {
  245. location: {
  246. pathname: '/organizations/org-slug/events/',
  247. query: {
  248. query: 'Dumpster',
  249. eventSlug: 'project-slug:deadbeef',
  250. },
  251. },
  252. },
  253. });
  254. const wrapper = mount(
  255. <EventDetails
  256. organization={organization}
  257. eventSlug="project-slug:deadbeef"
  258. location={{query: {eventSlug: 'project-slug:deadbeef'}}}
  259. eventView={allEventsView}
  260. />,
  261. routerContext
  262. );
  263. await tick();
  264. await wrapper.update();
  265. // Get the first link as we wrap react-router's link
  266. const tagLink = wrapper.find('EventDetails TagsTable TagValue Link').first();
  267. // Should remove eventSlug and append new tag value causing
  268. // the view to re-render
  269. expect(tagLink.props().to).toEqual({
  270. pathname: '/organizations/org-slug/events/',
  271. query: {query: 'Dumpster browser:"Firefox"'},
  272. });
  273. });
  274. });