index.spec.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import {UserFeedback as UserFeedbackFixture} from 'sentry-fixture/userFeedback';
  2. import {initializeOrg} from 'sentry-test/initializeOrg';
  3. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  4. import ProjectsStore from 'sentry/stores/projectsStore';
  5. import UserFeedback from 'sentry/views/userFeedback';
  6. describe('UserFeedback', function () {
  7. const {organization, router, routerContext} = initializeOrg();
  8. const pageLinks =
  9. '<https://sentry.io/api/0/organizations/sentry/user-feedback/?statsPeriod=14d&cursor=0:0:1>; rel="previous"; results="false"; cursor="0:0:1", ' +
  10. '<https://sentry.io/api/0/organizations/sentry/user-feedback/?statsPeriod=14d&cursor=0:100:0>; rel="next"; results="true"; cursor="0:100:0"';
  11. const project = TestStubs.Project({isMember: true});
  12. const routeProps = {
  13. routes: router.routes,
  14. route: {},
  15. router,
  16. location: router.location,
  17. routeParams: router.params,
  18. };
  19. beforeEach(function () {
  20. ProjectsStore.loadInitialData([project]);
  21. MockApiClient.addMockResponse({
  22. url: '/organizations/org-slug/user-feedback/',
  23. body: [UserFeedbackFixture()],
  24. headers: {Link: pageLinks},
  25. });
  26. MockApiClient.addMockResponse({
  27. url: '/organizations/org-slug/environments/',
  28. body: TestStubs.Environments(),
  29. });
  30. });
  31. afterEach(function () {
  32. ProjectsStore.reset();
  33. });
  34. it('renders', function () {
  35. const params = {
  36. organization: TestStubs.Organization(),
  37. params: {
  38. orgId: organization.slug,
  39. },
  40. ...routeProps,
  41. };
  42. MockApiClient.addMockResponse({
  43. url: '/organizations/org-slug/projects/',
  44. body: [project],
  45. headers: {Link: pageLinks},
  46. });
  47. render(<UserFeedback {...params} />, {context: routerContext});
  48. expect(screen.getByText('Something bad happened')).toBeInTheDocument();
  49. });
  50. it('renders no project message', function () {
  51. ProjectsStore.loadInitialData([]);
  52. const params = {
  53. organization: TestStubs.Organization(),
  54. params: {
  55. orgId: organization.slug,
  56. },
  57. ...routeProps,
  58. };
  59. render(<UserFeedback {...params} />, {context: routerContext});
  60. expect(
  61. screen.getByText('You need at least one project to use this view')
  62. ).toBeInTheDocument();
  63. });
  64. it('renders empty state', function () {
  65. MockApiClient.addMockResponse({
  66. url: '/organizations/org-slug/user-feedback/',
  67. body: [],
  68. });
  69. const params = {
  70. organization: TestStubs.Organization({
  71. projects: [TestStubs.Project({isMember: true})],
  72. }),
  73. params: {
  74. orgId: organization.slug,
  75. },
  76. ...routeProps,
  77. };
  78. render(<UserFeedback {...params} />, {context: routerContext});
  79. expect(screen.getByTestId('user-feedback-empty')).toBeInTheDocument();
  80. });
  81. it('renders empty state with project query', function () {
  82. MockApiClient.addMockResponse({
  83. url: '/organizations/org-slug/user-feedback/',
  84. body: [],
  85. });
  86. const params = {
  87. ...routeProps,
  88. organization: TestStubs.Organization({
  89. projects: [TestStubs.Project({isMember: true})],
  90. }),
  91. location: {
  92. ...routeProps.location,
  93. pathname: 'sentry',
  94. query: {project: '112'},
  95. search: '',
  96. },
  97. params: {
  98. orgId: organization.slug,
  99. },
  100. };
  101. render(<UserFeedback {...params} />, {context: routerContext});
  102. expect(screen.getByTestId('user-feedback-empty')).toBeInTheDocument();
  103. });
  104. it('renders issue status filter', async function () {
  105. const params = {
  106. organization: TestStubs.Organization({
  107. projects: [TestStubs.Project({isMember: true})],
  108. }),
  109. params: {
  110. orgId: organization.slug,
  111. },
  112. ...routeProps,
  113. };
  114. render(<UserFeedback {...params} />, {context: routerContext});
  115. // "Unresolved" is selected by default
  116. const unresolved = screen.getByRole('radio', {name: 'Unresolved'});
  117. expect(unresolved).toBeInTheDocument();
  118. expect(unresolved).toBeChecked();
  119. // Select "All Issues"
  120. const all = screen.getByRole('radio', {name: 'All Issues'});
  121. expect(all).toBeInTheDocument();
  122. expect(all).not.toBeChecked();
  123. await userEvent.click(all);
  124. expect(router.replace).toHaveBeenCalledWith(
  125. expect.objectContaining({query: {status: ''}})
  126. );
  127. });
  128. it('renders empty state with multi project query', function () {
  129. MockApiClient.addMockResponse({
  130. url: '/organizations/org-slug/user-feedback/',
  131. body: [],
  132. });
  133. const params = {
  134. ...routeProps,
  135. organization: TestStubs.Organization({
  136. projects: [TestStubs.Project({isMember: true})],
  137. }),
  138. location: {
  139. ...routeProps.location,
  140. pathname: 'sentry',
  141. query: {project: ['112', '113']},
  142. search: '',
  143. },
  144. params: {
  145. orgId: organization.slug,
  146. },
  147. };
  148. render(<UserFeedback {...params} />, {context: routerContext});
  149. expect(screen.getByTestId('user-feedback-empty')).toBeInTheDocument();
  150. });
  151. });