index.spec.tsx 5.0 KB

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