Stock tools button and bot position logs (#546)
* add button to add stock tools * show bot position in logs * controls page testpull/547/head
parent
44283e020c
commit
0a8dedcc66
|
@ -0,0 +1,55 @@
|
|||
jest.mock("react-redux", () => ({
|
||||
connect: jest.fn()
|
||||
}));
|
||||
|
||||
const mockStorj: Dictionary<boolean> = {};
|
||||
|
||||
jest.mock("../../session", () => {
|
||||
return {
|
||||
Session: {
|
||||
getBool: (k: string) => {
|
||||
mockStorj[k] = !!mockStorj[k];
|
||||
return mockStorj[k];
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
import * as React from "react";
|
||||
import { mount } from "enzyme";
|
||||
import { Controls } from "../controls";
|
||||
import { bot } from "../../__test_support__/fake_state/bot";
|
||||
import { fakePeripheral, fakeWebcamFeed } from "../../__test_support__/fake_state/resources";
|
||||
import { fakeState } from "../../__test_support__/fake_state";
|
||||
import { Dictionary } from "farmbot";
|
||||
import { BooleanSetting } from "../../session_keys";
|
||||
import { Props } from "../interfaces";
|
||||
|
||||
describe("<Controls />", () => {
|
||||
function fakeProps(): Props {
|
||||
return {
|
||||
dispatch: jest.fn(),
|
||||
bot: bot,
|
||||
feeds: [fakeWebcamFeed()],
|
||||
user: undefined,
|
||||
peripherals: [fakePeripheral()],
|
||||
resources: fakeState().resources
|
||||
};
|
||||
}
|
||||
|
||||
it("shows webcam widget", () => {
|
||||
mockStorj[BooleanSetting.hideWebcamWidget] = false;
|
||||
const wrapper = mount(<Controls {...fakeProps() } />);
|
||||
const txt = wrapper.text().toLowerCase();
|
||||
["webcam", "move", "peripherals"]
|
||||
.map(string => expect(txt).toContain(string));
|
||||
});
|
||||
|
||||
it("hides webcam widget", () => {
|
||||
mockStorj[BooleanSetting.hideWebcamWidget] = true;
|
||||
const wrapper = mount(<Controls {...fakeProps() } />);
|
||||
const txt = wrapper.text().toLowerCase();
|
||||
["move", "peripherals"].map(string => expect(txt).toContain(string));
|
||||
expect(txt).not.toContain("webcam");
|
||||
});
|
||||
});
|
|
@ -56,24 +56,24 @@ export class Peripherals extends React.Component<PeripheralsProps, PeripheralSta
|
|||
}
|
||||
}
|
||||
|
||||
emptyPeripheral = (): TaggedPeripheral => {
|
||||
taggedPeripheral = (pin: number, label: string): TaggedPeripheral => {
|
||||
return {
|
||||
uuid: "WILL_BE_CHANGED_BY_REDUCER",
|
||||
specialStatus: SpecialStatus.SAVED,
|
||||
kind: "Peripheral",
|
||||
body: { pin: 0, label: "New Peripheral" }
|
||||
body: { pin, label }
|
||||
};
|
||||
}
|
||||
|
||||
emptyPeripheral = (): TaggedPeripheral => {
|
||||
return this.taggedPeripheral(0, "New Peripheral");
|
||||
}
|
||||
|
||||
farmduinoPeripherals = (dispatch: Function) => {
|
||||
function newPeripheral(pin: number, label: string) {
|
||||
dispatch(init({
|
||||
uuid: "WILL_BE_CHANGED_BY_REDUCER",
|
||||
specialStatus: SpecialStatus.SAVED,
|
||||
kind: "Peripheral",
|
||||
body: { pin, label }
|
||||
}));
|
||||
}
|
||||
const newPeripheral = (pin: number, label: string) => {
|
||||
dispatch(init(this.taggedPeripheral(pin, label)));
|
||||
};
|
||||
|
||||
newPeripheral(7, "Lighting");
|
||||
newPeripheral(8, "Water");
|
||||
newPeripheral(9, "Vacuum");
|
||||
|
|
|
@ -25,7 +25,12 @@ export interface SelectOptionsParams {
|
|||
export interface Log {
|
||||
id?: number | undefined;
|
||||
message: string;
|
||||
meta: { type: ALLOWED_MESSAGE_TYPES; };
|
||||
meta: {
|
||||
type: ALLOWED_MESSAGE_TYPES;
|
||||
x?: number;
|
||||
y?: number;
|
||||
z?: number;
|
||||
};
|
||||
channels: string[];
|
||||
created_at: number;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,17 @@ describe("<Logs />", () => {
|
|||
expect(filterBtn.text().toLowerCase()).toEqual("filters active");
|
||||
expect(filterBtn.hasClass("green")).toBeTruthy();
|
||||
});
|
||||
|
||||
it("shows position", () => {
|
||||
const logs = fakeLogs();
|
||||
logs[0].body.meta.x = 100;
|
||||
logs[1].body.meta.x = 0;
|
||||
logs[1].body.meta.y = 1;
|
||||
logs[1].body.meta.z = 2;
|
||||
const wrapper = mount(<Logs logs={logs} />);
|
||||
expect(wrapper.text()).toContain("Unknown");
|
||||
expect(wrapper.text()).toContain("0, 1, 2");
|
||||
});
|
||||
});
|
||||
|
||||
describe("<LogsFilterMenu />", () => {
|
||||
|
|
|
@ -19,7 +19,7 @@ const LogsTable = (props: LogsTableProps) => {
|
|||
<tr>
|
||||
<th><label>{t("Type")}</label></th>
|
||||
<th><label>{t("Message")}</label></th>
|
||||
{/* <th><label>{t("Position (x, y, z)")}</label></th> */}
|
||||
<th><label>{t("Position (x, y, z)")}</label></th>
|
||||
<th><label>{t("Time")}</label></th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
@ -38,6 +38,7 @@ const LogsRow = (tlog: TaggedLog, state: LogsState) => {
|
|||
const type = (log.meta || {}).type;
|
||||
const filtered = state[type as keyof LogsState];
|
||||
const displayLog = _.isUndefined(filtered) || filtered;
|
||||
const { x, y, z } = log.meta;
|
||||
return displayLog ?
|
||||
<tr key={tlog.uuid}>
|
||||
<td>
|
||||
|
@ -47,7 +48,13 @@ const LogsRow = (tlog: TaggedLog, state: LogsState) => {
|
|||
<td>
|
||||
{log.message || "Loading"}
|
||||
</td>
|
||||
{/* <td>0, 0, 0</td> // TODO: display log position data*/}
|
||||
<td>
|
||||
{
|
||||
(_.isNumber(x) && _.isNumber(y) && _.isNumber(z))
|
||||
? `${x}, ${y}, ${z}`
|
||||
: "Unknown"
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
{time}
|
||||
</td>
|
||||
|
|
|
@ -1,31 +1,30 @@
|
|||
import * as React from "react";
|
||||
import { ToolForm } from "../tool_form";
|
||||
import { render } from "enzyme";
|
||||
import { mapStateToProps } from "../../state_to_props";
|
||||
import { fakeState } from "../../../__test_support__/fake_state";
|
||||
import { mount } from "enzyme";
|
||||
import { fakeTool } from "../../../__test_support__/fake_state/resources";
|
||||
|
||||
describe("<ToolForm/>", () => {
|
||||
function bootstrapTest() {
|
||||
const state = fakeState();
|
||||
const toggle = jest.fn();
|
||||
const props = mapStateToProps(state);
|
||||
function fakeProps() {
|
||||
return {
|
||||
state,
|
||||
toggle,
|
||||
props,
|
||||
component: render(<ToolForm dispatch={state.dispatch}
|
||||
tools={props.tools}
|
||||
toggle={toggle} />)
|
||||
dispatch: jest.fn(),
|
||||
toggle: jest.fn(),
|
||||
tools: [fakeTool(), fakeTool()]
|
||||
};
|
||||
}
|
||||
|
||||
it("renders", () => {
|
||||
const test = bootstrapTest();
|
||||
// FAILED
|
||||
expect(test.component.find("input").length)
|
||||
.toEqual(test.props.tools.length);
|
||||
const p = fakeProps();
|
||||
const wrapper = mount(<ToolForm {...p} />);
|
||||
expect(wrapper.find("input").length).toEqual(p.tools.length);
|
||||
});
|
||||
|
||||
it("shows a DIRTY flag when any of the tools are dirty", () => {
|
||||
pending("Might not need this test- seems to be testing getArrayStatus()");
|
||||
it("adds stock tools", () => {
|
||||
const p = fakeProps();
|
||||
const wrapper = mount(<ToolForm {...p} />);
|
||||
const add = wrapper.find("button").at(3);
|
||||
expect(add.text()).toEqual("Stock Tools");
|
||||
add.simulate("click");
|
||||
expect(p.dispatch).toHaveBeenCalledTimes(6);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -15,15 +15,32 @@ import { edit, destroy, init, saveAll } from "../../api/crud";
|
|||
import { ToolTips } from "../../constants";
|
||||
|
||||
export class ToolForm extends React.Component<ToolFormProps, {}> {
|
||||
emptyTool = (): TaggedTool => {
|
||||
taggedTool = (name: string): TaggedTool => {
|
||||
return {
|
||||
uuid: "ERROR: GENERATED BY REDUCER - UUID SHOULD BE UNSEEN",
|
||||
specialStatus: SpecialStatus.SAVED,
|
||||
kind: "Tool",
|
||||
body: { name: "Tool " + (this.props.tools.length + 1) }
|
||||
body: { name }
|
||||
};
|
||||
}
|
||||
|
||||
emptyTool = (): TaggedTool => {
|
||||
return this.taggedTool("Tool " + (this.props.tools.length + 1));
|
||||
}
|
||||
|
||||
stockTools = (dispatch: Function) => {
|
||||
const newTool = (name: string) => {
|
||||
dispatch(init(this.taggedTool(name)));
|
||||
};
|
||||
|
||||
newTool("Seeder");
|
||||
newTool("Watering Nozzle");
|
||||
newTool("Weeder");
|
||||
newTool("Soil Sensor");
|
||||
newTool("Seed Bin");
|
||||
newTool("Seed Tray");
|
||||
}
|
||||
|
||||
render() {
|
||||
const toggle = () => this.props.toggle();
|
||||
const { dispatch, tools } = this.props;
|
||||
|
@ -46,6 +63,12 @@ export class ToolForm extends React.Component<ToolFormProps, {}> {
|
|||
onClick={() => { dispatch(init(this.emptyTool())); }}>
|
||||
<i className="fa fa-plus" />
|
||||
</button>
|
||||
<button
|
||||
className="fb-button green"
|
||||
onClick={() => { this.stockTools(dispatch); }}>
|
||||
<i className="fa fa-plus" style={{ marginRight: "0.5rem" }} />
|
||||
Stock Tools
|
||||
</button>
|
||||
</WidgetHeader>
|
||||
<WidgetBody>
|
||||
<Row>
|
||||
|
|
Loading…
Reference in New Issue