CEC-1058 fleet forms (#123)

* working fleets page

* unit tests

* snapshots

* updating messages and snapshots

* updating extraneous snaps
This commit is contained in:
Drew Taylor
2022-03-11 15:48:30 -08:00
committed by GitHub
parent a9c154c472
commit 34d670c101
28 changed files with 2695 additions and 50 deletions

View File

@@ -131,6 +131,146 @@ describe("CANFiltersContext", () => {
checkBaseResults("", "false");
});
});
describe("updateFilter", () => {
beforeEach(async () => {
const TestComp = () => {
const { busy, updateFilter } = useCANFiltersContext();
const { message, setMessage } = useStatusContext();
const update = async (data) => {
try {
await updateFilter("TESTVIN1234567890", data.can_id, data);
} catch (e) {
setMessage(e.message);
}
};
return (
<>
<div data-testid="error">{message}</div>
<div data-testid="busy">{busy.toString()}</div>
<button data-testid="updateFilterNull" onClick={() => update(null)} />
<button data-testid="updateFilterNoCANID" onClick={() => update({})} />
<button
data-testid="updateFilter"
onClick={() =>
update({ can_id: "123", interval: 1000 })
}
/>
</>
);
};
render(
<StatusProvider>
<CANFiltersProvider>
<TestComp />
</CANFiltersProvider>
</StatusProvider>
);
});
afterEach(() => {
cleanup();
});
it("initial state", () => {
checkBaseResults("", "false");
});
it("updateFilterNull", async () => {
fireEvent.click(screen.getByTestId("updateFilterNull"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("Cannot read property 'can_id' of null", "false");
});
it("updateFilterNoCANID", async () => {
fireEvent.click(screen.getByTestId("updateFilterNoCANID"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("CAN ID required", "false");
});
it("updateFilter", async () => {
fireEvent.click(screen.getByTestId("updateFilter"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("", "false");
});
});
describe("deleteFilter", () => {
beforeEach(async () => {
const TestComp = () => {
const { busy, deleteFilter } = useCANFiltersContext();
const { message, setMessage } = useStatusContext();
const deleteF = async (can_id) => {
try {
await deleteFilter("TESTVIN1234567890", can_id);
} catch (e) {
setMessage(e.message);
}
};
return (
<>
<div data-testid="error">{message}</div>
<div data-testid="busy">{busy.toString()}</div>
<button data-testid="deleteFilterNull" onClick={() => deleteF(null)} />
<button data-testid="deleteFilterNonexistent" onClick={() => deleteF(-1)} />
<button
data-testid="deleteFilter"
onClick={() =>
deleteF(123)
}
/>
</>
);
};
render(
<StatusProvider>
<CANFiltersProvider>
<TestComp />
</CANFiltersProvider>
</StatusProvider>
);
});
afterEach(() => {
cleanup();
});
it("initial state", () => {
checkBaseResults("", "false");
});
it("deleteFilterNull", async () => {
fireEvent.click(screen.getByTestId("deleteFilterNull"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("CAN ID required", "false");
});
it("deleteFilterNonexistent", async () => {
fireEvent.click(screen.getByTestId("deleteFilterNonexistent"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("", "false");
});
it("deleteFilter", async () => {
fireEvent.click(screen.getByTestId("deleteFilter"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("", "false");
});
});
});
const expectedFiltersData = [

View File

@@ -0,0 +1,112 @@
import React, { useContext, useState } from "react";
import api from "../../services/fleetsAPI";
const FleetContext = React.createContext();
export const FleetProvider = ({ children }) => {
const [busy, setBusy] = useState(false);
const [fleets, setFleets] = useState([]);
const [totalFleets, setTotalFleets] = useState(0);
const addFleet = async (fleet, token) => {
try {
setBusy(true);
validateFleet(fleet);
const result = await api.addFleet(fleet, token);
if (result.error) throw new Error(`Add fleet error. ${result.message}`);
return result;
} finally {
setBusy(false);
}
};
const getFleets = async (search, token) => {
try {
setBusy(true);
const result = await api.getFleets(search, token);
if (result.error) {
setFleets([])
throw new Error(`Get fleets error. ${result.message}`);
}
setFleets(result.data)
if (result.total) {
setTotalFleets(result.total);
}
return result;
} finally {
setBusy(false);
}
};
const updateFleet = async (name, fleet, token) => {
try {
setBusy(true);
validateFleetName(name);
validateFleet(fleet);
const result = await api.updateFleet(name, fleet, token);
if (result.error) {
throw new Error(`Update fleet error. ${result.message}`);
}
return result;
} finally {
setBusy(false);
}
}
const deleteFleet = async (name, token) => {
try {
setBusy(true);
validateFleetName(name);
const result = await api.deleteFleet(name, token);
if (result.error) {
throw new Error(`Delete filter error. ${result.message}`);
}
const index = fleets.findIndex(element => element.name === name);
if (index >= 0) fleets.splice(index, 1);
return result;
} finally {
setBusy(false);
}
}
return (
<FleetContext.Provider
value={{
busy,
fleets,
totalFleets,
addFleet,
getFleets,
updateFleet,
deleteFleet
}}
>
{children}
</FleetContext.Provider>
);
};
const validateFleet = (fleet) => {
if (fleet == null) {
throw new Error("No fleet data");
}
validateFleetName(fleet.name);
}
const validateFleetName = (name) => {
if (name == null || !/^[A-Za-z-]+$/.test(name)) {
throw new Error("Invalid name");
}
}
export const useFleetContext = () => useContext(FleetContext);

View File

@@ -0,0 +1,280 @@
jest.mock("../../services/fleetsAPI")
import {
render,
cleanup,
screen,
fireEvent,
waitFor,
} from "@testing-library/react";
import { FleetProvider, useFleetContext } from "./FleetContext";
import { StatusProvider, useStatusContext } from "./StatusContext";
const checkFleetResults = (error, busy, fleets) => {
checkBaseResults(error, busy);
expect(screen.getByTestId("fleets").innerHTML).toEqual(fleets);
};
const checkBaseResults = (error, busy) => {
expect(screen.getByTestId("error").innerHTML).toEqual(error);
expect(screen.getByTestId("busy").innerHTML).toEqual(busy);
};
describe("FleetContext", () => {
describe("getFleets", () => {
beforeEach(() => {
const TestComp = () => {
const { busy, error, fleets, getFleets } = useFleetContext();
return (
<>
<div data-testid="error">{error}</div>
<div data-testid="busy">{busy.toString()}</div>
<div data-testid="fleets">{JSON.stringify(fleets)}</div>
<button
data-testid="getFleets"
onClick={() => getFleets()}
/>
</>
);
};
render(
<FleetProvider>
<TestComp />
</FleetProvider>
);
});
afterEach(() => {
cleanup();
});
it("initial state", () => {
checkFleetResults("", "false", "[]");
});
it("getFleets", async () => {
fireEvent.click(screen.getByTestId("getFleets"));
await waitFor(() =>
expect(screen.getByTestId("fleets").innerHTML).not.toBe("[]")
);
checkFleetResults("", "false", JSON.stringify(expectedFleetsData));
});
});
describe("addFleet", () => {
beforeEach(async () => {
const TestComp = () => {
const { busy, addFleet } = useFleetContext();
const { message, setMessage } = useStatusContext();
const add = async (fleet) => {
try {
await addFleet(fleet);
} catch (e) {
setMessage(e.message);
}
};
return (
<>
<div data-testid="error">{message}</div>
<div data-testid="busy">{busy.toString()}</div>
<button data-testid="addFleetNull" onClick={() => add(null)} />
<button data-testid="addFleetNoName" onClick={() => add({})} />
<button
data-testid="addFleet"
onClick={() =>
add({ name: "EU-WEST", log_level: "warn", canbus: { enabled: false } })
}
/>
</>
);
};
render(
<StatusProvider>
<FleetProvider>
<TestComp />
</FleetProvider>
</StatusProvider>
);
});
afterEach(() => {
cleanup();
});
it("initial state", () => {
checkBaseResults("", "false");
});
it("addFleetNull", async () => {
fireEvent.click(screen.getByTestId("addFleetNull"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("No fleet data", "false");
});
it("addFleetNoName", async () => {
fireEvent.click(screen.getByTestId("addFleetNoName"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("Invalid name", "false");
});
it("addFleet", async () => {
fireEvent.click(screen.getByTestId("addFleet"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("", "false");
});
});
describe("updateFleet", () => {
beforeEach(async () => {
const TestComp = () => {
const { busy, updateFleet } = useFleetContext();
const { message, setMessage } = useStatusContext();
const update = async (data) => {
try {
await updateFleet("EU-WEST", data);
} catch (e) {
setMessage(e.message);
}
};
return (
<>
<div data-testid="error">{message}</div>
<div data-testid="busy">{busy.toString()}</div>
<button data-testid="updateFleetNull" onClick={() => update(null)} />
<button data-testid="updateFleetNoName" onClick={() => update({})} />
<button
data-testid="updateFleet"
onClick={() =>
update({ name: "EU-WEST", log_level: "warn", canbus: { enabled: false } })
}
/>
</>
);
};
render(
<StatusProvider>
<FleetProvider>
<TestComp />
</FleetProvider>
</StatusProvider>
);
});
afterEach(() => {
cleanup();
});
it("initial state", () => {
checkBaseResults("", "false");
});
it("updateFleetNull", async () => {
fireEvent.click(screen.getByTestId("updateFleetNull"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("No fleet data", "false");
});
it("updateFleetNoName", async () => {
fireEvent.click(screen.getByTestId("updateFleetNoName"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("Invalid name", "false");
});
it("updateFleet", async () => {
fireEvent.click(screen.getByTestId("updateFleet"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("", "false");
});
});
describe("deleteFleet", () => {
beforeEach(async () => {
const TestComp = () => {
const { busy, deleteFleet } = useFleetContext();
const { message, setMessage } = useStatusContext();
const deleteF = async (name) => {
try {
await deleteFleet(name);
} catch (e) {
setMessage(e.message);
}
};
return (
<>
<div data-testid="error">{message}</div>
<div data-testid="busy">{busy.toString()}</div>
<button data-testid="deleteFleetNull" onClick={() => deleteF(null)} />
<button data-testid="deleteFleetNonexistent" onClick={() => deleteF("INVALID")} />
<button
data-testid="deleteFleet"
onClick={() =>
deleteF("US-WEST")
}
/>
</>
);
};
render(
<StatusProvider>
<FleetProvider>
<TestComp />
</FleetProvider>
</StatusProvider>
);
});
afterEach(() => {
cleanup();
});
it("initial state", () => {
checkBaseResults("", "false");
});
it("deleteFleetNull", async () => {
fireEvent.click(screen.getByTestId("deleteFleetNull"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("Invalid name", "false");
});
it("deleteFleetNonexistent", async () => {
fireEvent.click(screen.getByTestId("deleteFleetNonexistent"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("", "false");
});
it("deleteFleet", async () => {
fireEvent.click(screen.getByTestId("deleteFleet"));
await waitFor(() =>
expect(screen.getByTestId("busy").innerHTML).toEqual("false")
);
checkBaseResults("", "false");
});
});
});
const expectedFleetsData = [
{ name: "US-WEST", log_level: "info", canbus: { enabled: true } },
{ name: "US-CENTRAL", log_level: "warn", canbus: { enabled: false } },
{ name: "US-EAST", log_level: "error", canbus: { enabled: true } },
];

View File

@@ -0,0 +1,21 @@
let busy = false;
let fleets = [
{ name: "US-WEST", log_level: "info", canbus: { enabled: true } },
{ name: "US-CENTRAL", log_level: "warn", canbus: { enabled: false } },
{ name: "US-EAST", log_level: "error", canbus: { enabled: true } },
];
let totalFleets = 3;
export const FleetProvider = ({ children }) => {
return <div data-testid="mocked-fleetprovider">{children}</div>;
};
export const useFleetContext = () => ({
busy,
fleets,
totalFleets,
addFleet: jest.fn(),
getFleets: jest.fn(),
updateFleet: jest.fn(),
deleteFleet: jest.fn(),
});