issueAlertOptions.spec.tsx 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import selectEvent from 'react-select-event';
  2. import {initializeOrg} from 'sentry-test/initializeOrg';
  3. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  4. import IssueAlertOptions from 'sentry/views/projectInstall/issueAlertOptions';
  5. describe('IssueAlertOptions', function () {
  6. const {organization} = initializeOrg();
  7. const URL = `/projects/${organization.slug}/rule-conditions/`;
  8. const props = {
  9. onChange: jest.fn(),
  10. };
  11. beforeEach(() => {
  12. MockApiClient.addMockResponse({
  13. url: `/projects/${organization.slug}/rule-conditions/`,
  14. body: TestStubs.MOCK_RESP_VERBOSE,
  15. });
  16. });
  17. afterEach(() => {
  18. MockApiClient.clearMockResponses();
  19. jest.clearAllMocks();
  20. });
  21. it('should render only the `Default Rule` and `Create Later` option on empty response:[]', () => {
  22. MockApiClient.addMockResponse({
  23. url: URL,
  24. body: [],
  25. });
  26. render(<IssueAlertOptions {...props} />, {organization});
  27. expect(screen.getAllByRole('radio')).toHaveLength(2);
  28. });
  29. it('should render only the `Default Rule` and `Create Later` option on empty response:{}', () => {
  30. MockApiClient.addMockResponse({
  31. url: URL,
  32. body: {},
  33. });
  34. render(<IssueAlertOptions {...props} />, {organization});
  35. expect(screen.getAllByRole('radio')).toHaveLength(2);
  36. });
  37. it('should render only the `Default Rule` and `Create Later` option on responses with different allowable intervals', () => {
  38. MockApiClient.addMockResponse({
  39. url: URL,
  40. body: TestStubs.MOCK_RESP_INCONSISTENT_INTERVALS,
  41. });
  42. render(<IssueAlertOptions {...props} />, {organization});
  43. expect(screen.getAllByRole('radio')).toHaveLength(2);
  44. });
  45. it('should render all(three) options on responses with different placeholder values', () => {
  46. MockApiClient.addMockResponse({
  47. url: URL,
  48. body: TestStubs.MOCK_RESP_INCONSISTENT_PLACEHOLDERS,
  49. });
  50. render(<IssueAlertOptions {...props} />, {organization});
  51. expect(screen.getAllByRole('radio')).toHaveLength(3);
  52. });
  53. it('should ignore conditions that are not `sentry.rules.conditions.event_frequency.EventFrequencyCondition` and `sentry.rules.conditions.event_frequency.EventUniqueUserFrequencyCondition`', async () => {
  54. MockApiClient.addMockResponse({
  55. url: URL,
  56. body: TestStubs.MOCK_RESP_ONLY_IGNORED_CONDITIONS_INVALID,
  57. });
  58. render(<IssueAlertOptions {...props} />, {organization});
  59. expect(screen.getAllByRole('radio')).toHaveLength(3);
  60. await selectEvent.select(screen.getByText('Select...'), 'users affected by');
  61. expect(props.onChange).toHaveBeenCalledWith(
  62. expect.objectContaining({
  63. defaultRules: false,
  64. shouldCreateCustomRule: true,
  65. })
  66. );
  67. });
  68. it('should render all(three) options on a valid response', () => {
  69. MockApiClient.addMockResponse({
  70. url: URL,
  71. body: TestStubs.MOCK_RESP_VERBOSE,
  72. });
  73. render(<IssueAlertOptions {...props} />);
  74. expect(screen.getAllByRole('radio')).toHaveLength(3);
  75. });
  76. it('should pre-populate fields from server response', async () => {
  77. MockApiClient.addMockResponse({
  78. url: URL,
  79. body: TestStubs.MOCK_RESP_VERBOSE,
  80. });
  81. render(<IssueAlertOptions {...props} />);
  82. await selectEvent.select(screen.getByText('occurrences of'), 'users affected by');
  83. await selectEvent.select(screen.getByText('one minute'), '30 days');
  84. expect(props.onChange).toHaveBeenCalledWith(
  85. expect.objectContaining({
  86. defaultRules: false,
  87. shouldCreateCustomRule: true,
  88. })
  89. );
  90. });
  91. it('should pre-fill threshold value after a valid server response', () => {
  92. MockApiClient.addMockResponse({
  93. url: URL,
  94. body: TestStubs.MOCK_RESP_VERBOSE,
  95. });
  96. render(<IssueAlertOptions {...props} />);
  97. expect(screen.getByTestId('range-input')).toHaveValue(10);
  98. });
  99. it('should provide fallthroughType with issue action for issue-alert-fallback-targeting', async () => {
  100. MockApiClient.addMockResponse({
  101. url: URL,
  102. body: TestStubs.MOCK_RESP_VERBOSE,
  103. });
  104. const org = {...organization, features: ['issue-alert-fallback-targeting']};
  105. render(<IssueAlertOptions {...props} organization={org} />);
  106. await userEvent.click(screen.getByLabelText(/When there are more than/i));
  107. expect(props.onChange).toHaveBeenCalledWith(
  108. expect.objectContaining({
  109. actions: [
  110. {
  111. id: 'sentry.mail.actions.NotifyEmailAction',
  112. targetType: 'IssueOwners',
  113. fallthroughType: 'ActiveMembers',
  114. },
  115. ],
  116. })
  117. );
  118. });
  119. });