dataExport.spec.jsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  2. import {addErrorMessage} from 'sentry/actionCreators/indicator';
  3. import WrappedDataExport from 'sentry/components/dataExport';
  4. jest.mock('sentry/actionCreators/indicator');
  5. const mockUnauthorizedOrg = TestStubs.Organization({
  6. features: [],
  7. });
  8. const mockAuthorizedOrg = TestStubs.Organization({
  9. features: ['discover-query'],
  10. });
  11. const mockPayload = {
  12. queryType: 'Issues-by-Tag',
  13. queryInfo: {project_id: '1', group_id: '1027', key: 'user'},
  14. };
  15. const mockRouterContext = mockOrganization =>
  16. TestStubs.routerContext([
  17. {
  18. organization: mockOrganization,
  19. },
  20. ]);
  21. describe('DataExport', function () {
  22. it('should not render anything for an unauthorized organization', function () {
  23. render(<WrappedDataExport payload={mockPayload} />, {
  24. context: mockRouterContext(mockUnauthorizedOrg),
  25. });
  26. expect(screen.queryByRole('button')).not.toBeInTheDocument();
  27. });
  28. it('should render the button for an authorized organization', function () {
  29. render(<WrappedDataExport payload={mockPayload} />, {
  30. context: mockRouterContext(mockAuthorizedOrg),
  31. });
  32. expect(screen.getByText(/Export All to CSV/)).toBeInTheDocument();
  33. });
  34. it('should render custom children if provided', function () {
  35. render(
  36. <WrappedDataExport payload={mockPayload}>
  37. This is an example string
  38. </WrappedDataExport>,
  39. {context: mockRouterContext(mockAuthorizedOrg)}
  40. );
  41. expect(screen.getByText(/This is an example string/)).toBeInTheDocument();
  42. });
  43. it('should respect the disabled prop and not be clickable', async function () {
  44. const postDataExport = MockApiClient.addMockResponse({
  45. url: `/organizations/${mockAuthorizedOrg.slug}/data-export/`,
  46. method: 'POST',
  47. body: {id: 721},
  48. });
  49. render(<WrappedDataExport payload={mockPayload} disabled />, {
  50. context: mockRouterContext(mockAuthorizedOrg),
  51. });
  52. await userEvent.click(screen.getByRole('button'));
  53. expect(postDataExport).not.toHaveBeenCalled();
  54. expect(screen.getByRole('button')).toBeDisabled();
  55. });
  56. it('should send a request and disable itself when clicked', async function () {
  57. const postDataExport = MockApiClient.addMockResponse({
  58. url: `/organizations/${mockAuthorizedOrg.slug}/data-export/`,
  59. method: 'POST',
  60. body: {id: 721},
  61. });
  62. render(<WrappedDataExport payload={mockPayload} />, {
  63. context: mockRouterContext(mockAuthorizedOrg),
  64. });
  65. await userEvent.click(screen.getByRole('button'));
  66. expect(postDataExport).toHaveBeenCalledWith(
  67. `/organizations/${mockAuthorizedOrg.slug}/data-export/`,
  68. {
  69. data: {
  70. query_type: mockPayload.queryType,
  71. query_info: mockPayload.queryInfo,
  72. },
  73. method: 'POST',
  74. error: expect.anything(),
  75. success: expect.anything(),
  76. }
  77. );
  78. await waitFor(() => {
  79. expect(screen.getByRole('button')).toBeDisabled();
  80. });
  81. });
  82. it('should reset the state when receiving a new payload', async function () {
  83. MockApiClient.addMockResponse({
  84. url: `/organizations/${mockAuthorizedOrg.slug}/data-export/`,
  85. method: 'POST',
  86. body: {id: 721},
  87. });
  88. const {rerender} = render(<WrappedDataExport payload={mockPayload} />, {
  89. context: mockRouterContext(mockAuthorizedOrg),
  90. });
  91. await userEvent.click(screen.getByText(/Export All to CSV/));
  92. await waitFor(() => {
  93. expect(screen.getByRole('button')).toBeDisabled();
  94. });
  95. rerender(<WrappedDataExport payload={{...mockPayload, queryType: 'Discover'}} />);
  96. await waitFor(() => {
  97. expect(screen.getByRole('button')).toBeEnabled();
  98. });
  99. });
  100. it('should display default error message if non provided', async function () {
  101. MockApiClient.addMockResponse({
  102. url: `/organizations/${mockAuthorizedOrg.slug}/data-export/`,
  103. method: 'POST',
  104. statusCode: 400,
  105. });
  106. render(<WrappedDataExport payload={mockPayload} />, {
  107. context: mockRouterContext(mockAuthorizedOrg),
  108. });
  109. await userEvent.click(screen.getByRole('button'));
  110. await waitFor(() => {
  111. expect(addErrorMessage).toHaveBeenCalledWith(
  112. "We tried our hardest, but we couldn't export your data. Give it another go."
  113. );
  114. });
  115. await waitFor(() => {
  116. expect(screen.getByRole('button')).toBeEnabled();
  117. });
  118. });
  119. it('should display provided error message', async function () {
  120. MockApiClient.addMockResponse({
  121. url: `/organizations/${mockAuthorizedOrg.slug}/data-export/`,
  122. method: 'POST',
  123. statusCode: 400,
  124. body: {detail: 'uh oh'},
  125. });
  126. render(<WrappedDataExport payload={mockPayload} />, {
  127. context: mockRouterContext(mockAuthorizedOrg),
  128. });
  129. await userEvent.click(screen.getByRole('button'));
  130. await waitFor(() => {
  131. expect(addErrorMessage).toHaveBeenCalledWith('uh oh');
  132. });
  133. });
  134. });