From 6cb1c63db64614dba8376d5152e0cff91b159ef1 Mon Sep 17 00:00:00 2001 From: John Chipps-Harding Date: Fri, 27 Sep 2019 17:10:49 +0100 Subject: [PATCH] Arguments now a single object --- .npmignore | 1 + CHANGELOG.md | 4 ++ README.md | 19 +++++--- index.js | 6 +-- package.json | 1 + test.js | 132 ++++++++++++++++++++++++++------------------------- 6 files changed, 90 insertions(+), 73 deletions(-) diff --git a/.npmignore b/.npmignore index f4b1198..d774130 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,3 @@ .git .github +coverage diff --git a/CHANGELOG.md b/CHANGELOG.md index b6142af..1e3ca7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ All notable changes to this project are documented in this file. +## Unreleased + +- Changed: Input arguments now a configuration object. + ## 0.2.2 - Fixed: `payload` equality fix. diff --git a/README.md b/README.md index d276015..a1d66fa 100755 --- a/README.md +++ b/README.md @@ -13,10 +13,10 @@ If you need a simple way to load data quickly this is for you. It allows you to You can optionally specify a polling interval and manually trigger a refresh. It also gracefully cancels any open requests if you decide to change the URL and restarts timers if the polling interval changes. ```javascript -const { data, loading, changed, error, refresh } = useApi( - "https://some-api.com", - 10000 -); +const { data, loading, changed, error, refresh } = useApi({ + apiEndpoint: "https://some-api.com", + pollInterval: 10000 +}); ``` ## Installation @@ -37,7 +37,10 @@ import useApi from '@signal-noise/use-api'; import PeopleList from './PeopleList'; const PeopleList = () = { - const { data, loading, error, refresh } = useApi("https://some-api.com", 10000); + const { data, loading, error, refresh } = useApi({ + apiEndpoint: "https://some-api.com", + pollInterval: 10000 + )}; const people = data.people || []; @@ -62,7 +65,11 @@ import PeopleList from './PeopleList'; const PeopleSearch = () = { const [keywords, setKeywords] = useState("kazumi"); - const { data } = useApi("https://some-api.com", 0, { keywords }, "post"); + const { data } = useApi({ + apiEndpoint: "https://some-api.com", + payload: { keywords }, + method: "post" + }); const people = data.people || []; diff --git a/index.js b/index.js index 8073371..6fd9b0f 100755 --- a/index.js +++ b/index.js @@ -4,13 +4,13 @@ const isEqual = require("lodash.isequal"); const { CancelToken } = axios; -const useApi = ( +const useApi = ({ apiEndpoint, - pollInterval, + pollInterval = 0, payload, method = "get", changed -) => { +}) => { const [data, setData] = useState({}); const [error, setError] = useState(null); const [loading, setLoading] = useState(true); diff --git a/package.json b/package.json index 0228ea3..44f8915 100755 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ ], "scripts": { "test": "jest", + "test:watch": "jest --watch", "coverage": "jest --coverage", "release": "np", "lint": "npm-run-all --parallel lint:*", diff --git a/test.js b/test.js index a8d8e9f..d861152 100755 --- a/test.js +++ b/test.js @@ -5,7 +5,7 @@ const { renderHook, act } = require("@testing-library/react-hooks"); describe("performs requests", () => { let mock; - const url = "http://mock"; + const apiEndpoint = "http://mock"; beforeEach(() => { mock = new MockAdapter(axios); @@ -19,9 +19,11 @@ describe("performs requests", () => { }); it("loads data from a url using GET", async () => { - mock.onGet(url).reply(200, "response"); + mock.onGet(apiEndpoint).reply(200, "response"); - const { result, waitForNextUpdate } = renderHook(() => useApi(url)); + const { result, waitForNextUpdate } = renderHook(() => + useApi({ apiEndpoint }) + ); expect(result.current.data).toEqual({}); expect(result.current.loading).toBeTruthy(); @@ -33,15 +35,15 @@ describe("performs requests", () => { }); it("sends querystring data and loads data from a url using GET", async () => { - const params = { query: "hello" }; + const payload = { query: "hello" }; mock - .onGet(url) + .onGet(apiEndpoint) .reply(config => config.params.query === "hello" ? [200, "response"] : [400, "error"] ); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, params) + useApi({ apiEndpoint, payload }) ); expect(result.current.data).toEqual({}); @@ -54,11 +56,11 @@ describe("performs requests", () => { }); it("allows different formats of GET method param (GET)", async () => { - const params = { query: "hello" }; - mock.onGet(url).reply(200, "response"); + const payload = { query: "hello" }; + mock.onGet(apiEndpoint).reply(200, "response"); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, params, "GET") + useApi({ apiEndpoint, payload, method: "GET" }) ); await waitForNextUpdate(); @@ -68,11 +70,11 @@ describe("performs requests", () => { }); it("allows different formats of GET method param (Get)", async () => { - const params = { query: "hello" }; - mock.onGet(url).reply(200, "response"); + const payload = { query: "hello" }; + mock.onGet(apiEndpoint).reply(200, "response"); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, params, "Get") + useApi({ apiEndpoint, payload, method: "Get" }) ); await waitForNextUpdate(); @@ -82,11 +84,11 @@ describe("performs requests", () => { }); it("allows different formats of GET method param (gEt)", async () => { - const params = { query: "hello" }; - mock.onGet(url).reply(200, "response"); + const payload = { query: "hello" }; + mock.onGet(apiEndpoint).reply(200, "response"); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, params, "gEt") + useApi({ apiEndpoint, payload, method: "gEt" }) ); await waitForNextUpdate(); @@ -96,11 +98,11 @@ describe("performs requests", () => { }); it("loads data from a url using POST", async () => { - const postData = { query: "hello" }; - mock.onPost(url, postData).reply(200, "response"); + const payload = { query: "hello" }; + mock.onPost(apiEndpoint, payload).reply(200, "response"); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, postData, "post") + useApi({ apiEndpoint, payload, method: "post" }) ); expect(result.current.data).toEqual({}); @@ -113,11 +115,11 @@ describe("performs requests", () => { }); it("allows different formats of POST method param (Post)", async () => { - const postData = { query: "hello" }; - mock.onPost(url, postData).reply(200, "response"); + const payload = { query: "hello" }; + mock.onPost(apiEndpoint, payload).reply(200, "response"); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, postData, "Post") + useApi({ apiEndpoint, payload, method: "Post" }) ); await waitForNextUpdate(); @@ -127,11 +129,11 @@ describe("performs requests", () => { }); it("allows different formats of POST method param (POST)", async () => { - const postData = { query: "hello" }; - mock.onPost(url, postData).reply(200, "response"); + const payload = { query: "hello" }; + mock.onPost(apiEndpoint, payload).reply(200, "response"); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, postData, "POST") + useApi({ apiEndpoint, payload, method: "POST" }) ); await waitForNextUpdate(); @@ -141,11 +143,11 @@ describe("performs requests", () => { }); it("allows different formats of POST method param (pOst)", async () => { - const postData = { query: "hello" }; - mock.onPost(url, postData).reply(200, "response"); + const payload = { query: "hello" }; + mock.onPost(apiEndpoint, payload).reply(200, "response"); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, postData, "pOst") + useApi({ apiEndpoint, payload, method: "pOst" }) ); await waitForNextUpdate(); @@ -155,10 +157,10 @@ describe("performs requests", () => { }); it("warns about bad finding a bad string in method type", async () => { - mock.onGet(url).reply(200, "response"); + const payload = { query: "hello" }; const { result } = renderHook(() => - useApi(url, 0, { query: "hello" }, "POSTITNOIE") + useApi({ apiEndpoint, payload, method: "POSTITNOTE" }) ); expect(result.current.error).toBeTruthy(); @@ -166,10 +168,11 @@ describe("performs requests", () => { }); it("warns about garbage in method type", async () => { - mock.onGet(url).reply(200, "response"); + const payload = { query: "hello" }; + // mock.onGet(url).reply(200, "response"); const { result } = renderHook(() => - useApi(url, 0, { query: "hello" }, { something: "wrong" }) + useApi({ apiEndpoint, payload, method: { something: "wrong" } }) ); expect(result.current.error).toBeTruthy(); @@ -177,9 +180,11 @@ describe("performs requests", () => { }); it("loads and polls data from a url", async () => { - mock.onGet(url).reply(200, "response"); + mock.onGet(apiEndpoint).reply(200, "response"); - const { result, waitForNextUpdate } = renderHook(() => useApi(url, 1000)); + const { result, waitForNextUpdate } = renderHook(() => + useApi({ apiEndpoint, pollInterval: 1000 }) + ); expect(result.current.data).toEqual({}); expect(result.current.loading).toBeTruthy(); @@ -189,7 +194,7 @@ describe("performs requests", () => { expect(result.current.data).toEqual("response"); expect(result.current.loading).toBeFalsy(); - mock.onGet(url).reply(200, "response2"); + mock.onGet(apiEndpoint).reply(200, "response2"); act(() => { jest.advanceTimersByTime(1000); @@ -200,7 +205,7 @@ describe("performs requests", () => { expect(result.current.data).toEqual("response2"); expect(result.current.loading).toBeFalsy(); - mock.onGet(url).reply(200, "response3"); + mock.onGet(apiEndpoint).reply(200, "response3"); act(() => { jest.advanceTimersByTime(1000); @@ -213,9 +218,11 @@ describe("performs requests", () => { }); it("can be manually refreshed", async () => { - mock.onGet(url).reply(200, "response"); + mock.onGet(apiEndpoint).reply(200, "response"); - const { result, waitForNextUpdate } = renderHook(() => useApi(url, 0)); + const { result, waitForNextUpdate } = renderHook(() => + useApi({ apiEndpoint }) + ); expect(result.current.data).toEqual({}); expect(result.current.loading).toBeTruthy(); @@ -225,7 +232,7 @@ describe("performs requests", () => { expect(result.current.data).toEqual("response"); expect(result.current.loading).toBeFalsy(); - mock.onGet(url).reply(200, "response2"); + mock.onGet(apiEndpoint).reply(200, "response2"); act(() => { result.current.refresh(); @@ -238,18 +245,16 @@ describe("performs requests", () => { }); it("refreshes when payload changes", async () => { - const postData = { query: "hello" }; - const postData2 = { query: "world" }; - mock.onPost(url, postData).reply(200, "response"); + const payload = { query: "hello" }; + const payload2 = { query: "world" }; + mock.onPost(apiEndpoint, payload).reply(200, "response"); const { result, waitForNextUpdate, rerender } = renderHook( - ({ apiEndpoint, pollInterval, payload, method }) => - useApi(apiEndpoint, pollInterval, payload, method), + props => useApi(props), { initialProps: { - apiEndpoint: url, - pollInterval: 0, - payload: postData, + apiEndpoint, + payload: payload, method: "post" } } @@ -260,12 +265,11 @@ describe("performs requests", () => { expect(result.current.data).toEqual("response"); expect(result.current.loading).toBeFalsy(); - mock.onPost(url, postData2).reply(200, "response2"); + mock.onPost(apiEndpoint, payload2).reply(200, "response2"); rerender({ - apiEndpoint: url, - pollInterval: 0, - payload: postData2, + apiEndpoint, + payload: payload2, method: "post" }); @@ -276,9 +280,11 @@ describe("performs requests", () => { }); it("returns an error on request error", async () => { - mock.onGet(url).reply(404, "response"); + mock.onGet(apiEndpoint).reply(404, "response"); - const { result, waitForNextUpdate } = renderHook(() => useApi(url, 0)); + const { result, waitForNextUpdate } = renderHook(() => + useApi({ apiEndpoint }) + ); expect(result.current.data).toEqual({}); expect(result.current.loading).toBeTruthy(); @@ -290,11 +296,11 @@ describe("performs requests", () => { }); it("notified when data has changed", async () => { - mock.onGet(url).reply(200, "response"); + mock.onGet(apiEndpoint).reply(200, "response"); const mockChanged = jest.fn(); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, null, "get", mockChanged) + useApi({ apiEndpoint, changed: mockChanged }) ); await waitForNextUpdate(); @@ -302,7 +308,7 @@ describe("performs requests", () => { expect(result.current.data).toEqual("response"); expect(result.current.loading).toBeFalsy(); - mock.onGet(url).reply(200, "response2"); + mock.onGet(apiEndpoint).reply(200, "response2"); act(() => { result.current.refresh(); @@ -316,11 +322,11 @@ describe("performs requests", () => { }); it("does not notify when data has not changed", async () => { - mock.onGet(url).reply(200, "response"); + mock.onGet(apiEndpoint).reply(200, "response"); const mockChanged = jest.fn(); const { result, waitForNextUpdate } = renderHook(() => - useApi(url, 0, null, "get", mockChanged) + useApi({ apiEndpoint, changed: mockChanged }) ); await waitForNextUpdate(); @@ -340,22 +346,20 @@ describe("performs requests", () => { }); it("request can be aborted mid-request", async () => { - mock.onGet(url).reply(() => new Promise(() => {})); - mock.onGet(url + "2").reply(200, "response2"); + mock.onGet(apiEndpoint).reply(() => new Promise(() => {})); + mock.onGet(apiEndpoint + "2").reply(200, "response2"); const { result, waitForNextUpdate, rerender } = renderHook( - ({ apiEndpoint, pollInterval }) => useApi(apiEndpoint, pollInterval), + props => useApi(props), { initialProps: { - apiEndpoint: url, - pollInterval: 0 + apiEndpoint } } ); rerender({ - apiEndpoint: url + "2", - pollInterval: 0 + apiEndpoint: apiEndpoint + "2" }); await waitForNextUpdate();