From 5e0f115a67f745305b940e79d1d7bd59c3142c0d Mon Sep 17 00:00:00 2001 From: Mcat12 Date: Sun, 5 May 2019 15:05:56 -0700 Subject: [PATCH 1/7] Add WithAPIData tests Signed-off-by: Mcat12 --- src/components/common/WithAPIData.tsx | 4 +- .../common/__tests__/WithAPIData.test.tsx | 321 ++++++++++++++++++ 2 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 src/components/common/__tests__/WithAPIData.test.tsx diff --git a/src/components/common/WithAPIData.tsx b/src/components/common/WithAPIData.tsx index 2a165b3..e5977d4 100644 --- a/src/components/common/WithAPIData.tsx +++ b/src/components/common/WithAPIData.tsx @@ -102,9 +102,7 @@ export class WithAPIData extends Component< if (cancelOptions) { // If the request should be repeated, wait for the interval and then // refresh with data from the API - new Promise(resolve => - setTimeout(resolve, cancelOptions.interval) - ).then(() => this.loadData()); + setTimeout(() => this.loadData(), cancelOptions.interval); } return; } diff --git a/src/components/common/__tests__/WithAPIData.test.tsx b/src/components/common/__tests__/WithAPIData.test.tsx new file mode 100644 index 0000000..aa7d5a3 --- /dev/null +++ b/src/components/common/__tests__/WithAPIData.test.tsx @@ -0,0 +1,321 @@ +/* Pi-hole: A black hole for Internet advertisements + * (c) 2019 Pi-hole, LLC (https://pi-hole.net) + * Network-wide ad blocking via your own hardware. + * + * Web Interface + * WithAPIData component test + * + * This file is copyright under the latest version of the EUPL. + * Please see LICENSE file for your rights under this license. */ + +import React from "react"; +import { shallow, ShallowWrapper } from "enzyme"; +import { + WithAPIData, + WithAPIDataProps, + WithAPIDataState +} from "../WithAPIData"; + +const tick = global.tick; +const emptyRender = () => null; +const emptyAPICall = () => Promise.resolve({}); + +type WithAPIDataWrapper = ShallowWrapper< + WithAPIDataProps, + WithAPIDataState, + WithAPIData +>; + +it("should use renderInitial at the start", () => { + const renderInitial = jest.fn(() => "test"); + const wrapper = shallow( + + ); + + expect(renderInitial).toHaveBeenCalled(); + expect(wrapper).toHaveText("test"); +}); + +it("should use renderOk after fetching the data", async () => { + const renderOk = jest.fn(data => data); + const wrapper = shallow( + Promise.resolve("test")} + renderOk={renderOk} + /> + ); + + // Let the API call resolve + await tick(); + + expect(renderOk).toHaveBeenCalled(); + expect(wrapper).toHaveText("test"); +}); + +it("should cancel the in-flight request when unmounting", () => { + const renderOk = jest.fn(data => data); + const apiCall = jest.fn(emptyAPICall); + const wrapper = shallow( + + ); + + wrapper.unmount(); + + expect(apiCall).toHaveBeenCalled(); + expect(renderOk).not.toHaveBeenCalled(); + expect(wrapper).not.toHaveText("test"); +}); + +it("should only rerender once if refresh is called twice", async () => { + let called = false; + const renderOk = jest.fn((_, refresh) => { + if (called) return null; + called = true; + refresh(); + refresh(); + return null; + }); + + shallow( + + ); + + // Let the two API calls resolve + await tick(); + await tick(); + + expect(renderOk).toHaveBeenCalledTimes(2); +}); + +it("should ignore cancel errors if the option is enabled", async () => { + const apiCall = () => Promise.reject({ isCanceled: true }); + const renderOk = jest.fn(emptyRender); + const renderErr = jest.fn(emptyRender); + + shallow( + + ); + + // Let the API call resolve + await tick(); + + // If the request was canceled, neither the Ok nor Err renderers would have + // been called + expect(renderErr).not.toHaveBeenCalled(); + expect(renderOk).not.toHaveBeenCalled(); +}); + +it("should throw non-cancel errors when ignoring cancel errors", async () => { + const error = { test: true }; + const apiCall = () => Promise.reject(error); + const renderOk = jest.fn(emptyRender); + const renderErr = jest.fn(() => "test"); + + const wrapper: WithAPIDataWrapper = shallow( + + ); + + // Let the API call resolve + await tick(); + + expect(renderErr).toHaveBeenCalledWith(error, wrapper.instance().loadData); + expect(renderOk).not.toHaveBeenCalled(); + expect(wrapper).toHaveText("test"); +}); + +it("should throw cancel errors when not ignoring cancel", async () => { + const error = { isCanceled: true }; + const apiCall = () => Promise.reject(error); + const renderOk = jest.fn(emptyRender); + const renderErr = jest.fn(() => "test"); + + const wrapper: WithAPIDataWrapper = shallow( + + ); + + // Let the API call resolve + await tick(); + + expect(renderErr).toHaveBeenCalledWith(error, wrapper.instance().loadData); + expect(renderOk).not.toHaveBeenCalled(); + expect(wrapper).toHaveText("test"); +}); + +it("should clear the data when flushOnUpdate is true and props are changed", async () => { + const renderInitial = jest.fn(() => "initial"); + const renderOk = jest.fn(() => "ok"); + const apiCall = jest.fn(() => Promise.resolve("test")); + const wrapper: WithAPIDataWrapper = shallow( + + ); + + // Let the API call resolve + await tick(); + + expect(apiCall).toBeCalledTimes(1); + expect(renderInitial).toHaveBeenCalledTimes(1); + expect(renderOk).toHaveBeenCalledTimes(1); + + // Change the props in a small way + wrapper.setProps({ repeatOptions: { ignoreCancel: false, interval: 0 } }); + + // Let the second API call resolve + await tick(); + + expect(apiCall).toBeCalledTimes(2); + expect(renderInitial).toHaveBeenCalledTimes(2); + expect(renderOk).toHaveBeenCalledTimes(3); +}); + +it("should use the provided data on refresh instead of hitting the API", async () => { + let refreshTest: ((data: any) => void) | undefined = undefined; + const renderOk = jest.fn((data, refresh) => { + refreshTest = refresh; + return data; + }); + const apiCall = jest.fn(() => Promise.resolve("test data")); + const wrapper = shallow( + + ); + + // Let the API call resolve + await tick(); + + // Call the refresh function with the new data + expect(refreshTest).toBeDefined(); + refreshTest!("new data"); + + expect(apiCall).toHaveBeenCalledTimes(1); + expect(renderOk).toHaveBeenCalledTimes(2); + expect(wrapper).toHaveText("new data"); +}); + +it("should wait for the interval after refreshing with provided data", async () => { + jest.useFakeTimers(); + + let refreshTest: ((data: any) => void) | undefined = undefined; + const renderOk = jest.fn((data, refresh) => { + refreshTest = refresh; + return data; + }); + const apiCall = jest.fn(() => Promise.resolve("test data")); + + shallow( + + ); + + // Let the API call resolve + await tick(); + + // Call the refresh function with the new data + expect(refreshTest).toBeDefined(); + refreshTest!("new data"); + + // Wait for the interval + jest.advanceTimersByTime(1000); + + // The API call should have been triggered again + expect(apiCall).toHaveBeenCalledTimes(2); +}); + +it("should pass through repeat options", async () => { + jest.useFakeTimers(); + + const wrapper: WithAPIDataWrapper = shallow( + + ); + + // Let the API call resolve + await tick(); + + expect(setTimeout).toHaveBeenCalledWith(wrapper.instance().loadData, 1000); +}); + +it("should pass through repeat options after refresh", async () => { + jest.useFakeTimers(); + + let refreshTest: ((data: any) => void) | undefined = undefined; + const renderOk = jest.fn((data, refresh) => { + refreshTest = refresh; + return data; + }); + const apiCall = jest.fn(() => Promise.resolve("test data")); + + shallow( + + ); + + // Let the API call resolve + await tick(); + + // Call the refresh function with the new data + expect(refreshTest).toBeDefined(); + refreshTest!("new data"); + + expect(setTimeout).toHaveBeenCalledTimes(2); +}); From d543bf334a96060b00b67c681455317e22be8ec8 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Thu, 13 Jun 2019 11:55:17 +0000 Subject: [PATCH 2/7] Bump @types/jest from 24.0.13 to 24.0.14 Bumps [@types/jest](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jest) from 24.0.13 to 24.0.14. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jest) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1cfc247..bbc5894 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2610,9 +2610,9 @@ } }, "@types/jest": { - "version": "24.0.13", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.13.tgz", - "integrity": "sha512-3m6RPnO35r7Dg+uMLj1+xfZaOgIHHHut61djNjzwExXN4/Pm9has9C6I1KMYSfz7mahDhWUOVg4HW/nZdv5Pww==", + "version": "24.0.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-24.0.14.tgz", + "integrity": "sha512-IxS2AO0nOr4zrpKfRCxobQUb1bSK6ejodZ7odCzHXMjsASCI8J10N8qVQhrCjvJTc3bUjGGeuD+ytKZqyhajqQ==", "dev": true, "requires": { "@types/jest-diff": "*" diff --git a/package.json b/package.json index 77cf7ef..56eadbc 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "@types/enzyme": "^3.9.3", "@types/enzyme-adapter-react-16": "^1.0.5", "@types/fetch-mock": "^7.3.0", - "@types/jest": "^24.0.13", + "@types/jest": "^24.0.14", "@types/lodash.debounce": "^4.0.6", "@types/lodash.isequal": "^4.5.5", "@types/node": "^12.0.8", From fd14e4fe9e5580270eeaf13aa5bc1c93b66ca15b Mon Sep 17 00:00:00 2001 From: Richard Denton Date: Sat, 15 Jun 2019 08:40:30 +0800 Subject: [PATCH 3/7] Adds styling to the FTL settings tab, fixes #166 Signed-off-by: Richard Denton --- src/components/settings/FTLInfo.tsx | 49 ++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 7 deletions(-) diff --git a/src/components/settings/FTLInfo.tsx b/src/components/settings/FTLInfo.tsx index f4c4b49..b6f43b3 100644 --- a/src/components/settings/FTLInfo.tsx +++ b/src/components/settings/FTLInfo.tsx @@ -10,6 +10,7 @@ import React, { Component } from "react"; import { WithTranslation, withTranslation } from "react-i18next"; +import { Form, Col, Input, FormGroup, Label } from "reactstrap"; import api from "../../util/api"; import { WithAPIData } from "../common/WithAPIData"; @@ -24,13 +25,47 @@ class FTLInfo extends Component { const { t } = this.props; return ( -
-        {t("Queries")}: {this.props.queries}
-        
- {t("Filesize")}: {this.props.fileSize.toLocaleString()} B
- {t("SQLite version")}: {this.props.sqliteVersion.toLocaleString()} -
-
+
+ + + + + + + + + + + + + + + + + + +
); } } From 1d560ac3ccaa48aba9adb4c7bbe51e291c86db4a Mon Sep 17 00:00:00 2001 From: Richard Denton Date: Sun, 16 Jun 2019 08:54:08 +0800 Subject: [PATCH 4/7] Fix mismatching labels, correct usage of toLocaleString(), ensure formatter has been run Signed-off-by: Richard Denton --- src/components/settings/FTLInfo.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/settings/FTLInfo.tsx b/src/components/settings/FTLInfo.tsx index b6f43b3..88ee63f 100644 --- a/src/components/settings/FTLInfo.tsx +++ b/src/components/settings/FTLInfo.tsx @@ -27,7 +27,7 @@ class FTLInfo extends Component { return (
- @@ -48,12 +48,12 @@ class FTLInfo extends Component { plaintext readOnly id="filesize" - value={this.props.fileSize.toLocaleString()} + value={`${this.props.fileSize.toLocaleString()} B`} /> - From fdffe32eddabeae78e22110ce205b39c583fee28 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Sun, 16 Jun 2019 02:19:25 +0000 Subject: [PATCH 5/7] Bump @types/react from 16.8.19 to 16.8.20 Bumps [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) from 16.8.19 to 16.8.20. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index bbc5894..5cc1f8d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2676,9 +2676,9 @@ "dev": true }, "@types/react": { - "version": "16.8.19", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.19.tgz", - "integrity": "sha512-QzEzjrd1zFzY9cDlbIiFvdr+YUmefuuRYrPxmkwG0UQv5XF35gFIi7a95m1bNVcFU0VimxSZ5QVGSiBmlggQXQ==", + "version": "16.8.20", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.20.tgz", + "integrity": "sha512-ZLmI+ubSJpfUIlQuULDDrdyuFQORBuGOvNnMue8HeA0GVrAJbWtZQhcBvnBPNRBI/GrfSfrKPFhthzC2SLEtLQ==", "dev": true, "requires": { "@types/prop-types": "*", diff --git a/package.json b/package.json index 56eadbc..0f6ed58 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "@types/lodash.debounce": "^4.0.6", "@types/lodash.isequal": "^4.5.5", "@types/node": "^12.0.8", - "@types/react": "^16.8.19", + "@types/react": "^16.8.20", "@types/react-bootstrap-daterangepicker": "0.0.26", "@types/react-bootstrap-typeahead": "^3.4.5", "@types/react-dom": "^16.8.4", From 5ff00d6c8cead2b4625c0de03f33f53636282bdf Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Sun, 16 Jun 2019 03:27:23 +0000 Subject: [PATCH 6/7] Bump @types/react-router-dom from 4.3.3 to 4.3.4 Bumps [@types/react-router-dom](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-router-dom) from 4.3.3 to 4.3.4. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-router-dom) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5cc1f8d..b3792bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2714,9 +2714,9 @@ } }, "@types/react-router": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.0.1.tgz", - "integrity": "sha512-vOyVO0u3Cs0w6G5DzYqNVqcTsurEnDgOmmkJf2s7VwtunWzpPgI6dHsCBX68vXqeICpP6jCfojgJcHkm5BV7hQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.0.2.tgz", + "integrity": "sha512-sdMN284GEOcqDEMS/hE/XD06Abw2fws30+xkZf3C9cSRcWopiv/HDTmunYI7DKLYKVRaWFkq1lkuJ6qeYu0E7A==", "dev": true, "requires": { "@types/history": "*", @@ -2724,9 +2724,9 @@ } }, "@types/react-router-dom": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-4.3.3.tgz", - "integrity": "sha512-xj0DmFjgvAqRfh/kJPO7apD5G30yPQe+8slu/dugioQOkdKpyzc4Fgk4hoTelm6CSHz7pI2PPsW5+Y6GRBF2zw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-4.3.4.tgz", + "integrity": "sha512-xrwaWHpnxKk/TTRe7pmoGy3E4SyF/ojFqNfFJacw7OLdfLXRvGfk4r/XePVaZNVfeJzL8fcnNilPN7xOdJ/vGw==", "dev": true, "requires": { "@types/history": "*", diff --git a/package.json b/package.json index 0f6ed58..944f696 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@types/react-bootstrap-daterangepicker": "0.0.26", "@types/react-bootstrap-typeahead": "^3.4.5", "@types/react-dom": "^16.8.4", - "@types/react-router-dom": "^4.3.3", + "@types/react-router-dom": "^4.3.4", "@types/react-table": "^6.8.3", "@types/reactstrap": "^8.0.1", "@types/sha.js": "^2.4.0", From 2b58777dea563a484953bbeac5e09ed49fc365c0 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" Date: Sun, 16 Jun 2019 03:34:00 +0000 Subject: [PATCH 7/7] Bump typescript from 3.5.1 to 3.5.2 Bumps [typescript](https://github.com/Microsoft/TypeScript) from 3.5.1 to 3.5.2. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v3.5.1...v3.5.2) Signed-off-by: dependabot-preview[bot] --- package-lock.json | 6 +++--- package.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b3792bf..3e12456 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21687,9 +21687,9 @@ "dev": true }, "typescript": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.1.tgz", - "integrity": "sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw==", + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz", + "integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==", "dev": true }, "uglify-js": { diff --git a/package.json b/package.json index 944f696..5643f3c 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "prettier": "^1.18.2", "react-scripts": "^3.0.1", "react-test-renderer": "^16.8.6", - "typescript": "^3.5.1" + "typescript": "^3.5.2" }, "dependencies": { "@coreui/coreui": "^2.1.12",