environments/review-react-quer-1t63ue/deployments/714
Justin 2 years ago
parent 15f536e949
commit 6b297c3a7e

@ -2,8 +2,7 @@ import userEvent from '@testing-library/user-event';
import { Map as ImmutableMap } from 'immutable'; import { Map as ImmutableMap } from 'immutable';
import React from 'react'; import React from 'react';
import { __stub } from '../../../api'; import { mock, render, screen, waitFor } from '../../../jest/test-helpers';
import { render, screen, waitFor } from '../../../jest/test-helpers';
import FeedCarousel from '../feed-carousel'; import FeedCarousel from '../feed-carousel';
jest.mock('../../../hooks/useDimensions', () => ({ jest.mock('../../../hooks/useDimensions', () => ({
@ -55,63 +54,63 @@ describe('<FeedCarousel />', () => {
}; };
}); });
it('should render the Carousel', () => { describe('with avatars', () => {
store.carousels = { beforeEach(() => {
avatars: [ mock.onGet('/api/v1/truth/carousels/avatars')
{ account_id: '1', acct: 'a', account_avatar: 'https://example.com/some.jpg' }, .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', () => { describe('with 0 avatars', () => {
beforeEach(() => { beforeEach(() => {
store.carousels = { mock.onGet('/api/v1/truth/carousels/avatars').reply(200, []);
avatars: [],
};
}); });
it('renders the error message', () => { it('renders nothing', async() => {
render(<FeedCarousel />, undefined, store); 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', () => { describe('with a failed request to the API', () => {
beforeEach(() => { beforeEach(() => {
store.carousels = { mock.onGet('/api/v1/truth/carousels/avatars').networkError();
avatars: [],
error: true,
};
}); });
it('renders the error message', () => { it('renders the error message', async() => {
render(<FeedCarousel />, undefined, store); 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', () => { describe('with multiple pages of avatars', () => {
beforeEach(() => { beforeEach(() => {
store.carousels = { mock.onGet('/api/v1/truth/carousels/avatars')
error: false, .reply(200, [
avatars: [], { 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' },
__stub(mock => { { 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(() => { Element.prototype.getBoundingClientRect = jest.fn(() => {
return { return {

@ -1,6 +1,7 @@
import { configureMockStore } from '@jedmao/redux-mock-store'; 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 { render, RenderOptions } from '@testing-library/react';
import MockAdapter from 'axios-mock-adapter';
import { merge } from 'immutable'; import { merge } from 'immutable';
import React, { FC, ReactElement } from 'react'; import React, { FC, ReactElement } from 'react';
import { IntlProvider } from 'react-intl'; import { IntlProvider } from 'react-intl';
@ -10,7 +11,7 @@ import { Action, applyMiddleware, createStore } from 'redux';
import thunk from 'redux-thunk'; import thunk from 'redux-thunk';
import '@testing-library/jest-dom'; 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 NotificationsContainer from '../features/ui/containers/notifications_container';
import { default as rootReducer } from '../reducers'; 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); 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 = {} }) => { const TestApp: FC<any> = ({ children, storeProps, routerProps = {} }) => {
let store: ReturnType<typeof createTestStore>; let store: ReturnType<typeof createTestStore>;
let appState = rootState; let appState = rootState;
@ -71,6 +90,12 @@ const customRender = (
...options, ...options,
}); });
const queryWrapper: React.FC = ({ children }) => (
<QueryClientProvider client={queryClient}>
{children}
</QueryClientProvider>
);
const mockWindowProperty = (property: any, value: any) => { const mockWindowProperty = (property: any, value: any) => {
const { [property]: originalProperty } = window; const { [property]: originalProperty } = window;
delete window[property]; delete window[property];
@ -97,4 +122,6 @@ export {
rootReducer, rootReducer,
mockWindowProperty, mockWindowProperty,
createTestStore, createTestStore,
mock,
queryWrapper,
}; };

@ -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 { useQuery } from '@tanstack/react-query';
import API from './client'; import API from 'soapbox/queries/client';
type Avatar = { type Avatar = {
account_id: string account_id: string
@ -13,17 +13,15 @@ const getCarouselAvatars = async() => {
return data; return data;
}; };
export default function useCarouselAvatars(): { data: Avatar[], isFetching: boolean, isError: boolean, isSuccess: boolean } { export default function useCarouselAvatars() {
const { data, isFetching, isError, isSuccess } = useQuery<Avatar[]>(['carouselAvatars'], getCarouselAvatars, { const result = useQuery<Avatar[]>(['carouselAvatars'], getCarouselAvatars, {
placeholderData: [], placeholderData: [],
}); });
const avatars = data as Avatar[]; const avatars = result.data;
return { return {
data: avatars, ...result,
isFetching, data: avatars || [],
isError,
isSuccess,
}; };
} }

Loading…
Cancel
Save