bug fixes and tests
parent
4cf3f4fd2c
commit
89c10de58b
|
@ -0,0 +1,109 @@
|
|||
jest.mock("fastclick", () => ({
|
||||
attach: jest.fn(),
|
||||
}));
|
||||
|
||||
import * as React from "react";
|
||||
import { App, AppProps } from "../app";
|
||||
import { mount } from "enzyme";
|
||||
import { bot } from "../__test_support__/fake_state/bot";
|
||||
import { fakeUser } from "../__test_support__/fake_state/resources";
|
||||
import { createStore } from "redux";
|
||||
import { reducers } from "../redux/root_reducer";
|
||||
|
||||
describe("<App />: Controls Pop-Up", () => {
|
||||
function fakeProps(): AppProps {
|
||||
return {
|
||||
dispatch: jest.fn(),
|
||||
loaded: [],
|
||||
logs: [],
|
||||
user: fakeUser(),
|
||||
bot: bot
|
||||
};
|
||||
}
|
||||
|
||||
function controlsPopUp(page: string, exists: boolean) {
|
||||
it(`doesn't render controls pop-up on ${page} page`, () => {
|
||||
Object.defineProperty(location, "pathname", {
|
||||
value: "/app/" + page, configurable: true
|
||||
});
|
||||
const wrapper = mount(<App {...fakeProps() } />,
|
||||
{ context: { store: createStore(reducers) } });
|
||||
if (exists) {
|
||||
expect(wrapper.html()).toContain("controls-popup");
|
||||
} else {
|
||||
expect(wrapper.html()).not.toContain("controls-popup");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
controlsPopUp("designer", true);
|
||||
controlsPopUp("designer/plants", true);
|
||||
controlsPopUp("controls", false);
|
||||
controlsPopUp("device", true);
|
||||
controlsPopUp("sequences", true);
|
||||
controlsPopUp("sequences/for_regimens", true);
|
||||
controlsPopUp("regimens", false);
|
||||
controlsPopUp("tools", true);
|
||||
controlsPopUp("farmware", true);
|
||||
controlsPopUp("account", false);
|
||||
|
||||
});
|
||||
|
||||
describe.skip("<App />: Loading", () => {
|
||||
function fakeProps(): AppProps {
|
||||
return {
|
||||
dispatch: jest.fn(),
|
||||
loaded: [],
|
||||
logs: [],
|
||||
user: fakeUser(),
|
||||
bot: bot
|
||||
};
|
||||
}
|
||||
|
||||
it("MUST_LOADs not loaded", () => {
|
||||
const wrapper = mount(<App {...fakeProps() } />,
|
||||
{ context: { store: createStore(reducers) } });
|
||||
expect(wrapper.html()).toContain("spinner");
|
||||
});
|
||||
|
||||
it("MUST_LOADs partially loaded", () => {
|
||||
const p = fakeProps();
|
||||
p.loaded = ["sequences"];
|
||||
const wrapper = mount(<App {...p } />,
|
||||
{ context: { store: createStore(reducers) } });
|
||||
expect(wrapper.html()).toContain("spinner");
|
||||
});
|
||||
|
||||
it("MUST_LOADs loaded", () => {
|
||||
const p = fakeProps();
|
||||
p.loaded = ["sequences", "regimens", "farm_events", "points"];
|
||||
const wrapper = mount(<App {...p } />,
|
||||
{ context: { store: createStore(reducers) } });
|
||||
expect(wrapper.html()).not.toContain("spinner");
|
||||
});
|
||||
});
|
||||
|
||||
describe("<App />: NavBar", () => {
|
||||
function fakeProps(): AppProps {
|
||||
return {
|
||||
dispatch: jest.fn(),
|
||||
loaded: [],
|
||||
logs: [],
|
||||
user: fakeUser(),
|
||||
bot: bot
|
||||
};
|
||||
}
|
||||
|
||||
it("displays links", () => {
|
||||
const wrapper = mount(<App {...fakeProps() } />,
|
||||
{ context: { store: createStore(reducers) } });
|
||||
expect(wrapper.text())
|
||||
.toContain("Farm DesignerControlsDeviceSequencesRegimensToolsFarmware");
|
||||
});
|
||||
|
||||
it("displays ticker", () => {
|
||||
const wrapper = mount(<App {...fakeProps() } />,
|
||||
{ context: { store: createStore(reducers) } });
|
||||
expect(wrapper.text()).toContain("No logs yet.");
|
||||
});
|
||||
});
|
|
@ -1,9 +1,24 @@
|
|||
jest.mock("../device", () => ({
|
||||
devices: {
|
||||
current: {
|
||||
moveRelative: jest.fn(() => { return Promise.resolve(); }),
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
import * as React from "react";
|
||||
import { ControlsPopup } from "../controls_popup";
|
||||
import { mount } from "enzyme";
|
||||
import { devices } from "../device";
|
||||
|
||||
describe("<ControlsPopup />", () => {
|
||||
const wrapper = mount(<ControlsPopup dispatch={jest.fn()} />);
|
||||
beforeEach(function () {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const wrapper = mount(<ControlsPopup
|
||||
dispatch={jest.fn()}
|
||||
axisInversion={{ x: true, y: false, z: false }} />);
|
||||
|
||||
it("Has a false initial state", () => {
|
||||
expect(wrapper.state("isOpen")).toBeFalsy();
|
||||
|
@ -15,4 +30,32 @@ describe("<ControlsPopup />", () => {
|
|||
expect(wrapper.state("isOpen")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("x axis is inverted", () => {
|
||||
const { mock } = devices.current.moveRelative as jest.Mock<{}>;
|
||||
const button = wrapper.find("button").first();
|
||||
expect(button.props().title).toBe("move x axis");
|
||||
button.simulate("click");
|
||||
const args = mock.calls[0][0];
|
||||
expect(args.x).toBe(100);
|
||||
expect(args.y).toBe(0);
|
||||
expect(args.z).toBe(0);
|
||||
});
|
||||
|
||||
it("y axis is not inverted", () => {
|
||||
const { mock } = devices.current.moveRelative as jest.Mock<{}>;
|
||||
const button = wrapper.find("button").at(2);
|
||||
expect(button.props().title).toBe("move y axis");
|
||||
button.simulate("click");
|
||||
const args = mock.calls[0][0];
|
||||
expect(args.x).toBe(0);
|
||||
expect(args.y).toBe(100);
|
||||
expect(args.z).toBe(0);
|
||||
});
|
||||
|
||||
it("disabled when closed", () => {
|
||||
const { mock } = devices.current.moveRelative as jest.Mock<{}>;
|
||||
wrapper.setState({ isOpen: false });
|
||||
[0, 1, 2, 3].map((i) => wrapper.find("button").at(i).simulate("click"));
|
||||
expect(mock.calls.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ fastClick.attach(document.body);
|
|||
/** For the logger module */
|
||||
init();
|
||||
|
||||
interface AppProps {
|
||||
export interface AppProps {
|
||||
dispatch: Function;
|
||||
loaded: ResourceName[];
|
||||
logs: Log[];
|
||||
|
@ -76,6 +76,7 @@ export class App extends React.Component<AppProps, {}> {
|
|||
|
||||
render() {
|
||||
const syncLoaded = this.isLoaded;
|
||||
const currentPath = window.location.pathname;
|
||||
return <div className="app">
|
||||
<HotKeys dispatch={this.props.dispatch} />
|
||||
<NavBar
|
||||
|
@ -85,7 +86,12 @@ export class App extends React.Component<AppProps, {}> {
|
|||
logs={this.props.logs} />
|
||||
{!syncLoaded && <Spinner radius={33} strokeWidth={6} />}
|
||||
{syncLoaded && this.props.children}
|
||||
<ControlsPopup dispatch={this.props.dispatch} />
|
||||
{!currentPath.startsWith("/app/controls") &&
|
||||
!currentPath.startsWith("/app/account") &&
|
||||
!currentPath.startsWith("/app/regimens") &&
|
||||
<ControlsPopup
|
||||
dispatch={this.props.dispatch}
|
||||
axisInversion={this.props.bot.axis_inversion} />}
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import * as React from "react";
|
||||
|
||||
import { DirectionButton } from "./controls/direction_button";
|
||||
import { Xyz } from "./devices/interfaces";
|
||||
|
||||
export interface State {
|
||||
isOpen: boolean;
|
||||
|
@ -9,6 +10,7 @@ export interface State {
|
|||
|
||||
export interface Props {
|
||||
dispatch: Function;
|
||||
axisInversion: Record<Xyz, boolean>;
|
||||
}
|
||||
|
||||
export class ControlsPopup extends React.Component<Props, Partial<State>> {
|
||||
|
@ -32,27 +34,27 @@ export class ControlsPopup extends React.Component<Props, Partial<State>> {
|
|||
<DirectionButton
|
||||
axis="x"
|
||||
direction="right"
|
||||
isInverted={false}
|
||||
isInverted={this.props.axisInversion.x}
|
||||
steps={this.state.stepSize}
|
||||
disabled={false} />
|
||||
disabled={!isOpen} />
|
||||
<DirectionButton
|
||||
axis="y"
|
||||
direction="up"
|
||||
isInverted={false}
|
||||
isInverted={this.props.axisInversion.y}
|
||||
steps={this.state.stepSize}
|
||||
disabled={false} />
|
||||
disabled={!isOpen} />
|
||||
<DirectionButton
|
||||
axis="y"
|
||||
direction="down"
|
||||
isInverted={false}
|
||||
isInverted={this.props.axisInversion.y}
|
||||
steps={this.state.stepSize}
|
||||
disabled={false} />
|
||||
disabled={!isOpen} />
|
||||
<DirectionButton
|
||||
axis="x"
|
||||
direction="left"
|
||||
isInverted={false}
|
||||
isInverted={this.props.axisInversion.x}
|
||||
steps={this.state.stepSize}
|
||||
disabled={false} />
|
||||
disabled={!isOpen} />
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
max-width: 100%;
|
||||
margin: auto;
|
||||
max-height: 650px;
|
||||
min-height: 200px;
|
||||
}
|
||||
|
||||
.image-flipper-left {
|
||||
|
|
|
@ -30,13 +30,11 @@ describe("checkControllerUpdates()", function () {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("calls checkUpdates", () => {
|
||||
it("calls checkUpdates", async () => {
|
||||
const { mock } = devices.current.checkUpdates as jest.Mock<{}>;
|
||||
actions.checkControllerUpdates();
|
||||
await actions.checkControllerUpdates();
|
||||
expect(mock.calls.length).toEqual(1);
|
||||
// TODO: It would be nice if this worked to check for sent toasts.
|
||||
// See expectations for each test in comments below.
|
||||
// expect(mockOk.mock.calls.length).toEqual(1);
|
||||
expect(mockOk.mock.calls.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -45,11 +43,11 @@ describe("powerOff()", function () {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("calls powerOff", () => {
|
||||
it("calls powerOff", async () => {
|
||||
const { mock } = devices.current.powerOff as jest.Mock<{}>;
|
||||
actions.powerOff();
|
||||
await actions.powerOff();
|
||||
expect(mock.calls.length).toEqual(1);
|
||||
// expect(mockOk.mock.calls.length).toEqual(1);
|
||||
expect(mockOk.mock.calls.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -58,11 +56,11 @@ describe("reboot()", function () {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("calls reboot", () => {
|
||||
it("calls reboot", async () => {
|
||||
const { mock } = devices.current.reboot as jest.Mock<{}>;
|
||||
actions.reboot();
|
||||
await actions.reboot();
|
||||
expect(mock.calls.length).toEqual(1);
|
||||
// expect(mockOk.mock.calls.length).toEqual(1);
|
||||
expect(mockOk.mock.calls.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -105,13 +103,13 @@ describe("execSequence()", function () {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("calls execSequence", () => {
|
||||
it("calls execSequence", async () => {
|
||||
const { mock } = devices.current.execSequence as jest.Mock<{}>;
|
||||
const s = fakeSequence().body;
|
||||
actions.execSequence(s);
|
||||
await actions.execSequence(s);
|
||||
expect(mock.calls.length).toEqual(1);
|
||||
expect(mock.calls[0][0]).toEqual(s.id);
|
||||
// expect(mockOk.mock.calls.length).toEqual(1);
|
||||
expect(mockOk.mock.calls.length).toEqual(1);
|
||||
});
|
||||
|
||||
it("implodes when executing unsaved sequences", () => {
|
||||
|
@ -132,7 +130,6 @@ describe("MCUFactoryReset()", function () {
|
|||
const { mock } = devices.current.resetMCU as jest.Mock<{}>;
|
||||
actions.MCUFactoryReset();
|
||||
expect(mock.calls.length).toEqual(1);
|
||||
// expect(mockOk.mock.calls.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -141,12 +138,12 @@ describe("botConfigChange()", function () {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("calls updateMcu", () => {
|
||||
it("calls updateMcu", async () => {
|
||||
const { mock } = devices.current.updateMcu as jest.Mock<{}>;
|
||||
actions.botConfigChange("encoder_enabled_x", 0);
|
||||
await actions.botConfigChange("encoder_enabled_x", 0);
|
||||
expect(mock.calls.length).toEqual(1);
|
||||
expect(mock.calls[0][0]).toEqual({ "encoder_enabled_x": 0 });
|
||||
// expect(mockOk.mock.calls.length).toEqual(0);
|
||||
expect(mockOk.mock.calls.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -155,13 +152,13 @@ describe("pinToggle()", function () {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("calls togglePin", () => {
|
||||
it("calls togglePin", async () => {
|
||||
const { mock } = devices.current.togglePin as jest.Mock<{}>;
|
||||
actions.pinToggle(5);
|
||||
await actions.pinToggle(5);
|
||||
expect(mock.calls.length).toEqual(1);
|
||||
const argList = mock.calls[0];
|
||||
expect(argList[0].pin_number).toEqual(5);
|
||||
// expect(mockOk.mock.calls.length).toEqual(0);
|
||||
expect(mockOk.mock.calls.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -170,14 +167,14 @@ describe("homeAll()", function () {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it("calls home", () => {
|
||||
it("calls home", async () => {
|
||||
const { mock } = devices.current.home as jest.Mock<{}>;
|
||||
actions.homeAll(100);
|
||||
await actions.homeAll(100);
|
||||
expect(mock.calls.length).toEqual(1);
|
||||
const argList = mock.calls[0];
|
||||
expect(argList[0].axis).toEqual("all");
|
||||
expect(argList[0].speed).toEqual(100);
|
||||
// expect(mockOk.mock.calls.length).toEqual(1);
|
||||
expect(mockOk.mock.calls.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue