diff --git a/app/soapbox/features/feed-filtering/__tests__/feed-carousel.test.tsx b/app/soapbox/features/feed-filtering/__tests__/feed-carousel.test.tsx index c17ea2c5a..9cc88a6c3 100644 --- a/app/soapbox/features/feed-filtering/__tests__/feed-carousel.test.tsx +++ b/app/soapbox/features/feed-filtering/__tests__/feed-carousel.test.tsx @@ -2,7 +2,9 @@ import userEvent from '@testing-library/user-event'; import { Map as ImmutableMap } from 'immutable'; import React from 'react'; -import { mock, render, screen, waitFor } from '../../../jest/test-helpers'; +import { __stub } from 'soapbox/api'; + +import { render, screen, waitFor } from '../../../jest/test-helpers'; import FeedCarousel from '../feed-carousel'; jest.mock('../../../hooks/useDimensions', () => ({ @@ -56,13 +58,15 @@ describe('', () => { 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' }, - ]); + __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' }, + ]); + }); }); it('should render the Carousel', async() => { @@ -76,7 +80,7 @@ describe('', () => { describe('with 0 avatars', () => { beforeEach(() => { - mock.onGet('/api/v1/truth/carousels/avatars').reply(200, []); + __stub((mock) => mock.onGet('/api/v1/truth/carousels/avatars').reply(200, [])); }); it('renders nothing', async() => { @@ -90,7 +94,7 @@ describe('', () => { describe('with a failed request to the API', () => { beforeEach(() => { - mock.onGet('/api/v1/truth/carousels/avatars').networkError(); + __stub((mock) => mock.onGet('/api/v1/truth/carousels/avatars').networkError()); }); it('renders the error message', async() => { @@ -104,13 +108,15 @@ describe('', () => { describe('with multiple pages of 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' }, - ]); + __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' }, + ]); + }); Element.prototype.getBoundingClientRect = jest.fn(() => { return { diff --git a/app/soapbox/jest/test-helpers.tsx b/app/soapbox/jest/test-helpers.tsx index e0761eb27..0894d4d40 100644 --- a/app/soapbox/jest/test-helpers.tsx +++ b/app/soapbox/jest/test-helpers.tsx @@ -1,7 +1,7 @@ import { configureMockStore } from '@jedmao/redux-mock-store'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { render, RenderOptions } from '@testing-library/react'; -import MockAdapter from 'axios-mock-adapter'; +import { renderHook, RenderHookOptions } from '@testing-library/react-hooks'; import { merge } from 'immutable'; import React, { FC, ReactElement } from 'react'; import { IntlProvider } from 'react-intl'; @@ -27,7 +27,7 @@ const applyActions = (state: any, actions: any, reducer: any) => { return actions.reduce((state: any, action: any) => reducer(state, action), state); }; -const mock = new MockAdapter(undefined as any, { onNoMatch: 'throwException' }); +/** React Query client for tests. */ const queryClient = new QueryClient({ logger: { // eslint-disable-next-line no-console @@ -42,10 +42,6 @@ const queryClient = new QueryClient({ }, }); -beforeEach(() => { - mock.reset(); -}); - const createTestStore = (initialState: any) => createStore(rootReducer, initialState, applyMiddleware(thunk)); const TestApp: FC = ({ children, storeProps, routerProps = {} }) => { let store: ReturnType; @@ -88,11 +84,17 @@ const customRender = ( ...options, }); -const queryWrapper: React.FC = ({ children }) => ( - - {children} - -); +/** Like renderHook, but with access to the Redux store. */ +const customRenderHook = ( + callback: (props?: any) => any, + options?: Omit, 'wrapper'>, + store?: any, +) => { + return renderHook(callback, { + wrapper: ({ children }) => , + ...options, + }); +}; const mockWindowProperty = (property: any, value: any) => { const { [property]: originalProperty } = window; @@ -114,12 +116,11 @@ const mockWindowProperty = (property: any, value: any) => { export * from '@testing-library/react'; export { customRender as render, + customRenderHook as renderHook, mockStore, applyActions, rootState, rootReducer, mockWindowProperty, createTestStore, - mock, - queryWrapper, }; diff --git a/app/soapbox/queries/__tests__/carousels.test.ts b/app/soapbox/queries/__tests__/carousels.test.ts index 61edbce11..9ee5fa4c2 100644 --- a/app/soapbox/queries/__tests__/carousels.test.ts +++ b/app/soapbox/queries/__tests__/carousels.test.ts @@ -1,25 +1,24 @@ -import { renderHook } from '@testing-library/react-hooks'; - -import { mock, queryWrapper, waitFor } from 'soapbox/jest/test-helpers'; +import { __stub } from 'soapbox/api'; +import { renderHook, waitFor } from 'soapbox/jest/test-helpers'; import useCarouselAvatars from '../carousels'; describe('useCarouselAvatars', () => { - describe('with a successul query', () => { + describe('with a successful 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' }, - ]); + __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' }, + ]); + }); }); it('is successful', async() => { - const { result } = renderHook(() => useCarouselAvatars(), { - wrapper: queryWrapper, - }); + const { result } = renderHook(() => useCarouselAvatars()); await waitFor(() => expect(result.current.isFetching).toBe(false)); @@ -27,15 +26,15 @@ describe('useCarouselAvatars', () => { }); }); - describe('with an unsuccessul query', () => { + describe('with an unsuccessful query', () => { beforeEach(() => { - mock.onGet('/api/v1/truth/carousels/avatars').networkError(); + __stub((mock) => { + mock.onGet('/api/v1/truth/carousels/avatars').networkError(); + }); }); it('is successful', async() => { - const { result } = renderHook(() => useCarouselAvatars(), { - wrapper: queryWrapper, - }); + const { result } = renderHook(() => useCarouselAvatars()); await waitFor(() => expect(result.current.isFetching).toBe(false));