createAlertButton.spec.jsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  2. import {navigateTo} from 'sentry/actionCreators/navigation';
  3. import CreateAlertButton, {
  4. CreateAlertFromViewButton,
  5. } from 'sentry/components/createAlertButton';
  6. import GuideStore from 'sentry/stores/guideStore';
  7. import EventView from 'sentry/utils/discover/eventView';
  8. import {DEFAULT_EVENT_VIEW} from 'sentry/views/discover/data';
  9. const onClickMock = jest.fn();
  10. jest.mock('sentry/actionCreators/navigation');
  11. describe('CreateAlertFromViewButton', () => {
  12. const organization = TestStubs.Organization();
  13. afterEach(() => {
  14. jest.resetAllMocks();
  15. });
  16. it('should trigger onClick callback', async () => {
  17. const context = TestStubs.routerContext();
  18. const eventView = EventView.fromSavedQuery({
  19. ...DEFAULT_EVENT_VIEW,
  20. query: 'event.type:error',
  21. projects: [2],
  22. });
  23. render(
  24. <CreateAlertFromViewButton
  25. location={location}
  26. organization={organization}
  27. eventView={eventView}
  28. projects={[TestStubs.Project()]}
  29. onClick={onClickMock}
  30. />,
  31. {context}
  32. );
  33. await userEvent.click(screen.getByRole('button', {name: 'Create Alert'}));
  34. expect(onClickMock).toHaveBeenCalledTimes(1);
  35. });
  36. it('disables the button for org-member', () => {
  37. const eventView = EventView.fromSavedQuery({
  38. ...DEFAULT_EVENT_VIEW,
  39. });
  40. const noAccessOrg = {
  41. ...organization,
  42. access: [],
  43. };
  44. const noAccessProj = {
  45. ...TestStubs.Project(),
  46. access: [],
  47. };
  48. render(
  49. <CreateAlertFromViewButton
  50. location={location}
  51. organization={noAccessOrg}
  52. eventView={eventView}
  53. projects={[noAccessProj]}
  54. onClick={onClickMock}
  55. />,
  56. {
  57. context: TestStubs.routerContext([{organization: noAccessOrg}]),
  58. organization: noAccessOrg,
  59. }
  60. );
  61. expect(screen.getByRole('button', {name: 'Create Alert'})).toBeDisabled();
  62. });
  63. it('enables the button for org-owner/manager', () => {
  64. const eventView = EventView.fromSavedQuery({
  65. ...DEFAULT_EVENT_VIEW,
  66. });
  67. const noAccessProj = {
  68. ...TestStubs.Project(),
  69. access: [],
  70. };
  71. render(
  72. <CreateAlertFromViewButton
  73. location={location}
  74. organization={organization}
  75. eventView={eventView}
  76. projects={[noAccessProj]}
  77. onClick={onClickMock}
  78. />,
  79. {
  80. context: TestStubs.routerContext([{organization}]),
  81. organization,
  82. }
  83. );
  84. expect(screen.getByRole('button', {name: 'Create Alert'})).toBeEnabled();
  85. });
  86. it('enables the button for team-admin', () => {
  87. const eventView = EventView.fromSavedQuery({
  88. ...DEFAULT_EVENT_VIEW,
  89. });
  90. const noAccessOrg = {
  91. ...organization,
  92. access: [],
  93. };
  94. const projects = [
  95. {
  96. ...TestStubs.Project(),
  97. id: 1,
  98. slug: 'admin-team',
  99. access: ['alerts:write'],
  100. },
  101. {
  102. ...TestStubs.Project(),
  103. id: 2,
  104. slug: 'contributor-team',
  105. access: ['alerts:read'],
  106. },
  107. ];
  108. render(
  109. <CreateAlertFromViewButton
  110. location={location}
  111. organization={noAccessOrg}
  112. eventView={eventView}
  113. projects={projects}
  114. onClick={onClickMock}
  115. />,
  116. {
  117. context: TestStubs.routerContext([{organization: noAccessOrg}]),
  118. organization: noAccessOrg,
  119. }
  120. );
  121. expect(screen.getByRole('button', {name: 'Create Alert'})).toBeEnabled();
  122. });
  123. it('shows a guide for org-member', () => {
  124. const noAccessOrg = {
  125. ...organization,
  126. access: [],
  127. };
  128. render(<CreateAlertButton organization={noAccessOrg} showPermissionGuide />, {
  129. organization: noAccessOrg,
  130. });
  131. expect(GuideStore.state.anchors).toEqual(new Set(['alerts_write_member']));
  132. });
  133. it('shows a guide for org-owner/manager', () => {
  134. const adminAccessOrg = {
  135. ...organization,
  136. access: ['org:write'],
  137. };
  138. render(<CreateAlertButton organization={adminAccessOrg} showPermissionGuide />, {
  139. organization: adminAccessOrg,
  140. });
  141. expect(GuideStore.state.anchors).toEqual(new Set(['alerts_write_owner']));
  142. });
  143. it('redirects to alert wizard with no project', async () => {
  144. render(<CreateAlertButton organization={organization} />, {
  145. organization,
  146. });
  147. await userEvent.click(screen.getByRole('button'));
  148. expect(navigateTo).toHaveBeenCalledWith(
  149. `/organizations/org-slug/alerts/wizard/?`,
  150. expect.objectContaining({
  151. params: expect.objectContaining({
  152. orgId: 'org-slug',
  153. }),
  154. })
  155. );
  156. });
  157. it('redirects to alert wizard with a project', () => {
  158. render(<CreateAlertButton organization={organization} projectSlug="proj-slug" />, {
  159. organization,
  160. });
  161. expect(screen.getByRole('button')).toHaveAttribute(
  162. 'href',
  163. '/organizations/org-slug/alerts/wizard/?project=proj-slug'
  164. );
  165. });
  166. it('removes a duplicate project filter', async () => {
  167. const context = TestStubs.routerContext();
  168. const eventView = EventView.fromSavedQuery({
  169. ...DEFAULT_EVENT_VIEW,
  170. query: 'event.type:error project:project-slug',
  171. projects: [2],
  172. });
  173. render(
  174. <CreateAlertFromViewButton
  175. location={location}
  176. organization={organization}
  177. eventView={eventView}
  178. projects={[TestStubs.Project()]}
  179. onClick={onClickMock}
  180. />,
  181. {context}
  182. );
  183. await userEvent.click(screen.getByRole('button'));
  184. expect(context.context.router.push).toHaveBeenCalledWith({
  185. pathname: `/organizations/org-slug/alerts/new/metric/`,
  186. query: expect.objectContaining({
  187. query: 'event.type:error ',
  188. project: 'project-slug',
  189. }),
  190. });
  191. });
  192. });