index.spec.jsx 9.3 KB

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