From d347413c0431c2616cfe52d67ca3439778c6dacf Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Mon, 3 Dec 2018 19:06:13 -0800 Subject: [PATCH] dev stuff --- ...38_add_show_dev_menu_to_web_app_configs.rb | 9 ++ webpack/account/__tests__/dev_widget_test.tsx | 49 +++++++++++ webpack/account/__tests__/index_test.tsx | 16 +++- webpack/account/dev_widget.tsx | 85 +++++++++++++++++++ webpack/account/index.tsx | 6 ++ .../move/__tests__/settings_menu_test.tsx | 3 +- webpack/controls/move/settings_menu.tsx | 3 +- .../__tests__/garden_map_legend_test.tsx | 3 +- .../map/legend/garden_map_legend.tsx | 5 +- webpack/farm_designer/plants/plant_panel.tsx | 3 +- .../saved_gardens/saved_gardens.tsx | 3 +- webpack/nav/additional_menu.tsx | 3 +- 12 files changed, 179 insertions(+), 9 deletions(-) create mode 100644 db/migrate/20181204005038_add_show_dev_menu_to_web_app_configs.rb create mode 100644 webpack/account/__tests__/dev_widget_test.tsx create mode 100644 webpack/account/dev_widget.tsx diff --git a/db/migrate/20181204005038_add_show_dev_menu_to_web_app_configs.rb b/db/migrate/20181204005038_add_show_dev_menu_to_web_app_configs.rb new file mode 100644 index 000000000..353e4edf2 --- /dev/null +++ b/db/migrate/20181204005038_add_show_dev_menu_to_web_app_configs.rb @@ -0,0 +1,9 @@ +class AddShowDevMenuToWebAppConfigs < ActiveRecord::Migration[5.2] + safety_assured + def change + add_column :web_app_configs, + :show_dev_menu, + :boolean, + default: false + end +end diff --git a/webpack/account/__tests__/dev_widget_test.tsx b/webpack/account/__tests__/dev_widget_test.tsx new file mode 100644 index 000000000..b83405209 --- /dev/null +++ b/webpack/account/__tests__/dev_widget_test.tsx @@ -0,0 +1,49 @@ +jest.mock("../../config_storage/actions", () => ({ + setWebAppConfigValue: jest.fn() +})); + +import * as React from "react"; +import { mount, shallow } from "enzyme"; +import { + DevWidget, FUTURE_FE_FEATURES, FBOS_VERSION_OVERRIDE, + DevWidgetFERow, DevWidgetFBOSRow +} from "../dev_widget"; +import { setWebAppConfigValue } from "../../config_storage/actions"; + +describe("", () => { + const fakeProps = () => ({ dispatch: jest.fn() }); + + it("renders", () => { + const wrapper = mount(); + localStorage[FUTURE_FE_FEATURES] = "true"; + localStorage[FBOS_VERSION_OVERRIDE] = "1.0.0"; + wrapper.find("button").first().simulate("click"); + expect(setWebAppConfigValue).toHaveBeenCalledWith("show_dev_menu", false); + expect(localStorage[FUTURE_FE_FEATURES]).toEqual(undefined); + expect(localStorage[FBOS_VERSION_OVERRIDE]).toEqual(undefined); + }); + + it("changes override value", () => { + const wrapper = shallow(); + wrapper.find("BlurableInput").simulate("commit", + { currentTarget: { value: "1.2.3" } }); + expect(localStorage[FBOS_VERSION_OVERRIDE]).toEqual("1.2.3"); + wrapper.find(".fa-times").simulate("click"); + expect(localStorage[FBOS_VERSION_OVERRIDE]).toEqual(undefined); + }); + + it("increases override value", () => { + const wrapper = mount(); + wrapper.find(".fa-angle-double-up").simulate("click"); + expect(localStorage[FBOS_VERSION_OVERRIDE]).toEqual("1000.0.0"); + wrapper.find(".fa-times").simulate("click"); + expect(localStorage[FBOS_VERSION_OVERRIDE]).toEqual(undefined); + }); + + it("toggles unstable FE features", () => { + localStorage[FUTURE_FE_FEATURES] = "true"; + const wrapper = mount(); + wrapper.find("button").simulate("click"); + expect(localStorage[FUTURE_FE_FEATURES]).toEqual(undefined); + }); +}); diff --git a/webpack/account/__tests__/index_test.tsx b/webpack/account/__tests__/index_test.tsx index c9443835a..46b1f2ee4 100644 --- a/webpack/account/__tests__/index_test.tsx +++ b/webpack/account/__tests__/index_test.tsx @@ -5,7 +5,7 @@ jest.mock("react-redux", () => ({ import * as React from "react"; import { fakeState } from "../../__test_support__/fake_state"; import { mapStateToProps } from "../state_to_props"; -import { shallow } from "enzyme"; +import { shallow, mount } from "enzyme"; import { Account } from "../index"; import { edit } from "../../api/crud"; @@ -41,4 +41,18 @@ describe("", () => { el.find("Settings").simulate("save"); expect(props.dispatch).toHaveBeenCalledTimes(1); }); + + it("doesn't show dev widget", () => { + const props = mapStateToProps(fakeState()); + props.getConfigValue = () => false; + const wrapper = mount(); + expect(wrapper.text()).not.toContain("Dev options"); + }); + + it("shows dev widget", () => { + const props = mapStateToProps(fakeState()); + props.getConfigValue = () => true; + const wrapper = mount(); + expect(wrapper.text()).toContain("Dev options"); + }); }); diff --git a/webpack/account/dev_widget.tsx b/webpack/account/dev_widget.tsx new file mode 100644 index 000000000..7bb202c01 --- /dev/null +++ b/webpack/account/dev_widget.tsx @@ -0,0 +1,85 @@ +import * as React from "react"; +import { + Widget, WidgetHeader, WidgetBody, Row, Col, BlurableInput +} from "../ui"; +import { ToggleButton } from "../controls/toggle_button"; +import { setWebAppConfigValue } from "../config_storage/actions"; +import { BooleanConfigKey } from "farmbot/dist/resources/configs/web_app"; + +export const FUTURE_FE_FEATURES = "FUTURE_FEATURES"; +/** Unstable FE features enabled? */ +export const futureFeaturesEnabled = () => + !!localStorage.getItem(FUTURE_FE_FEATURES); +/** Show unstable FE features for development purposes. */ +export const enableFutureFeatures = () => + localStorage.setItem(FUTURE_FE_FEATURES, "true"); +const disableFutureFeatures = () => + localStorage.removeItem(FUTURE_FE_FEATURES); + +export const FBOS_VERSION_OVERRIDE = "IM_A_DEVELOPER"; +/** Escape hatch for platform developers doing offline development. */ +const overriddenFbosVersion = () => + localStorage.getItem(FBOS_VERSION_OVERRIDE); +const resetFbosVersionOverride = () => + localStorage.removeItem(FBOS_VERSION_OVERRIDE); +const setFbosVersionOverride = (override: string) => + localStorage.setItem(FBOS_VERSION_OVERRIDE, override); + +export const DevWidgetFERow = () => + + + + + + + + ; + +export const DevWidgetFBOSRow = () => { + return + + + + + + + + + + + ; diff --git a/webpack/account/index.tsx b/webpack/account/index.tsx index 9647fcc8b..ed4366dd0 100644 --- a/webpack/account/index.tsx +++ b/webpack/account/index.tsx @@ -13,6 +13,8 @@ import { success } from "farmbot-toastr/dist"; import { LabsFeatures } from "./labs/labs_features"; import { ExportAccountPanel } from "./components/export_account_panel"; import { requestAccountExport } from "./request_account_export"; +import { DevWidget } from "./dev_widget"; +import { BooleanConfigKey } from "farmbot/dist/resources/configs/web_app"; const KEYS: (keyof User)[] = ["id", "name", "email", "created_at", "updated_at"]; @@ -89,6 +91,10 @@ export class Account extends React.Component { + + {this.props.getConfigValue("show_dev_menu" as BooleanConfigKey) && + } + ; } diff --git a/webpack/controls/move/__tests__/settings_menu_test.tsx b/webpack/controls/move/__tests__/settings_menu_test.tsx index de106752f..3dfd68924 100644 --- a/webpack/controls/move/__tests__/settings_menu_test.tsx +++ b/webpack/controls/move/__tests__/settings_menu_test.tsx @@ -2,6 +2,7 @@ import * as React from "react"; import { mount } from "enzyme"; import { BooleanSetting } from "../../../session_keys"; import { moveWidgetSetting, MoveWidgetSettingsMenu } from "../settings_menu"; +import { enableFutureFeatures } from "../../../account/dev_widget"; describe("moveWidgetSetting()", () => { it("renders setting", () => { @@ -23,7 +24,7 @@ describe("", () => { it("displays motor plot toggle", () => { const noToggle = mount(); expect(noToggle.text()).not.toContain("Motor position plot"); - localStorage.setItem("FUTURE_FEATURES", "true"); + enableFutureFeatures(); const wrapper = mount(); expect(wrapper.text()).toContain("Motor position plot"); }); diff --git a/webpack/controls/move/settings_menu.tsx b/webpack/controls/move/settings_menu.tsx index fb2619b01..4ac36788a 100644 --- a/webpack/controls/move/settings_menu.tsx +++ b/webpack/controls/move/settings_menu.tsx @@ -4,6 +4,7 @@ import { BooleanSetting } from "../../session_keys"; import { ToggleButton } from "../toggle_button"; import { ToggleWebAppBool, GetWebAppBool } from "./interfaces"; import { BooleanConfigKey } from "farmbot/dist/resources/configs/web_app"; +import { futureFeaturesEnabled } from "../../account/dev_widget"; export const moveWidgetSetting = (toggle: ToggleWebAppBool, getValue: GetWebAppBool) => ({ label, setting }: { label: string, setting: BooleanConfigKey }) => @@ -43,7 +44,7 @@ export const MoveWidgetSettingsMenu = ({ toggle, getValue }: { label={t("perform homing (find home)")} setting={BooleanSetting.home_button_homing} /> - {localStorage.getItem("FUTURE_FEATURES") && + {futureFeaturesEnabled() &&

{t("Motor position plot")}

", () => { const fakeProps = (): GardenMapLegendProps => ({ @@ -47,7 +48,7 @@ describe("", () => { }); it("shows submenu", () => { - localStorage.setItem("FUTURE_FEATURES", "true"); + enableFutureFeatures(); const wrapper = mount(); expect(wrapper.html()).toContain("filter"); expect(wrapper.html()).toContain("extras"); diff --git a/webpack/farm_designer/map/legend/garden_map_legend.tsx b/webpack/farm_designer/map/legend/garden_map_legend.tsx index 2746f246a..9a8cbf113 100644 --- a/webpack/farm_designer/map/legend/garden_map_legend.tsx +++ b/webpack/farm_designer/map/legend/garden_map_legend.tsx @@ -11,6 +11,7 @@ import { MoveModeLink } from "../../plants/move_to"; import { SavedGardensLink } from "../../saved_gardens/saved_gardens"; import { GetWebAppConfigValue } from "../../../config_storage/actions"; import { BooleanSetting } from "../../../session_keys"; +import { futureFeaturesEnabled } from "../../../account/dev_widget"; const OriginSelector = ({ quadrant, update }: { quadrant: BotOriginQuadrant, @@ -78,7 +79,7 @@ const LayerToggles = (props: GardenMapLegendProps) => { label={t("Points?")} onClick={toggle("show_points")} submenuTitle={t("extras")} - popover={!!localStorage.getItem("FUTURE_FEATURES") + popover={futureFeaturesEnabled() ? : undefined} /> { dispatch={props.dispatch} getConfigValue={getConfigValue} imageAgeInfo={props.imageAgeInfo} />} /> - {localStorage.getItem("FUTURE_FEATURES") && + {futureFeaturesEnabled() && ; diff --git a/webpack/nav/additional_menu.tsx b/webpack/nav/additional_menu.tsx index 7dbb1ee0b..8f71e4296 100644 --- a/webpack/nav/additional_menu.tsx +++ b/webpack/nav/additional_menu.tsx @@ -4,6 +4,7 @@ import { AccountMenuProps } from "./interfaces"; import { docLink } from "../ui/doc_link"; import { Link } from "../link"; import { shortRevision } from "../util"; +import { futureFeaturesEnabled } from "../account/dev_widget"; export const AdditionalMenu = (props: AccountMenuProps) => { return
@@ -13,7 +14,7 @@ export const AdditionalMenu = (props: AccountMenuProps) => { {t("Account Settings")}
- {localStorage.getItem("FUTURE_FEATURES") && + {futureFeaturesEnabled() && {t("Help")}