From cb44640ca5e59de98daf5997c0308bd8a88c813b Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Wed, 17 Apr 2019 12:30:58 -0700 Subject: [PATCH] misc fixes --- frontend/__tests__/app_test.tsx | 24 +-------- frontend/app.tsx | 11 ++-- frontend/constants.ts | 3 +- .../__tests__/direction_axes_props_test.ts | 4 +- .../controls/move/direction_axes_props.ts | 3 +- frontend/css/_mobile.scss | 3 -- frontend/css/navbar.scss | 1 + .../encoders_and_endstops.tsx | 3 ++ frontend/help/__tests__/tour_test.tsx | 2 +- frontend/help/tour.tsx | 3 +- frontend/messages/__tests__/alerts_test.tsx | 1 + frontend/messages/__tests__/cards_test.tsx | 12 ++++- frontend/messages/__tests__/index_test.tsx | 1 + .../messages/__tests__/state_to_props_test.ts | 18 ++++++- frontend/messages/alerts.tsx | 3 +- frontend/messages/cards.tsx | 51 +++++++++++++------ frontend/messages/index.tsx | 3 +- frontend/messages/interfaces.ts | 14 +++++ frontend/messages/state_to_props.ts | 26 +++++++--- frontend/util/__tests__/page_test.ts | 7 --- frontend/util/__tests__/page_test.tsx | 25 +++++++++ frontend/util/page.ts | 3 +- 22 files changed, 143 insertions(+), 78 deletions(-) delete mode 100644 frontend/util/__tests__/page_test.ts create mode 100644 frontend/util/__tests__/page_test.tsx diff --git a/frontend/__tests__/app_test.tsx b/frontend/__tests__/app_test.tsx index 223a8acf0..016f51973 100644 --- a/frontend/__tests__/app_test.tsx +++ b/frontend/__tests__/app_test.tsx @@ -1,8 +1,3 @@ -let mockDev = false; -jest.mock("../account/dev/dev_support", () => ({ - DevSettings: { futureFeaturesEnabled: () => mockDev } -})); - jest.mock("react-redux", () => ({ connect: jest.fn() })); let mockPath = ""; @@ -16,7 +11,7 @@ import { App, AppProps, mapStateToProps } from "../app"; import { mount } from "enzyme"; import { bot } from "../__test_support__/fake_state/bot"; import { - fakeUser, fakeWebAppConfig, fakeEnigma + fakeUser, fakeWebAppConfig } from "../__test_support__/fake_state/resources"; import { fakeState } from "../__test_support__/fake_state"; import { @@ -147,21 +142,4 @@ describe("mapStateToProps()", () => { const result = mapStateToProps(state); expect(result.axisInversion.x).toEqual(true); }); - - it("doesn't show API alerts", () => { - const state = fakeState(); - state.resources = buildResourceIndex([fakeEnigma()]); - mockDev = false; - const props = mapStateToProps(state); - expect(props.alertCount).toEqual(0); - }); - - it("shows API alerts", () => { - const state = fakeState(); - const enigma = fakeEnigma(); - state.resources = buildResourceIndex([enigma]); - mockDev = true; - const props = mapStateToProps(state); - expect(props.alertCount).toEqual(1); - }); }); diff --git a/frontend/app.tsx b/frontend/app.tsx index 8e91bfaee..d331c7688 100644 --- a/frontend/app.tsx +++ b/frontend/app.tsx @@ -10,12 +10,11 @@ import { maybeFetchUser, maybeGetTimeSettings, getDeviceAccountSettings, - selectAllEnigmas, } from "./resources/selectors"; import { HotKeys } from "./hotkeys"; import { ControlsPopup } from "./controls_popup"; import { Content } from "./constants"; -import { validBotLocationData, validFwConfig, validFbosConfig, betterCompact } from "./util"; +import { validBotLocationData, validFwConfig, validFbosConfig } from "./util"; import { BooleanSetting } from "./session_keys"; import { getPathArray } from "./history"; import { @@ -29,7 +28,7 @@ import { t } from "./i18next_wrapper"; import { ResourceIndex } from "./resources/interfaces"; import { isBotOnline } from "./devices/must_be_online"; import { getStatus } from "./connectivity/reducer_support"; -import { DevSettings } from "./account/dev/dev_support"; +import { getAlerts } from "./messages/state_to_props"; /** For the logger module */ init(); @@ -56,10 +55,6 @@ export interface AppProps { export function mapStateToProps(props: Everything): AppProps { const webAppConfigValue = getWebAppConfigValue(() => props); const fbosConfig = validFbosConfig(getFbosConfig(props.resources.index)); - const botAlerts = betterCompact(Object.values(props.bot.hardware.enigmas || {})); - const apiAlerts = selectAllEnigmas(props.resources.index).map(x => x.body); - const alerts = - botAlerts.concat(DevSettings.futureFeaturesEnabled() ? apiAlerts : []); return { timeSettings: maybeGetTimeSettings(props.resources.index), dispatch: props.dispatch, @@ -80,7 +75,7 @@ export function mapStateToProps(props: Everything): AppProps { tour: props.resources.consumers.help.currentTour, resources: props.resources.index, autoSync: !!(fbosConfig && fbosConfig.auto_sync), - alertCount: alerts.length, + alertCount: getAlerts(props.resources.index, props.bot).length, }; } /** Time at which the app gives up and asks the user to refresh */ diff --git a/frontend/constants.ts b/frontend/constants.ts index b84668ffc..d570ab88a 100644 --- a/frontend/constants.ts +++ b/frontend/constants.ts @@ -422,8 +422,7 @@ export namespace Content { // App Settings export const CONFIRM_STEP_DELETION = - trim(`Show a confirmation dialog when the sequence delete step - icon is pressed.`); + trim(`Show a confirmation dialog when deleting a sequence step.`); export const HIDE_WEBCAM_WIDGET = trim(`If not using a webcam, use this setting to remove the diff --git a/frontend/controls/move/__tests__/direction_axes_props_test.ts b/frontend/controls/move/__tests__/direction_axes_props_test.ts index 6e2024582..9c0c60bf7 100644 --- a/frontend/controls/move/__tests__/direction_axes_props_test.ts +++ b/frontend/controls/move/__tests__/direction_axes_props_test.ts @@ -13,7 +13,7 @@ describe("calcMicrostepsPerMm()", () => { }); it("calculates value with microstepping", () => { - expect(calcMicrostepsPerMm(5, 4)).toEqual(20); + expect(calcMicrostepsPerMm(5, 4)).toEqual(5); }); }); @@ -30,7 +30,7 @@ describe("calculateAxialLengths()", () => { firmwareSettings.movement_step_per_mm_z = 25; firmwareSettings.movement_microsteps_z = 4; expect(calculateAxialLengths({ firmwareSettings })).toEqual({ - x: 0, y: 20, z: 1 + x: 0, y: 20, z: 4 }); }); }); diff --git a/frontend/controls/move/direction_axes_props.ts b/frontend/controls/move/direction_axes_props.ts index aa683d45e..d2a788b4e 100644 --- a/frontend/controls/move/direction_axes_props.ts +++ b/frontend/controls/move/direction_axes_props.ts @@ -4,7 +4,8 @@ import { McuParams } from "farmbot"; export const calcMicrostepsPerMm = ( steps_per_mm: number | undefined, microsteps_per_step: number | undefined) => - (steps_per_mm || 1) * (microsteps_per_step || 1); + // The firmware currently interprets steps_per_mm as microsteps_per_mm. + (steps_per_mm || 1) * (1 || microsteps_per_step || 1); const calcAxisLength = ( nr_steps: number | undefined, diff --git a/frontend/css/_mobile.scss b/frontend/css/_mobile.scss index becad7829..5ded2f101 100644 --- a/frontend/css/_mobile.scss +++ b/frontend/css/_mobile.scss @@ -26,9 +26,6 @@ 0% { transform: translateX(-11rem) } - 90% { - transform: translateX(1rem) - } 100% { transform: translateX(0) } diff --git a/frontend/css/navbar.scss b/frontend/css/navbar.scss index 07abc0413..e9cdf660e 100644 --- a/frontend/css/navbar.scss +++ b/frontend/css/navbar.scss @@ -100,6 +100,7 @@ nav { } div { display: inline; + vertical-align: middle; } } } diff --git a/frontend/devices/components/hardware_settings/encoders_and_endstops.tsx b/frontend/devices/components/hardware_settings/encoders_and_endstops.tsx index 65e2444eb..d20792295 100644 --- a/frontend/devices/components/hardware_settings/encoders_and_endstops.tsx +++ b/frontend/devices/components/hardware_settings/encoders_and_endstops.tsx @@ -76,6 +76,9 @@ export function EncodersAndEndStops(props: EncodersProps) { x={"encoder_scaling_x"} y={"encoder_scaling_y"} z={"encoder_scaling_z"} + xScale={sourceFwConfig("movement_microsteps_x").value} + yScale={sourceFwConfig("movement_microsteps_y").value} + zScale={sourceFwConfig("movement_microsteps_z").value} intSize={shouldDisplay(Feature.long_scaling_factor) ? "long" : "short"} gray={encodersDisabled} sourceFwConfig={sourceFwConfig} diff --git a/frontend/help/__tests__/tour_test.tsx b/frontend/help/__tests__/tour_test.tsx index adbba4c07..05988be11 100644 --- a/frontend/help/__tests__/tour_test.tsx +++ b/frontend/help/__tests__/tour_test.tsx @@ -37,7 +37,7 @@ describe("", () => { const wrapper = shallow(); wrapper.instance().callback(fakeCallbackData({ type: "tour:end" })); expect(wrapper.state()).toEqual({ run: false, index: 0 }); - expect(history.push).toHaveBeenCalledWith("/app/help"); + expect(history.push).toHaveBeenCalledWith("/app/messages"); }); it("navigates through tour: next", () => { diff --git a/frontend/help/tour.tsx b/frontend/help/tour.tsx index 09c2da694..c1bcd5f3e 100644 --- a/frontend/help/tour.tsx +++ b/frontend/help/tour.tsx @@ -1,5 +1,4 @@ import * as React from "react"; - import Joyride, { Step as TourStep, CallBackProps } from "react-joyride"; import { Color } from "../ui"; import { history } from "../history"; @@ -44,7 +43,7 @@ export class Tour extends React.Component { } if (type === "tour:end") { this.setState({ run: false }); - history.push("/app/help"); + history.push("/app/messages"); } }; diff --git a/frontend/messages/__tests__/alerts_test.tsx b/frontend/messages/__tests__/alerts_test.tsx index 759c960bf..86e503e37 100644 --- a/frontend/messages/__tests__/alerts_test.tsx +++ b/frontend/messages/__tests__/alerts_test.tsx @@ -39,6 +39,7 @@ describe("", () => { apiFirmwareValue: undefined, timeSettings: fakeTimeSettings(), dispatch: jest.fn(), + findApiAlertById: jest.fn(), }); it("renders no alerts", () => { diff --git a/frontend/messages/__tests__/cards_test.tsx b/frontend/messages/__tests__/cards_test.tsx index ac84e0866..ab3d6b48b 100644 --- a/frontend/messages/__tests__/cards_test.tsx +++ b/frontend/messages/__tests__/cards_test.tsx @@ -1,9 +1,12 @@ +jest.mock("../../api/crud", () => ({ destroy: jest.fn() })); + import * as React from "react"; import { mount } from "enzyme"; import { AlertCard } from "../cards"; import { AlertCardProps } from "../interfaces"; import { fakeTimeSettings } from "../../__test_support__/fake_time_settings"; import { FBSelect } from "../../ui"; +import { destroy } from "../../api/crud"; describe("", () => { const fakeProps = (): AlertCardProps => ({ @@ -19,8 +22,13 @@ describe("", () => { }); it("renders unknown card", () => { - const wrapper = mount(); + const p = fakeProps(); + p.alert.id = 1; + p.findApiAlertById = () => "uuid"; + const wrapper = mount(); expect(wrapper.text()).toContain("noun: verb (author)"); + wrapper.find(".fa-times").simulate("click"); + expect(destroy).toHaveBeenCalledWith("uuid"); }); it("renders firmware card", () => { @@ -28,6 +36,8 @@ describe("", () => { p.alert.problem_tag = "farmbot_os.firmware.missing"; const wrapper = mount(); expect(wrapper.text()).toContain("Firmware missing"); + wrapper.find(".fa-times").simulate("click"); + expect(destroy).not.toHaveBeenCalled(); }); it("renders seed data card", () => { diff --git a/frontend/messages/__tests__/index_test.tsx b/frontend/messages/__tests__/index_test.tsx index 9eab1b332..292e46d35 100644 --- a/frontend/messages/__tests__/index_test.tsx +++ b/frontend/messages/__tests__/index_test.tsx @@ -12,6 +12,7 @@ describe("", () => { apiFirmwareValue: undefined, timeSettings: fakeTimeSettings(), dispatch: Function, + findApiAlertById: jest.fn(), }); it("renders page", () => { diff --git a/frontend/messages/__tests__/state_to_props_test.ts b/frontend/messages/__tests__/state_to_props_test.ts index 22b4fdbfb..c1db91c07 100644 --- a/frontend/messages/__tests__/state_to_props_test.ts +++ b/frontend/messages/__tests__/state_to_props_test.ts @@ -6,7 +6,9 @@ jest.mock("../../account/dev/dev_support", () => ({ import { fakeState } from "../../__test_support__/fake_state"; import { mapStateToProps } from "../state_to_props"; import { buildResourceIndex } from "../../__test_support__/resource_index_builder"; -import { fakeEnigma, fakeFbosConfig } from "../../__test_support__/fake_state/resources"; +import { + fakeEnigma, fakeFbosConfig +} from "../../__test_support__/fake_state/resources"; describe("mapStateToProps()", () => { it("handles undefined", () => { @@ -18,7 +20,9 @@ describe("mapStateToProps()", () => { it("doesn't show API alerts", () => { const state = fakeState(); - state.resources = buildResourceIndex([fakeEnigma()]); + const enigma = fakeEnigma(); + enigma.body.problem_tag = "api.seed_data.missing"; + state.resources = buildResourceIndex([enigma]); mockDev = false; const props = mapStateToProps(state); expect(props.alerts).toEqual([]); @@ -27,6 +31,7 @@ describe("mapStateToProps()", () => { it("shows API alerts", () => { const state = fakeState(); const enigma = fakeEnigma(); + enigma.body.problem_tag = "api.seed_data.missing"; state.resources = buildResourceIndex([enigma]); mockDev = true; const props = mapStateToProps(state); @@ -42,4 +47,13 @@ describe("mapStateToProps()", () => { const props = mapStateToProps(state); expect(props.apiFirmwareValue).toEqual("arduino"); }); + + it("finds alert", () => { + const state = fakeState(); + const alert = fakeEnigma(); + alert.body.id = 1; + state.resources = buildResourceIndex([alert]); + const props = mapStateToProps(state); + expect(props.findApiAlertById(1)).toEqual(alert.uuid); + }); }); diff --git a/frontend/messages/alerts.tsx b/frontend/messages/alerts.tsx index b8273cab7..292e2dba2 100644 --- a/frontend/messages/alerts.tsx +++ b/frontend/messages/alerts.tsx @@ -37,6 +37,7 @@ export const Alerts = (props: AlertsProps) => alert={x} dispatch={props.dispatch} apiFirmwareValue={props.apiFirmwareValue} - timeSettings={props.timeSettings} />)} + timeSettings={props.timeSettings} + findApiAlertById={props.findApiAlertById} />)} ; diff --git a/frontend/messages/cards.tsx b/frontend/messages/cards.tsx index 051ba9351..736a6e58a 100644 --- a/frontend/messages/cards.tsx +++ b/frontend/messages/cards.tsx @@ -3,7 +3,8 @@ import { t } from "../i18next_wrapper"; import { AlertCardProps, AlertCardTemplateProps, FirmwareMissingProps, SeedDataMissingProps, SeedDataMissingState, TourNotTakenProps, - CommonAlertCardProps + CommonAlertCardProps, + DismissAlertProps } from "./interfaces"; import { formatLogTime } from "../logs"; import { @@ -13,20 +14,21 @@ import { DropDownItem, Row, Col, FBSelect, docLink } from "../ui"; import { Content } from "../constants"; import { TourList } from "../help/tour_list"; import { splitProblemTag } from "./alerts"; +import { destroy } from "../api/crud"; export const AlertCard = (props: AlertCardProps) => { - const { alert, timeSettings } = props; - const commonProps = { alert, timeSettings }; + const { alert, timeSettings, findApiAlertById, dispatch } = props; + const commonProps = { alert, timeSettings, findApiAlertById, dispatch }; switch (alert.problem_tag) { case "farmbot_os.firmware.missing": return ; case "api.seed_data.missing": return ; + dispatch={dispatch} />; case "api.tour.not_taken": return ; + dispatch={dispatch} />; case "api.user.not_welcomed": return ; case "api.documentation.unread": @@ -35,20 +37,27 @@ export const AlertCard = (props: AlertCardProps) => { return UnknownAlert(commonProps); } }; +const dismissAlert = (props: DismissAlertProps) => () => + (props.id && props.findApiAlertById && props.dispatch) + ? props.dispatch(destroy(props.findApiAlertById(props.id))) + : () => { }; -const AlertCardTemplate = (props: AlertCardTemplateProps) => -
+const AlertCardTemplate = (props: AlertCardTemplateProps) => { + const { alert, findApiAlertById, dispatch } = props; + return

{t(props.title)}

-

{formatLogTime(props.alert.created_at, props.timeSettings)}

- +

{formatLogTime(alert.created_at, props.timeSettings)}

+

{t(props.message)}

{props.children}
; +}; const UnknownAlert = (props: CommonAlertCardProps) => { const { problem_tag, created_at, priority } = props.alert; @@ -60,7 +69,9 @@ const UnknownAlert = (props: CommonAlertCardProps) => { title={`${t(noun)}: ${t(verb)} (${t(author)})`} message={t("Unknown problem of priority {{priority}} created at {{createdAt}}", { priority, createdAt })} - timeSettings={props.timeSettings} />; + timeSettings={props.timeSettings} + dispatch={props.dispatch} + findApiAlertById={props.findApiAlertById} />; }; const FirmwareMissing = (props: FirmwareMissingProps) => @@ -69,7 +80,9 @@ const FirmwareMissing = (props: FirmwareMissingProps) => className={"firmware-missing-alert"} title={t("Firmware missing")} message={t("Your device has no firmware installed.")} - timeSettings={props.timeSettings}> + timeSettings={props.timeSettings} + dispatch={props.dispatch} + findApiAlertById={props.findApiAlertById}> @@ -92,7 +105,9 @@ class SeedDataMissing className={"seed-data-missing-alert"} title={t("Choose your FarmBot")} message={t(Content.SEED_DATA_SELECTION)} - timeSettings={this.props.timeSettings}> + timeSettings={this.props.timeSettings} + dispatch={this.props.dispatch} + findApiAlertById={this.props.findApiAlertById}> @@ -115,7 +130,9 @@ const TourNotTaken = (props: TourNotTakenProps) => className={"tour-not-taken-alert"} title={t("Take a guided tour")} message={t(Content.TAKE_A_TOUR)} - timeSettings={props.timeSettings}> + timeSettings={props.timeSettings} + dispatch={props.dispatch} + findApiAlertById={props.findApiAlertById}>

{t("Choose a tour to begin")}:

; @@ -126,7 +143,9 @@ const UserNotWelcomed = (props: CommonAlertCardProps) => className={"user-not-welcomed-alert"} title={t("Welcome to the FarmBot Web App")} message={t(Content.WELCOME)} - timeSettings={props.timeSettings}> + timeSettings={props.timeSettings} + dispatch={props.dispatch} + findApiAlertById={props.findApiAlertById}>

{t("You're currently viewing the")} {t("Message Center")}.  {t(Content.MESSAGE_CENTER_WELCOME)} @@ -142,7 +161,9 @@ const DocumentationUnread = (props: CommonAlertCardProps) => className={"documentation-unread-alert"} title={t("Learn more about the app")} message={t(Content.READ_THE_DOCS)} - timeSettings={props.timeSettings}> + timeSettings={props.timeSettings} + dispatch={props.dispatch} + findApiAlertById={props.findApiAlertById}>

{t("Head over to")}   { + timeSettings={this.props.timeSettings} + findApiAlertById={this.props.findApiAlertById} />

diff --git a/frontend/messages/interfaces.ts b/frontend/messages/interfaces.ts index 12d71ce6e..124faeee9 100644 --- a/frontend/messages/interfaces.ts +++ b/frontend/messages/interfaces.ts @@ -1,12 +1,14 @@ import { FirmwareHardware, Enigma } from "farmbot"; import { TimeSettings } from "../interfaces"; import { BotState } from "../devices/interfaces"; +import { UUID } from "../resources/interfaces"; export interface MessagesProps { alerts: Alert[]; apiFirmwareValue: FirmwareHardware | undefined; timeSettings: TimeSettings; dispatch: Function; + findApiAlertById(id: number): UUID; } export interface AlertsProps { @@ -14,6 +16,7 @@ export interface AlertsProps { apiFirmwareValue: string | undefined; timeSettings: TimeSettings; dispatch: Function; + findApiAlertById(id: number): UUID; } export interface ProblemTag { @@ -36,11 +39,14 @@ export interface AlertCardProps { apiFirmwareValue: string | undefined; timeSettings: TimeSettings; dispatch: Function; + findApiAlertById?(id: number): UUID; } export interface CommonAlertCardProps { alert: Alert; timeSettings: TimeSettings; + findApiAlertById?(id: number): UUID; + dispatch?: Function; } export interface AlertCardTemplateProps { @@ -50,6 +56,14 @@ export interface AlertCardTemplateProps { message: string; timeSettings: TimeSettings; children?: React.ReactNode; + findApiAlertById?(id: number): UUID; + dispatch?: Function; +} + +export interface DismissAlertProps { + id?: number; + findApiAlertById?(id: number): UUID; + dispatch?: Function; } export interface FirmwareMissingProps extends CommonAlertCardProps { diff --git a/frontend/messages/state_to_props.ts b/frontend/messages/state_to_props.ts index 699002fff..bafe8bdb2 100644 --- a/frontend/messages/state_to_props.ts +++ b/frontend/messages/state_to_props.ts @@ -1,11 +1,15 @@ import { Everything } from "../interfaces"; -import { MessagesProps } from "./interfaces"; +import { MessagesProps, Alert } from "./interfaces"; import { validFbosConfig, betterCompact } from "../util"; import { getFbosConfig } from "../resources/getters"; import { sourceFbosConfigValue } from "../devices/components/source_config_value"; import { DevSettings } from "../account/dev/dev_support"; -import { selectAllEnigmas, maybeGetTimeSettings } from "../resources/selectors"; +import { + selectAllEnigmas, maybeGetTimeSettings, findResourceById +} from "../resources/selectors"; import { isFwHardwareValue } from "../devices/components/fbos_settings/board_type"; +import { ResourceIndex, UUID } from "../resources/interfaces"; +import { BotState } from "../devices/interfaces"; export const mapStateToProps = (props: Everything): MessagesProps => { const { hardware } = props.bot; @@ -13,15 +17,23 @@ export const mapStateToProps = (props: Everything): MessagesProps => { const sourceFbosConfig = sourceFbosConfigValue(fbosConfig, hardware.configuration); const apiFirmwareValue = sourceFbosConfig("firmware_hardware").value; - const botAlerts = betterCompact(Object.values(props.bot.hardware.enigmas || {})); - const apiAlerts = selectAllEnigmas(props.resources.index).map(x => x.body); - const alerts = - botAlerts.concat(DevSettings.futureFeaturesEnabled() ? apiAlerts : []); + const findApiAlertById = (id: number): UUID => + findResourceById(props.resources.index, "Enigma", id); return { - alerts, + alerts: getAlerts(props.resources.index, props.bot), apiFirmwareValue: isFwHardwareValue(apiFirmwareValue) ? apiFirmwareValue : undefined, timeSettings: maybeGetTimeSettings(props.resources.index), dispatch: props.dispatch, + findApiAlertById, }; }; + +export const getAlerts = + (resourceIndex: ResourceIndex, bot: BotState): Alert[] => { + const botAlerts = betterCompact(Object.values(bot.hardware.enigmas || {})); + const apiAlerts = selectAllEnigmas(resourceIndex).map(x => x.body) + .filter(x => DevSettings.futureFeaturesEnabled() || + x.problem_tag !== "api.seed_data.missing"); + return botAlerts.concat(apiAlerts); + }; diff --git a/frontend/util/__tests__/page_test.ts b/frontend/util/__tests__/page_test.ts deleted file mode 100644 index 5b7b1082e..000000000 --- a/frontend/util/__tests__/page_test.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { stopIE } from "../stop_ie"; - -describe("stopIE()", () => { - it("not IE", () => { - expect(stopIE).not.toThrow(); - }); -}); diff --git a/frontend/util/__tests__/page_test.tsx b/frontend/util/__tests__/page_test.tsx new file mode 100644 index 000000000..be8ba5133 --- /dev/null +++ b/frontend/util/__tests__/page_test.tsx @@ -0,0 +1,25 @@ +import { updatePageInfo, attachToRoot } from "../page"; +import React from "react"; + +describe("updatePageInfo()", () => { + it("sets page title", () => { + updatePageInfo("page name"); + expect(document.title).toEqual("Page name - FarmBot"); + }); + + it("sets page title: Farm Designer", () => { + updatePageInfo("designer"); + expect(document.title).toEqual("Farm designer - FarmBot"); + }); +}); + +describe("attachToRoot()", () => { + class Foo extends React.Component<{ text: string }> { + render() { return

{this.props.text}

; } + } + it("attaches page", () => { + attachToRoot(Foo, { text: "Bar" }); + expect(document.body.innerHTML).toEqual(`

Bar

`); + expect(document.body.textContent).toEqual("Bar"); + }); +}); diff --git a/frontend/util/page.ts b/frontend/util/page.ts index 56deaacf4..f7ac67d13 100644 --- a/frontend/util/page.ts +++ b/frontend/util/page.ts @@ -4,14 +4,13 @@ import { Attributes } from "react"; import { render } from "react-dom"; - import { capitalize } from "lodash"; import { t } from "../i18next_wrapper"; /** Dynamically change the meta title of the page. */ export function updatePageInfo(pageName: string) { if (pageName === "designer") { pageName = "Farm Designer"; } - document.title = t(capitalize(pageName)); + document.title = `${t(capitalize(pageName))} - FarmBot`; // Possibly add meta "content" here dynamically as well }