From f82331e7ad392991fc625ece4ce32a1185e88a02 Mon Sep 17 00:00:00 2001 From: Sergio Pedercini Date: Wed, 23 Dec 2020 17:29:25 +0100 Subject: [PATCH] Fix a bug that prevents to handle API errors. --- package.json | 2 +- src/hooks/useApi.js | 10 ++++++- src/hooks/useApi.spec.js | 56 ++++++++++++++++++++++------------------ tests/index.spec.js | 47 +++++++++++++++++++++------------ 4 files changed, 71 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index 77b9cd0..35af334 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-giphy-searchbox", - "version": "1.5.0", + "version": "1.5.1", "description": "React Giphy Searchbox", "main": "lib/index.js", "module": "es/index.js", diff --git a/src/hooks/useApi.js b/src/hooks/useApi.js index 6265f23..7f5425b 100644 --- a/src/hooks/useApi.js +++ b/src/hooks/useApi.js @@ -17,7 +17,15 @@ const useApi = () => { } fetch(url) - .then(response => response.json()) + .then(response => { + if (!response.ok) { + return response.json().then(json => { + throw json + }) + } + + return response.json() + }) .then(response => { if (isMore) { dispatch({ diff --git a/src/hooks/useApi.spec.js b/src/hooks/useApi.spec.js index ec90a31..54b32b8 100644 --- a/src/hooks/useApi.spec.js +++ b/src/hooks/useApi.spec.js @@ -1,76 +1,82 @@ -import fetchMock from 'fetch-mock-jest' import { renderHook, act } from '@testing-library/react-hooks' +import giphyTrendingGet404Error from '../../tests/fixtures/giphyTrendingGet404Error.json' +import giphyTrendingGetSuccess from '../../tests/fixtures/giphyTrendingGetSuccess.json' import useApi from './useApi' describe('useApi', () => { - const fetchingValues = { + const fetchingInitValues = { loading: true, error: false, data: [], lastPage: false, } - fetchMock.mock('/foo', { - status: 200, - data: [{ foo: 'foo' }], - pagination: { - total_count: 200, - count: 25, - offset: 0, - }, - }) - - fetchMock.mock('/foo2', { status: 500 }) - test('perform a get request and receive some data', async () => { const { result, waitForNextUpdate } = renderHook(() => useApi()) - const [, fetchImages] = result.current + window.fetch = jest.fn().mockResolvedValueOnce({ + ok: true, + status: 200, + json: async () => giphyTrendingGetSuccess, + }) + act(() => { - fetchImages('/foo') + fetchImages() }) - expect(result.current[0]).toEqual(fetchingValues) + expect(result.current[0]).toEqual(fetchingInitValues) await waitForNextUpdate() expect(result.current[0]).toEqual({ loading: false, error: false, - data: [{ foo: 'foo' }], + data: giphyTrendingGetSuccess.data, lastPage: false, }) }) test('perform a get request with `isMore` option and receive some data', async () => { const { result, waitForNextUpdate } = renderHook(() => useApi()) - const [, fetchImages] = result.current + window.fetch = jest.fn().mockResolvedValueOnce({ + ok: true, + status: 200, + json: async () => giphyTrendingGetSuccess, + }) + act(() => { - fetchImages('/foo', true) + fetchImages('', true) }) - expect(result.current[0]).toEqual(fetchingValues) + expect(result.current[0]).toEqual(fetchingInitValues) await waitForNextUpdate() expect(result.current[0]).toEqual({ loading: false, error: false, - data: [{ foo: 'foo' }], + data: giphyTrendingGetSuccess.data, lastPage: false, }) }) test('perform a get request and receive an error', async () => { const { result, waitForNextUpdate } = renderHook(() => useApi()) + const [, fetchImages] = result.current - const [, fetch] = result.current + window.fetch = jest.fn().mockResolvedValueOnce({ + ok: false, + status: 404, + json: async () => giphyTrendingGet404Error, + }) act(() => { - fetch('/foo2') + fetchImages() }) - expect(result.current[0]).toEqual(fetchingValues) + expect(result.current[0]).toEqual(fetchingInitValues) + await waitForNextUpdate() + expect(result.current[0]).toEqual({ loading: false, error: true, diff --git a/tests/index.spec.js b/tests/index.spec.js index d90f04e..e6ba303 100644 --- a/tests/index.spec.js +++ b/tests/index.spec.js @@ -10,12 +10,6 @@ import assetsPoweredByGiphy from '../src/assets/poweredByGiphy.png' // TO-DO: Test the loading more (infinite scrolling) -const fetchMock = data => { - return Promise.resolve({ - json: () => Promise.resolve(data), - }) -} - describe('ReactGiphySearchbox', () => { const onSelect = jest.fn() const onSearch = jest.fn() @@ -51,12 +45,13 @@ describe('ReactGiphySearchbox', () => { }) test('fetches Giphy Api and displays trending gifs', async () => { - window.fetch = jest - .fn() - .mockImplementationOnce(() => fetchMock(giphyTrendingGetSuccess)) + window.fetch = jest.fn().mockResolvedValueOnce({ + ok: true, + status: 200, + json: async () => giphyTrendingGetSuccess, + }) const { getByTestId } = buildSubject() - // Loading message displayed const Loader = await waitForElement(() => getByTestId('SpinnerText')) expect(Loader).toHaveTextContent(defaults.messageLoading) @@ -71,9 +66,11 @@ describe('ReactGiphySearchbox', () => { }) test('fetches Giphy Api and returns an error', async () => { - window.fetch = jest - .fn() - .mockRejectedValueOnce(() => fetchMock(giphyTrendingGet404Error)) + window.fetch = jest.fn().mockResolvedValueOnce({ + ok: false, + status: 404, + json: async () => giphyTrendingGet404Error, + }) const { getByTestId } = buildSubject() expect(getByTestId('SpinnerText')).toHaveTextContent( @@ -91,8 +88,16 @@ describe('ReactGiphySearchbox', () => { let Loader window.fetch = jest .fn() - .mockImplementationOnce(() => fetchMock(giphyTrendingGetSuccess)) - .mockImplementationOnce(() => fetchMock(giphySearchGetSuccess)) + .mockResolvedValueOnce({ + ok: true, + status: 200, + json: async () => giphyTrendingGetSuccess, + }) + .mockResolvedValueOnce({ + ok: true, + status: 200, + json: async () => giphySearchGetSuccess, + }) const { getByTestId } = buildSubject() @@ -132,8 +137,16 @@ describe('ReactGiphySearchbox', () => { let Loader window.fetch = jest .fn() - .mockImplementationOnce(() => fetchMock(giphyTrendingGetSuccess)) - .mockImplementationOnce(() => fetchMock(giphySearchGetSuccessEmpty)) + .mockResolvedValueOnce({ + ok: true, + status: 200, + json: async () => giphyTrendingGetSuccess, + }) + .mockResolvedValueOnce({ + ok: true, + status: 200, + json: async () => giphySearchGetSuccessEmpty, + }) const { getByTestId } = buildSubject()