header.spec.tsx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. import {GroupFixture} from 'sentry-fixture/group';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {ProjectFixture} from 'sentry-fixture/project';
  4. import {TeamFixture} from 'sentry-fixture/team';
  5. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  6. import {IssueCategory, PriorityLevel} from 'sentry/types/group';
  7. import {browserHistory} from 'sentry/utils/browserHistory';
  8. import GroupHeader from 'sentry/views/issueDetails/header';
  9. import {ReprocessingStatus} from 'sentry/views/issueDetails/utils';
  10. describe('GroupHeader', () => {
  11. const baseUrl = 'BASE_URL/';
  12. const organization = OrganizationFixture();
  13. const project = ProjectFixture({
  14. teams: [TeamFixture()],
  15. });
  16. describe('issue category: error, js project', () => {
  17. const defaultProps = {
  18. organization,
  19. baseUrl,
  20. group: GroupFixture({issueCategory: IssueCategory.ERROR}),
  21. groupReprocessingStatus: ReprocessingStatus.NO_STATUS,
  22. project,
  23. };
  24. it('displays the correct tabs with all features enabled', async () => {
  25. const orgWithFeatures = OrganizationFixture({
  26. features: ['similarity-view', 'event-attachments', 'session-replay'],
  27. });
  28. const jsProjectWithSimilarityView = ProjectFixture({
  29. features: ['similarity-view'],
  30. platform: 'javascript',
  31. });
  32. const MOCK_GROUP = GroupFixture();
  33. MockApiClient.addMockResponse({
  34. url: `/organizations/${organization.slug}/replay-count/`,
  35. method: 'GET',
  36. body: {
  37. [MOCK_GROUP.id]: ['replay42', 'replay256'],
  38. },
  39. });
  40. render(
  41. <GroupHeader
  42. {...defaultProps}
  43. organization={orgWithFeatures}
  44. project={jsProjectWithSimilarityView}
  45. />,
  46. {organization: orgWithFeatures}
  47. );
  48. await userEvent.click(screen.getByRole('tab', {name: /details/i}));
  49. expect(browserHistory.push).toHaveBeenLastCalledWith('BASE_URL/');
  50. await userEvent.click(screen.getByRole('tab', {name: /activity/i}));
  51. expect(browserHistory.push).toHaveBeenCalledWith({
  52. pathname: 'BASE_URL/activity/',
  53. query: {},
  54. });
  55. await userEvent.click(screen.getByRole('tab', {name: /user feedback/i}));
  56. expect(browserHistory.push).toHaveBeenCalledWith({
  57. pathname: 'BASE_URL/feedback/',
  58. query: {},
  59. });
  60. await userEvent.click(screen.getByRole('tab', {name: /attachments/i}));
  61. expect(browserHistory.push).toHaveBeenCalledWith({
  62. pathname: 'BASE_URL/attachments/',
  63. query: {},
  64. });
  65. await userEvent.click(screen.getByRole('tab', {name: /tags/i}));
  66. expect(browserHistory.push).toHaveBeenCalledWith({
  67. pathname: 'BASE_URL/tags/',
  68. query: {},
  69. });
  70. await userEvent.click(screen.getByRole('tab', {name: /all events/i}));
  71. expect(browserHistory.push).toHaveBeenCalledWith({
  72. pathname: 'BASE_URL/events/',
  73. query: {},
  74. });
  75. await userEvent.click(screen.getByRole('tab', {name: /merged issues/i}));
  76. expect(browserHistory.push).toHaveBeenCalledWith({
  77. pathname: 'BASE_URL/merged/',
  78. query: {},
  79. });
  80. await userEvent.click(screen.getByRole('tab', {name: /replays/i}));
  81. expect(browserHistory.push).toHaveBeenCalledWith({
  82. pathname: 'BASE_URL/replays/',
  83. query: {},
  84. });
  85. expect(screen.queryByRole('tab', {name: /replays/i})).toBeInTheDocument();
  86. });
  87. });
  88. describe('issue category: error, mobile project', () => {
  89. const defaultProps = {
  90. organization,
  91. baseUrl,
  92. group: GroupFixture({issueCategory: IssueCategory.ERROR}),
  93. groupReprocessingStatus: ReprocessingStatus.NO_STATUS,
  94. project,
  95. };
  96. it('displays the correct tabs with all features enabled', async () => {
  97. const orgWithFeatures = OrganizationFixture({
  98. features: ['similarity-view', 'event-attachments', 'session-replay'],
  99. });
  100. const mobileProjectWithSimilarityView = ProjectFixture({
  101. features: ['similarity-view'],
  102. platform: 'unity',
  103. });
  104. const MOCK_GROUP = GroupFixture();
  105. MockApiClient.addMockResponse({
  106. url: `/organizations/${organization.slug}/replay-count/`,
  107. method: 'GET',
  108. body: {
  109. [MOCK_GROUP.id]: ['replay42', 'replay256'],
  110. },
  111. });
  112. render(
  113. <GroupHeader
  114. {...defaultProps}
  115. organization={orgWithFeatures}
  116. project={mobileProjectWithSimilarityView}
  117. />,
  118. {organization: orgWithFeatures}
  119. );
  120. await userEvent.click(screen.getByRole('tab', {name: /similar issues/i}));
  121. expect(browserHistory.push).toHaveBeenCalledWith({
  122. pathname: 'BASE_URL/similar/',
  123. query: {},
  124. });
  125. expect(screen.queryByRole('tab', {name: /replays/i})).not.toBeInTheDocument();
  126. });
  127. });
  128. describe('issue category: performance', () => {
  129. const defaultProps = {
  130. organization,
  131. baseUrl,
  132. group: GroupFixture({issueCategory: IssueCategory.PERFORMANCE}),
  133. groupReprocessingStatus: ReprocessingStatus.NO_STATUS,
  134. project,
  135. };
  136. it('displays the correct tabs with all features enabled', async () => {
  137. const orgWithFeatures = OrganizationFixture({
  138. features: ['similarity-view', 'event-attachments', 'session-replay'],
  139. });
  140. const projectWithSimilarityView = ProjectFixture({
  141. features: ['similarity-view'],
  142. });
  143. const MOCK_GROUP = GroupFixture({issueCategory: IssueCategory.PERFORMANCE});
  144. MockApiClient.addMockResponse({
  145. url: `/organizations/${organization.slug}/replay-count/`,
  146. method: 'GET',
  147. body: {
  148. [MOCK_GROUP.id]: ['replay42', 'replay256'],
  149. },
  150. });
  151. render(
  152. <GroupHeader
  153. {...defaultProps}
  154. organization={orgWithFeatures}
  155. project={projectWithSimilarityView}
  156. />,
  157. {organization: orgWithFeatures}
  158. );
  159. await userEvent.click(screen.getByRole('tab', {name: /details/i}));
  160. expect(browserHistory.push).toHaveBeenLastCalledWith('BASE_URL/');
  161. await userEvent.click(screen.getByRole('tab', {name: /tags/i}));
  162. expect(browserHistory.push).toHaveBeenCalledWith({
  163. pathname: 'BASE_URL/tags/',
  164. query: {},
  165. });
  166. await userEvent.click(screen.getByRole('tab', {name: /sampled events/i}));
  167. expect(browserHistory.push).toHaveBeenCalledWith({
  168. pathname: 'BASE_URL/events/',
  169. query: {},
  170. });
  171. expect(screen.queryByRole('tab', {name: /user feedback/i})).not.toBeInTheDocument();
  172. expect(screen.queryByRole('tab', {name: /attachments/i})).not.toBeInTheDocument();
  173. expect(screen.queryByRole('tab', {name: /merged issues/i})).not.toBeInTheDocument();
  174. expect(
  175. screen.queryByRole('tab', {name: /similar issues/i})
  176. ).not.toBeInTheDocument();
  177. expect(screen.queryByRole('tab', {name: /replays/i})).not.toBeInTheDocument();
  178. });
  179. });
  180. describe('priority', () => {
  181. beforeEach(() => {
  182. MockApiClient.addMockResponse({
  183. url: '/organizations/org-slug/prompts-activity/',
  184. body: {data: {dismissed_ts: null}},
  185. });
  186. MockApiClient.addMockResponse({
  187. url: '/organizations/org-slug/replay-count/',
  188. body: {},
  189. });
  190. });
  191. it('shows priority even if stats is off', async () => {
  192. render(
  193. <GroupHeader
  194. baseUrl=""
  195. organization={OrganizationFixture()}
  196. group={GroupFixture({
  197. priority: PriorityLevel.HIGH,
  198. // Setting an issue category where stats are turned off
  199. issueCategory: IssueCategory.UPTIME,
  200. })}
  201. project={ProjectFixture()}
  202. groupReprocessingStatus={ReprocessingStatus.NO_STATUS}
  203. />
  204. );
  205. expect(await screen.findByText('Priority')).toBeInTheDocument();
  206. expect(await screen.findByText('High')).toBeInTheDocument();
  207. });
  208. it('can change priority', async () => {
  209. const mockModifyIssue = MockApiClient.addMockResponse({
  210. url: `/organizations/org-slug/issues/`,
  211. method: 'PUT',
  212. body: {},
  213. });
  214. render(
  215. <GroupHeader
  216. baseUrl=""
  217. organization={OrganizationFixture()}
  218. group={GroupFixture({priority: PriorityLevel.MEDIUM})}
  219. project={ProjectFixture()}
  220. groupReprocessingStatus={ReprocessingStatus.NO_STATUS}
  221. />
  222. );
  223. await userEvent.click(screen.getByRole('button', {name: 'Modify issue priority'}));
  224. await userEvent.click(screen.getByRole('menuitemradio', {name: 'High'}));
  225. expect(mockModifyIssue).toHaveBeenCalledWith(
  226. expect.anything(),
  227. expect.objectContaining({
  228. data: {priority: PriorityLevel.HIGH},
  229. })
  230. );
  231. });
  232. });
  233. });