123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- import * as React from 'react';
- import {createMemoryHistory, Route, Router, RouterContext} from 'react-router';
- import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
- import useApiRequests from 'sentry/utils/useApiRequests';
- import {RouteContext} from 'sentry/views/routeContext';
- describe('useApiRequests', () => {
- afterEach(() => {
- MockApiClient.clearMockResponses();
- });
- describe('error handling', () => {
- function HomePage() {
- const {renderComponent, data} = useApiRequests<{message: {value?: string}}>({
- endpoints: [['message', '/some/path/to/something/']],
- shouldRenderBadRequests: true,
- });
- return renderComponent(<div>{data.message?.value}</div>);
- }
- function UniqueErrorsAsyncComponent() {
- const {renderComponent, data} = useApiRequests({
- endpoints: [
- ['first', '/first/path/'],
- ['second', '/second/path/'],
- ['third', '/third/path/'],
- ],
- shouldRenderBadRequests: true,
- });
- // @ts-expect-error
- return renderComponent(<div>{data.message?.value}</div>);
- }
- const memoryHistory = createMemoryHistory();
- memoryHistory.push('/');
- function App() {
- return (
- <Router
- history={memoryHistory}
- render={props => {
- return (
- <RouteContext.Provider value={props}>
- <RouterContext {...props} />
- </RouteContext.Provider>
- );
- }}
- >
- <Route path="/" component={HomePage} />
- <Route path="/unique-error" component={UniqueErrorsAsyncComponent} />
- </Router>
- );
- }
- it('renders on successful request', async function () {
- const mockRequest = MockApiClient.addMockResponse({
- url: '/some/path/to/something/',
- method: 'GET',
- body: {
- value: 'hi',
- },
- });
- render(<App />);
- await waitFor(() => {
- expect(screen.getByText('hi')).toBeInTheDocument();
- });
- expect(mockRequest).toHaveBeenCalledTimes(1);
- });
- it('renders error message', async function () {
- MockApiClient.addMockResponse({
- url: '/some/path/to/something/',
- method: 'GET',
- body: {
- detail: 'oops there was a problem',
- },
- statusCode: 400,
- });
- render(<App />);
- await waitFor(() => {
- expect(screen.getByText('oops there was a problem')).toBeInTheDocument();
- });
- });
- it('renders only unique error message', async function () {
- MockApiClient.addMockResponse({
- url: '/first/path/',
- method: 'GET',
- body: {
- detail: 'oops there was a problem 1',
- },
- statusCode: 400,
- });
- MockApiClient.addMockResponse({
- url: '/second/path/',
- method: 'GET',
- body: {
- detail: 'oops there was a problem 2',
- },
- statusCode: 400,
- });
- MockApiClient.addMockResponse({
- url: '/third/path/',
- method: 'GET',
- body: {
- detail: 'oops there was a different problem',
- },
- statusCode: 400,
- });
- memoryHistory.push('/unique-error');
- render(<App />);
- await waitFor(() => {
- expect(screen.getByTestId('loading-error')).toHaveTextContent(
- 'oops there was a problem 1'
- );
- });
- await waitFor(() => {
- expect(screen.getByTestId('loading-error')).toHaveTextContent(
- 'oops there was a problem 2'
- );
- });
- await waitFor(() => {
- expect(screen.getByTestId('loading-error')).toHaveTextContent(
- 'oops there was a different problem'
- );
- });
- });
- });
- describe('slow requests', () => {
- it('calls onLoadAllEndpointsSuccess when all endpoints have been loaded', async () => {
- const requestQueue: Array<() => void> = [];
- jest.spyOn(MockApiClient.prototype, 'request').mockImplementation((_, options) => {
- requestQueue.push(() => {
- return options?.success?.({message: 'good'});
- });
- });
- const mockOnAllEndpointsSuccess = jest.fn();
- function MultiRouteComponent() {
- const {remainingRequests} = useApiRequests({
- endpoints: [
- ['data', '/some/path/to/something/'],
- ['project', '/another/path/here'],
- ],
- onLoadAllEndpointsSuccess: mockOnAllEndpointsSuccess,
- });
- return <div data-test-id="remaining-requests">{remainingRequests}</div>;
- }
- const memoryHistory = createMemoryHistory();
- memoryHistory.push('/multi');
- function App() {
- return (
- <Router
- history={memoryHistory}
- render={props => {
- return (
- <RouteContext.Provider value={props}>
- <RouterContext {...props} />
- </RouteContext.Provider>
- );
- }}
- >
- <Route path="/multi" component={MultiRouteComponent} />
- </Router>
- );
- }
- render(<App />);
- expect(await screen.findByText('2')).toBeInTheDocument();
- const req1 = requestQueue.shift();
- req1?.();
- expect(await screen.findByText('1')).toBeInTheDocument();
- const req2 = requestQueue.shift();
- req2?.();
- expect(await screen.findByText('0')).toBeInTheDocument();
- expect(mockOnAllEndpointsSuccess).toHaveBeenCalled();
- jest.restoreAllMocks();
- });
- });
- });
|