group.spec.tsx 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import {GroupFixture} from 'sentry-fixture/group';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {ProjectFixture} from 'sentry-fixture/project';
  4. import {initializeOrg} from 'sentry-test/initializeOrg';
  5. import {act, render, screen, userEvent, within} from 'sentry-test/reactTestingLibrary';
  6. import StreamGroup from 'sentry/components/stream/group';
  7. import GroupStore from 'sentry/stores/groupStore';
  8. import GuideStore from 'sentry/stores/guideStore';
  9. import type {GroupStatusResolution, MarkReviewed} from 'sentry/types';
  10. import {EventOrGroupType, GroupStatus, PriorityLevel} from 'sentry/types';
  11. import {trackAnalytics} from 'sentry/utils/analytics';
  12. jest.mock('sentry/utils/analytics');
  13. describe('StreamGroup', function () {
  14. let group1;
  15. beforeEach(function () {
  16. group1 = GroupFixture({
  17. id: '1337',
  18. project: ProjectFixture({
  19. id: '13',
  20. slug: 'foo-project',
  21. }),
  22. type: EventOrGroupType.ERROR,
  23. inbox: {
  24. date_added: '2020-11-24T13:17:42.248751Z',
  25. reason: 0,
  26. reason_details: null,
  27. },
  28. });
  29. MockApiClient.addMockResponse({
  30. url: '/organizations/org-slug/projects/',
  31. body: [ProjectFixture({slug: 'foo-project'})],
  32. });
  33. GroupStore.loadInitialData([group1]);
  34. });
  35. afterEach(function () {
  36. jest.mocked(trackAnalytics).mockClear();
  37. GroupStore.reset();
  38. });
  39. it('renders with anchors', async function () {
  40. const {routerContext, organization} = initializeOrg();
  41. render(<StreamGroup id="1337" hasGuideAnchor {...routerContext} />, {
  42. context: routerContext,
  43. organization,
  44. });
  45. expect(await screen.findByTestId('group')).toBeInTheDocument();
  46. expect(GuideStore.state.anchors).toEqual(new Set(['dynamic_counts', 'issue_stream']));
  47. });
  48. it('marks as reviewed', async function () {
  49. const {routerContext, organization} = initializeOrg();
  50. render(
  51. <StreamGroup
  52. id="1337"
  53. query="is:unresolved is:for_review assigned_or_suggested:[me, none]"
  54. {...routerContext}
  55. />,
  56. {context: routerContext, organization}
  57. );
  58. expect(await screen.findByTestId('group')).toHaveAttribute(
  59. 'data-test-reviewed',
  60. 'false'
  61. );
  62. const data: MarkReviewed = {inbox: false};
  63. act(() => GroupStore.onUpdate('1337', undefined, data));
  64. act(() => GroupStore.onUpdateSuccess('1337', undefined, data));
  65. // Reviewed only applies styles, difficult to select with RTL
  66. expect(screen.getByTestId('group')).toHaveAttribute('data-test-reviewed', 'true');
  67. });
  68. it('marks as resolved', async function () {
  69. const {routerContext, organization} = initializeOrg();
  70. render(<StreamGroup id="1337" query="is:unresolved" />, {
  71. context: routerContext,
  72. organization,
  73. });
  74. expect(await screen.findByTestId('group')).toBeInTheDocument();
  75. expect(screen.queryByTestId('resolved-issue')).not.toBeInTheDocument();
  76. const data: GroupStatusResolution = {
  77. status: GroupStatus.RESOLVED,
  78. statusDetails: {},
  79. };
  80. act(() => GroupStore.onUpdate('1337', undefined, data));
  81. act(() => GroupStore.onUpdateSuccess('1337', undefined, data));
  82. expect(screen.getByTestId('resolved-issue')).toBeInTheDocument();
  83. });
  84. it('can change priority', async function () {
  85. MockApiClient.addMockResponse({
  86. url: '/organizations/org-slug/prompts-activity/',
  87. body: {data: {dismissed_ts: null}},
  88. });
  89. const mockModifyGroup = MockApiClient.addMockResponse({
  90. url: '/organizations/org-slug/issues/',
  91. method: 'PUT',
  92. body: {priority: PriorityLevel.HIGH},
  93. });
  94. render(<StreamGroup id="1337" query="is:unresolved" />, {
  95. organization: OrganizationFixture({features: ['issue-priority-ui']}),
  96. });
  97. const priorityDropdown = screen.getByRole('button', {name: 'Modify issue priority'});
  98. expect(within(priorityDropdown).getByText('Med')).toBeInTheDocument();
  99. await userEvent.click(priorityDropdown);
  100. await userEvent.click(screen.getByRole('menuitemradio', {name: 'High'}));
  101. expect(within(priorityDropdown).getByText('High')).toBeInTheDocument();
  102. expect(mockModifyGroup).toHaveBeenCalledWith(
  103. '/organizations/org-slug/issues/',
  104. expect.objectContaining({
  105. data: expect.objectContaining({
  106. priority: 'high',
  107. }),
  108. })
  109. );
  110. });
  111. it('tracks clicks from issues stream', async function () {
  112. const {routerContext, organization} = initializeOrg();
  113. render(
  114. <StreamGroup
  115. id="1337"
  116. query="is:unresolved is:for_review assigned_or_suggested:[me, none]"
  117. {...routerContext}
  118. />,
  119. {context: routerContext, organization}
  120. );
  121. // skipHover - Prevent stacktrace preview from being rendered
  122. await userEvent.click(screen.getByText('RequestError'), {skipHover: true});
  123. });
  124. });