asyncComponent.spec.jsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import {render, screen} from 'sentry-test/reactTestingLibrary';
  2. import {Client} from 'sentry/api';
  3. import AsyncComponent from 'sentry/components/asyncComponent';
  4. describe('AsyncComponent', function () {
  5. class TestAsyncComponent extends AsyncComponent {
  6. shouldRenderBadRequests = true;
  7. constructor(props) {
  8. super(props);
  9. this.state = {};
  10. }
  11. getEndpoints() {
  12. return [['data', '/some/path/to/something/']];
  13. }
  14. renderBody() {
  15. return <div>{this.state.data.message}</div>;
  16. }
  17. }
  18. it('renders on successful request', function () {
  19. Client.clearMockResponses();
  20. Client.addMockResponse({
  21. url: '/some/path/to/something/',
  22. method: 'GET',
  23. body: {
  24. message: 'hi',
  25. },
  26. });
  27. render(<TestAsyncComponent />);
  28. expect(screen.getByText('hi')).toBeInTheDocument();
  29. });
  30. it('renders error message', function () {
  31. Client.clearMockResponses();
  32. Client.addMockResponse({
  33. url: '/some/path/to/something/',
  34. method: 'GET',
  35. body: {
  36. detail: 'oops there was a problem',
  37. },
  38. statusCode: 400,
  39. });
  40. render(<TestAsyncComponent />);
  41. expect(screen.getByText('oops there was a problem')).toBeInTheDocument();
  42. });
  43. it('renders only unique error message', function () {
  44. Client.clearMockResponses();
  45. Client.addMockResponse({
  46. url: '/first/path/',
  47. method: 'GET',
  48. body: {
  49. detail: 'oops there was a problem',
  50. },
  51. statusCode: 400,
  52. });
  53. Client.addMockResponse({
  54. url: '/second/path/',
  55. method: 'GET',
  56. body: {
  57. detail: 'oops there was a problem',
  58. },
  59. statusCode: 400,
  60. });
  61. Client.addMockResponse({
  62. url: '/third/path/',
  63. method: 'GET',
  64. body: {
  65. detail: 'oops there was a different problem',
  66. },
  67. statusCode: 400,
  68. });
  69. class UniqueErrorsAsyncComponent extends AsyncComponent {
  70. shouldRenderBadRequests = true;
  71. getEndpoints() {
  72. return [
  73. ['first', '/first/path/'],
  74. ['second', '/second/path/'],
  75. ['third', '/third/path/'],
  76. ];
  77. }
  78. renderBody() {
  79. return <div>{this.state.data.message}</div>;
  80. }
  81. }
  82. render(<UniqueErrorsAsyncComponent />);
  83. expect(
  84. screen.getByText('oops there was a problem oops there was a different problem')
  85. ).toBeInTheDocument();
  86. });
  87. describe('multi-route component', () => {
  88. class MultiRouteComponent extends TestAsyncComponent {
  89. getEndpoints() {
  90. return [
  91. ['data', '/some/path/to/something/'],
  92. ['project', '/another/path/here'],
  93. ];
  94. }
  95. renderLoading() {
  96. return (
  97. <div data-test-id="remaining-requests">{this.state.remainingRequests}</div>
  98. );
  99. }
  100. }
  101. it('calls onLoadAllEndpointsSuccess when all endpoints have been loaded', () => {
  102. jest.useFakeTimers();
  103. jest.spyOn(Client.prototype, 'request').mockImplementation((url, options) => {
  104. const timeout = url.includes('something') ? 100 : 50;
  105. setTimeout(
  106. () =>
  107. options.success({
  108. message: 'good',
  109. }),
  110. timeout
  111. );
  112. });
  113. const mockOnAllEndpointsSuccess = jest.spyOn(
  114. MultiRouteComponent.prototype,
  115. 'onLoadAllEndpointsSuccess'
  116. );
  117. render(<MultiRouteComponent />);
  118. expect(screen.getByTestId('remaining-requests')).toHaveTextContent('2');
  119. jest.advanceTimersByTime(40);
  120. expect(screen.getByTestId('remaining-requests')).toHaveTextContent('2');
  121. jest.advanceTimersByTime(40);
  122. expect(screen.getByTestId('remaining-requests')).toHaveTextContent('1');
  123. expect(mockOnAllEndpointsSuccess).not.toHaveBeenCalled();
  124. jest.advanceTimersByTime(40);
  125. expect(screen.queryByTestId('remaining-requests')).not.toBeInTheDocument();
  126. expect(mockOnAllEndpointsSuccess).toHaveBeenCalled();
  127. jest.restoreAllMocks();
  128. });
  129. });
  130. });