diff --git a/src/components/App/__snapshots__/App.test.js.snap b/src/components/App/__snapshots__/App.test.js.snap
index 985b9b9..8b94ada 100644
--- a/src/components/App/__snapshots__/App.test.js.snap
+++ b/src/components/App/__snapshots__/App.test.js.snap
@@ -5348,45 +5348,7 @@ exports[`App Route /package-status authenticated 1`] = `
+ />
{
const { setMessage } = useStatusContext();
const { token: { idToken: { jwtToken: token } } } = useUserContext();
@@ -16,7 +16,7 @@ export default forwardRef(({
useImperativeHandle(ref, () => ({
async submit() {
return vehiclesAPI
- .addTags(vins, tags, token)
+ .addTags(ids, tags, token)
.then((data) => {
if (data.error) {
setMessage(`${data.error}: ${data.message}`);
@@ -32,7 +32,7 @@ export default forwardRef(({
return (
- You are adding tags to the following VINs: {vinCSV}.
+ You are adding tags to the following VINs: {idCSV}.
{
diff --git a/src/components/BulkActions/actions/AddToFleet.test.jsx b/src/components/BulkActions/actions/AddToFleet.test.jsx
index 2b9d2b9..3110d92 100644
--- a/src/components/BulkActions/actions/AddToFleet.test.jsx
+++ b/src/components/BulkActions/actions/AddToFleet.test.jsx
@@ -40,8 +40,8 @@ describe("BulkActions/AddToFleet", () => {
diff --git a/src/components/Manifest/Toolbar/actions/Cancel.jsx b/src/components/BulkActions/actions/Cancel.jsx
similarity index 85%
rename from src/components/Manifest/Toolbar/actions/Cancel.jsx
rename to src/components/BulkActions/actions/Cancel.jsx
index 2a815dc..db144e4 100644
--- a/src/components/Manifest/Toolbar/actions/Cancel.jsx
+++ b/src/components/BulkActions/actions/Cancel.jsx
@@ -1,8 +1,8 @@
import { forwardRef, useImperativeHandle } from "react";
-import { useStatusContext } from "../../../Contexts/StatusContext";
-import { useUserContext } from "../../../Contexts/UserContext";
-import TaskRunner from "../../../../utils/taskRunner";
-import updatesAPI from "../../../../services/updatesAPI";
+import { useStatusContext } from "../../Contexts/StatusContext";
+import { useUserContext } from "../../Contexts/UserContext";
+import TaskRunner from "../../../utils/taskRunner";
+import updatesAPI from "../../../services/updatesAPI";
export default forwardRef(({
ids,
diff --git a/src/components/Manifest/Toolbar/actions/Cancel.test.jsx b/src/components/BulkActions/actions/Cancel.test.jsx
similarity index 63%
rename from src/components/Manifest/Toolbar/actions/Cancel.test.jsx
rename to src/components/BulkActions/actions/Cancel.test.jsx
index 1fa05b3..819ea49 100644
--- a/src/components/Manifest/Toolbar/actions/Cancel.test.jsx
+++ b/src/components/BulkActions/actions/Cancel.test.jsx
@@ -1,17 +1,17 @@
-jest.mock("../../../Contexts/UserContext");
-jest.mock("../../../Contexts/StatusContext");
-jest.mock("../../../../services/updatesAPI");
+jest.mock("../../Contexts/UserContext");
+jest.mock("../../Contexts/StatusContext");
+jest.mock("../../../services/updatesAPI");
import React from "react";
import {
render,
act,
} from "@testing-library/react";
-import { UserProvider, setToken } from "../../../Contexts/UserContext";
-import { StatusProvider } from "../../../Contexts/StatusContext";
-import { TEST_AUTH_OBJECT_FISKER } from "../../../../utils/testing";
+import { UserProvider, setToken } from "../../Contexts/UserContext";
+import { StatusProvider } from "../../Contexts/StatusContext";
+import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
import Cancel from "./Cancel";
-import updatesAPI from "../../../../services/updatesAPI";
+import updatesAPI from "../../../services/updatesAPI";
describe("Manifest/Cancel", () => {
beforeAll(() => {
diff --git a/src/components/BulkActions/actions/DeleteVehicles.jsx b/src/components/BulkActions/actions/DeleteVehicles.jsx
index 452fbd3..ede865d 100644
--- a/src/components/BulkActions/actions/DeleteVehicles.jsx
+++ b/src/components/BulkActions/actions/DeleteVehicles.jsx
@@ -5,8 +5,8 @@ import TaskRunner from "../../../utils/taskRunner";
import vehiclesAPI from "../../../services/vehiclesAPI";
export default forwardRef(({
- vins,
- vinCSV,
+ ids,
+ idCSV,
}, ref) => {
const { setMessage } = useStatusContext();
const { token: { idToken: { jwtToken: token } } } = useUserContext();
@@ -14,11 +14,11 @@ export default forwardRef(({
useImperativeHandle(ref, () => ({
async submit() {
return new Promise((resolve, reject) => {
- const taskRunner = new TaskRunner(5, vins.length);
+ const taskRunner = new TaskRunner(5, ids.length);
let errorCount = 0;
const task = (vin, index) => {
- const progressMessage = `${index + 1}/${vins.length}`;
+ const progressMessage = `${index + 1}/${ids.length}`;
return async () => vehiclesAPI.deleteVehicle(vin, token)
.then((response) => {
if (response.error) {
@@ -32,12 +32,12 @@ export default forwardRef(({
.catch((error) => reject(error));
}
- vins.forEach((vin, i) => {
+ ids.forEach((vin, i) => {
taskRunner.push(task(vin, i));
});
taskRunner.onComplete().then((responses) => {
- const completeMessage = `${vins.length - errorCount}/${vins.length}`;
+ const completeMessage = `${ids.length - errorCount}/${ids.length}`;
setMessage(`Successfully deleted ${completeMessage} vehicles.`);
resolve(responses);
});
@@ -48,7 +48,7 @@ export default forwardRef(({
return (
- You are about to delete the following VINs: {vinCSV}.
+ You are about to delete the following VINs: {idCSV}.
);
diff --git a/src/components/BulkActions/actions/DeleteVehicles.test.jsx b/src/components/BulkActions/actions/DeleteVehicles.test.jsx
index 8e019f0..e453362 100644
--- a/src/components/BulkActions/actions/DeleteVehicles.test.jsx
+++ b/src/components/BulkActions/actions/DeleteVehicles.test.jsx
@@ -27,8 +27,8 @@ describe("BulkActions/DeleteVehicles", () => {
diff --git a/src/components/BulkActions/actions/Redeploy.jsx b/src/components/BulkActions/actions/Redeploy.jsx
new file mode 100644
index 0000000..4e81e4b
--- /dev/null
+++ b/src/components/BulkActions/actions/Redeploy.jsx
@@ -0,0 +1,55 @@
+import { forwardRef, useImperativeHandle } from "react";
+import { useStatusContext } from "../../Contexts/StatusContext";
+import { useUserContext } from "../../Contexts/UserContext";
+import TaskRunner from "../../../utils/taskRunner";
+import updatesAPI from "../../../services/updatesAPI";
+
+export default forwardRef(({
+ ids,
+ idCSV,
+}, ref) => {
+ const { setMessage } = useStatusContext();
+ const { token: { idToken: { jwtToken: token } } } = useUserContext();
+
+ useImperativeHandle(ref, () => ({
+ async submit() {
+ return new Promise((resolve, reject) => {
+ const taskRunner = new TaskRunner(5, ids.length);
+ let errorCount = 0;
+
+ const task = (id, index) => {
+ const progressMessage = `${index + 1}/${ids.length}`;
+ return async () => updatesAPI.deployCarUpdate(id, token)
+ .then((response) => {
+ if (response.error) {
+ errorCount += 1;
+ setMessage(`${progressMessage} ${response.error}: ${response.message}`);
+ } else {
+ setMessage(`${progressMessage} Redeployed update ${id}`);
+ }
+ return response;
+ })
+ .catch((error) => reject(error));
+ }
+
+ ids.forEach((id, i) => {
+ taskRunner.push(task(id, i));
+ });
+
+ taskRunner.onComplete().then((responses) => {
+ const completeMessage = `${ids.length - errorCount}/${ids.length}`;
+ setMessage(`Successfully rededployed ${completeMessage} updates.`);
+ resolve(responses);
+ });
+ });
+ },
+ }));
+
+ return (
+
+
+ You are redeploying the following updates: {idCSV}.
+
+
+ );
+});
\ No newline at end of file
diff --git a/src/components/BulkActions/actions/Redeploy.test.jsx b/src/components/BulkActions/actions/Redeploy.test.jsx
new file mode 100644
index 0000000..cf2fc9b
--- /dev/null
+++ b/src/components/BulkActions/actions/Redeploy.test.jsx
@@ -0,0 +1,40 @@
+jest.mock("../../Contexts/UserContext");
+jest.mock("../../Contexts/StatusContext");
+jest.mock("../../../services/updatesAPI");
+
+import React from "react";
+import {
+ render,
+ act,
+} from "@testing-library/react";
+import { UserProvider, setToken } from "../../Contexts/UserContext";
+import { StatusProvider } from "../../Contexts/StatusContext";
+import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
+import Redeploy from "./Redeploy";
+import updatesAPI from "../../../services/updatesAPI";
+
+describe("Manifest/Redeploy", () => {
+ beforeAll(() => {
+ setToken(TEST_AUTH_OBJECT_FISKER);
+ });
+
+ it("makes request to redeploy an update", async () => {
+ const api = jest.spyOn(updatesAPI, "deployCarUpdate");
+ const ref = React.createRef();
+
+ render(
+
+
+
+
+
+ );
+
+ await act(async () => ref.current.submit());
+ expect(api).toHaveBeenCalledTimes(3);
+ });
+});
\ No newline at end of file
diff --git a/src/components/BulkActions/actions/SendSMS.jsx b/src/components/BulkActions/actions/SendSMS.jsx
index 004a512..0d2cd6e 100644
--- a/src/components/BulkActions/actions/SendSMS.jsx
+++ b/src/components/BulkActions/actions/SendSMS.jsx
@@ -12,8 +12,8 @@ import smsAPI from "../../../services/smsAPI";
import { SMS } from "../../Contexts/SMSContext";
export default forwardRef(({
- vins,
- vinCSV,
+ ids,
+ idCSV,
}, ref) => {
const [shouldAwait, setShouldAwait] = useState(false);
const [smsMessage, setSmsMessage] = useState("");
@@ -23,9 +23,9 @@ export default forwardRef(({
useImperativeHandle(ref, () => ({
async submit() {
return new Promise((resolve) => {
- const taskRunner = new TaskRunner(5, vins.length);
+ const taskRunner = new TaskRunner(5, ids.length);
- vins.forEach((vin) => {
+ ids.forEach((vin) => {
taskRunner.push(async () => {
const { iccid } = await vehiclesAPI.getVehicle(vin, token);
@@ -47,7 +47,7 @@ export default forwardRef(({
taskRunner.onComplete()
.then((responses) => {
- setMessage(`Sent ${vins.length} SMS messages`);
+ setMessage(`Sent ${ids.length} SMS messages`);
resolve(responses);
});
});
@@ -57,7 +57,7 @@ export default forwardRef(({
return (
- You are about to send SMS to the following vins: {vinCSV}.
+ You are about to send SMS to the following vins: {idCSV}.
{
diff --git a/src/components/BulkActions/actions/UpdateConfig.jsx b/src/components/BulkActions/actions/UpdateConfig.jsx
index a193a91..f8e411b 100644
--- a/src/components/BulkActions/actions/UpdateConfig.jsx
+++ b/src/components/BulkActions/actions/UpdateConfig.jsx
@@ -9,8 +9,8 @@ import TaskRunner from "../../../utils/taskRunner";
import vehiclesAPI from "../../../services/vehiclesAPI";
export default forwardRef(({
- vins,
- vinCSV,
+ ids,
+ idCSV,
}, ref) => {
const { setMessage } = useStatusContext();
const { token: { idToken: { jwtToken: token } } } = useUserContext();
@@ -20,11 +20,11 @@ export default forwardRef(({
useImperativeHandle(ref, () => ({
async submit() {
return new Promise((resolve, reject) => {
- const taskRunner = new TaskRunner(5, vins.length);
+ const taskRunner = new TaskRunner(5, ids.length);
let errorCount = 0;
const task = (vin, index) => {
- const progressMessage = `${index + 1}/${vins.length}`;
+ const progressMessage = `${index + 1}/${ids.length}`;
return async () => vehiclesAPI.updateConfig(vin, forcePush, token)
.then((response) => {
if (response.error) {
@@ -38,12 +38,12 @@ export default forwardRef(({
.catch((error) => reject(error));
}
- vins.forEach((vin, i) => {
+ ids.forEach((vin, i) => {
taskRunner.push(task(vin, i));
});
taskRunner.onComplete().then((responses) => {
- const completeMessage = `${vins.length - errorCount}/${vins.length}`;
+ const completeMessage = `${ids.length - errorCount}/${ids.length}`;
setMessage(`Successfully updated ${completeMessage} vehicles.`);
resolve(responses);
});
@@ -58,7 +58,7 @@ export default forwardRef(({
return (
- You are updating the config for the following VINs: {vinCSV}.
+ You are updating the config for the following VINs: {idCSV}.
{
diff --git a/src/components/BulkActions/index.jsx b/src/components/BulkActions/index.jsx
index 6bd2f96..13a0de6 100644
--- a/src/components/BulkActions/index.jsx
+++ b/src/components/BulkActions/index.jsx
@@ -11,11 +11,14 @@ const AddToFleet = lazy(() => import("./actions/AddToFleet"));
const DeleteVehicles = lazy(() => import("./actions/DeleteVehicles"));
const UpdateConfig = lazy(() => import("./actions/UpdateConfig"));
const SendSMS = lazy(() => import("./actions/SendSMS"));
+const Cancel = lazy(() => import("./actions/Cancel"));
+const Redeploy = lazy(() => import("./actions/Redeploy"));
export default function BulkActions({
- vins = [],
+ ids = [],
actions = [],
}) {
+ const [open, setOpen] = useState(false);
const [title, setTitle] = useState("Action");
const [active, setActive] = useState(null);
const activeRef = useRef();
@@ -52,16 +55,28 @@ export default function BulkActions({
disabled: !hasRole(groups, Permissions.FiskerCreate, providers),
trigger: () => setActive("sms"),
},
+ {
+ id: "cancel",
+ name: "Cancel Updates",
+ disabled: false,
+ trigger: () => setActive("cancel"),
+ },
+ {
+ id: "redeploy",
+ name: "Redploy Updates",
+ disabled: false,
+ trigger: () => setActive("redeploy"),
+ }
].filter((action) => actions.includes(action.id));
const payload = {
- vins,
- vinCSV: (vins && vins.length > 0) ? vins.join(", ") : "N/A",
+ ids,
+ idCSV: (ids && ids.length > 0) ? ids.join(", ") : "N/A",
ref: activeRef
};
const handleClose = () => {
- setActive(null);
+ setOpen(false).then(() => setActive(null));
}
const handleSubmit = () => {
@@ -73,14 +88,14 @@ export default function BulkActions({
setTitle(filteredActions.find((action) => active === action.id)?.name || "Action");
}, [active, filteredActions]);
- if (!vins || vins.length === 0) return <>>;
+ if (!ids || ids.length === 0) return <>>;
return (
<>
-
+ setOpen(true)} />
@@ -91,6 +106,8 @@ export default function BulkActions({
{active === "deleteVehicles" && }
{active === "updateConfig" && }
{active === "sms" && }
+ {active === "cancel" && }
+ {active === "redeploy" && }
diff --git a/src/components/BulkActions/index.test.jsx b/src/components/BulkActions/index.test.jsx
index 2471c91..0c783ec 100644
--- a/src/components/BulkActions/index.test.jsx
+++ b/src/components/BulkActions/index.test.jsx
@@ -28,7 +28,7 @@ describe("BulkActions", () => {
@@ -45,7 +45,7 @@ describe("BulkActions", () => {
@@ -63,7 +63,7 @@ describe("BulkActions", () => {
diff --git a/src/components/Contexts/CarUpdatesContext.jsx b/src/components/Contexts/CarUpdatesContext.jsx
index ef4d3d3..3b11bc4 100644
--- a/src/components/Contexts/CarUpdatesContext.jsx
+++ b/src/components/Contexts/CarUpdatesContext.jsx
@@ -62,7 +62,7 @@ export const CarUpdatesProvider = ({ children }) => {
setBusy(true);
result = await api.deployCarUpdate(id, token);
if (result.error)
- throw new Error(`Cancel car update error. ${result.message}`);
+ throw new Error(`Retry car update error. ${result.message}`);
} finally {
setBusy(false);
}
diff --git a/src/components/Controls/CarUpdatesTable/index.jsx b/src/components/Controls/CarUpdatesTable/index.jsx
index 7da1829..f370728 100644
--- a/src/components/Controls/CarUpdatesTable/index.jsx
+++ b/src/components/Controls/CarUpdatesTable/index.jsx
@@ -9,6 +9,7 @@ import {
TableRow,
} from "@material-ui/core";
import CancelIcon from "@material-ui/icons/Cancel";
+import ReplayIcon from "@material-ui/icons/Replay";
import React, { useEffect, useState } from "react";
import { Link } from "react-router-dom";
@@ -71,6 +72,7 @@ const MainForm = ({ vin, token }) => {
const [order, setOrder] = useState("desc");
const {
cancelUpdate,
+ deployUpdate,
getCarUpdates,
carUpdates,
totalCarUpdates,
@@ -158,6 +160,31 @@ const MainForm = ({ vin, token }) => {
}
};
+ const sendDeploy = async (row) => {
+ try {
+ await deployUpdate(row.id, token);
+ setMessage(`Sent deploy for ${updateName(row)}`);
+ } catch (e) {
+ setMessage(e.message);
+ }
+ };
+
+ const isRedeployAvailable = (status) => {
+ switch (status) {
+ case "manifest_succeeded":
+ case "manifest_canceled":
+ case "manifest_error":
+ case "manifest_cancel_pending":
+ case "rollback_succeeded":
+ case "manifest_rejected":
+ case "rollback_failed":
+ case "cleanup_succeeded":
+ return true;
+ default:
+ return false;
+ }
+ }
+
return (
{
>
+ sendDeploy(row)}
+ aria-label={`Send deploy for ${row.vin}`}
+ size="small"
+ disabled={!isRedeployAvailable(row.status)}
+ >
+
+
diff --git a/src/components/Controls/DropDownButton/index.jsx b/src/components/Controls/DropDownButton/index.jsx
index 9da3f34..e5c572d 100644
--- a/src/components/Controls/DropDownButton/index.jsx
+++ b/src/components/Controls/DropDownButton/index.jsx
@@ -11,12 +11,13 @@ import {
} from "@mui/material";
import ArrowDropDownIcon from "@mui/icons-material/ArrowDropDown";
-const DropDownButton = ({ actions = [], payload = [] }) => {
+const DropDownButton = ({ actions = [], payload = [], onClick = () => { } }) => {
const [open, setOpen] = useState(false);
const [selectedIndex, setSelectedIndex] = useState(0);
const anchorRef = useRef(null);
const handleClick = () => {
+ onClick()
actions[selectedIndex].trigger(...payload);
};
diff --git a/src/components/Fleets/Status/Details/__snapshots__/index.test.jsx.snap b/src/components/Fleets/Status/Details/__snapshots__/index.test.jsx.snap
index 1d198d8..6389849 100644
--- a/src/components/Fleets/Status/Details/__snapshots__/index.test.jsx.snap
+++ b/src/components/Fleets/Status/Details/__snapshots__/index.test.jsx.snap
@@ -145,47 +145,7 @@ exports[`FleetDetailsTab Render 1`] = `
+ />
diff --git a/src/components/Fleets/Status/__snapshots__/DetailsTab.test.jsx.snap b/src/components/Fleets/Status/__snapshots__/DetailsTab.test.jsx.snap
index 4e0190c..7532a9e 100644
--- a/src/components/Fleets/Status/__snapshots__/DetailsTab.test.jsx.snap
+++ b/src/components/Fleets/Status/__snapshots__/DetailsTab.test.jsx.snap
@@ -153,47 +153,7 @@ exports[`DetailsTab Render 1`] = `
+ />
diff --git a/src/components/Fleets/Status/__snapshots__/index.test.jsx.snap b/src/components/Fleets/Status/__snapshots__/index.test.jsx.snap
index b7d2e95..a90b39c 100644
--- a/src/components/Fleets/Status/__snapshots__/index.test.jsx.snap
+++ b/src/components/Fleets/Status/__snapshots__/index.test.jsx.snap
@@ -241,47 +241,7 @@ exports[`FleetStatus Render 1`] = `
+ />
diff --git a/src/components/Manifest/Status/index.jsx b/src/components/Manifest/Status/index.jsx
index 4f51793..1482679 100644
--- a/src/components/Manifest/Status/index.jsx
+++ b/src/components/Manifest/Status/index.jsx
@@ -30,7 +30,7 @@ import { useLocalStorage } from "../../useLocalStorage";
import useStyles from "../../useStyles";
import ManifestDetails from "../Details";
import TableHeaderSortable from "../../Table/HeaderSortable";
-import Toolbar from "../Toolbar";
+import BulkActions from "../../BulkActions";
const PAGE_SIZE = "MANIFEST_STATUS_PAGE_SIZE";
@@ -191,7 +191,7 @@ const MainForm = () => {
-
+
diff --git a/src/components/Manifest/Toolbar/__snapshots__/index.test.jsx.snap b/src/components/Manifest/Toolbar/__snapshots__/index.test.jsx.snap
deleted file mode 100644
index eec1c36..0000000
--- a/src/components/Manifest/Toolbar/__snapshots__/index.test.jsx.snap
+++ /dev/null
@@ -1,53 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Toolbar Render 1`] = `
-
-`;
diff --git a/src/components/Manifest/Toolbar/index.jsx b/src/components/Manifest/Toolbar/index.jsx
deleted file mode 100644
index b98d892..0000000
--- a/src/components/Manifest/Toolbar/index.jsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import { useEffect, useState, useRef, Suspense, lazy } from "react";
-import DropDownButton from "../../Controls/DropDownButton";
-import { Modal } from "../../BulkActions/Modal";
-import { useUserContext } from "../../Contexts/UserContext";
-import { Permissions, hasRole } from "../../../utils/roles";
-
-// Code-splitting individual actions
-// https://react.dev/reference/react/lazy
-const Cancel = lazy(() => import("./actions/Cancel"));
-
-export default function Toolbar({
- ids = [],
- actions = [],
-}) {
- const [title, setTitle] = useState("Action");
- const [open, setOpen] = useState(false);
- const [active, setActive] = useState(null);
- const activeRef = useRef();
- const { groups, providers } = useUserContext();
-
- const hasAccess = hasRole(groups, Permissions.FiskerMagnaCreate, providers);
-
- const filteredActions = [
- {
- id: "cancel",
- name: "Cancel Updates",
- disabled: !hasAccess || ids.length <= 0,
- trigger: () => {
- setOpen(true);
- setActive("cancel");
- },
- },
- ].filter((action) => actions.includes(action.id));
-
- const payload = {
- ids,
- idCSV: ids.join(", "),
- ref: activeRef
- };
-
- const handleClose = () => {
- setOpen(false).then(() => setActive(null));
- }
-
- const handleSubmit = () => {
- activeRef.current.submit();
- handleClose();
- }
-
- useEffect(() => {
- setTitle(filteredActions.find((action) => active === action.id)?.name || "Action");
- }, [active, filteredActions]);
-
- return (
- <>
-
-
- Loading...}>
-
- {active === "cancel" && }
-
-
-
- >
- )
-}
\ No newline at end of file
diff --git a/src/components/Manifest/Toolbar/index.test.jsx b/src/components/Manifest/Toolbar/index.test.jsx
deleted file mode 100644
index 1fe9bbd..0000000
--- a/src/components/Manifest/Toolbar/index.test.jsx
+++ /dev/null
@@ -1,77 +0,0 @@
-jest.mock("../../Contexts/UserContext");
-jest.mock("../../Contexts/StatusContext");
-
-import React from "react";
-import {
- fireEvent,
- render,
- screen,
- waitFor,
-} from "@testing-library/react";
-import { UserProvider, setToken } from "../../Contexts/UserContext";
-import { StatusProvider } from "../../Contexts/StatusContext";
-import { TEST_AUTH_OBJECT_FISKER } from "../../../utils/testing";
-import Toolbar from ".";
-import addSnapshotSerializer from "../../../utils/snapshot";
-
-describe("Toolbar", () => {
- beforeAll(() => {
- setToken(TEST_AUTH_OBJECT_FISKER);
- global.URL.createObjectURL = jest.fn();
- global.URL.revokeObjectURL = jest.fn();
- addSnapshotSerializer(expect);
- });
-
- it("Render", async () => {
- const { container } = render(
-
-
-
-
-
- );
- await waitFor(() => {
- /* render */
- });
- expect(container).toMatchSnapshot();
- });
-
- it("opens a modal", async () => {
- render(
-
-
-
-
-
- );
-
- const buttonEl = screen.getByText("Cancel Updates");
- fireEvent.click(buttonEl);
- const submitEl = screen.getByText("Submit");
- expect(submitEl).toBeTruthy();
- });
-
- it("filters valid actions", async () => {
- render(
-
-
-
-
-
- );
-
- const dropdownBtn = screen.getByTestId("dropdown-button-expand");
- fireEvent.click(dropdownBtn);
- const dropdownOptions = screen.getAllByRole("menuitem");
- expect(dropdownOptions.length).toBe(1);
- });
-});
\ No newline at end of file
diff --git a/src/services/__mocks__/updatesAPI.js b/src/services/__mocks__/updatesAPI.js
index c7372f5..bc3356f 100644
--- a/src/services/__mocks__/updatesAPI.js
+++ b/src/services/__mocks__/updatesAPI.js
@@ -27,6 +27,10 @@ const updatesAPI = {
return { message: "OK" };
},
+ deployCarUpdate: async (id, token) => {
+ return { message: "OK" };
+ },
+
getSUMSVersions: async (token) => {
return {
"data": ["2023.02.01.0.0.A", "2023.02.01.0.0.B"]