Add tests
This commit is contained in:
parent
15f536e949
commit
6b297c3a7e
4 changed files with 115 additions and 46 deletions
|
@ -2,8 +2,7 @@ import userEvent from '@testing-library/user-event';
|
|||
import { Map as ImmutableMap } from 'immutable';
|
||||
import React from 'react';
|
||||
|
||||
import { __stub } from '../../../api';
|
||||
import { render, screen, waitFor } from '../../../jest/test-helpers';
|
||||
import { mock, render, screen, waitFor } from '../../../jest/test-helpers';
|
||||
import FeedCarousel from '../feed-carousel';
|
||||
|
||||
jest.mock('../../../hooks/useDimensions', () => ({
|
||||
|
@ -55,63 +54,63 @@ describe('<FeedCarousel />', () => {
|
|||
};
|
||||
});
|
||||
|
||||
it('should render the Carousel', () => {
|
||||
store.carousels = {
|
||||
avatars: [
|
||||
{ account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' },
|
||||
],
|
||||
};
|
||||
describe('with avatars', () => {
|
||||
beforeEach(() => {
|
||||
mock.onGet('/api/v1/truth/carousels/avatars')
|
||||
.reply(200, [
|
||||
{ account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg' },
|
||||
]);
|
||||
});
|
||||
|
||||
render(<FeedCarousel />, undefined, store);
|
||||
it('should render the Carousel', async() => {
|
||||
render(<FeedCarousel />, undefined, store);
|
||||
|
||||
expect(screen.queryAllByTestId('feed-carousel')).toHaveLength(1);
|
||||
await waitFor(() => {
|
||||
expect(screen.queryAllByTestId('feed-carousel')).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with 0 avatars', () => {
|
||||
beforeEach(() => {
|
||||
store.carousels = {
|
||||
avatars: [],
|
||||
};
|
||||
mock.onGet('/api/v1/truth/carousels/avatars').reply(200, []);
|
||||
});
|
||||
|
||||
it('renders the error message', () => {
|
||||
it('renders nothing', async() => {
|
||||
render(<FeedCarousel />, undefined, store);
|
||||
|
||||
expect(screen.queryAllByTestId('feed-carousel-error')).toHaveLength(0);
|
||||
await waitFor(() => {
|
||||
expect(screen.queryAllByTestId('feed-carousel')).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with a failed request to the API', () => {
|
||||
beforeEach(() => {
|
||||
store.carousels = {
|
||||
avatars: [],
|
||||
error: true,
|
||||
};
|
||||
mock.onGet('/api/v1/truth/carousels/avatars').networkError();
|
||||
});
|
||||
|
||||
it('renders the error message', () => {
|
||||
it('renders the error message', async() => {
|
||||
render(<FeedCarousel />, undefined, store);
|
||||
|
||||
expect(screen.getByTestId('feed-carousel-error')).toBeInTheDocument();
|
||||
await waitFor(() => {
|
||||
expect(screen.getByTestId('feed-carousel-error')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with multiple pages of avatars', () => {
|
||||
beforeEach(() => {
|
||||
store.carousels = {
|
||||
error: false,
|
||||
avatars: [],
|
||||
};
|
||||
|
||||
__stub(mock => {
|
||||
mock.onGet('/api/v1/truth/carousels/avatars')
|
||||
.reply(200, [
|
||||
{ account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg' },
|
||||
]);
|
||||
});
|
||||
mock.onGet('/api/v1/truth/carousels/avatars')
|
||||
.reply(200, [
|
||||
{ account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg' },
|
||||
]);
|
||||
|
||||
Element.prototype.getBoundingClientRect = jest.fn(() => {
|
||||
return {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { configureMockStore } from '@jedmao/redux-mock-store';
|
||||
import { QueryClientProvider } from '@tanstack/react-query';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { render, RenderOptions } from '@testing-library/react';
|
||||
import MockAdapter from 'axios-mock-adapter';
|
||||
import { merge } from 'immutable';
|
||||
import React, { FC, ReactElement } from 'react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
|
@ -10,7 +11,7 @@ import { Action, applyMiddleware, createStore } from 'redux';
|
|||
import thunk from 'redux-thunk';
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
import { queryClient } from 'soapbox/queries/client';
|
||||
import API from 'soapbox/queries/client';
|
||||
|
||||
import NotificationsContainer from '../features/ui/containers/notifications_container';
|
||||
import { default as rootReducer } from '../reducers';
|
||||
|
@ -28,8 +29,26 @@ const applyActions = (state: any, actions: any, reducer: any) => {
|
|||
return actions.reduce((state: any, action: any) => reducer(state, action), state);
|
||||
};
|
||||
|
||||
const createTestStore = (initialState: any) => createStore(rootReducer, initialState, applyMiddleware(thunk));
|
||||
const mock = new MockAdapter(API, { onNoMatch: 'throwException' });
|
||||
const queryClient = new QueryClient({
|
||||
logger: {
|
||||
// eslint-disable-next-line no-console
|
||||
log: console.log,
|
||||
warn: console.warn,
|
||||
error: () => { },
|
||||
},
|
||||
defaultOptions: {
|
||||
queries: {
|
||||
retry: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
mock.reset();
|
||||
});
|
||||
|
||||
const createTestStore = (initialState: any) => createStore(rootReducer, initialState, applyMiddleware(thunk));
|
||||
const TestApp: FC<any> = ({ children, storeProps, routerProps = {} }) => {
|
||||
let store: ReturnType<typeof createTestStore>;
|
||||
let appState = rootState;
|
||||
|
@ -71,6 +90,12 @@ const customRender = (
|
|||
...options,
|
||||
});
|
||||
|
||||
const queryWrapper: React.FC = ({ children }) => (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
{children}
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
const mockWindowProperty = (property: any, value: any) => {
|
||||
const { [property]: originalProperty } = window;
|
||||
delete window[property];
|
||||
|
@ -97,4 +122,6 @@ export {
|
|||
rootReducer,
|
||||
mockWindowProperty,
|
||||
createTestStore,
|
||||
mock,
|
||||
queryWrapper,
|
||||
};
|
||||
|
|
45
app/soapbox/queries/__tests__/carousels.test.ts
Normal file
45
app/soapbox/queries/__tests__/carousels.test.ts
Normal file
|
@ -0,0 +1,45 @@
|
|||
import { renderHook } from '@testing-library/react-hooks';
|
||||
|
||||
import { mock, queryWrapper, waitFor } from 'soapbox/jest/test-helpers';
|
||||
|
||||
import useCarouselAvatars from '../carousels';
|
||||
|
||||
describe('useCarouselAvatars', () => {
|
||||
describe('with a successul query', () => {
|
||||
beforeEach(() => {
|
||||
mock.onGet('/api/v1/truth/carousels/avatars')
|
||||
.reply(200, [
|
||||
{ account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '2', acct: 'b', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '3', acct: 'c', account_avatar: 'https://example.com/some.jpg' },
|
||||
{ account_id: '4', acct: 'd', account_avatar: 'https://example.com/some.jpg' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('is successful', async() => {
|
||||
const { result } = renderHook(() => useCarouselAvatars(), {
|
||||
wrapper: queryWrapper,
|
||||
});
|
||||
|
||||
await waitFor(() => expect(result.current.isFetching).toBe(false));
|
||||
|
||||
expect(result.current.data?.length).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('with an unsuccessul query', () => {
|
||||
beforeEach(() => {
|
||||
mock.onGet('/api/v1/truth/carousels/avatars').networkError();
|
||||
});
|
||||
|
||||
it('is successful', async() => {
|
||||
const { result } = renderHook(() => useCarouselAvatars(), {
|
||||
wrapper: queryWrapper,
|
||||
});
|
||||
|
||||
await waitFor(() => expect(result.current.isFetching).toBe(false));
|
||||
|
||||
expect(result.current.error).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import API from './client';
|
||||
import API from 'soapbox/queries/client';
|
||||
|
||||
type Avatar = {
|
||||
account_id: string
|
||||
|
@ -13,17 +13,15 @@ const getCarouselAvatars = async() => {
|
|||
return data;
|
||||
};
|
||||
|
||||
export default function useCarouselAvatars(): { data: Avatar[], isFetching: boolean, isError: boolean, isSuccess: boolean } {
|
||||
const { data, isFetching, isError, isSuccess } = useQuery<Avatar[]>(['carouselAvatars'], getCarouselAvatars, {
|
||||
export default function useCarouselAvatars() {
|
||||
const result = useQuery<Avatar[]>(['carouselAvatars'], getCarouselAvatars, {
|
||||
placeholderData: [],
|
||||
});
|
||||
|
||||
const avatars = data as Avatar[];
|
||||
const avatars = result.data;
|
||||
|
||||
return {
|
||||
data: avatars,
|
||||
isFetching,
|
||||
isError,
|
||||
isSuccess,
|
||||
...result,
|
||||
data: avatars || [],
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue