diff --git a/.env.dev b/.env.dev index add2ed2..b51cbe0 100644 --- a/.env.dev +++ b/.env.dev @@ -2,4 +2,4 @@ REACT_APP_CERT_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/certificate REACT_APP_AUTH_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/compute_auth REACT_APP_UPLOAD_SERVICE_URL=https://dev-gw.cloud.fiskerinc.com/ota_update REACT_APP_AUTH_CALLBACK_URL=https://dev-ota-admin.cloud.fiskerinc.com -REACT_APP_SUPERSET_URL=https://dev-superset.cloud.fiskerinc.com +REACT_APP_SUPERSET_URL=https://superset-dev.cloud.fiskerinc.com/superset/dashboard/8/?native_filters_key=KPnPthpLQ8rT--6PUdsPzQAcwnleRGHk_3dg0PVYfrXc3SE6zZ2x0p7JuerAZ0Pg diff --git a/.env.local b/.env.local index e8d2226..5b55344 100644 --- a/.env.local +++ b/.env.local @@ -2,4 +2,4 @@ REACT_APP_AUTH_SERVICE_URL=http://localhost/compute_auth REACT_APP_CERT_SERVICE_URL=http://localhost/certificate REACT_APP_UPLOAD_SERVICE_URL=http://localhost/ota_update REACT_APP_AUTH_CALLBACK_URL=http://localhost:3000 -REACT_APP_SUPERSET_URL=https://dev-superset.cloud.fiskerinc.com +REACT_APP_SUPERSET_URL=https://superset-dev.cloud.fiskerinc.com/superset/dashboard/8/?native_filters_key=KPnPthpLQ8rT--6PUdsPzQAcwnleRGHk_3dg0PVYfrXc3SE6zZ2x0p7JuerAZ0Pg diff --git a/.env.prd b/.env.prd index d8ce7fe..b8da28c 100644 --- a/.env.prd +++ b/.env.prd @@ -2,4 +2,4 @@ REACT_APP_AUTH_SERVICE_URL=https://gw.cloud.fiskerinc.com/compute_auth REACT_APP_CERT_SERVICE_URL=https://gw.cloud.fiskerinc.com/certificate REACT_APP_UPLOAD_SERVICE_URL=https://gw.cloud.fiskerinc.com/ota_update REACT_APP_AUTH_CALLBACK_URL=https://ota-admin.cloud.fiskerinc.com -REACT_APP_SUPERSET_URL=https://superset.cloud.fiskerinc.com +REACT_APP_SUPERSET_URL=https://superset.cloud.fiskerinc.com/superset/dashboard/9/?native_filters_key=mfJ1VjGTcLUKz7gQs_DgClZhjcdNucYMrPruNibcyDnhkDwdHbAumBRVTpA5tFH_ diff --git a/.env.stg b/.env.stg index 70fac71..224b2c2 100644 --- a/.env.stg +++ b/.env.stg @@ -2,4 +2,4 @@ REACT_APP_AUTH_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/compute_auth REACT_APP_CERT_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/certificate REACT_APP_UPLOAD_SERVICE_URL=https://stg-gw.cloud.fiskerinc.com/ota_update REACT_APP_AUTH_CALLBACK_URL=https://stg-ota-admin.cloud.fiskerinc.com -REACT_APP_SUPERSET_URL=https://stg-superset.cloud.fiskerinc.com +REACT_APP_SUPERSET_URL=https://stg-superset.cloud.fiskerinc.com/superset/dashboard/6/?native_filters_key=XBwRgJIvmxhqBhqlz45kuTnXc1iUY_M_ovzXCzXy5_l-AOFAXEaGLWpYIsfrEHGR diff --git a/package-lock.json b/package-lock.json index 50501fd..ea0312a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4038,6 +4038,19 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, "node_modules/@jridgewell/resolve-uri": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", @@ -4046,15 +4059,32 @@ "node": ">=6.0.0" } }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "node_modules/@jridgewell/sourcemap-codec": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", + "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -7895,60 +7925,6 @@ "node": ">=8.0.0" } }, - "node_modules/env-cmd/node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/env-cmd/node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/env-cmd/node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/env-cmd/node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/env-cmd/node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -15929,13 +15905,13 @@ } }, "node_modules/terser": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.0.tgz", - "integrity": "sha512-R3AUhNBGWiFc77HXag+1fXpAxTAFRQTJemlJKjAgD9r8xXTpjNKqIXwHM/o7Rh+O0kUJtS3WQVdBeMKFk5sw9A==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "dependencies": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "bin": { @@ -15983,14 +15959,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/terser/node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "engines": { - "node": ">= 8" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -20213,20 +20181,44 @@ } } }, + "@jridgewell/gen-mapping": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", + "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/resolve-uri": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz", "integrity": "sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew==" }, + "@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" + }, + "@jridgewell/source-map": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", + "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, "@jridgewell/sourcemap-codec": { "version": "1.4.11", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz", "integrity": "sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg==" }, "@jridgewell/trace-mapping": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz", - "integrity": "sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ==", + "version": "0.3.14", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz", + "integrity": "sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ==", "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -23058,44 +23050,6 @@ "requires": { "commander": "^4.0.0", "cross-spawn": "^7.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } } }, "error-ex": { @@ -28831,13 +28785,13 @@ } }, "terser": { - "version": "5.12.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.12.0.tgz", - "integrity": "sha512-R3AUhNBGWiFc77HXag+1fXpAxTAFRQTJemlJKjAgD9r8xXTpjNKqIXwHM/o7Rh+O0kUJtS3WQVdBeMKFk5sw9A==", + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz", + "integrity": "sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA==", "requires": { + "@jridgewell/source-map": "^0.3.2", "acorn": "^8.5.0", "commander": "^2.20.0", - "source-map": "~0.7.2", "source-map-support": "~0.5.20" }, "dependencies": { @@ -28845,11 +28799,6 @@ "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" } } }, diff --git a/src/components/App/App.test.js b/src/components/App/App.test.js index b78ce25..1c40617 100644 --- a/src/components/App/App.test.js +++ b/src/components/App/App.test.js @@ -17,6 +17,7 @@ import { import { setToken } from "../Contexts/UserContext"; import { TEST_AUTH_OBJECT } from "../../utils/testing"; import App from "."; +import addSnapshotSerializer from "../../utils/snapshot"; const LOADING_STATUS = "Loading..."; @@ -43,32 +44,8 @@ const sleepAndCheck = async (path, selector, compare) => { }; describe("App", () => { - const rxMakeStyles = /makeStyles-(\w+)-(\d+)/gi; - beforeAll(() => { - // Stablize Table Pagination control ids - expect.addSnapshotSerializer({ - test: function (val) { - return val && typeof val === "string" && val.indexOf("mui-") > -1; - }, - print: function (val) { - let str = val; - str = str.replace(/mui-\d*/g, "mui-00000"); - - return `"${str}"`; - }, - }); - expect.addSnapshotSerializer({ - test: (val) => { - return val && typeof val === "string" && val.search(rxMakeStyles) > -1; - }, - print: function (val) { - let str = val; - str = str.replace(rxMakeStyles, "makeStyles-$1-0000"); - - return `"${str}"`; - }, - }); + addSnapshotSerializer(expect); }, 60000); afterEach(() => { @@ -132,6 +109,10 @@ describe("App", () => { await check("/tools/certificates/add", "span.MuiButton-label", "Sign In"); }); + it("Route /tools/sms/send unauthenticated", async () => { + await check("/tools/sms/send", "span.MuiButton-label", "Sign In"); + }); + it("Route /page-not-found unauthenticated", async () => { await check("/page-not-found", "h1", "Page Not Found"); }); @@ -189,4 +170,9 @@ describe("App", () => { setToken(TEST_AUTH_OBJECT); await check("/tools/certificates/add", "h6", "Create Certificate"); }); + + it("Route /tools/sms/send authenticated", async () => { + setToken(TEST_AUTH_OBJECT); + await check("/tools/sms/send", "h6", "Send SMS"); + }); }); diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap index f76157a..e6a4999 100644 --- a/src/components/App/__snapshots__/App.test.js.snap +++ b/src/components/App/__snapshots__/App.test.js.snap @@ -6,10 +6,10 @@ exports[`App Route / authenticated 1`] = ` data-testid="mocked-userprovider" >
Fisker Admin Portal
@@ -212,12 +212,10 @@ exports[`App Route / authenticated 1`] = `
  • +
  • + +
    + + SMS + +
    + +
    +
  • @@ -504,10 +524,10 @@ exports[`App Route /home authenticated 1`] = ` data-testid="mocked-userprovider" >
    @@ -1002,10 +1042,10 @@ exports[`App Route /package-create authenticated 1`] = ` data-testid="mocked-userprovider" >
    VIN sorted ascending @@ -3172,7 +3252,7 @@ exports[`App Route /package-deploy authenticated 1`] = ` />

    Rows per page:

    @@ -3182,7 +3262,7 @@ exports[`App Route /package-deploy authenticated 1`] = `

    Rows per page:

    @@ -3845,7 +3945,7 @@ exports[`App Route /package-status authenticated 1`] = `
    ID sorted ascending @@ -4648,7 +4768,7 @@ exports[`App Route /packages authenticated 1`] = ` />

    Rows per page:

    @@ -4658,7 +4778,7 @@ exports[`App Route /packages authenticated 1`] = `
    +
    +`; + +exports[`App Route /tools/sms/send authenticated 1`] = ` +
    +
    +
    +
    +
    +
    +
    + Send SMS +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    + +
    + + +
    +
    +
    + +
    + + +
    +
    + + + +
    +
    +
    +
    +
    +
    +`; + +exports[`App Route /tools/sms/send unauthenticated 1`] = ` +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    +
    + @@ -5925,10 +6681,10 @@ exports[`App Route /vehicle-add authenticated 1`] = ` data-testid="mocked-userprovider" >
    @@ -7648,10 +8493,10 @@ exports[`App Route /vehicle-status unauthenticated 1`] = ` data-testid="mocked-userprovider" >
    VIN sorted ascending @@ -8341,7 +9206,7 @@ exports[`App Route /vehicles authenticated 1`] = ` />

    Rows per page:

    @@ -8351,7 +9216,7 @@ exports[`App Route /vehicles authenticated 1`] = `
    + + + Timestamp + Signal + Value + + + + {signals.map((signal, i) => ( + + {signal.timestamp} + {signal.signal} + {signal.value} + + ))} + +
    + ); +}; + +export default CANSignals; diff --git a/src/components/Cars/List/__snapshots__/index.test.jsx.snap b/src/components/Cars/List/__snapshots__/index.test.jsx.snap index a85e3fe..11f684d 100644 --- a/src/components/Cars/List/__snapshots__/index.test.jsx.snap +++ b/src/components/Cars/List/__snapshots__/index.test.jsx.snap @@ -15,13 +15,13 @@ exports[`VehicleTable Render 1`] = ` data-testid="mocked-vehicleprovider" >
    VIN sorted ascending diff --git a/src/components/Cars/List/index.test.jsx b/src/components/Cars/List/index.test.jsx index 64cf8db..08b6335 100644 --- a/src/components/Cars/List/index.test.jsx +++ b/src/components/Cars/List/index.test.jsx @@ -1,8 +1,8 @@ jest.mock("../../Contexts/VehicleContext"); jest.mock("../../Contexts/StatusContext"); jest.mock("../../Contexts/UserContext"); -jest.mock('@material-ui/core/utils/unstable_useId', () => - jest.fn().mockReturnValue('mui-test-id'), +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") ); import { render, waitFor } from "@testing-library/react"; @@ -12,7 +12,8 @@ import { VehicleProvider } from "../../Contexts/VehicleContext"; import { StatusProvider } from "../../Contexts/StatusContext"; import { UserProvider, setToken } from "../../Contexts/UserContext"; import { TEST_AUTH_OBJECT } from "../../../utils/testing"; -import MainForm from "./index" +import MainForm from "./index"; +import addSnapshotSerializer from "../../../utils/snapshot"; const renderVehicleTable = async () => { const { container } = render( @@ -26,11 +27,17 @@ const renderVehicleTable = async () => { ); - await waitFor(() => { /* render */ }); + await waitFor(() => { + /* render */ + }); return container; }; describe("VehicleTable", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + it("Render", async () => { setToken(TEST_AUTH_OBJECT); const container = await renderVehicleTable(); diff --git a/src/components/Cars/Status/CANFiltersTab.test.jsx b/src/components/Cars/Status/CANFiltersTab.test.jsx index e292f95..f7ac32d 100644 --- a/src/components/Cars/Status/CANFiltersTab.test.jsx +++ b/src/components/Cars/Status/CANFiltersTab.test.jsx @@ -1,8 +1,8 @@ jest.mock("../../Contexts/CANFiltersContext"); jest.mock("../../Contexts/StatusContext"); jest.mock("../../Contexts/UserContext"); -jest.mock('@material-ui/core/utils/unstable_useId', () => - jest.fn().mockReturnValue('mui-test-id'), +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") ); import { render, waitFor } from "@testing-library/react"; @@ -10,7 +10,8 @@ import { BrowserRouter } from "react-router-dom"; import { setToken } from "../../Contexts/UserContext"; import { TEST_AUTH_OBJECT } from "../../../utils/testing"; -import CANFiltersTab from "./CANFiltersTab" +import CANFiltersTab from "./CANFiltersTab"; +import addSnapshotSerializer from "../../../utils/snapshot"; const renderCANFiltersTab = async () => { const { container } = render( @@ -18,11 +19,17 @@ const renderCANFiltersTab = async () => { ); - await waitFor(() => { /* render */ }); + await waitFor(() => { + /* render */ + }); return container; }; describe("CANFiltersTab", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + it("Render", async () => { setToken(TEST_AUTH_OBJECT); const container = await renderCANFiltersTab(); diff --git a/src/components/Cars/Status/CANSignalsTab.jsx b/src/components/Cars/Status/CANSignalsTab.jsx new file mode 100644 index 0000000..ad35df1 --- /dev/null +++ b/src/components/Cars/Status/CANSignalsTab.jsx @@ -0,0 +1,35 @@ +import React from "react"; +import clsx from "clsx"; +import { Typography } from "@material-ui/core"; + +import useStyles from "../../useStyles"; +import { useUserContext } from "../../Contexts/UserContext"; +import CANSignals from "../CANSignals"; +import { VehicleProvider } from "../../Contexts/VehicleContext"; + +const Main = (props) => { + const { + token: { + idToken: { jwtToken: token }, + }, + } = useUserContext(); + const classes = useStyles(); + const { vin } = props; + + return ( +
    + + CAN Signals + + +
    + ); +}; + +const CANSignalsTab = (props) => ( + +
    + +); + +export default CANSignalsTab; diff --git a/src/components/Cars/Status/CarUpdatesTab.test.jsx b/src/components/Cars/Status/CarUpdatesTab.test.jsx index 436dea2..291be4b 100644 --- a/src/components/Cars/Status/CarUpdatesTab.test.jsx +++ b/src/components/Cars/Status/CarUpdatesTab.test.jsx @@ -1,8 +1,8 @@ jest.mock("../../Contexts/CANFiltersContext"); jest.mock("../../Contexts/StatusContext"); jest.mock("../../Contexts/UserContext"); -jest.mock('@material-ui/core/utils/unstable_useId', () => - jest.fn().mockReturnValue('mui-test-id'), +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") ); import { render, waitFor } from "@testing-library/react"; @@ -12,7 +12,8 @@ import { CANFiltersProvider } from "../../Contexts/CANFiltersContext"; import { StatusProvider } from "../../Contexts/StatusContext"; import { UserProvider, setToken } from "../../Contexts/UserContext"; import { TEST_AUTH_OBJECT } from "../../../utils/testing"; -import MainForm from "./CarUpdatesTab" +import MainForm from "./CarUpdatesTab"; +import addSnapshotSerializer from "../../../utils/snapshot"; const renderCarUpdatesTab = async () => { const { container } = render( @@ -26,11 +27,17 @@ const renderCarUpdatesTab = async () => { ); - await waitFor(() => { /* render */ }); + await waitFor(() => { + /* render */ + }); return container; }; describe("CarUpdatesTab", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + it("Render", async () => { setToken(TEST_AUTH_OBJECT); const container = await renderCarUpdatesTab(); diff --git a/src/components/Cars/Status/Details/__snapshots__/index.test.jsx.snap b/src/components/Cars/Status/Details/__snapshots__/index.test.jsx.snap index ae78611..3dcc0a7 100644 --- a/src/components/Cars/Status/Details/__snapshots__/index.test.jsx.snap +++ b/src/components/Cars/Status/Details/__snapshots__/index.test.jsx.snap @@ -15,13 +15,13 @@ exports[`VehicleDetailsTab Render 1`] = ` data-testid="mocked-vehicleprovider" >

    @@ -38,7 +38,7 @@ exports[`VehicleDetailsTab Render 1`] = `

    CANBus @@ -80,7 +80,7 @@ exports[`VehicleDetailsTab Render 1`] = `

    { const { container } = render( @@ -23,11 +24,17 @@ const renderVehicleDetailsTab = async () => { ); - await waitFor(() => { /* render */ }); + await waitFor(() => { + /* render */ + }); return container; }; describe("VehicleDetailsTab", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + it("Render", async () => { setToken(TEST_AUTH_OBJECT); const container = await renderVehicleDetailsTab(); diff --git a/src/components/Cars/Status/DetailsTab.test.jsx b/src/components/Cars/Status/DetailsTab.test.jsx index 06c7a1f..4057a10 100644 --- a/src/components/Cars/Status/DetailsTab.test.jsx +++ b/src/components/Cars/Status/DetailsTab.test.jsx @@ -1,8 +1,8 @@ jest.mock("../../Contexts/VehicleContext"); jest.mock("../../Contexts/StatusContext"); jest.mock("../../Contexts/UserContext"); -jest.mock('@material-ui/core/utils/unstable_useId', () => - jest.fn().mockReturnValue('mui-test-id'), +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") ); import { render, waitFor } from "@testing-library/react"; @@ -12,27 +12,34 @@ import { VehicleProvider } from "../../Contexts/VehicleContext"; import { StatusProvider } from "../../Contexts/StatusContext"; import { UserProvider, setToken } from "../../Contexts/UserContext"; import { TEST_AUTH_OBJECT } from "../../../utils/testing"; -import MainForm from "./DetailsTab" +import MainForm from "./DetailsTab"; +import addSnapshotSerializer from "../../../utils/snapshot"; const renderDetailsTab = async () => { const { container } = render( - + - + ); - await waitFor(() => { /* render */ }); + await waitFor(() => { + /* render */ + }); return container; }; describe("DetailsTab", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + it("Render", async () => { setToken(TEST_AUTH_OBJECT); const container = await renderDetailsTab(); diff --git a/src/components/Cars/Status/DigitalTwinTab.jsx b/src/components/Cars/Status/DigitalTwinTab.jsx new file mode 100644 index 0000000..de84bb1 --- /dev/null +++ b/src/components/Cars/Status/DigitalTwinTab.jsx @@ -0,0 +1,64 @@ +import React, { useEffect, useState } from "react"; +import clsx from "clsx"; +import { Typography } from "@material-ui/core"; + +import useStyles from "../../useStyles"; +import DigitalTwin from "../../DigitalTwin"; +import { + useVehicleContext, + VehicleProvider, +} from "../../Contexts/VehicleContext"; +import { useStatusContext } from "../../Contexts/StatusContext"; +import { useUserContext } from "../../Contexts/UserContext"; +import { logger } from "../../../services/monitoring"; + +const Main = (props) => { + const { getState } = useVehicleContext(); + const { + token: { + idToken: { jwtToken: token }, + }, + } = useUserContext(); + const { setMessage } = useStatusContext(); + const classes = useStyles(); + const [carState, setCarState] = useState(null); + const { vin } = props; + + useEffect(() => { + if (!vin) return; + (async () => { + try { + const result = await getState(token, vin); + setCarState(result.data); + } catch (e) { + setMessage(e.message); + logger.warn(e.stack); + } + })(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [vin]); + + return ( +
    + + Digital Twin + + {carState && ( + <> +
    + Connected: {carState.online.toString()} +
    + + + )} +
    + ); +}; + +const DigitalTwinTab = (props) => ( + +
    + +); + +export default DigitalTwinTab; diff --git a/src/components/Cars/Status/DigitalTwinTab.test.jsx b/src/components/Cars/Status/DigitalTwinTab.test.jsx new file mode 100644 index 0000000..aa9c27a --- /dev/null +++ b/src/components/Cars/Status/DigitalTwinTab.test.jsx @@ -0,0 +1,41 @@ +jest.mock("../../Contexts/VehicleContext"); +jest.mock("../../Contexts/StatusContext"); +jest.mock("../../Contexts/UserContext"); +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") +); + +import React from "react"; +import { render, waitFor } from "@testing-library/react"; + +import { StatusProvider } from "../../Contexts/StatusContext"; +import { UserProvider, setToken } from "../../Contexts/UserContext"; +import { TEST_AUTH_OBJECT } from "../../../utils/testing"; +import DigitalTwinTab from "./DigitalTwinTab"; +import addSnapshotSerializer from "../../../utils/snapshot"; + +const renderDetailsTab = async () => { + const { container } = render( + + + + + + ); + await waitFor(() => { + /* render */ + }); + return container; +}; + +describe("DigitalTwinTab", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + + it("Render", async () => { + setToken(TEST_AUTH_OBJECT); + const container = await renderDetailsTab(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/src/components/Cars/Status/__snapshots__/CANFiltersTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/CANFiltersTab.test.jsx.snap index 9262594..5aca30a 100644 --- a/src/components/Cars/Status/__snapshots__/CANFiltersTab.test.jsx.snap +++ b/src/components/Cars/Status/__snapshots__/CANFiltersTab.test.jsx.snap @@ -3,7 +3,7 @@ exports[`CANFiltersTab Render 1`] = `
    Car ECUs
    ECU sorted descending diff --git a/src/components/Cars/Status/__snapshots__/DetailsTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/DetailsTab.test.jsx.snap index 0c0ee83..3c50755 100644 --- a/src/components/Cars/Status/__snapshots__/DetailsTab.test.jsx.snap +++ b/src/components/Cars/Status/__snapshots__/DetailsTab.test.jsx.snap @@ -12,7 +12,7 @@ exports[`DetailsTab Render 1`] = ` data-testid="mocked-userprovider" >

    @@ -47,7 +47,7 @@ exports[`DetailsTab Render 1`] = `

    CANBus @@ -89,7 +89,7 @@ exports[`DetailsTab Render 1`] = `

    +`; diff --git a/src/components/Cars/Status/__snapshots__/index.test.jsx.snap b/src/components/Cars/Status/__snapshots__/index.test.jsx.snap index e1bc42d..34e37ea 100644 --- a/src/components/Cars/Status/__snapshots__/index.test.jsx.snap +++ b/src/components/Cars/Status/__snapshots__/index.test.jsx.snap @@ -12,10 +12,10 @@ exports[`CarStatus Render 1`] = ` data-testid="mocked-userprovider" >
    + +
    @@ -97,10 +133,10 @@ exports[`CarStatus Render 1`] = ` role="tabpanel" >
    ); }; function tabProps(index) { return { id: `tab-${index}`, - "aria-controls": `tabpanel-${index}` + "aria-controls": `tabpanel-${index}`, }; } diff --git a/src/components/Cars/Status/index.test.jsx b/src/components/Cars/Status/index.test.jsx index e92b00a..9eaed1a 100644 --- a/src/components/Cars/Status/index.test.jsx +++ b/src/components/Cars/Status/index.test.jsx @@ -1,8 +1,8 @@ jest.mock("../../Contexts/CANFiltersContext"); jest.mock("../../Contexts/StatusContext"); jest.mock("../../Contexts/UserContext"); -jest.mock('@material-ui/core/utils/unstable_useId', () => - jest.fn().mockReturnValue('mui-test-id'), +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") ); import { render, waitFor } from "@testing-library/react"; @@ -12,7 +12,8 @@ import { CANFiltersProvider } from "../../Contexts/CANFiltersContext"; import { StatusProvider } from "../../Contexts/StatusContext"; import { UserProvider, setToken } from "../../Contexts/UserContext"; import { TEST_AUTH_OBJECT } from "../../../utils/testing"; -import CarStatus from "./index" +import CarStatus from "./index"; +import addSnapshotSerializer from "../../../utils/snapshot"; const renderCarStatus = async () => { const { container } = render( @@ -26,11 +27,17 @@ const renderCarStatus = async () => { ); - await waitFor(() => { /* render */ }); + await waitFor(() => { + /* render */ + }); return container; }; describe("CarStatus", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + it("Render", async () => { setToken(TEST_AUTH_OBJECT); const container = await renderCarStatus(); diff --git a/src/components/Cars/Update/__snapshots__/index.test.jsx.snap b/src/components/Cars/Update/__snapshots__/index.test.jsx.snap index 86ff5c7..78c7610 100644 --- a/src/components/Cars/Update/__snapshots__/index.test.jsx.snap +++ b/src/components/Cars/Update/__snapshots__/index.test.jsx.snap @@ -15,11 +15,11 @@ exports[`VehicleUpdate Render 1`] = ` data-testid="mocked-vehicleprovider" >
    { - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10); const [pageIndex, setPageIndex] = useState(0); const [orderBy, setOrderBy] = useState("id"); const [order, setOrder] = useState("desc"); diff --git a/src/components/Fleets/Table/index.test.jsx b/src/components/Fleets/Table/index.test.jsx index c8bf957..31d2b6b 100644 --- a/src/components/Fleets/Table/index.test.jsx +++ b/src/components/Fleets/Table/index.test.jsx @@ -1,8 +1,8 @@ jest.mock("../../Contexts/FleetContext"); jest.mock("../../Contexts/StatusContext"); jest.mock("../../Contexts/UserContext"); -jest.mock('@material-ui/core/utils/unstable_useId', () => - jest.fn().mockReturnValue('mui-test-id'), +jest.mock("@material-ui/core/utils/unstable_useId", () => + jest.fn().mockReturnValue("mui-test-id") ); import { render, waitFor } from "@testing-library/react"; @@ -12,7 +12,8 @@ import { FleetProvider } from "../../Contexts/FleetContext"; import { StatusProvider } from "../../Contexts/StatusContext"; import { UserProvider, setToken } from "../../Contexts/UserContext"; import { TEST_AUTH_OBJECT } from "../../../utils/testing"; -import MainForm from "./index" +import MainForm from "./index"; +import addSnapshotSerializer from "../../../utils/snapshot"; const renderFleetTable = async () => { const { container } = render( @@ -26,11 +27,17 @@ const renderFleetTable = async () => { ); - await waitFor(() => { /* render */ }); + await waitFor(() => { + /* render */ + }); return container; }; describe("FleetTable", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + it("Render", async () => { setToken(TEST_AUTH_OBJECT); const container = await renderFleetTable(); diff --git a/src/components/Fleets/Update/__snapshots__/index.test.jsx.snap b/src/components/Fleets/Update/__snapshots__/index.test.jsx.snap index 096bdca..24169cd 100644 --- a/src/components/Fleets/Update/__snapshots__/index.test.jsx.snap +++ b/src/components/Fleets/Update/__snapshots__/index.test.jsx.snap @@ -15,11 +15,11 @@ exports[`FleetUpdate Render 1`] = ` data-testid="mocked-fleetprovider" >
    Registered sorted ascending diff --git a/src/components/Suppliers/List/index.test.jsx b/src/components/Suppliers/List/index.test.jsx index eda2fd9..520e896 100644 --- a/src/components/Suppliers/List/index.test.jsx +++ b/src/components/Suppliers/List/index.test.jsx @@ -12,6 +12,7 @@ import { StatusProvider } from "../../Contexts/StatusContext"; import { UserProvider, setToken } from "../../Contexts/UserContext"; import { TEST_AUTH_OBJECT } from "../../../utils/testing"; import MainForm from "./index"; +import addSnapshotSerializer from "../../../utils/snapshot"; const renderSuppliersPage = async () => { const { container } = render( @@ -32,6 +33,10 @@ const renderSuppliersPage = async () => { }; describe("Suppliers page", () => { + beforeAll(() => { + addSnapshotSerializer(expect); + }); + it("Render", async () => { setToken(TEST_AUTH_OBJECT); const container = await renderSuppliersPage(); diff --git a/src/components/Suppliers/Table/index.jsx b/src/components/Suppliers/Table/index.jsx index 2de71e7..4be3ef8 100644 --- a/src/components/Suppliers/Table/index.jsx +++ b/src/components/Suppliers/Table/index.jsx @@ -16,6 +16,7 @@ import { useStatusContext } from "../../Contexts/StatusContext"; import { LocalDateTimeString } from "../../../utils/dates"; import TableHeaderSortable from "../../Table/HeaderSortable"; import { logger } from "../../../services/monitoring"; +import {useLocalStorage} from "../../useLocalStorage"; const tableColumns = [ { @@ -48,9 +49,11 @@ const tableColumns = [ }, ]; +const PAGE_SIZE="SUPPLIER_TABLE_PAGE_SIZE"; + const SupplierTable = (props) => { const { token, classes } = props; - const [pageSize, setPageSize] = useState(10); + const [pageSize, setPageSize] = useLocalStorage(PAGE_SIZE, 10); const [pageIndex, setPageIndex] = useState(0); const [orderBy, setOrderBy] = useState("created_at"); const [order, setOrder] = useState("asc"); diff --git a/src/components/VehicleMap/index.jsx b/src/components/VehicleMap/index.jsx index b66abd8..5006802 100644 --- a/src/components/VehicleMap/index.jsx +++ b/src/components/VehicleMap/index.jsx @@ -179,7 +179,8 @@ const Component = () => { doors={carState.doors} location={carState.location} windows={carState.windows} - updatedAt={carState.updated} + trex_version={carState.trex_version} + updated={carState.updated} className={classes.popup} onClose={handleClose} /> diff --git a/src/components/VehicleMap/popup.jsx b/src/components/VehicleMap/popup.jsx index 8451d24..b990691 100644 --- a/src/components/VehicleMap/popup.jsx +++ b/src/components/VehicleMap/popup.jsx @@ -1,84 +1,63 @@ import React from "react"; -import Dialog from '@material-ui/core/Dialog'; -import MuiDialogTitle from '@material-ui/core/DialogTitle'; -import IconButton from '@material-ui/core/IconButton'; -import CloseIcon from '@material-ui/icons/Close'; -import Typography from '@material-ui/core/Typography'; +import Dialog from "@material-ui/core/Dialog"; +import MuiDialogTitle from "@material-ui/core/DialogTitle"; +import IconButton from "@material-ui/core/IconButton"; +import CloseIcon from "@material-ui/icons/Close"; +import Typography from "@material-ui/core/Typography"; import useStyles from "../useStyles"; -import { LocalDateTimeString } from "../../utils/dates"; +import DigitalTwin from "../DigitalTwin"; const VehiclePopUp = (props) => { - const classes = useStyles(); - const { vin, online, battery, doors, location, updatedAt, windows, onClose } = props; + const classes = useStyles(); + const { vin, online, battery, doors, location, windows, onClose } = props; - return ( - - {vin} -
    -

    Connected: {online.toString()}

    - {online && ( -
    - {battery != null && ( -

    Battery: {battery.percent}%

    - )} - {doors != null && ( -
    -

    Doors

    - {Object.entries(doors).map((value) => (

    {value[0]}: {value[1] ? "open" : "closed"}

    ))} -
    - )} - {windows != null && ( -
    -

    Windows

    - {Object.entries(windows).map((value) => (

    {value[0]}: {value[1] ? "open" : "closed"}

    ))} -
    - )} - {location != null && ( -
    -

    Location

    - {Object.entries(location).map((value) => { - if (value[0] === "altitude") { - return (

    {value[0]}: {value[1]}

    ); - } else { - return (

    {value[0]}: {value[1]}°

    ) - } - })} -
    - )} - {updatedAt != null && ( -
    -

    Updated at: {LocalDateTimeString(updatedAt)}

    -
    - )} -
    - )} - {(!online || (battery == null && doors == null && location == null && windows == null)) && ( -

    No vehicle data to display.

    - )} -
    -
    - ); + return ( + + + {vin} + +
    +

    + Connected: {online.toString()} +

    + {online && } + {(!online || + (battery == null && + doors == null && + location == null && + windows == null)) &&

    No vehicle data to display.

    } +
    +
    + ); }; const DialogTitle = (props) => { - const { children, onClose, ...other } = props; - const classes = useStyles(); - return ( - - {children} - {onClose ? ( - - - - ) : null} - - ); + const { children, onClose, ...other } = props; + const classes = useStyles(); + return ( + + {children} + {onClose ? ( + + + + ) : null} + + ); }; export { VehiclePopUp }; diff --git a/src/components/useLocalStorage.js b/src/components/useLocalStorage.js new file mode 100644 index 0000000..28b6dc4 --- /dev/null +++ b/src/components/useLocalStorage.js @@ -0,0 +1,21 @@ +import { useState, useEffect } from "react"; + +export function getStorageValue(key, defaultValue) { + // getting stored value + const saved = localStorage.getItem(key); + const initial = JSON.parse(saved); + return initial || defaultValue; +} + +export const useLocalStorage = (key, defaultValue) => { + const [value, setValue] = useState(() => { + return getStorageValue(key, defaultValue); + }); + + useEffect(() => { + // storing input name + localStorage.setItem(key, JSON.stringify(value)); + }, [key, value]); + + return [value, setValue]; +}; \ No newline at end of file diff --git a/src/components/useLocalStorage.test.js b/src/components/useLocalStorage.test.js new file mode 100644 index 0000000..04e9f51 --- /dev/null +++ b/src/components/useLocalStorage.test.js @@ -0,0 +1,41 @@ +import {getStorageValue, useLocalStorage} from './useLocalStorage' +import {cleanup, render, screen} from "@testing-library/react"; + +describe('getStorageValue', () => { + it('getting stored value', () => { + let val = getStorageValue('key', 'defaultValue'); + expect(val).toBe('defaultValue'); + + localStorage.setItem('key', JSON.stringify('value')); + val = getStorageValue('key', 'defaultValue'); + expect(val).toBe('value'); + }); +}) + + +describe('useLocalStorage', () => { + beforeEach(() => { + const TestComponent = () => { + const [value, setValue] = useLocalStorage('key2', 'defaultValue'); + return ( +
    + +
    {value}
    +
    + ); + } + + render(); + }); + + afterEach(() => { + cleanup(); + }); + + + it('getting default value and setting it', () => { + expect(screen.getByTestId('val').innerHTML).toEqual('defaultValue'); + screen.getByTestId('setVal').click(); + expect(screen.getByTestId('val').innerHTML).toEqual('newValue'); + }); +}) \ No newline at end of file diff --git a/src/components/useStyles.jsx b/src/components/useStyles.jsx index bb18d22..df12ed4 100644 --- a/src/components/useStyles.jsx +++ b/src/components/useStyles.jsx @@ -171,6 +171,15 @@ const useStyles = makeStyles((theme) => ({ grow: { flexGrow: 1, }, + iframeResponsive: { + position: "absolute", + top: 0, + left: 0, + bottom: 0, + right: 0, + width: "100%", + height: "100%", + }, embeddedWrapper: { marginTop: 10, position: "relative", diff --git a/src/services/smsAPI.js b/src/services/smsAPI.js new file mode 100644 index 0000000..396d50f --- /dev/null +++ b/src/services/smsAPI.js @@ -0,0 +1,27 @@ +import { + errorHandler, + getAuthHeaderOptions, + fetchRespHandler, +} from "../utils/http"; + +const API_ENDPOINT = process.env.REACT_APP_UPLOAD_SERVICE_URL; + +const smsAPI = { + /** + * Sends a SMS to an ICCID + * @param {*} data + * @param {*} token + * @returns + */ + send: async (data, token) => + fetch(`${API_ENDPOINT}/sms`, { + method: "POST", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + body: JSON.stringify(data), + }).then(fetchRespHandler).catch(errorHandler), +}; + +export default smsAPI; \ No newline at end of file diff --git a/src/services/vehiclesAPI.js b/src/services/vehiclesAPI.js index ea1d408..d57c1d0 100644 --- a/src/services/vehiclesAPI.js +++ b/src/services/vehiclesAPI.js @@ -152,6 +152,17 @@ const vehiclesAPI = { }) .then(fetchRespHandler) .catch(errorHandler), + + getCANSignals: async (vin, token) => + fetch(`${API_ENDPOINT}/cansignals/${vin}`, { + method: "GET", + headers: Object.assign( + { "Content-Type": "application/json" }, + getAuthHeaderOptions(token) + ), + }) + .then(fetchRespHandler) + .catch(errorHandler), }; export default vehiclesAPI; diff --git a/src/utils/snapshot.js b/src/utils/snapshot.js new file mode 100644 index 0000000..54395e8 --- /dev/null +++ b/src/utils/snapshot.js @@ -0,0 +1,35 @@ +const rxMakeStyles = /makeStyles-(\w+)-(\d+)/gi; +const rxMUIStyles = /mui-\d*/g; + +const snapshotSerializers = [ + { + test: (val) => { + return val && typeof val === "string" && val.indexOf("mui-") > -1; + }, + print: (val) => { + let str = val; + str = str.replace(rxMUIStyles, "mui-0"); + + return `"${str}"`; + }, + }, + { + test: (val) => { + return val && typeof val === "string" && val.search(rxMakeStyles) > -1; + }, + print: (val) => { + let str = val; + str = str.replace(rxMakeStyles, "makeStyles-$1-0"); + + return `"${str}"`; + }, + }, +]; + +const addSnapshotSerializer = (expect) => { + snapshotSerializers.forEach((serializer) => { + expect.addSnapshotSerializer(serializer); + }); +}; + +export default addSnapshotSerializer;