Skip to content

Commit

Permalink
migrate controls UI
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielburnworth committed Jun 25, 2020
1 parent e1312c3 commit 1a64ffc
Show file tree
Hide file tree
Showing 42 changed files with 510 additions and 575 deletions.
2 changes: 1 addition & 1 deletion config/routes.rb
Expand Up @@ -109,7 +109,7 @@
get "/logout" => "dashboard#logout", as: :logout

get "/app" => "dashboard#main_app", as: :dashboard
get "/app/controls" => "dashboard#main_app", as: :app_landing_page
get "/app/designer/controls" => "dashboard#main_app", as: :app_landing_page
get "/app/messages" => "dashboard#main_app", as: :app_message_center
match "/app/*path", to: "dashboard#main_app", via: :all, constraints: { format: "html" }

Expand Down
39 changes: 13 additions & 26 deletions frontend/__tests__/app_test.tsx
@@ -1,7 +1,7 @@
let mockPath = "";
jest.mock("../history", () => ({
getPathArray: jest.fn(() => mockPath.split("/")),
history: { getCurrentLocation: () => ({ pathname: mockPath }) }
let mockShowPopUp = false;
jest.mock("../controls_popup", () => ({
ControlsPopup: () => <div className="controls-popup" />,
showControlsPopup: () => mockShowPopUp,
}));

import * as React from "react";
Expand Down Expand Up @@ -47,28 +47,16 @@ const fakeProps = (): AppProps => ({
});

describe("<App />: Controls Pop-Up", () => {
it.each<["renders" | "doesn't render", string]>([
["renders", "designer"],
["renders", "designer/plants"],
["doesn't render", "controls"],
["renders", "device"],
["renders", "sequences"],
["renders", "sequences/for_regimens"],
["doesn't render", "regimens"],
["renders", "tools"],
["renders", "farmware"],
["renders", "messages"],
["renders", "logs"],
["renders", "help"],
["doesn't render", "account"],
])("%s controls pop-up on %s page", (expected, page) => {
mockPath = "/app/" + page;
it("renders controls pop-up", () => {
mockShowPopUp = true;
const wrapper = mount(<App {...fakeProps()} />);
if (expected == "renders") {
expect(wrapper.html()).toContain("controls-popup");
} else {
expect(wrapper.html()).not.toContain("controls-popup");
}
expect(wrapper.html()).toContain("controls-popup");
});

it("doesn't render controls pop-up", () => {
mockShowPopUp = false;
const wrapper = mount(<App {...fakeProps()} />);
expect(wrapper.html()).not.toContain("controls-popup");
});
});

Expand Down Expand Up @@ -123,7 +111,6 @@ describe("<App />: NavBar", () => {
const t = wrapper.text();
const strings = [
"Farm Designer",
"Controls",
"Sequences",
"Regimens",
];
Expand Down
30 changes: 29 additions & 1 deletion frontend/__tests__/controls_popup_test.tsx
@@ -1,11 +1,17 @@
let mockPath = "";
jest.mock("../history", () => ({
getPathArray: jest.fn(() => mockPath.split("/")),
history: { getCurrentLocation: () => ({ pathname: mockPath }) }
}));

const mockDevice = {
moveRelative: jest.fn(() => Promise.resolve()),
takePhoto: jest.fn(() => Promise.resolve()),
};
jest.mock("../device", () => ({ getDevice: () => mockDevice }));

import * as React from "react";
import { ControlsPopup } from "../controls_popup";
import { ControlsPopup, showControlsPopup } from "../controls_popup";
import { mount } from "enzyme";
import { bot } from "../__test_support__/fake_state/bot";
import { ControlsPopupProps } from "../controls/move/interfaces";
Expand Down Expand Up @@ -101,3 +107,25 @@ describe("<ControlsPopup />", () => {
expect(mockDevice.takePhoto).not.toHaveBeenCalled();
});
});

describe("showControlsPopup()", () => {
it.each<["shows" | "doesn't show", string]>([
["shows", "designer"],
["shows", "designer/plants"],
["doesn't show", "designer/controls"],
["shows", "device"],
["shows", "sequences"],
["shows", "sequences/for_regimens"],
["doesn't show", "regimens"],
["shows", "tools"],
["shows", "farmware"],
["shows", "messages"],
["shows", "logs"],
["shows", "help"],
["shows", ""],
["doesn't show", "account"],
])("%s controls pop-up on %s page", (expected, page) => {
mockPath = "/app/" + page;
expect(showControlsPopup()).toEqual(expected == "shows");
});
});
2 changes: 1 addition & 1 deletion frontend/account/labs/labs_features_list_data.ts
Expand Up @@ -46,7 +46,7 @@ export const fetchLabFeatures =
value: false
},
{
name: t("Hide Sensors widget"),
name: t("Hide Sensors panel"),
description: t(Content.HIDE_SENSORS_WIDGET),
storageKey: BooleanSetting.hide_sensors,
value: false
Expand Down
6 changes: 2 additions & 4 deletions frontend/app.tsx
Expand Up @@ -14,11 +14,10 @@ import {
getDeviceAccountSettings,
} from "./resources/selectors";
import { HotKeys } from "./hotkeys";
import { ControlsPopup } from "./controls_popup";
import { ControlsPopup, showControlsPopup } from "./controls_popup";
import { Content } from "./constants";
import { validBotLocationData, validFwConfig, validFbosConfig } from "./util";
import { BooleanSetting } from "./session_keys";
import { getPathArray } from "./history";
import {
getWebAppConfigValue, GetWebAppConfigValue,
} from "./config_storage/actions";
Expand Down Expand Up @@ -132,7 +131,6 @@ export class RawApp extends React.Component<AppProps, {}> {

render() {
const syncLoaded = this.isLoaded;
const currentPage = getPathArray()[2];
const { location_data, mcu_params } = this.props.bot.hardware;
return <div className="app">
{!syncLoaded && <LoadingPlant animate={this.props.animate} />}
Expand All @@ -153,7 +151,7 @@ export class RawApp extends React.Component<AppProps, {}> {
apiFirmwareValue={this.props.apiFirmwareValue}
pings={this.props.pings} />}
{syncLoaded && this.props.children}
{!(["controls", "account", "regimens"].includes(currentPage)) &&
{showControlsPopup() &&
<ControlsPopup
dispatch={this.props.dispatch}
axisInversion={this.props.axisInversion}
Expand Down
Expand Up @@ -13,7 +13,9 @@ import {
handleCreateOrUpdate,
} from "../auto_sync";
import { destroyOK } from "../../resources/actions";
import { SkipMqttData, BadMqttData, UpdateMqttData, DeleteMqttData } from "../interfaces";
import {
SkipMqttData, BadMqttData, UpdateMqttData, DeleteMqttData,
} from "../interfaces";
import { unpackUUID } from "../../util";
import { TaggedSequence } from "farmbot";

Expand Down
10 changes: 5 additions & 5 deletions frontend/constants.ts
Expand Up @@ -534,11 +534,11 @@ export namespace Content {

export const HIDE_WEBCAM_WIDGET =
trim(`If not using a webcam, use this setting to remove the
widget from the Controls page.`);
widget from the Controls panel.`);

export const HIDE_SENSORS_WIDGET =
trim(`If not using sensors, use this setting to remove the
widget from the Controls page.`);
panel from the Farm Designer.`);

export const BROWSER_SPEAK_LOGS =
trim(`Have the browser also read aloud log messages on the
Expand Down Expand Up @@ -681,8 +681,8 @@ export namespace Content {
will clear data for the current trail.`);

export const MAP_MISSED_STEPS =
trim(`Display missed step indicators in map. Requires stall detection
to be enabled.`);
trim(`Display high motor load warning indicators in map.
Requires VIRTUAL FARMBOT TRAIL and stall detection to be enabled.`);

export const DYNAMIC_MAP_SIZE =
trim(`Change the garden map size based on axis length.
Expand Down Expand Up @@ -983,7 +983,6 @@ export enum DeviceSetting {
name = `name`,
timezone = `timezone`,
camera = `camera`,
firmware = `Firmware`,
osUpdateTime = `update time`,
osAutoUpdate = `auto update`,
farmbotOS = `Farmbot OS`,
Expand All @@ -992,6 +991,7 @@ export enum DeviceSetting {

// Firmware
firmwareSection = `Firmware`,
firmware = `Firmware`,
restartFirmware = `Restart Firmware`,
flashFirmware = `Flash firmware`,

Expand Down
95 changes: 8 additions & 87 deletions frontend/controls/__tests__/controls_test.tsx
@@ -1,93 +1,14 @@
jest.mock("../../history", () => ({ push: jest.fn() }));

import * as React from "react";
import { mount } from "enzyme";
import { RawControls as Controls } from "../controls";
import { bot } from "../../__test_support__/fake_state/bot";
import {
fakePeripheral, fakeWebcamFeed, fakeSensor,
} from "../../__test_support__/fake_state/resources";
import { Dictionary } from "farmbot";
import { Props } from "../interfaces";
import { fakeTimeSettings } from "../../__test_support__/fake_time_settings";
import { Controls } from "../controls";
import { push } from "../../history";

describe("<Controls />", () => {
const mockConfig: Dictionary<boolean> = {};

const fakeProps = (): Props => ({
dispatch: jest.fn(),
bot: bot,
feeds: [fakeWebcamFeed()],
peripherals: [fakePeripheral()],
sensors: [fakeSensor()],
firmwareSettings: bot.hardware.mcu_params,
shouldDisplay: () => true,
getWebAppConfigVal: jest.fn(key => mockConfig[key]),
sensorReadings: [],
timeSettings: fakeTimeSettings(),
env: {},
firmwareHardware: undefined,
});

it("shows webcam widget", () => {
mockConfig.hide_webcam_widget = false;
const wrapper = mount(<Controls {...fakeProps()} />);
const txt = wrapper.text().toLowerCase();
["webcam", "move", "peripherals", "sensors"]
.map(string => expect(txt).toContain(string));
});

it("hides webcam widget", () => {
mockConfig.hide_webcam_widget = true;
const wrapper = mount(<Controls {...fakeProps()} />);
const txt = wrapper.text().toLowerCase();
["move", "peripherals", "sensors"]
.map(string => expect(txt).toContain(string));
expect(txt).not.toContain("webcam");
});

it("shows sensors widget", () => {
mockConfig.hide_webcam_widget = false;
mockConfig.hide_sensors = false;
const wrapper = mount(<Controls {...fakeProps()} />);
const txt = wrapper.text().toLowerCase();
["webcam", "move", "peripherals", "sensors"]
.map(string => expect(txt).toContain(string));
});

it("hides sensors widget", () => {
mockConfig.hide_webcam_widget = true;
mockConfig.hide_sensors = true;
const wrapper = mount(<Controls {...fakeProps()} />);
const txt = wrapper.text().toLowerCase();
["move", "peripherals"]
.map(string => expect(txt).toContain(string));
["webcam", "sensors"]
.map(string => expect(txt).not.toContain(string));
});

it("hides sensors widget based on model", () => {
mockConfig.hide_sensors = false;
const p = fakeProps();
p.firmwareHardware = "express_k10";
const wrapper = mount(<Controls {...p} />);
const txt = wrapper.text().toLowerCase();
["move", "peripherals"]
.map(string => expect(txt).toContain(string));
["sensors"].map(string => expect(txt).not.toContain(string));
});

it("doesn't show sensor readings widget", () => {
const p = fakeProps();
mockConfig.hide_sensors = true;
const wrapper = mount(<Controls {...p} />);
const txt = wrapper.text().toLowerCase();
expect(txt).not.toContain("sensor history");
});

it("shows sensor readings widget", () => {
const p = fakeProps();
mockConfig.hide_sensors = false;
const wrapper = mount(<Controls {...p} />);
const txt = wrapper.text().toLowerCase();
expect(txt).toContain("sensor history");
it("redirects", () => {
const wrapper = mount(<Controls />);
expect(wrapper.text().toLowerCase()).toContain("redirecting");
expect(push).toHaveBeenCalledWith("/app/designer/controls");
});
});
25 changes: 0 additions & 25 deletions frontend/controls/__tests__/state_to_props_test.ts

This file was deleted.

0 comments on commit 1a64ffc

Please sign in to comment.