CEC-180 Cache Control (#30)
* Set cache expire to 1 day Add snapshot tests for new screens * Fix table pagniation random ids for snapshot tests * Auto reload on chunk load error * OTA Admin Portal => Admin Portal
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
# Fisker OTA Admin Portal
|
# Fisker Admin Portal
|
||||||
|
|
||||||
Front-end web application for administarting OTA services
|
Front-end web application for administarting OTA services
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
|
||||||
Run `./run.sh` from the terminal or
|
Run `./run.sh` from the terminal or
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ server {
|
|||||||
root /usr/share/nginx/html;
|
root /usr/share/nginx/html;
|
||||||
include /etc/nginx/mime.types;
|
include /etc/nginx/mime.types;
|
||||||
|
|
||||||
|
expires 1d;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
try_files $uri /index.html;
|
try_files $uri /index.html;
|
||||||
}
|
}
|
||||||
|
|||||||
104
package-lock.json
generated
104
package-lock.json
generated
@@ -2177,25 +2177,26 @@
|
|||||||
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
|
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
|
||||||
},
|
},
|
||||||
"@types/react": {
|
"@types/react": {
|
||||||
"version": "17.0.1",
|
"version": "17.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.3.tgz",
|
||||||
"integrity": "sha512-w8t9f53B2ei4jeOqf/gxtc2Sswnc3LBK5s0DyJcg5xd10tMHXts2N31cKjWfH9IC/JvEPa/YF1U4YeP1t4R6HQ==",
|
"integrity": "sha512-wYOUxIgs2HZZ0ACNiIayItyluADNbONl7kt8lkLjVK8IitMH5QMyAh75Fwhmo37r1m7L2JaFj03sIfxBVDvRAg==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/prop-types": "*",
|
"@types/prop-types": "*",
|
||||||
|
"@types/scheduler": "*",
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": {
|
"csstype": {
|
||||||
"version": "3.0.6",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz",
|
||||||
"integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw=="
|
"integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/react-transition-group": {
|
"@types/react-transition-group": {
|
||||||
"version": "4.4.0",
|
"version": "4.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz",
|
||||||
"integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==",
|
"integrity": "sha512-vIo69qKKcYoJ8wKCJjwSgCTM+z3chw3g18dkrDfVX665tMH7tmbDxEAnPdey4gTlwZz5QuHGzd+hul0OVZDqqQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
@@ -2208,6 +2209,11 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/scheduler": {
|
||||||
|
"version": "0.16.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.1.tgz",
|
||||||
|
"integrity": "sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA=="
|
||||||
|
},
|
||||||
"@types/source-list-map": {
|
"@types/source-list-map": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
|
||||||
@@ -4655,9 +4661,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"csstype": {
|
"csstype": {
|
||||||
"version": "2.6.14",
|
"version": "2.6.16",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.14.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.16.tgz",
|
||||||
"integrity": "sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A=="
|
"integrity": "sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q=="
|
||||||
},
|
},
|
||||||
"cyclist": {
|
"cyclist": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
@@ -4998,9 +5004,9 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": {
|
"csstype": {
|
||||||
"version": "3.0.6",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz",
|
||||||
"integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw=="
|
"integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -8942,9 +8948,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss": {
|
"jss": {
|
||||||
"version": "10.5.1",
|
"version": "10.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss/-/jss-10.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jss/-/jss-10.6.0.tgz",
|
||||||
"integrity": "sha512-hbbO3+FOTqVdd7ZUoTiwpHzKXIo5vGpMNbuXH1a0wubRSWLWSBvwvaq4CiHH/U42CmjOnp6lVNNs/l+Z7ZdDmg==",
|
"integrity": "sha512-n7SHdCozmxnzYGXBHe0NsO0eUf9TvsHVq2MXvi4JmTn3x5raynodDVE/9VQmBdWFyyj9HpHZ2B4xNZ7MMy7lkw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"csstype": "^3.0.2",
|
"csstype": "^3.0.2",
|
||||||
@@ -8954,77 +8960,77 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": {
|
"csstype": {
|
||||||
"version": "3.0.6",
|
"version": "3.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.7.tgz",
|
||||||
"integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw=="
|
"integrity": "sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g=="
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-camel-case": {
|
"jss-plugin-camel-case": {
|
||||||
"version": "10.5.1",
|
"version": "10.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.6.0.tgz",
|
||||||
"integrity": "sha512-9+oymA7wPtswm+zxVti1qiowC5q7bRdCJNORtns2JUj/QHp2QPXYwSNRD8+D2Cy3/CEMtdJzlNnt5aXmpS6NAg==",
|
"integrity": "sha512-JdLpA3aI/npwj3nDMKk308pvnhoSzkW3PXlbgHAzfx0yHWnPPVUjPhXFtLJzgKZge8lsfkUxvYSQ3X2OYIFU6A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"hyphenate-style-name": "^1.0.3",
|
"hyphenate-style-name": "^1.0.3",
|
||||||
"jss": "10.5.1"
|
"jss": "10.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-default-unit": {
|
"jss-plugin-default-unit": {
|
||||||
"version": "10.5.1",
|
"version": "10.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.6.0.tgz",
|
||||||
"integrity": "sha512-D48hJBc9Tj3PusvlillHW8Fz0y/QqA7MNmTYDQaSB/7mTrCZjt7AVRROExoOHEtd2qIYKOYJW3Jc2agnvsXRlQ==",
|
"integrity": "sha512-7y4cAScMHAxvslBK2JRK37ES9UT0YfTIXWgzUWD5euvR+JR3q+o8sQKzBw7GmkQRfZijrRJKNTiSt1PBsLI9/w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.5.1"
|
"jss": "10.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-global": {
|
"jss-plugin-global": {
|
||||||
"version": "10.5.1",
|
"version": "10.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.6.0.tgz",
|
||||||
"integrity": "sha512-jX4XpNgoaB8yPWw/gA1aPXJEoX0LNpvsROPvxlnYe+SE0JOhuvF7mA6dCkgpXBxfTWKJsno7cDSCgzHTocRjCQ==",
|
"integrity": "sha512-I3w7ji/UXPi3VuWrTCbHG9rVCgB4yoBQLehGDTmsnDfXQb3r1l3WIdcO8JFp9m0YMmyy2CU7UOV6oPI7/Tmu+w==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.5.1"
|
"jss": "10.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-nested": {
|
"jss-plugin-nested": {
|
||||||
"version": "10.5.1",
|
"version": "10.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.6.0.tgz",
|
||||||
"integrity": "sha512-xXkWKOCljuwHNjSYcXrCxBnjd8eJp90KVFW1rlhvKKRXnEKVD6vdKXYezk2a89uKAHckSvBvBoDGsfZrldWqqQ==",
|
"integrity": "sha512-fOFQWgd98H89E6aJSNkEh2fAXquC9aZcAVjSw4q4RoQ9gU++emg18encR4AT4OOIFl4lQwt5nEyBBRn9V1Rk8g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.5.1",
|
"jss": "10.6.0",
|
||||||
"tiny-warning": "^1.0.2"
|
"tiny-warning": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-props-sort": {
|
"jss-plugin-props-sort": {
|
||||||
"version": "10.5.1",
|
"version": "10.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.6.0.tgz",
|
||||||
"integrity": "sha512-t+2vcevNmMg4U/jAuxlfjKt46D/jHzCPEjsjLRj/J56CvP7Iy03scsUP58Iw8mVnaV36xAUZH2CmAmAdo8994g==",
|
"integrity": "sha512-oMCe7hgho2FllNc60d9VAfdtMrZPo9n1Iu6RNa+3p9n0Bkvnv/XX5San8fTPujrTBScPqv9mOE0nWVvIaohNuw==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.5.1"
|
"jss": "10.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-rule-value-function": {
|
"jss-plugin-rule-value-function": {
|
||||||
"version": "10.5.1",
|
"version": "10.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.6.0.tgz",
|
||||||
"integrity": "sha512-3gjrSxsy4ka/lGQsTDY8oYYtkt2esBvQiceGBB4PykXxHoGRz14tbCK31Zc6DHEnIeqsjMUGbq+wEly5UViStQ==",
|
"integrity": "sha512-TKFqhRTDHN1QrPTMYRlIQUOC2FFQb271+AbnetURKlGvRl/eWLswcgHQajwuxI464uZk91sPiTtdGi7r7XaWfA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"jss": "10.5.1",
|
"jss": "10.6.0",
|
||||||
"tiny-warning": "^1.0.2"
|
"tiny-warning": "^1.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jss-plugin-vendor-prefixer": {
|
"jss-plugin-vendor-prefixer": {
|
||||||
"version": "10.5.1",
|
"version": "10.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.6.0.tgz",
|
||||||
"integrity": "sha512-cLkH6RaPZWHa1TqSfd2vszNNgxT1W0omlSjAd6hCFHp3KIocSrW21gaHjlMU26JpTHwkc+tJTCQOmE/O1A4FKQ==",
|
"integrity": "sha512-doJ7MouBXT1lypLLctCwb4nJ6lDYqrTfVS3LtXgox42Xz0gXusXIIDboeh6UwnSmox90QpVnub7au8ybrb0krQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"@babel/runtime": "^7.3.1",
|
"@babel/runtime": "^7.3.1",
|
||||||
"css-vendor": "^2.0.8",
|
"css-vendor": "^2.0.8",
|
||||||
"jss": "10.5.1"
|
"jss": "10.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"jsx-ast-utils": {
|
"jsx-ast-utils": {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@datadog/browser-rum": "^2.6.2",
|
"@datadog/browser-rum": "^2.6.2",
|
||||||
"@material-ui/core": "^4.11.2",
|
"@material-ui/core": "^4.11.3",
|
||||||
"@material-ui/icons": "^4.11.2",
|
"@material-ui/icons": "^4.11.2",
|
||||||
"@testing-library/jest-dom": "^5.11.8",
|
"@testing-library/jest-dom": "^5.11.8",
|
||||||
"@testing-library/react": "^11.2.2",
|
"@testing-library/react": "^11.2.2",
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
<meta name="theme-color" content="#000000" />
|
<meta name="theme-color" content="#000000" />
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Web site created using create-react-app"
|
content="Fisker Admin Portal"
|
||||||
/>
|
/>
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
|
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" />
|
||||||
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
|
||||||
<title>File Upload App</title>
|
<title>Fisker Admin Portal</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"short_name": "OTA Admin Portal",
|
"short_name": "Admin Portal",
|
||||||
"name": "Fisker OTA Admin Portal",
|
"name": "Fisker Admin Portal",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "favicon.ico",
|
"src": "favicon.ico",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
jest.mock("../Contexts/UserContext");
|
|
||||||
jest.mock("../Contexts/FileUploadContext");
|
jest.mock("../Contexts/FileUploadContext");
|
||||||
jest.mock("../Contexts/VehicleContext");
|
jest.mock("../Contexts/VehicleContext");
|
||||||
|
jest.mock("../Contexts/UpdatesContext");
|
||||||
|
jest.mock("../Contexts/UserContext");
|
||||||
jest.mock("../../services/monitoring");
|
jest.mock("../../services/monitoring");
|
||||||
|
|
||||||
import { render, screen, cleanup, waitForElementToBeRemoved } from "@testing-library/react";
|
import { render, screen, cleanup, waitForElementToBeRemoved } from "@testing-library/react";
|
||||||
@@ -19,7 +20,27 @@ const renderRoute = async (route) => {
|
|||||||
return container;
|
return container;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const check = async (path, selector, compare) => {
|
||||||
|
const container = await renderRoute(path);
|
||||||
|
expect(container.querySelector(selector).innerHTML).toEqual(compare);
|
||||||
|
expect(container).toMatchSnapshot();
|
||||||
|
};
|
||||||
|
|
||||||
describe("App", () => {
|
describe("App", () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
// Stablize Table Pagination control ids
|
||||||
|
expect.addSnapshotSerializer({
|
||||||
|
test: function(val) {
|
||||||
|
return val && typeof val === "string" && val.indexOf("mui-") >= 0;
|
||||||
|
},
|
||||||
|
print: function(val) {
|
||||||
|
let str = val;
|
||||||
|
str = str.replace(/mui-[0-9]*/g, "mui-00000");
|
||||||
|
|
||||||
|
return `"${str}"`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
setToken(null);
|
setToken(null);
|
||||||
@@ -27,67 +48,101 @@ describe("App", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("Route / unauthenticated", async () => {
|
it("Route / unauthenticated", async () => {
|
||||||
const container = await renderRoute("/");
|
await check("/", "span.MuiButton-label", "Sign In");
|
||||||
expect(container.querySelector("span.MuiButton-label").innerHTML).toEqual("Sign In");
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /home unauthenticated", async () => {
|
it("Route /home unauthenticated", async () => {
|
||||||
const container = await renderRoute("/home");
|
await check("/home", "span.MuiButton-label", "Sign In");
|
||||||
expect(container.querySelector("span.MuiButton-label").innerHTML).toEqual("Sign In");
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /package-upload unauthenticated", async () => {
|
it("Route /package-upload unauthenticated", async () => {
|
||||||
const container = await renderRoute("/package-upload");
|
await check("/package-upload", "span.MuiButton-label", "Sign In");
|
||||||
expect(container.querySelector("span.MuiButton-label").innerHTML).toEqual("Sign In");
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /vehicle-add unauthenticated", async () => {
|
it("Route /vehicle-add unauthenticated", async () => {
|
||||||
const container = await renderRoute("/vehicle-add");
|
await check("/vehicle-add", "span.MuiButton-label", "Sign In");
|
||||||
expect(container.querySelector("span.MuiButton-label").innerHTML).toEqual("Sign In");
|
});
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
|
it("Route /updates unauthenticated", async () => {
|
||||||
|
await check("/updates", "span.MuiButton-label", "Sign In");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /update unauthenticated", async () => {
|
||||||
|
await check("/update/1", "span.MuiButton-label", "Sign In");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /carupdate-deploy unauthenticated", async () => {
|
||||||
|
await check("/carupdate-deploy/1", "span.MuiButton-label", "Sign In");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /carupdate-status unauthenticated", async () => {
|
||||||
|
await check("/carupdate-status/1", "span.MuiButton-label", "Sign In");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /vehicles unauthenticated", async () => {
|
||||||
|
await check("/vehicles", "span.MuiButton-label", "Sign In");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /vehicle-status unauthenticated", async () => {
|
||||||
|
await check("/vehicle-status/FISKER123", "span.MuiButton-label", "Sign In");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route / authenticated", async () => {
|
it("Route / authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT);
|
||||||
const container = await renderRoute("/");
|
await check("/", "h1", "Welcome John!");
|
||||||
expect(container.querySelector("h1").innerHTML).toEqual("Welcome John!");
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /home authenticated", async () => {
|
it("Route /home authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT);
|
||||||
const container = await renderRoute("/home");
|
await check("/home", "h1", "Welcome John!");
|
||||||
expect(container.querySelector("h1").innerHTML).toEqual("Welcome John!");
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /package-upload authenticated", async () => {
|
it("Route /package-upload authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT);
|
||||||
const container = await renderRoute("/package-upload");
|
await check("/package-upload", "h1", "Upload Update Package");
|
||||||
expect(container.querySelector("h1").innerHTML).toEqual("Upload Update Package");
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /vehicle-add authenticated", async () => {
|
it("Route /vehicle-add authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT);
|
||||||
const container = await renderRoute("/vehicle-add");
|
await check("/vehicle-add", "h1", "Add Vehicle");
|
||||||
expect(container.querySelector("h1").innerHTML).toEqual("Add Vehicle");
|
});
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
|
it("Route /updates authenticated", async () => {
|
||||||
|
setToken(TEST_AUTH_OBJECT);
|
||||||
|
await check("/updates", "h1", "Updates");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /update authenticated", async () => {
|
||||||
|
setToken(TEST_AUTH_OBJECT);
|
||||||
|
await check("/update/1", "h1", "Update Package 1");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /carupdate-deploy authenticated", async () => {
|
||||||
|
setToken(TEST_AUTH_OBJECT);
|
||||||
|
await check("/carupdate-deploy/1", "h1", "[1] ");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /carupdate-status authenticated", async () => {
|
||||||
|
setToken(TEST_AUTH_OBJECT);
|
||||||
|
await check("/carupdate-status/1", "h1", "");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /vehicles authenticated", async () => {
|
||||||
|
setToken(TEST_AUTH_OBJECT);
|
||||||
|
await check("/vehicles", "h1", "Vehicles");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Route /vehicle-status authenticated", async () => {
|
||||||
|
setToken(TEST_AUTH_OBJECT);
|
||||||
|
await check("/vehicle-status/FISKER123", "h1", "FISKER123 Updates");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /page-not-found unauthenticated", async () => {
|
it("Route /page-not-found unauthenticated", async () => {
|
||||||
const container = await renderRoute("/page-not-found");
|
await check("/page-not-found", "h1", "Page Not Found");
|
||||||
expect(container.querySelector("h1").innerHTML).toEqual("Page Not Found");
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Route /page-not-found authenticated", async () => {
|
it("Route /page-not-found authenticated", async () => {
|
||||||
setToken(TEST_AUTH_OBJECT);
|
setToken(TEST_AUTH_OBJECT);
|
||||||
const container = await renderRoute("/page-not-found");
|
await check("/page-not-found", "h1", "Page Not Found");
|
||||||
expect(container.querySelector("h1").innerHTML).toEqual("Page Not Found");
|
|
||||||
expect(container).toMatchSnapshot();
|
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -49,7 +49,7 @@ export default function CarStatusModal(props) {
|
|||||||
aria-labelledby="transition-modal-title"
|
aria-labelledby="transition-modal-title"
|
||||||
aria-describedby="transition-modal-description"
|
aria-describedby="transition-modal-description"
|
||||||
className={classes.modal}
|
className={classes.modal}
|
||||||
open={props.vin}
|
open={props.vin !== null && props.vin !== undefined}
|
||||||
onClose={props.handleClose}
|
onClose={props.handleClose}
|
||||||
BackdropComponent={Backdrop}
|
BackdropComponent={Backdrop}
|
||||||
BackdropProps={{
|
BackdropProps={{
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import {
|
|||||||
fireEvent,
|
fireEvent,
|
||||||
waitFor,
|
waitFor,
|
||||||
} from "@testing-library/react";
|
} from "@testing-library/react";
|
||||||
import { UpdatesProvider, useUpdatesContext } from "../Contexts/UpdatesContext";
|
import { UpdatesProvider, useUpdatesContext } from "./UpdatesContext";
|
||||||
import { StatusProvider, useStatusContext } from "../Contexts/StatusContext";
|
import { StatusProvider, useStatusContext } from "./StatusContext";
|
||||||
import { TEST_AUTH_OBJECT } from "../../utils/testing";
|
import { TEST_AUTH_OBJECT } from "../../utils/testing";
|
||||||
|
|
||||||
describe("UpdatesContext", () => {
|
describe("UpdatesContext", () => {
|
||||||
26
src/components/Contexts/__mocks__/UpdatesContext.jsx
Normal file
26
src/components/Contexts/__mocks__/UpdatesContext.jsx
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const UpdatesContext = React.createContext();
|
||||||
|
|
||||||
|
let busy = false;
|
||||||
|
let packages = [];
|
||||||
|
let totalPackages = 0;
|
||||||
|
let carUpdates = [];
|
||||||
|
let totalCarUpdates = 0;
|
||||||
|
|
||||||
|
export const UpdatesProvider = ({ children }) => {
|
||||||
|
return <div data-testid="mocked-updatesprovider">{children}</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useUpdatesContext = () => ({
|
||||||
|
busy,
|
||||||
|
packages,
|
||||||
|
totalPackages,
|
||||||
|
carUpdates,
|
||||||
|
totalCarUpdates,
|
||||||
|
getPackages: jest.fn(() => packages),
|
||||||
|
updatePackage: jest.fn((data) => data),
|
||||||
|
createCarUpdates: jest.fn((data) => data),
|
||||||
|
getCarUpdates: jest.fn(() => carUpdates),
|
||||||
|
getVINUpdates: jest.fn(() => carUpdates),
|
||||||
|
});
|
||||||
@@ -2,6 +2,7 @@ import React from "react";
|
|||||||
|
|
||||||
let busy = false;
|
let busy = false;
|
||||||
let vehicles = [];
|
let vehicles = [];
|
||||||
|
let totalVehicles = 0;
|
||||||
let error = null;
|
let error = null;
|
||||||
|
|
||||||
export const VehicleProvider = ({ children }) => {
|
export const VehicleProvider = ({ children }) => {
|
||||||
@@ -11,6 +12,7 @@ export const VehicleProvider = ({ children }) => {
|
|||||||
export const useVehicleContext = () => ({
|
export const useVehicleContext = () => ({
|
||||||
busy,
|
busy,
|
||||||
vehicles,
|
vehicles,
|
||||||
|
totalVehicles,
|
||||||
getVehicles: jest.fn(() => vehicles),
|
getVehicles: jest.fn(() => vehicles),
|
||||||
addVehicle: jest.fn(),
|
addVehicle: jest.fn(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,25 +2,60 @@ import React, { Component } from "react";
|
|||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
import { Typography } from "@material-ui/core";
|
import { Typography } from "@material-ui/core";
|
||||||
|
|
||||||
|
const reload = () => {
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
export default class ErrorBoundary extends Component {
|
export default class ErrorBoundary extends Component {
|
||||||
state = {
|
state = {
|
||||||
error: "",
|
error: "",
|
||||||
errorInfo: "",
|
errorInfo: "",
|
||||||
hasError: false,
|
hasError: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static getDerivedStateFromError(error) {
|
static getDerivedStateFromError(error) {
|
||||||
return { hasError: true, error };
|
return { hasError: true, error };
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidCatch(error, errorInfo) {
|
componentDidCatch(error, errorInfo) {
|
||||||
this.setState({ errorInfo });
|
this.setState({ errorInfo });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
if (this.state.hasError)
|
if (this.state.hasError) {
|
||||||
|
if (this.state.error && this.state.error.name === "ChunkLoadError") {
|
||||||
|
reload();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Typography variant="h3" align="center">
|
<div
|
||||||
Client-side Error Occured and Logged
|
style={{
|
||||||
</Typography>
|
position: "absolute",
|
||||||
|
top: "50%",
|
||||||
|
left: "50%",
|
||||||
|
transform: "translate(-50%, -50%)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Typography variant="h3" align="center">
|
||||||
|
Sorry, an error has occured and been logged
|
||||||
|
</Typography>
|
||||||
|
<Typography
|
||||||
|
variant="h5"
|
||||||
|
align="center"
|
||||||
|
style={{
|
||||||
|
cursor: "pointer",
|
||||||
|
textDecorationColor: "Blue",
|
||||||
|
textDecorationStyle: "solid",
|
||||||
|
textDecorationLine: "underline",
|
||||||
|
color: "Blue",
|
||||||
|
}}
|
||||||
|
onClick={reload}
|
||||||
|
>
|
||||||
|
Click to reload
|
||||||
|
</Typography>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
return this.props.children;
|
return this.props.children;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user