index.spec.jsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {act, render, screen} from 'sentry-test/reactTestingLibrary';
  3. import ProjectsStore from 'sentry/stores/projectsStore';
  4. import EventView from 'sentry/utils/discover/eventView';
  5. import {ALL_VIEWS, DEFAULT_EVENT_VIEW} from 'sentry/views/eventsV2/data';
  6. import EventDetails from 'sentry/views/eventsV2/eventDetails';
  7. describe('EventsV2 > EventDetails', function () {
  8. const allEventsView = EventView.fromSavedQuery(DEFAULT_EVENT_VIEW);
  9. const errorsView = EventView.fromSavedQuery(
  10. ALL_VIEWS.find(view => view.name === 'Errors by Title')
  11. );
  12. beforeEach(function () {
  13. act(() => ProjectsStore.loadInitialData([TestStubs.Project()]));
  14. MockApiClient.addMockResponse({
  15. url: '/organizations/org-slug/projects/',
  16. body: [],
  17. });
  18. MockApiClient.addMockResponse({
  19. url: '/organizations/org-slug/discover/',
  20. body: {
  21. meta: {
  22. id: 'string',
  23. title: 'string',
  24. 'project.name': 'string',
  25. timestamp: 'date',
  26. },
  27. data: [
  28. {
  29. id: 'deadbeef',
  30. title: 'Oh no something bad',
  31. 'project.name': 'project-slug',
  32. timestamp: '2019-05-23T22:12:48+00:00',
  33. },
  34. ],
  35. },
  36. });
  37. MockApiClient.addMockResponse({
  38. url: '/organizations/org-slug/events/project-slug:deadbeef/',
  39. method: 'GET',
  40. body: {
  41. id: '1234',
  42. size: 1200,
  43. projectSlug: 'project-slug',
  44. eventID: 'deadbeef',
  45. groupID: '123',
  46. title: 'Oh no something bad',
  47. location: '/users/login',
  48. message: 'It was not good',
  49. dateCreated: '2019-05-23T22:12:48+00:00',
  50. entries: [
  51. {
  52. type: 'message',
  53. message: 'bad stuff',
  54. data: {},
  55. },
  56. ],
  57. tags: [
  58. {key: 'browser', value: 'Firefox'},
  59. {key: 'device.uuid', value: 'test-uuid'},
  60. {key: 'release', value: '82ebf297206a'},
  61. ],
  62. },
  63. });
  64. MockApiClient.addMockResponse({
  65. url: '/issues/123/',
  66. method: 'GET',
  67. body: TestStubs.Group({id: '123'}),
  68. });
  69. MockApiClient.addMockResponse({
  70. url: '/organizations/org-slug/events-stats/',
  71. method: 'GET',
  72. body: {
  73. data: [
  74. [1234561700, [1]],
  75. [1234561800, [1]],
  76. ],
  77. },
  78. });
  79. MockApiClient.addMockResponse({
  80. url: '/projects/org-slug/project-slug/events/1234/committers/',
  81. method: 'GET',
  82. statusCode: 404,
  83. body: {},
  84. });
  85. MockApiClient.addMockResponse({
  86. url: '/projects/org-slug/project-slug/events/1234/grouping-info/',
  87. body: {},
  88. });
  89. // Missing event
  90. MockApiClient.addMockResponse({
  91. url: '/organizations/org-slug/events/project-slug:abad1/',
  92. method: 'GET',
  93. statusCode: 404,
  94. body: {},
  95. });
  96. });
  97. it('renders', async function () {
  98. render(
  99. <EventDetails
  100. organization={TestStubs.Organization()}
  101. params={{eventSlug: 'project-slug:deadbeef'}}
  102. location={{query: allEventsView.generateQueryStringObject()}}
  103. />
  104. );
  105. expect(await screen.findByText('Oh no something bad')).toBeInTheDocument();
  106. });
  107. it('renders a 404', async function () {
  108. render(
  109. <EventDetails
  110. organization={TestStubs.Organization()}
  111. params={{eventSlug: 'project-slug:abad1'}}
  112. location={{query: allEventsView.generateQueryStringObject()}}
  113. />
  114. );
  115. expect(await screen.findByText('Page Not Found')).toBeInTheDocument();
  116. });
  117. it('renders a chart in grouped view', async function () {
  118. render(
  119. <EventDetails
  120. organization={TestStubs.Organization()}
  121. params={{eventSlug: 'project-slug:deadbeef'}}
  122. location={{query: errorsView.generateQueryStringObject()}}
  123. />
  124. );
  125. expect(await screen.findByText('Oh no something bad')).toBeInTheDocument();
  126. });
  127. it('renders an alert when linked issues are missing', async function () {
  128. MockApiClient.addMockResponse({
  129. url: '/issues/123/',
  130. statusCode: 404,
  131. method: 'GET',
  132. body: {},
  133. });
  134. render(
  135. <EventDetails
  136. organization={TestStubs.Organization()}
  137. params={{eventSlug: 'project-slug:deadbeef'}}
  138. location={{query: allEventsView.generateQueryStringObject()}}
  139. />
  140. );
  141. expect(
  142. await screen.findByText(
  143. 'The linked issue cannot be found. It may have been deleted, or merged.'
  144. )
  145. ).toBeInTheDocument();
  146. });
  147. it('navigates when tag values are clicked', async function () {
  148. const {organization, routerContext} = initializeOrg({
  149. organization: TestStubs.Organization(),
  150. router: {
  151. location: {
  152. pathname: '/organizations/org-slug/discover/project-slug:deadbeef',
  153. query: {},
  154. },
  155. },
  156. });
  157. render(
  158. <EventDetails
  159. organization={organization}
  160. params={{eventSlug: 'project-slug:deadbeef'}}
  161. location={{query: allEventsView.generateQueryStringObject()}}
  162. />,
  163. {context: routerContext}
  164. );
  165. // Get the first link as we wrap react-router's link
  166. expect(await screen.findByText('Firefox')).toBeInTheDocument();
  167. expect(screen.getByRole('link', {name: 'Firefox'})).toHaveAttribute(
  168. 'href',
  169. '/organizations/org-slug/discover/results/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=browser%3AFirefox%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  170. );
  171. // Get the second link
  172. expect(screen.getByRole('link', {name: 'test-uuid'})).toHaveAttribute(
  173. 'href',
  174. '/organizations/org-slug/discover/results/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=tags%5Bdevice.uuid%5D%3Atest-uuid%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  175. );
  176. // Get the third link
  177. expect(screen.getByRole('link', {name: '82ebf297206a'})).toHaveAttribute(
  178. 'href',
  179. '/organizations/org-slug/discover/results/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=release%3A82ebf297206a%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  180. );
  181. });
  182. it('navigates to homepage when tag values are clicked', async function () {
  183. const {organization, routerContext, router} = initializeOrg({
  184. organization: TestStubs.Organization(),
  185. router: {
  186. location: {
  187. pathname: '/organizations/org-slug/discover/project-slug:deadbeef',
  188. query: {...allEventsView.generateQueryStringObject(), homepage: 'true'},
  189. },
  190. },
  191. });
  192. render(
  193. <EventDetails
  194. organization={organization}
  195. params={{eventSlug: 'project-slug:deadbeef'}}
  196. location={router.location}
  197. />,
  198. {context: routerContext}
  199. );
  200. // Get the first link as we wrap react-router's link
  201. expect(await screen.findByText('Firefox')).toBeInTheDocument();
  202. expect(screen.getByRole('link', {name: 'Firefox'})).toHaveAttribute(
  203. 'href',
  204. '/organizations/org-slug/discover/homepage/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=browser%3AFirefox%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  205. );
  206. // Get the second link
  207. expect(screen.getByRole('link', {name: 'test-uuid'})).toHaveAttribute(
  208. 'href',
  209. '/organizations/org-slug/discover/homepage/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=tags%5Bdevice.uuid%5D%3Atest-uuid%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  210. );
  211. // Get the third link
  212. expect(screen.getByRole('link', {name: '82ebf297206a'})).toHaveAttribute(
  213. 'href',
  214. '/organizations/org-slug/discover/homepage/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=release%3A82ebf297206a%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  215. );
  216. });
  217. it('appends tag value to existing query when clicked', async function () {
  218. const {organization, routerContext} = initializeOrg({
  219. organization: TestStubs.Organization(),
  220. router: {
  221. location: {
  222. pathname: '/organizations/org-slug/discover/project-slug:deadbeef',
  223. query: {},
  224. },
  225. },
  226. });
  227. render(
  228. <EventDetails
  229. organization={organization}
  230. params={{eventSlug: 'project-slug:deadbeef'}}
  231. location={{
  232. query: {...allEventsView.generateQueryStringObject(), query: 'Dumpster'},
  233. }}
  234. />,
  235. {context: routerContext}
  236. );
  237. // Get the first link as we wrap react-router's link
  238. expect(await screen.findByText('Firefox')).toBeInTheDocument();
  239. expect(screen.getByRole('link', {name: 'Firefox'})).toHaveAttribute(
  240. 'href',
  241. '/organizations/org-slug/discover/results/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=Dumpster%20browser%3AFirefox%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  242. );
  243. // Get the second link
  244. expect(screen.getByRole('link', {name: 'test-uuid'})).toHaveAttribute(
  245. 'href',
  246. '/organizations/org-slug/discover/results/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=Dumpster%20tags%5Bdevice.uuid%5D%3Atest-uuid%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  247. );
  248. // Get the third link
  249. expect(screen.getByRole('link', {name: '82ebf297206a'})).toHaveAttribute(
  250. 'href',
  251. '/organizations/org-slug/discover/results/?field=title&field=event.type&field=project&field=user.display&field=timestamp&name=All%20Events&query=Dumpster%20release%3A82ebf297206a%20title%3A%22Oh%20no%20something%20bad%22&sort=-timestamp&statsPeriod=24h&yAxis=count%28%29'
  252. );
  253. });
  254. it('links back to the homepage if the query param contains homepage flag', async () => {
  255. const {organization, router, routerContext} = initializeOrg({
  256. organization: TestStubs.Organization({
  257. features: ['discover-query-builder-as-landing-page'],
  258. }),
  259. router: {
  260. location: {
  261. pathname: '/organizations/org-slug/discover/project-slug:deadbeef',
  262. query: {...allEventsView.generateQueryStringObject(), homepage: true},
  263. },
  264. },
  265. });
  266. render(
  267. <EventDetails
  268. organization={organization}
  269. params={{eventSlug: 'project-slug:deadbeef'}}
  270. location={router.location}
  271. />,
  272. {context: routerContext, organization}
  273. );
  274. expect((await screen.findByText('Discover')).pathname).toEqual(
  275. '/organizations/org-slug/discover/homepage/'
  276. );
  277. });
  278. });