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', () => {
describe('error handling', () => {
function HomePage() {
const {renderComponent, data} = useApiRequests({
endpoints: [['message', '/some/path/to/something/']],
shouldRenderBadRequests: true,
});
return renderComponent(
{data.message?.value}
);
}
function UniqueErrorsAsyncComponent() {
const {renderComponent, data} = useApiRequests({
endpoints: [
['first', '/first/path/'],
['second', '/second/path/'],
['third', '/third/path/'],
],
shouldRenderBadRequests: true,
});
return renderComponent({data.message?.value}
);
}
const memoryHistory = createMemoryHistory();
memoryHistory.push('/');
function App() {
return (
{
return (
);
}}
>
);
}
it('renders on successful request', async function () {
MockApiClient.clearMockResponses();
MockApiClient.addMockResponse({
url: '/some/path/to/something/',
method: 'GET',
body: {
value: 'hi',
},
});
render();
await waitFor(() => {
expect(screen.getByText('hi')).toBeInTheDocument();
});
});
it('renders error message', async function () {
MockApiClient.clearMockResponses();
MockApiClient.addMockResponse({
url: '/some/path/to/something/',
method: 'GET',
body: {
detail: 'oops there was a problem',
},
statusCode: 400,
});
render();
await waitFor(() => {
expect(screen.getByText('oops there was a problem')).toBeInTheDocument();
});
});
it('renders only unique error message', async function () {
MockApiClient.clearMockResponses();
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();
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 {remainingRequests}
;
}
const memoryHistory = createMemoryHistory();
memoryHistory.push('/multi');
function App() {
return (
{
return (
);
}}
>
);
}
render();
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();
});
});
});