diff --git a/.env.cec-euprd b/.env.cec-euprd
index 74cb850..ae12566 100644
--- a/.env.cec-euprd
+++ b/.env.cec-euprd
@@ -15,6 +15,7 @@ REACT_APP_ROLE_GENERATE_CERTIFICATE=9af2d8c0-c26d-4d6d-bbd1-ac53cbd37ebc
REACT_APP_ROLE_MANUFACTURE=3412e11a-a2d1-4355-be3e-ef9aa5065b69
REACT_APP_ROLE_SUPPLIER_APPROVER=a6c9805e-80b2-42b2-bfbb-9df52e5504d8
REACT_APP_ROLE_MANIFEST_MIGRATION=42798c8a-9fa7-4fb4-82c0-9582cabe364f
+REACT_APP_ROLE_UPDATE_DEPLOY=e4af2c4c-6c5e-4784-9097-7c18e776d7b6
REACT_APP_ECCKEY_ENV=
REACT_APP_HOME_MAP_DEFAULT_LOCATION={"lat":49.8327,"lng":9.8816,"zoom":4.5}
REACT_APP_ENABLE_DEBUGMASK=1
\ No newline at end of file
diff --git a/.env.cec-prd b/.env.cec-prd
index 074549f..2f6cb8b 100644
--- a/.env.cec-prd
+++ b/.env.cec-prd
@@ -15,6 +15,7 @@ REACT_APP_ROLE_GENERATE_CERTIFICATE=9af2d8c0-c26d-4d6d-bbd1-ac53cbd37ebc
REACT_APP_ROLE_MANUFACTURE=3412e11a-a2d1-4355-be3e-ef9aa5065b69
REACT_APP_ROLE_SUPPLIER_APPROVER=a6c9805e-80b2-42b2-bfbb-9df52e5504d8
REACT_APP_ROLE_MANIFEST_MIGRATION=42798c8a-9fa7-4fb4-82c0-9582cabe364f
+REACT_APP_ROLE_UPDATE_DEPLOY=e4af2c4c-6c5e-4784-9097-7c18e776d7b6
REACT_APP_ECCKEY_ENV=
REACT_APP_HOME_MAP_DEFAULT_LOCATION={"lat":37.0902,"lng":-95.7129,"zoom":4.5}
REACT_APP_ENABLE_DEBUGMASK=1
\ No newline at end of file
diff --git a/.env.dev b/.env.dev
index 7fdf5cb..4c0d651 100644
--- a/.env.dev
+++ b/.env.dev
@@ -15,6 +15,7 @@ REACT_APP_ROLE_GENERATE_CERTIFICATE=746f34b0-9ba0-4b5d-8d84-0256a9c8e390
REACT_APP_ROLE_MANUFACTURE=3412e11a-a2d1-4355-be3e-ef9aa5065b69
REACT_APP_ROLE_SUPPLIER_APPROVER=a6c9805e-80b2-42b2-bfbb-9df52e5504d8
REACT_APP_ROLE_MANIFEST_MIGRATION=42798c8a-9fa7-4fb4-82c0-9582cabe364f
+REACT_APP_ROLE_UPDATE_DEPLOY=3590ec3f-1c05-428b-81a4-40b00baf83de
REACT_APP_ECCKEY_ENV=stage,prod
REACT_APP_HOME_MAP_DEFAULT_LOCATION={"lat":37.0902,"lng":-95.7129,"zoom":4.5}
REACT_APP_ENABLE_DEBUGMASK=1
\ No newline at end of file
diff --git a/.env.local b/.env.local
index 2311225..74b818d 100644
--- a/.env.local
+++ b/.env.local
@@ -15,6 +15,7 @@ REACT_APP_ROLE_GENERATE_CERTIFICATE=746f34b0-9ba0-4b5d-8d84-0256a9c8e390
REACT_APP_ROLE_MANUFACTURE=3412e11a-a2d1-4355-be3e-ef9aa5065b69
REACT_APP_ROLE_SUPPLIER_APPROVER=a6c9805e-80b2-42b2-bfbb-9df52e5504d8
REACT_APP_ROLE_MANIFEST_MIGRATION=42798c8a-9fa7-4fb4-82c0-9582cabe364f
+REACT_APP_ROLE_UPDATE_DEPLOY=3590ec3f-1c05-428b-81a4-40b00baf83de
REACT_APP_ECCKEY_ENV=dev,stage,prod
REACT_APP_HOME_MAP_DEFAULT_LOCATION={"lat":37.0902,"lng":-95.7129,"zoom":4.5}
REACT_APP_ENABLE_DEBUGMASK=1
\ No newline at end of file
diff --git a/.env.prd b/.env.prd
index 878fe6b..634e327 100644
--- a/.env.prd
+++ b/.env.prd
@@ -15,6 +15,7 @@ REACT_APP_ROLE_GENERATE_CERTIFICATE=746f34b0-9ba0-4b5d-8d84-0256a9c8e390
REACT_APP_ROLE_MANUFACTURE=3412e11a-a2d1-4355-be3e-ef9aa5065b69
REACT_APP_ROLE_SUPPLIER_APPROVER=a6c9805e-80b2-42b2-bfbb-9df52e5504d8
REACT_APP_ROLE_MANIFEST_MIGRATION=42798c8a-9fa7-4fb4-82c0-9582cabe364f
+REACT_APP_ROLE_UPDATE_DEPLOY=e4af2c4c-6c5e-4784-9097-7c18e776d7b6
REACT_APP_ECCKEY_ENV=stage
REACT_APP_HOME_MAP_DEFAULT_LOCATION={"lat":37.0902,"lng":-95.7129,"zoom":4.5}
REACT_APP_ENABLE_DEBUGMASK=1
\ No newline at end of file
diff --git a/.env.stg b/.env.stg
index df9db72..10457a5 100644
--- a/.env.stg
+++ b/.env.stg
@@ -15,6 +15,7 @@ REACT_APP_ROLE_GENERATE_CERTIFICATE=746f34b0-9ba0-4b5d-8d84-0256a9c8e390
REACT_APP_ROLE_MANUFACTURE=3412e11a-a2d1-4355-be3e-ef9aa5065b69
REACT_APP_ROLE_SUPPLIER_APPROVER=a6c9805e-80b2-42b2-bfbb-9df52e5504d8
REACT_APP_ROLE_MANIFEST_MIGRATION=42798c8a-9fa7-4fb4-82c0-9582cabe364f
+REACT_APP_ROLE_UPDATE_DEPLOY=3590ec3f-1c05-428b-81a4-40b00baf83de
REACT_APP_ECCKEY_ENV=prod
REACT_APP_HOME_MAP_DEFAULT_LOCATION={"lat":37.0902,"lng":-95.7129,"zoom":4.5}
REACT_APP_ENABLE_DEBUGMASK=1
\ No newline at end of file
diff --git a/.env.template b/.env.template
index 517bef2..291a90c 100644
--- a/.env.template
+++ b/.env.template
@@ -15,5 +15,6 @@ REACT_APP_ROLE_GENERATE_CERTIFICATE=746f34b0-9ba0-4b5d-8d84-0256a9c8e390
REACT_APP_ROLE_MANUFACTURE=3412e11a-a2d1-4355-be3e-ef9aa5065b69
REACT_APP_ROLE_SUPPLIER_APPROVER=a6c9805e-80b2-42b2-bfbb-9df52e5504d8
REACT_APP_ROLE_MANIFEST_MIGRATION=42798c8a-9fa7-4fb4-82c0-9582cabe364f
+REACT_APP_ROLE_UPDATE_DEPLOY=3590ec3f-1c05-428b-81a4-40b00baf83de
REACT_APP_ECCKEY_ENV=dev,stage,prod
REACT_APP_HOME_MAP_DEFAULT_LOCATION={"lat":37.0902,"lng":-95.7129,"zoom":4.5}
diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap
index d9392bd..f3480ec 100644
--- a/src/components/App/__snapshots__/App.test.js.snap
+++ b/src/components/App/__snapshots__/App.test.js.snap
@@ -6651,24 +6651,6 @@ exports[`App Route /packages authenticated 1`] = `
/>
-
-
-
@@ -11561,63 +11543,7 @@ exports[`App Route /vehicle-status authenticated 1`] = `
-
-
-
-
-
+ />
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 7cadd4e..24991b8 100644
--- a/src/components/Cars/Status/Details/__snapshots__/index.test.jsx.snap
+++ b/src/components/Cars/Status/Details/__snapshots__/index.test.jsx.snap
@@ -160,63 +160,7 @@ exports[`VehicleDetailsTab Render 1`] = `
-
-
-
-
-
+ />
diff --git a/src/components/Cars/Status/Details/index.jsx b/src/components/Cars/Status/Details/index.jsx
index cb8a973..2b7bf04 100644
--- a/src/components/Cars/Status/Details/index.jsx
+++ b/src/components/Cars/Status/Details/index.jsx
@@ -115,38 +115,38 @@ const MainForm = ({ vin }) => {
Info Source: {vehicle.info_source}
- Tags: {vehicle.tags ? vehicle.tags.join(", ") : "none" }
+ Tags: {vehicle.tags ? vehicle.tags.join(", ") : "none"}
- {vehicle.log_level != null && (
+ {vehicle.log_level != null && (
Log Level: {vehicle.log_level}
)}
- {vehicle.canbus && (
- <>
-
- CANBus Enabled: {vehicle.canbus.enabled.toString()}
-
-
- Max Memory Buffer Size: {vehicle.canbus.max_mem_buffer_size ?? "Default"}
-
-
- Data Logger Enabled: {vehicle.canbus.data_logger_enabled.toString()}
-
-
- Max Disk Buffer Size: {vehicle.canbus.max_disk_buffer_size ?? "Default"}
-
-
- Filters: {vehicle.canbus.filters ? vehicle.canbus.filters.length : 0}
-
-
- DTC Enabled: { (vehicle.canbus.dtc_enabled || false).toString() }
-
- >
- )}
-
+ {vehicle.canbus && (
+ <>
+
+ CANBus Enabled: {vehicle.canbus.enabled.toString()}
+
+
+ Max Memory Buffer Size: {vehicle.canbus.max_mem_buffer_size ?? "Default"}
+
+
+ Data Logger Enabled: {vehicle.canbus.data_logger_enabled.toString()}
+
+
+ Max Disk Buffer Size: {vehicle.canbus.max_disk_buffer_size ?? "Default"}
+
+
+ Filters: {vehicle.canbus.filters ? vehicle.canbus.filters.length : 0}
+
+
+ DTC Enabled: {(vehicle.canbus.dtc_enabled || false).toString()}
+
+ >
+ )}
+
{showDebugMask && (
@@ -156,19 +156,19 @@ const MainForm = ({ vin }) => {
)}
+ groups={groups}
+ providers={providers}
+ rolesPerProvider={Permissions.FiskerUpdateDeploy}
+ >
- }
+ label="Force Config Update"
+ control={
+
+ }
+ />
setShowUploadConfigModal(true)} >
diff --git a/src/components/Cars/Status/Details/index.test.jsx b/src/components/Cars/Status/Details/index.test.jsx
index b571949..94f6310 100644
--- a/src/components/Cars/Status/Details/index.test.jsx
+++ b/src/components/Cars/Status/Details/index.test.jsx
@@ -2,24 +2,25 @@ jest.mock("../../../Contexts/VehicleContext");
jest.mock("../../../Contexts/StatusContext");
jest.mock("../../../Contexts/UserContext");
-import { render, waitFor } from "@testing-library/react";
+import { render, screen, waitFor } from "@testing-library/react";
import { BrowserRouter } from "react-router-dom";
import routeData from "react-router";
import { VehicleProvider } from "../../../Contexts/VehicleContext";
import { StatusProvider } from "../../../Contexts/StatusContext";
import { UserProvider, setToken } from "../../../Contexts/UserContext";
-import { TEST_AUTH_OBJECT_FISKER }from "../../../../utils/testing";
+import { TEST_AUTH_OBJECT_FISKER } from "../../../../utils/testing";
import MainForm from "./index";
import addSnapshotSerializer from "../../../../utils/snapshot";
+import * as Roles from "../../../../utils/roles";
const renderVehicleDetailsTab = async () => {
const { container } = render(
-
+
-
+
@@ -46,4 +47,23 @@ describe("VehicleDetailsTab", () => {
const container = await renderVehicleDetailsTab();
expect(container).toMatchSnapshot();
});
+
+ it("renders update config control when required permission is present.", () => {
+ const hasRole = jest.spyOn(Roles, 'hasRole');
+ hasRole.mockReturnValue(true);
+ render(
+
+
+
+
+
+
+
+
+
+ );
+
+ expect(screen.getByLabelText("Force Config Update")).toBeTruthy();
+ hasRole.mockRestore();
+ })
});
diff --git a/src/components/Cars/Status/__snapshots__/DetailsTab.test.jsx.snap b/src/components/Cars/Status/__snapshots__/DetailsTab.test.jsx.snap
index fedbdd8..92ea782 100644
--- a/src/components/Cars/Status/__snapshots__/DetailsTab.test.jsx.snap
+++ b/src/components/Cars/Status/__snapshots__/DetailsTab.test.jsx.snap
@@ -168,63 +168,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 c65dfed..cae321f 100644
--- a/src/components/Cars/Status/__snapshots__/index.test.jsx.snap
+++ b/src/components/Cars/Status/__snapshots__/index.test.jsx.snap
@@ -349,63 +349,7 @@ exports[`CarStatus Render 1`] = `
-
-
-
-
-
+ />
diff --git a/src/components/Controls/RoleWrap/index.js b/src/components/Controls/RoleWrap/index.js
index 024875c..5fcd7bd 100644
--- a/src/components/Controls/RoleWrap/index.js
+++ b/src/components/Controls/RoleWrap/index.js
@@ -2,9 +2,9 @@ import React from "react";
import { hasRole } from "../../../utils/roles";
export const RoleWrap = (props) => {
- const {groups, rolesPerProvider, providers} = props;
+ const { groups, rolesPerProvider, providers } = props;
- const eitherComponent = props["eitherComponent"] || null;
+ const eitherComponent = props["eitherComponent"] || null;
if (!hasRole(groups, rolesPerProvider, providers)) {
return eitherComponent != null ? eitherComponent : <>>;
diff --git a/src/components/Manifest/List/index.jsx b/src/components/Manifest/List/index.jsx
index a115576..635ba1a 100644
--- a/src/components/Manifest/List/index.jsx
+++ b/src/components/Manifest/List/index.jsx
@@ -231,7 +231,7 @@ const MainForm = () => {
icon: ,
});
}
- if (hasRole(groups, Permissions.FiskerMagnaCreate, providers)) {
+ if (hasRole(groups, Permissions.FiskerUpdateDeploy, providers)) {
actions.push({
tip: `Deploy "${row.name} ${row.version}"`,
link: `/package-deploy/${row.id}`,
diff --git a/src/utils/roles.js b/src/utils/roles.js
index 69f1d18..e428a59 100644
--- a/src/utils/roles.js
+++ b/src/utils/roles.js
@@ -6,6 +6,7 @@ export const Roles = {
DELETE: process.env.REACT_APP_ROLE_DELETE,
CERTIFICATES: process.env.REACT_APP_ROLE_GENERATE_CERTIFICATE,
APPROVESUPPLIERS: process.env.REACT_APP_ROLE_SUPPLIER_APPROVER,
+ UPDATEDEPLOY: process.env.REACT_APP_ROLE_UPDATE_DEPLOY,
MANUFACTURE: process.env.REACT_APP_ROLE_MANUFACTURE,
MAGNAGROUP: process.env.REACT_APP_MAGNA_GROUP_ID,
MANIFEST_MIGRATION: process.env.REACT_APP_ROLE_MANIFEST_MIGRATION
@@ -81,6 +82,9 @@ export const Permissions = {
[Providers.FISKER_QA]: [Roles.MANUFACTURE],
[Providers.MAGNA]: [Roles.MAGNAGROUP],
},
+ FiskerUpdateDeploy: {
+ [Providers.FISKER]: [Roles.UPDATEDEPLOY],
+ },
Magna: {
[Providers.FISKER_QA]: [Roles.MANUFACTURE],
[Providers.MAGNA]: [Roles.MAGNAGROUP],
diff --git a/src/utils/roles.test.js b/src/utils/roles.test.js
index c4198ac..9b40e97 100644
--- a/src/utils/roles.test.js
+++ b/src/utils/roles.test.js
@@ -68,6 +68,15 @@ describe("Roles Helper", () => {
).toEqual(true);
});
+ it("Check FiskerUpdateDeploy permission", () => {
+ expect(
+ hasRole([Roles.UPDATEDEPLOY], Permissions.FiskerUpdateDeploy, [Providers.FISKER])
+ ).toEqual(true);
+ expect(
+ hasRole([Roles.UPDATEDEPLOY], Permissions.FiskerUpdateDeploy, [Providers.MAGNA])
+ ).toEqual(false);
+ });
+
it("Check Magna permission", () => {
expect(
hasRole([Roles.MAGNAGROUP], Permissions.Magna, [Providers.MAGNA])