projectIssues.spec.jsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  3. import ProjectIssues from 'sentry/views/projectDetail/projectIssues';
  4. describe('ProjectDetail > ProjectIssues', function () {
  5. let endpointMock, filteredEndpointMock, newIssuesEndpointMock;
  6. const {organization, router, routerContext} = initializeOrg({
  7. organization: {
  8. features: ['discover-basic'],
  9. },
  10. });
  11. beforeEach(function () {
  12. endpointMock = MockApiClient.addMockResponse({
  13. url: `/organizations/${organization.slug}/issues/?limit=5&query=error.unhandled%3Atrue%20is%3Aunresolved&sort=freq&statsPeriod=14d`,
  14. body: [TestStubs.Group(), TestStubs.Group({id: '2'})],
  15. });
  16. filteredEndpointMock = MockApiClient.addMockResponse({
  17. url: `/organizations/${organization.slug}/issues/?environment=staging&limit=5&query=error.unhandled%3Atrue%20is%3Aunresolved&sort=freq&statsPeriod=7d`,
  18. body: [TestStubs.Group(), TestStubs.Group({id: '2'})],
  19. });
  20. newIssuesEndpointMock = MockApiClient.addMockResponse({
  21. url: `/organizations/${organization.slug}/issues/?limit=5&query=is%3Aunresolved%20is%3Afor_review&sort=freq&statsPeriod=14d`,
  22. body: [TestStubs.Group(), TestStubs.Group({id: '2'})],
  23. });
  24. MockApiClient.addMockResponse({
  25. url: `/organizations/${organization.slug}/users/`,
  26. body: [],
  27. });
  28. });
  29. afterEach(function () {
  30. MockApiClient.clearMockResponses();
  31. jest.clearAllMocks();
  32. });
  33. it('renders a list', async function () {
  34. MockApiClient.addMockResponse({
  35. url: `/organizations/org-slug/issues/?limit=5&query=error.unhandled%3Atrue%20is%3Aunresolved&sort=freq&statsPeriod=14d`,
  36. body: [TestStubs.Group(), TestStubs.Group({id: '2'})],
  37. });
  38. render(<ProjectIssues organization={organization} location={router.location} />, {
  39. context: routerContext,
  40. organization,
  41. });
  42. expect(await screen.findAllByTestId('group')).toHaveLength(2);
  43. });
  44. it('renders a link to Issues', function () {
  45. render(<ProjectIssues organization={organization} location={router.location} />, {
  46. context: routerContext,
  47. organization,
  48. });
  49. const link = screen.getByLabelText('Open in Issues');
  50. expect(link).toBeInTheDocument();
  51. userEvent.click(link);
  52. expect(router.push).toHaveBeenCalledWith({
  53. pathname: '/organizations/org-slug/issues/',
  54. query: {
  55. limit: 5,
  56. query: 'error.unhandled:true is:unresolved',
  57. sort: 'freq',
  58. statsPeriod: '14d',
  59. },
  60. });
  61. });
  62. it('renders a segmented control', function () {
  63. render(<ProjectIssues organization={organization} location={router.location} />, {
  64. context: routerContext,
  65. organization,
  66. });
  67. // "Unhandled" segment is selected
  68. const unhandledSegment = screen.getByRole('radio', {name: 'Unhandled 0'});
  69. expect(unhandledSegment).toBeInTheDocument();
  70. expect(unhandledSegment).toBeChecked();
  71. // Select "New Issues" segment
  72. const newIssuesSegment = screen.getByRole('radio', {name: 'New Issues 0'});
  73. expect(newIssuesSegment).toBeInTheDocument();
  74. expect(newIssuesSegment).not.toBeChecked();
  75. userEvent.click(newIssuesSegment);
  76. waitFor(() => expect(newIssuesSegment).toBeChecked());
  77. expect(newIssuesEndpointMock).toHaveBeenCalled();
  78. });
  79. it('renders a link to Discover', function () {
  80. render(<ProjectIssues organization={organization} location={router.location} />, {
  81. context: routerContext,
  82. organization,
  83. });
  84. const link = screen.getByLabelText('Open in Discover');
  85. expect(link).toBeInTheDocument();
  86. userEvent.click(link);
  87. expect(router.push).toHaveBeenCalledWith({
  88. pathname: `/organizations/${organization.slug}/discover/results/`,
  89. query: {
  90. display: 'top5',
  91. field: ['issue', 'title', 'count()', 'count_unique(user)', 'project'],
  92. name: 'Frequent Unhandled Issues',
  93. query: 'event.type:error error.unhandled:true',
  94. sort: ['-count'],
  95. statsPeriod: '14d',
  96. },
  97. });
  98. });
  99. it('changes according to global header', function () {
  100. render(
  101. <ProjectIssues
  102. organization={organization}
  103. location={{
  104. query: {statsPeriod: '7d', environment: 'staging', somethingBad: 'nope'},
  105. }}
  106. />,
  107. {context: routerContext, organization}
  108. );
  109. expect(endpointMock).toHaveBeenCalledTimes(0);
  110. expect(filteredEndpointMock).toHaveBeenCalledTimes(1);
  111. const link = screen.getByLabelText('Open in Issues');
  112. expect(link).toBeInTheDocument();
  113. userEvent.click(link);
  114. expect(router.push).toHaveBeenCalledWith({
  115. pathname: `/organizations/${organization.slug}/issues/`,
  116. query: {
  117. limit: 5,
  118. environment: 'staging',
  119. statsPeriod: '7d',
  120. query: 'error.unhandled:true is:unresolved',
  121. sort: 'freq',
  122. },
  123. });
  124. });
  125. });