CEC-4576: update permission for updateDeploy action (#370)
* CEC-4576: use new UpdateDeploy permission * update manifest deploy permission
This commit is contained in:
@@ -6651,24 +6651,6 @@ exports[`App Route /packages authenticated 1`] = `
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
<a
|
||||
class=""
|
||||
href="/package-deploy/1"
|
||||
style="margin: 5px;"
|
||||
title="Deploy \\"Test Manifest 1.0\\""
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
aria-label="Deploy Test Manifest 1.0"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
@@ -11561,63 +11543,7 @@ exports[`App Route /vehicle-status authenticated 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
<label
|
||||
class="MuiFormControlLabel-root"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-0 MuiCheckbox-root MuiCheckbox-colorSecondary MuiIconButton-colorSecondary"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-0"
|
||||
data-indeterminate="false"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root MuiFormControlLabel-label MuiTypography-body1"
|
||||
>
|
||||
Force Config Update
|
||||
</span>
|
||||
</label>
|
||||
<a
|
||||
class=""
|
||||
href="/vehicle-status/FISKER123"
|
||||
title="Push Config Update to \\"FISKER123\\""
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
aria-label="Push Config Update to \\"FISKER123\\""
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-tzssek-MuiSvgIcon-root"
|
||||
data-testid="UploadIcon"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M5 20h14v-2H5v2zm0-10h4v6h6v-6h4l-7-7-7 7z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
/>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
|
||||
@@ -160,63 +160,7 @@ exports[`VehicleDetailsTab Render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
<label
|
||||
class="MuiFormControlLabel-root"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-0 MuiCheckbox-root MuiCheckbox-colorSecondary MuiIconButton-colorSecondary"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-0"
|
||||
data-indeterminate="false"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root MuiFormControlLabel-label MuiTypography-body1"
|
||||
>
|
||||
Force Config Update
|
||||
</span>
|
||||
</label>
|
||||
<a
|
||||
class=""
|
||||
href="/"
|
||||
title="Push Config Update to \\"TESTVIN1234567890\\""
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
aria-label="Push Config Update to \\"TESTVIN1234567890\\""
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-tzssek-MuiSvgIcon-root"
|
||||
data-testid="UploadIcon"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M5 20h14v-2H5v2zm0-10h4v6h6v-6h4l-7-7-7 7z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
/>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
|
||||
@@ -115,38 +115,38 @@ const MainForm = ({ vin }) => {
|
||||
<b>Info Source</b>: {vehicle.info_source}
|
||||
</p>
|
||||
<p>
|
||||
<b>Tags</b>: {vehicle.tags ? vehicle.tags.join(", ") : "none" }
|
||||
<b>Tags</b>: {vehicle.tags ? vehicle.tags.join(", ") : "none"}
|
||||
</p>
|
||||
</Grid>
|
||||
<Grid item md={12} className={classes.textCenterAlign}>
|
||||
{vehicle.log_level != null && (
|
||||
{vehicle.log_level != null && (
|
||||
<p>
|
||||
<b>Log Level</b>: {vehicle.log_level}
|
||||
</p>
|
||||
)}
|
||||
{vehicle.canbus && (
|
||||
<>
|
||||
<p>
|
||||
<b>CANBus Enabled</b>: {vehicle.canbus.enabled.toString()}
|
||||
</p>
|
||||
<p>
|
||||
<b>Max Memory Buffer Size</b>: {vehicle.canbus.max_mem_buffer_size ?? "Default"}
|
||||
</p>
|
||||
<p>
|
||||
<b>Data Logger Enabled</b>: {vehicle.canbus.data_logger_enabled.toString()}
|
||||
</p>
|
||||
<p>
|
||||
<b>Max Disk Buffer Size</b>: {vehicle.canbus.max_disk_buffer_size ?? "Default"}
|
||||
</p>
|
||||
<p>
|
||||
<b>Filters</b>: {vehicle.canbus.filters ? vehicle.canbus.filters.length : 0}
|
||||
</p>
|
||||
<p>
|
||||
<b>DTC Enabled</b>: { (vehicle.canbus.dtc_enabled || false).toString() }
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
{vehicle.canbus && (
|
||||
<>
|
||||
<p>
|
||||
<b>CANBus Enabled</b>: {vehicle.canbus.enabled.toString()}
|
||||
</p>
|
||||
<p>
|
||||
<b>Max Memory Buffer Size</b>: {vehicle.canbus.max_mem_buffer_size ?? "Default"}
|
||||
</p>
|
||||
<p>
|
||||
<b>Data Logger Enabled</b>: {vehicle.canbus.data_logger_enabled.toString()}
|
||||
</p>
|
||||
<p>
|
||||
<b>Max Disk Buffer Size</b>: {vehicle.canbus.max_disk_buffer_size ?? "Default"}
|
||||
</p>
|
||||
<p>
|
||||
<b>Filters</b>: {vehicle.canbus.filters ? vehicle.canbus.filters.length : 0}
|
||||
</p>
|
||||
<p>
|
||||
<b>DTC Enabled</b>: {(vehicle.canbus.dtc_enabled || false).toString()}
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
{showDebugMask && (
|
||||
<Grid item md={12} className={classes.textCenterAlign}>
|
||||
<p>
|
||||
@@ -156,19 +156,19 @@ const MainForm = ({ vin }) => {
|
||||
)}
|
||||
<Grid item md={12} className={classes.textCenterAlign}>
|
||||
<RoleWrap
|
||||
groups={groups}
|
||||
providers={providers}
|
||||
rolesPerProvider={Permissions.FiskerCreate}
|
||||
>
|
||||
groups={groups}
|
||||
providers={providers}
|
||||
rolesPerProvider={Permissions.FiskerUpdateDeploy}
|
||||
>
|
||||
<FormControlLabel
|
||||
label="Force Config Update"
|
||||
control={
|
||||
<Checkbox
|
||||
checked={forced}
|
||||
onChange={onForcedChange}
|
||||
/>
|
||||
}
|
||||
label="Force Config Update"
|
||||
control={
|
||||
<Checkbox
|
||||
checked={forced}
|
||||
onChange={onForcedChange}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<Tooltip key={`push-config-${vin}`} title={`Push Config Update to "${vin}"`}>
|
||||
<Link to="#" onClick={() => setShowUploadConfigModal(true)} >
|
||||
<UploadIcon aria-label={`Push Config Update to "${vin}"`} fontSize="large" />
|
||||
|
||||
@@ -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(
|
||||
<VehicleProvider>
|
||||
<StatusProvider>
|
||||
<UserProvider>
|
||||
<UserProvider >
|
||||
<BrowserRouter>
|
||||
<MainForm vin="TESTVIN1234567890"/>
|
||||
<MainForm vin="TESTVIN1234567890" />
|
||||
</BrowserRouter>
|
||||
</UserProvider>
|
||||
</StatusProvider>
|
||||
@@ -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(
|
||||
<VehicleProvider>
|
||||
<StatusProvider>
|
||||
<UserProvider>
|
||||
<BrowserRouter>
|
||||
<MainForm vin="TESTVIN1234567890" />
|
||||
</BrowserRouter>
|
||||
</UserProvider>
|
||||
</StatusProvider>
|
||||
</VehicleProvider>
|
||||
);
|
||||
|
||||
expect(screen.getByLabelText("Force Config Update")).toBeTruthy();
|
||||
hasRole.mockRestore();
|
||||
})
|
||||
});
|
||||
|
||||
@@ -168,63 +168,7 @@ exports[`DetailsTab Render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
<label
|
||||
class="MuiFormControlLabel-root"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-0 MuiCheckbox-root MuiCheckbox-colorSecondary MuiIconButton-colorSecondary"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-0"
|
||||
data-indeterminate="false"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root MuiFormControlLabel-label MuiTypography-body1"
|
||||
>
|
||||
Force Config Update
|
||||
</span>
|
||||
</label>
|
||||
<a
|
||||
class=""
|
||||
href="/testroute/TESTVIN1234567890"
|
||||
title="Push Config Update to \\"TESTVIN1234567890\\""
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
aria-label="Push Config Update to \\"TESTVIN1234567890\\""
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-tzssek-MuiSvgIcon-root"
|
||||
data-testid="UploadIcon"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M5 20h14v-2H5v2zm0-10h4v6h6v-6h4l-7-7-7 7z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
/>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
|
||||
@@ -349,63 +349,7 @@ exports[`CarStatus Render 1`] = `
|
||||
</div>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
<label
|
||||
class="MuiFormControlLabel-root"
|
||||
>
|
||||
<span
|
||||
aria-disabled="false"
|
||||
class="MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-0 MuiCheckbox-root MuiCheckbox-colorSecondary MuiIconButton-colorSecondary"
|
||||
>
|
||||
<span
|
||||
class="MuiIconButton-label"
|
||||
>
|
||||
<input
|
||||
class="PrivateSwitchBase-input-0"
|
||||
data-indeterminate="false"
|
||||
type="checkbox"
|
||||
value=""
|
||||
/>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="MuiSvgIcon-root"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTouchRipple-root"
|
||||
/>
|
||||
</span>
|
||||
<span
|
||||
class="MuiTypography-root MuiFormControlLabel-label MuiTypography-body1"
|
||||
>
|
||||
Force Config Update
|
||||
</span>
|
||||
</label>
|
||||
<a
|
||||
class=""
|
||||
href="/"
|
||||
title="Push Config Update to \\"TESTVIN1234567890\\""
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
aria-label="Push Config Update to \\"TESTVIN1234567890\\""
|
||||
class="MuiSvgIcon-root MuiSvgIcon-fontSizeLarge css-tzssek-MuiSvgIcon-root"
|
||||
data-testid="UploadIcon"
|
||||
focusable="false"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
d="M5 20h14v-2H5v2zm0-10h4v6h6v-6h4l-7-7-7 7z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
/>
|
||||
<div
|
||||
class="MuiGrid-root makeStyles-textCenterAlign-0 MuiGrid-item MuiGrid-grid-md-12"
|
||||
>
|
||||
|
||||
@@ -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 : <></>;
|
||||
|
||||
@@ -231,7 +231,7 @@ const MainForm = () => {
|
||||
icon: <EditIcon aria-label={`Update ${row.name} ${row.version}`} />,
|
||||
});
|
||||
}
|
||||
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}`,
|
||||
|
||||
Reference in New Issue
Block a user