index.spec.tsx 4.9 KB

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