import { act, renderHook, waitFor } from '@testing-library/react' import apiFetch from '@wordpress/api-fetch' import useSetUpProgress from '../useSetUpProgress' jest.mock('@wordpress/api-fetch') const mockApiFetch = apiFetch as jest.MockedFunction const setUpStatus = ( connected: boolean, { canConfigure = false, canUpdatePlugins = false } = {} ) => mockApiFetch.mockResolvedValue({ connected, canConfigure, canUpdatePlugins, } as never) describe('useSetUpProgress', () => { beforeEach(() => { jest.clearAllMocks() }) it('is loading until the set-up status is known', () => { mockApiFetch.mockReturnValue(new Promise(() => {}) as never) const { result } = renderHook(() => useSetUpProgress()) expect(result.current.progress).toBe('loading') }) it('reads the set-up status, which shop managers may read too', async () => { setUpStatus(true) renderHook(() => useSetUpProgress()) await waitFor(() => expect(mockApiFetch).toHaveBeenCalledWith({ path: '/posten-bring-checkout/overview/set-up', }) ) }) it('is complete when the plugin is connected', async () => { setUpStatus(true) const { result } = renderHook(() => useSetUpProgress()) await waitFor(() => expect(result.current.progress).toBe('complete')) }) it('is not connected when the plugin is not connected', async () => { setUpStatus(false) const { result } = renderHook(() => useSetUpProgress()) await waitFor(() => expect(result.current.progress).toBe('notConnected')) }) it('has failed when the set-up status cannot be read', async () => { mockApiFetch.mockRejectedValue(new Error('forbidden')) const { result } = renderHook(() => useSetUpProgress()) await waitFor(() => expect(result.current.progress).toBe('failed')) }) it('tells whether the user may update the plugin', async () => { setUpStatus(true, { canUpdatePlugins: true }) const { result } = renderHook(() => useSetUpProgress()) await waitFor(() => expect(result.current.canUpdatePlugins).toBe(true)) }) it('tells whether the user may configure the plugin', async () => { setUpStatus(false, { canConfigure: true }) const { result } = renderHook(() => useSetUpProgress()) await waitFor(() => expect(result.current.canConfigure).toBe(true)) }) it('does not let the user configure the plugin until known', () => { mockApiFetch.mockReturnValue(new Promise(() => {}) as never) const { result } = renderHook(() => useSetUpProgress()) expect(result.current.canConfigure).toBe(false) }) it('does not let the user update the plugin until known', () => { mockApiFetch.mockReturnValue(new Promise(() => {}) as never) const { result } = renderHook(() => useSetUpProgress()) expect(result.current.canUpdatePlugins).toBe(false) }) it('is complete as soon as the plugin has been connected, without asking again', async () => { setUpStatus(false) const { result } = renderHook(() => useSetUpProgress()) await waitFor(() => expect(result.current.progress).toBe('notConnected')) act(() => result.current.markConnected()) expect(result.current.progress).toBe('complete') expect(mockApiFetch).toHaveBeenCalledTimes(1) }) })