From dc50bff7b74687207bf5564f4e62cda6a4b7a330 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 15 Jun 2018 16:59:32 -0700 Subject: [PATCH 1/4] test fixes and button click helper --- webpack/__test_support__/helpers.ts | 29 +++++++++++- .../__tests__/axis_input_box_group_test.tsx | 5 +- webpack/controls/__tests__/move_test.tsx | 5 +- .../peripherals/__tests__/index_test.tsx | 44 ++++++++--------- .../controls/sensors/__tests__/index_test.tsx | 30 +++++------- .../controls/webcam/__tests__/edit_test.tsx | 47 +++++++++++++------ .../controls/webcam/__tests__/index_test.tsx | 24 +++++++--- .../__tests__/hardware_settings_test.tsx | 7 +-- .../plants/__tests__/create_points_test.tsx | 5 +- .../plants/__tests__/plant_panel_test.tsx | 13 ++--- .../plants/__tests__/select_plants_test.tsx | 11 ++--- .../__tests__/farmware_forms_test.tsx | 5 +- .../farmware/images/__tests__/photos_test.tsx | 5 +- .../components/__tests__/filter_menu_test.tsx | 9 ++-- .../regimens/editor/__tests__/index_test.tsx | 16 +++---- .../sequence_editor_middle_active_test.tsx | 17 +++---- .../components/__tests__/tool_form_test.tsx | 5 +- 17 files changed, 150 insertions(+), 127 deletions(-) diff --git a/webpack/__test_support__/helpers.ts b/webpack/__test_support__/helpers.ts index 8dab8e988..daae99546 100644 --- a/webpack/__test_support__/helpers.ts +++ b/webpack/__test_support__/helpers.ts @@ -1,6 +1,33 @@ -import { ReactWrapper } from "enzyme"; +import { ReactWrapper, ShallowWrapper } from "enzyme"; +import { range } from "lodash"; // tslint:disable-next-line:no-any export function getProp(i: ReactWrapper, key: string): any { return i.props()[key]; } + +/** Simulate a click and check button text for a button in a wrapper. */ +export function clickButton( + wrapper: ReactWrapper | ShallowWrapper, + position: number, + text: string, + options?: { partial_match?: boolean, button_tag?: string }) { + const btnTag = options && options.button_tag ? options.button_tag : "button"; + const button = wrapper.find(btnTag).at(position); + const expectedText = text.toLowerCase(); + const actualText = button.text().toLowerCase(); + options && options.partial_match + ? expect(actualText).toContain(expectedText) + : expect(actualText).toEqual(expectedText); + button.simulate("click"); +} + +/** Like `wrapper.text()`, but only includes buttons. */ +export function allButtonText(wrapper: ReactWrapper | ShallowWrapper): string { + const buttons = wrapper.find("button"); + const btnCount = buttons.length; + const btnPositions = range(btnCount); + const btnTextArray = btnPositions.map(position => + wrapper.find("button").at(position).text()); + return btnTextArray.join(""); +} diff --git a/webpack/controls/__tests__/axis_input_box_group_test.tsx b/webpack/controls/__tests__/axis_input_box_group_test.tsx index 370389376..14d7a64b8 100644 --- a/webpack/controls/__tests__/axis_input_box_group_test.tsx +++ b/webpack/controls/__tests__/axis_input_box_group_test.tsx @@ -3,6 +3,7 @@ import { mount } from "enzyme"; import { AxisInputBoxGroup } from "../axis_input_box_group"; import { BotPosition } from "../../devices/interfaces"; import { AxisInputBoxGroupProps } from "../interfaces"; +import { clickButton } from "../../__test_support__/helpers"; describe("", () => { beforeEach(function () { @@ -45,9 +46,7 @@ describe("", () => { props.position = coordinates.position; const wrapper = mount(); wrapper.setState(coordinates.inputs); - const buttons = wrapper.find("button"); - expect(buttons.text().toLowerCase()).toEqual("go"); - buttons.simulate("click"); + clickButton(wrapper, 0, "go"); expect(props.onCommit).toHaveBeenCalledWith(coordinates.expected); }); } diff --git a/webpack/controls/__tests__/move_test.tsx b/webpack/controls/__tests__/move_test.tsx index 30ea89adf..b1c27e1cb 100644 --- a/webpack/controls/__tests__/move_test.tsx +++ b/webpack/controls/__tests__/move_test.tsx @@ -21,6 +21,7 @@ import { toggleWebAppBool } from "../../config_storage/actions"; import { Dictionary } from "farmbot"; import { BooleanSetting } from "../../session_keys"; import { Actions } from "../../constants"; +import { clickButton } from "../../__test_support__/helpers"; describe("", () => { beforeEach(function () { @@ -78,9 +79,7 @@ describe("", () => { it("changes step size", () => { const p = fakeProps(); const wrapper = mount(); - const btn = wrapper.find("button").first(); - expect(btn.text()).toEqual("1"); - btn.simulate("click"); + clickButton(wrapper, 0, "1"); expect(p.dispatch).toHaveBeenCalledWith({ type: Actions.CHANGE_STEP_SIZE, payload: 1 diff --git a/webpack/controls/peripherals/__tests__/index_test.tsx b/webpack/controls/peripherals/__tests__/index_test.tsx index 21ddad842..fefcf7bc1 100644 --- a/webpack/controls/peripherals/__tests__/index_test.tsx +++ b/webpack/controls/peripherals/__tests__/index_test.tsx @@ -1,6 +1,5 @@ -const mockError = jest.fn(); jest.mock("farmbot-toastr", () => ({ - error: mockError + error: jest.fn() })); import * as React from "react"; @@ -9,6 +8,9 @@ import { Peripherals } from "../index"; import { bot } from "../../../__test_support__/fake_state/bot"; import { PeripheralsProps } from "../../../devices/interfaces"; import { fakePeripheral } from "../../../__test_support__/fake_state/resources"; +import { clickButton } from "../../../__test_support__/helpers"; +import { SpecialStatus } from "../../../resources/tagged_resources"; +import { error } from "farmbot-toastr"; describe("", () => { beforeEach(function () { @@ -25,7 +27,7 @@ describe("", () => { } it("renders", () => { - const wrapper = mount(); + const wrapper = mount(); ["Peripherals", "Edit", "Save", "Fake Pin", "1"].map(string => expect(wrapper.text()).toContain(string)); const saveButton = wrapper.find("button").at(1); @@ -34,22 +36,19 @@ describe("", () => { }); it("isEditing", () => { - const wrapper = mount(); + const wrapper = mount(); expect(wrapper.state().isEditing).toBeFalsy(); - const edit = wrapper.find("button").at(0); - expect(edit.text()).toEqual("Edit"); - edit.simulate("click"); + clickButton(wrapper, 0, "edit"); expect(wrapper.state().isEditing).toBeTruthy(); }); - function attemptSave(num: number, error: string) { + function attemptSave(num: number, errorString: string) { const p = fakeProps(); p.peripherals[0].body.pin = num; - const wrapper = mount(); - const save = wrapper.find("button").at(1); - expect(save.text()).toContain("Save"); - save.simulate("click"); - expect(mockError).toHaveBeenLastCalledWith(error); + p.peripherals[0].specialStatus = SpecialStatus.DIRTY; + const wrapper = mount(); + clickButton(wrapper, 1, "save", { partial_match: true }); + expect(error).toHaveBeenLastCalledWith(errorString); } it("save attempt: pin number too small", () => { @@ -63,30 +62,25 @@ describe("", () => { it("saves", () => { const p = fakeProps(); p.peripherals[0].body.pin = 1; - const wrapper = mount(); - const save = wrapper.find("button").at(1); - expect(save.text()).toContain("Save"); - save.simulate("click"); + p.peripherals[0].specialStatus = SpecialStatus.DIRTY; + const wrapper = mount(); + clickButton(wrapper, 1, "save", { partial_match: true }); expect(p.dispatch).toHaveBeenCalled(); }); it("adds empty peripheral", () => { const p = fakeProps(); - const wrapper = mount(); + const wrapper = mount(); wrapper.setState({ isEditing: true }); - const add = wrapper.find("button").at(2); - expect(add.text()).toEqual(""); - add.simulate("click"); + clickButton(wrapper, 2, ""); expect(p.dispatch).toHaveBeenCalled(); }); it("adds farmduino peripherals", () => { const p = fakeProps(); - const wrapper = mount(); + const wrapper = mount(); wrapper.setState({ isEditing: true }); - const add = wrapper.find("button").at(3); - expect(add.text()).toEqual("Farmduino"); - add.simulate("click"); + clickButton(wrapper, 3, "farmduino"); expect(p.dispatch).toHaveBeenCalledTimes(5); }); }); diff --git a/webpack/controls/sensors/__tests__/index_test.tsx b/webpack/controls/sensors/__tests__/index_test.tsx index 22cd42836..410dca69e 100644 --- a/webpack/controls/sensors/__tests__/index_test.tsx +++ b/webpack/controls/sensors/__tests__/index_test.tsx @@ -1,6 +1,5 @@ -const mockError = jest.fn(); jest.mock("farmbot-toastr", () => ({ - error: mockError + error: jest.fn() })); import * as React from "react"; @@ -9,6 +8,9 @@ import { Sensors } from "../index"; import { bot } from "../../../__test_support__/fake_state/bot"; import { SensorsProps } from "../../../devices/interfaces"; import { fakeSensor } from "../../../__test_support__/fake_state/resources"; +import { error } from "farmbot-toastr"; +import { clickButton } from "../../../__test_support__/helpers"; +import { SpecialStatus } from "../../../resources/tagged_resources"; describe("", () => { beforeEach(function () { @@ -40,9 +42,7 @@ describe("", () => { it("isEditing", () => { const wrapper = mount(); expect(wrapper.state().isEditing).toBeFalsy(); - const edit = wrapper.find("button").at(0); - expect(edit.text()).toEqual("Edit"); - edit.simulate("click"); + clickButton(wrapper, 0, "edit"); expect(wrapper.state().isEditing).toBeTruthy(); }); @@ -50,20 +50,18 @@ describe("", () => { const p = fakeProps(); p.sensors[0].body.pin = 1; p.sensors[1].body.pin = 1; + p.sensors[0].specialStatus = SpecialStatus.DIRTY; const wrapper = mount(); - const save = wrapper.find("button").at(1); - expect(save.text()).toContain("Save"); - save.simulate("click"); - expect(mockError).toHaveBeenLastCalledWith("Pin numbers must be unique."); + clickButton(wrapper, 1, "save", { partial_match: true }); + expect(error).toHaveBeenLastCalledWith("Pin numbers must be unique."); }); it("saves", () => { const p = fakeProps(); p.sensors[0].body.pin = 1; + p.sensors[0].specialStatus = SpecialStatus.DIRTY; const wrapper = mount(); - const save = wrapper.find("button").at(1); - expect(save.text()).toContain("Save"); - save.simulate("click"); + clickButton(wrapper, 1, "save", { partial_match: true }); expect(p.dispatch).toHaveBeenCalled(); }); @@ -71,9 +69,7 @@ describe("", () => { const p = fakeProps(); const wrapper = mount(); wrapper.setState({ isEditing: true }); - const add = wrapper.find("button").at(2); - expect(add.text()).toEqual(""); - add.simulate("click"); + clickButton(wrapper, 2, ""); expect(p.dispatch).toHaveBeenCalled(); }); @@ -81,9 +77,7 @@ describe("", () => { const p = fakeProps(); const wrapper = mount(); wrapper.setState({ isEditing: true }); - const add = wrapper.find("button").at(3); - expect(add.text()).toEqual("Stock sensors"); - add.simulate("click"); + clickButton(wrapper, 3, "stock sensors"); expect(p.dispatch).toHaveBeenCalledTimes(2); }); }); diff --git a/webpack/controls/webcam/__tests__/edit_test.tsx b/webpack/controls/webcam/__tests__/edit_test.tsx index e5aebf4d9..efce1113d 100644 --- a/webpack/controls/webcam/__tests__/edit_test.tsx +++ b/webpack/controls/webcam/__tests__/edit_test.tsx @@ -1,27 +1,44 @@ import * as React from "react"; import { fakeWebcamFeed } from "../../../__test_support__/fake_state/resources"; -import { shallow } from "enzyme"; +import { mount } from "enzyme"; import { props } from "../test_helpers"; import { Edit } from "../edit"; import { SpecialStatus } from "../../../resources/tagged_resources"; +import { clickButton } from "../../../__test_support__/helpers"; +import { WebcamPanelProps } from "../interfaces"; describe("", () => { - it("renders the list of feeds", () => { + const fakeProps = (): WebcamPanelProps => { const feed1 = fakeWebcamFeed(); const feed2 = fakeWebcamFeed(); feed1.specialStatus = SpecialStatus.DIRTY; - const p = props([feed1, feed2]); - const el = shallow(); - const inputs = el.html(); - expect(inputs).toContain(feed1.body.name); - expect(inputs).toContain(feed1.body.url); - expect(inputs).toContain(feed2.body.name); - expect(inputs).toContain(feed2.body.url); - expect(el.html()).toContain("Save*"); - el.find("button").at(1).simulate("click"); - expect(p.save).toHaveBeenCalledWith(feed1); - feed1.specialStatus = SpecialStatus.SAVED; - el.update(); - expect(el.text()).not.toContain("Save*"); + return props([feed1, feed2]); + }; + + it("renders the list of feeds", () => { + const p = fakeProps(); + const wrapper = mount(); + [ + p.feeds[0].body.name, + p.feeds[0].body.url, + p.feeds[1].body.name, + p.feeds[1].body.url + ].map(text => + expect(wrapper.html()).toContain(text)); + }); + + it("saves feeds", () => { + const p = fakeProps(); + const wrapper = mount(); + clickButton(wrapper, 1, "save*"); + expect(p.save).toHaveBeenCalledWith(p.feeds[0]); + }); + + it("shows feeds as saved", () => { + const p = fakeProps(); + p.feeds[0].specialStatus = SpecialStatus.SAVED; + p.feeds[1].specialStatus = SpecialStatus.SAVED; + const wrapper = mount(); + expect(wrapper.find("button").at(1).text()).toEqual("Save"); }); }); diff --git a/webpack/controls/webcam/__tests__/index_test.tsx b/webpack/controls/webcam/__tests__/index_test.tsx index cbd1285d6..315f2285b 100644 --- a/webpack/controls/webcam/__tests__/index_test.tsx +++ b/webpack/controls/webcam/__tests__/index_test.tsx @@ -8,15 +8,27 @@ import { WebcamPanel, preToggleCleanup } from "../index"; import { fakeWebcamFeed } from "../../../__test_support__/fake_state/resources"; import { destroy, save } from "../../../api/crud"; import { SpecialStatus } from "../../../resources/tagged_resources"; +import { clickButton, allButtonText } from "../../../__test_support__/helpers"; describe("", () => { - it("toggles form states", () => { + it("toggles form state to edit", () => { const props = { feeds: [], dispatch: jest.fn() }; - const el = mount(); - expect(el.text()).toContain("edit"); - el.find("button").first().simulate("click"); - el.update(); - expect(el.text()).toContain("view"); + const wrapper = mount(); + expect(wrapper.state().activeMenu).toEqual("show"); + const text = allButtonText(wrapper); + expect(text.toLowerCase()).not.toContain("view"); + clickButton(wrapper, 0, "edit"); + expect(wrapper.state().activeMenu).toEqual("edit"); + }); + + it("toggles form state to view", () => { + const props = { feeds: [], dispatch: jest.fn() }; + const wrapper = mount(); + wrapper.setState({ activeMenu: "edit" }); + const text = allButtonText(wrapper); + expect(text.toLowerCase()).not.toContain("edit"); + clickButton(wrapper, 2, "view"); + expect(wrapper.state().activeMenu).toEqual("show"); }); }); diff --git a/webpack/devices/components/__tests__/hardware_settings_test.tsx b/webpack/devices/components/__tests__/hardware_settings_test.tsx index cf01112cf..37bc1651d 100644 --- a/webpack/devices/components/__tests__/hardware_settings_test.tsx +++ b/webpack/devices/components/__tests__/hardware_settings_test.tsx @@ -6,6 +6,7 @@ import { Actions } from "../../../constants"; import { bot } from "../../../__test_support__/fake_state/bot"; import { panelState } from "../../../__test_support__/control_panel_state"; import { fakeFirmwareConfig } from "../../../__test_support__/fake_state/resources"; +import { clickButton } from "../../../__test_support__/helpers"; describe("", () => { beforeEach(() => { @@ -43,9 +44,9 @@ describe("", () => { payload: boolean | string) { const p = fakeProps(); const wrapper = mount(); - const button = wrapper.find(buttonElement).at(buttonIndex); - expect(button.text().toLowerCase()).toContain(buttonText); - button.simulate("click"); + clickButton(wrapper, buttonIndex, buttonText, { + button_tag: buttonElement, partial_match: true + }); expect(p.dispatch).toHaveBeenCalledWith({ payload, type }); } diff --git a/webpack/farm_designer/plants/__tests__/create_points_test.tsx b/webpack/farm_designer/plants/__tests__/create_points_test.tsx index 0b95d2b6f..66590cca3 100644 --- a/webpack/farm_designer/plants/__tests__/create_points_test.tsx +++ b/webpack/farm_designer/plants/__tests__/create_points_test.tsx @@ -16,6 +16,7 @@ import { CreatePoints, CreatePointsProps } from "../create_points"; import { initSave } from "../../../api/crud"; import { deletePoints } from "../../../farmware/weed_detector/actions"; import { Actions } from "../../../constants"; +import { clickButton } from "../../../__test_support__/helpers"; describe("", () => { beforeEach(function () { @@ -37,9 +38,7 @@ describe("", () => { it("creates point", () => { const wrapper = mount(); wrapper.setState({ cx: 10, cy: 20, r: 30, color: "red" }); - const button = wrapper.find("button").at(0); - expect(button.text()).toEqual("Create point"); - button.simulate("click"); + clickButton(wrapper, 0, "create point"); expect(initSave).toHaveBeenCalledWith({ body: { meta: { color: "red", created_by: "farm-designer" }, diff --git a/webpack/farm_designer/plants/__tests__/plant_panel_test.tsx b/webpack/farm_designer/plants/__tests__/plant_panel_test.tsx index d360f3195..20719dad6 100644 --- a/webpack/farm_designer/plants/__tests__/plant_panel_test.tsx +++ b/webpack/farm_designer/plants/__tests__/plant_panel_test.tsx @@ -10,6 +10,7 @@ import { PlantPanel, PlantPanelProps, EditPlantStatus, EditPlantStatusProps } fr import { shallow } from "enzyme"; import { FormattedPlantInfo } from "../map_state_to_props"; import { Actions } from "../../../constants"; +import { clickButton } from "../../../__test_support__/helpers"; describe("", () => { beforeEach(function () { @@ -48,9 +49,7 @@ describe("", () => { it("calls destroy", () => { const p = fakeProps(); const wrapper = shallow(); - const btn = wrapper.find("button").at(1); - expect(btn.text()).toEqual("Delete"); - btn.simulate("click"); + clickButton(wrapper, 1, "Delete"); expect(p.onDestroy).toHaveBeenCalledWith("Plant.0.0"); }); @@ -63,18 +62,14 @@ describe("", () => { it("enters select mode", () => { const wrapper = shallow(); - const btn = wrapper.find("button").last(); - btn.simulate("click"); - expect(btn.text()).toEqual("Delete multiple"); + clickButton(wrapper, 2, "Delete multiple"); expect(mockHistory).toHaveBeenCalledWith("/app/designer/plants/select"); }); it("navigates to 'move to' mode", () => { const dispatch = jest.fn(); const wrapper = shallow(); - const btn = wrapper.find("button").first(); - btn.simulate("click"); - expect(btn.text()).toEqual("Move FarmBot to this plant"); + clickButton(wrapper, 0, "Move FarmBot to this plant"); expect(mockHistory).toHaveBeenCalledWith("/app/designer/plants/move_to"); expect(dispatch).toHaveBeenCalledWith({ payload: { "x": 12, "y": 34, "z": undefined }, diff --git a/webpack/farm_designer/plants/__tests__/select_plants_test.tsx b/webpack/farm_designer/plants/__tests__/select_plants_test.tsx index 66b9cd0de..0760671bd 100644 --- a/webpack/farm_designer/plants/__tests__/select_plants_test.tsx +++ b/webpack/farm_designer/plants/__tests__/select_plants_test.tsx @@ -12,6 +12,7 @@ import { mount, shallow } from "enzyme"; import { SelectPlants, SelectPlantsProps } from "../select_plants"; import { fakePlant } from "../../../__test_support__/fake_state/resources"; import { Actions } from "../../../constants"; +import { clickButton } from "../../../__test_support__/helpers"; describe("", () => { beforeEach(function () { @@ -35,7 +36,7 @@ describe("", () => { } it("displays selected plant", () => { - const wrapper = mount(); + const wrapper = mount(); expect(wrapper.text()).toContain("Strawberry"); }); @@ -65,9 +66,7 @@ describe("", () => { const p = fakeProps(); p.dispatch = jest.fn(); const wrapper = mount(); - const selectAllButton = wrapper.find("button").at(1); - expect(selectAllButton.text()).toEqual("Select all"); - selectAllButton.simulate("click"); + clickButton(wrapper, 1, "select all"); expect(p.dispatch).toHaveBeenCalledWith( { payload: ["plant.1", "plant.2"], type: Actions.SELECT_PLANT }); }); @@ -76,9 +75,7 @@ describe("", () => { const p = fakeProps(); p.dispatch = jest.fn(); const wrapper = mount(); - const selectNoneButton = wrapper.find("button").at(2); - expect(selectNoneButton.text()).toEqual("Select none"); - selectNoneButton.simulate("click"); + clickButton(wrapper, 2, "select none"); expect(p.dispatch).toHaveBeenCalledWith( { payload: undefined, type: Actions.SELECT_PLANT }); }); diff --git a/webpack/farmware/__tests__/farmware_forms_test.tsx b/webpack/farmware/__tests__/farmware_forms_test.tsx index 976d2dac1..9237f851c 100644 --- a/webpack/farmware/__tests__/farmware_forms_test.tsx +++ b/webpack/farmware/__tests__/farmware_forms_test.tsx @@ -11,6 +11,7 @@ import * as React from "react"; import { mount, shallow } from "enzyme"; import { FarmwareForms } from "../farmware_forms"; import { fakeFarmwares } from "../../__test_support__/fake_farmwares"; +import { clickButton } from "../../__test_support__/helpers"; describe("", () => { it("doesn't render", () => { @@ -37,9 +38,7 @@ describe("", () => { const wrapper = mount(); - const run = wrapper.find("button").first(); - run.simulate("click"); - expect(run.text()).toEqual("Run"); + clickButton(wrapper, 0, "run"); expect(mockDevice.execScript).toHaveBeenCalledWith( "My Farmware", [{ kind: "pair", diff --git a/webpack/farmware/images/__tests__/photos_test.tsx b/webpack/farmware/images/__tests__/photos_test.tsx index 924569965..696c872b1 100644 --- a/webpack/farmware/images/__tests__/photos_test.tsx +++ b/webpack/farmware/images/__tests__/photos_test.tsx @@ -12,6 +12,7 @@ import { TaggedImage } from "../../../resources/tagged_resources"; import { fakeImages } from "../../../__test_support__/fake_state/images"; import { defensiveClone } from "../../../util"; import { destroy } from "../../../api/crud"; +import { clickButton } from "../../../__test_support__/helpers"; describe("", () => { beforeEach(() => { @@ -69,9 +70,7 @@ describe("", () => { timeOffset: 0 }; const wrapper = mount(); - const deleteButton = wrapper.find("button").at(1); - expect(deleteButton.text().toLowerCase()).toBe("delete photo"); - deleteButton.simulate("click"); + clickButton(wrapper, 1, "delete photo"); expect(destroy).toHaveBeenCalledWith("Position 1"); }); }); diff --git a/webpack/logs/components/__tests__/filter_menu_test.tsx b/webpack/logs/components/__tests__/filter_menu_test.tsx index c1f55971e..dafd4e220 100644 --- a/webpack/logs/components/__tests__/filter_menu_test.tsx +++ b/webpack/logs/components/__tests__/filter_menu_test.tsx @@ -2,6 +2,7 @@ import * as React from "react"; import { mount } from "enzyme"; import { LogsFilterMenu } from "../filter_menu"; import { LogsFilterMenuProps, LogsState } from "../../interfaces"; +import { clickButton } from "../../../__test_support__/helpers"; const logTypes = ["success", "busy", "warn", "error", "info", "fun", "debug"]; @@ -52,15 +53,11 @@ describe("", () => { const p = fakeProps(); p.setFilterLevel = (x) => () => setFilterLevel(x); const wrapper = mount(); - const max = wrapper.find("button").first(); - expect(max.text()).toEqual("max"); - max.simulate("click"); + clickButton(wrapper, 0, "max"); logTypes.map(logType => expect(setFilterLevel).toHaveBeenCalledWith(logType)); jest.clearAllMocks(); - const normal = wrapper.find("button").at(1); - expect(normal.text()).toEqual("normal"); - normal.simulate("click"); + clickButton(wrapper, 1, "normal"); logTypes.map(logType => expect(setFilterLevel).toHaveBeenCalledWith(logType)); }); diff --git a/webpack/regimens/editor/__tests__/index_test.tsx b/webpack/regimens/editor/__tests__/index_test.tsx index c8d6285bb..8de8fd0f0 100644 --- a/webpack/regimens/editor/__tests__/index_test.tsx +++ b/webpack/regimens/editor/__tests__/index_test.tsx @@ -12,6 +12,8 @@ import { RegimenEditor } from "../index"; import { fakeRegimen } from "../../../__test_support__/fake_state/resources"; import { RegimenEditorProps } from "../interfaces"; import { destroy, save } from "../../../api/crud"; +import { clickButton } from "../../../__test_support__/helpers"; +import { SpecialStatus } from "../../../resources/tagged_resources"; describe("", () => { beforeEach(function () { @@ -19,9 +21,11 @@ describe("", () => { }); function fakeProps(): RegimenEditorProps { + const regimen = fakeRegimen(); + regimen.specialStatus = SpecialStatus.DIRTY; return { dispatch: jest.fn(), - current: fakeRegimen(), + current: regimen, calendar: [{ day: "1", items: [{ @@ -31,7 +35,7 @@ describe("", () => { sortKey: 0, day: 1, dispatch: jest.fn(), - regimen: fakeRegimen(), + regimen: regimen, item: { sequence_id: 0, time_offset: 1000 } @@ -57,9 +61,7 @@ describe("", () => { it("deletes regimen", () => { const p = fakeProps(); const wrapper = mount(); - const deleteButton = wrapper.find("button").at(2); - expect(deleteButton.text()).toContain("Delete"); - deleteButton.simulate("click"); + clickButton(wrapper, 2, "delete"); const expectedUuid = p.current && p.current.uuid; expect(destroy).toHaveBeenCalledWith(expectedUuid); }); @@ -67,9 +69,7 @@ describe("", () => { it("saves regimen", () => { const p = fakeProps(); const wrapper = mount(); - const saveeButton = wrapper.find("button").at(0); - expect(saveeButton.text()).toContain("Save"); - saveeButton.simulate("click"); + clickButton(wrapper, 0, "save", { partial_match: true }); const expectedUuid = p.current && p.current.uuid; expect(save).toHaveBeenCalledWith(expectedUuid); }); diff --git a/webpack/sequences/__tests__/sequence_editor_middle_active_test.tsx b/webpack/sequences/__tests__/sequence_editor_middle_active_test.tsx index dc9d053e6..dcc717872 100644 --- a/webpack/sequences/__tests__/sequence_editor_middle_active_test.tsx +++ b/webpack/sequences/__tests__/sequence_editor_middle_active_test.tsx @@ -22,7 +22,7 @@ import * as React from "react"; import { SequenceEditorMiddleActive, onDrop } from "../sequence_editor_middle_active"; -import { mount, ReactWrapper, shallow } from "enzyme"; +import { mount, shallow } from "enzyme"; import { ActiveMiddleProps } from "../interfaces"; import { FAKE_RESOURCES, buildResourceIndex @@ -36,6 +36,7 @@ import { SpecialStatus } from "../../resources/tagged_resources"; import { move, splice } from "../step_tiles"; import { copySequence, editCurrentSequence } from "../actions"; import { execSequence } from "../../devices/actions"; +import { clickButton } from "../../__test_support__/helpers"; describe("", () => { const sequence = fakeSequence(); @@ -57,15 +58,9 @@ describe("", () => { }; } - function clickButton(position: number, text: string, wrapper: ReactWrapper) { - const button = wrapper.find("button").at(position); - expect(button.text()).toEqual(text); - button.simulate("click"); - } - it("saves", () => { const wrapper = mount(); - clickButton(0, "Save * ", wrapper); + clickButton(wrapper, 0, "Save * "); expect(save).toHaveBeenCalledWith(expect.stringContaining("Sequence")); }); @@ -74,19 +69,19 @@ describe("", () => { p.syncStatus = "synced"; p.sequence.specialStatus = SpecialStatus.SAVED; const wrapper = mount(); - clickButton(1, "Test", wrapper); + clickButton(wrapper, 1, "Test"); expect(execSequence).toHaveBeenCalledWith(p.sequence.body); }); it("deletes", () => { const wrapper = mount(); - clickButton(2, "Delete", wrapper); + clickButton(wrapper, 2, "Delete"); expect(destroy).toHaveBeenCalledWith(expect.stringContaining("Sequence")); }); it("copies", () => { const wrapper = mount(); - clickButton(3, "Copy", wrapper); + clickButton(wrapper, 3, "Copy"); expect(copySequence).toHaveBeenCalledWith(expect.objectContaining({ uuid: expect.stringContaining("Sequence") })); diff --git a/webpack/tools/components/__tests__/tool_form_test.tsx b/webpack/tools/components/__tests__/tool_form_test.tsx index 3f5a93975..565d5344e 100644 --- a/webpack/tools/components/__tests__/tool_form_test.tsx +++ b/webpack/tools/components/__tests__/tool_form_test.tsx @@ -3,6 +3,7 @@ import { ToolForm } from "../tool_form"; import { mount } from "enzyme"; import { fakeTool } from "../../../__test_support__/fake_state/resources"; import { ToolFormProps } from "../../interfaces"; +import { clickButton } from "../../../__test_support__/helpers"; describe("", () => { function fakeProps(): ToolFormProps { @@ -23,9 +24,7 @@ describe("", () => { it("adds stock tools", () => { const p = fakeProps(); const wrapper = mount(); - const add = wrapper.find("button").at(3); - expect(add.text()).toEqual("Stock Tools"); - add.simulate("click"); + clickButton(wrapper, 3, "stock tools"); expect(p.dispatch).toHaveBeenCalledTimes(6); }); From 7a9578e486fb802025748f4c4cb5d767069baa69 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 15 Jun 2018 17:28:42 -0700 Subject: [PATCH 2/4] test mock updates --- webpack/__tests__/routes_test.tsx | 8 ++-- .../__tests__/direction_button_test.tsx | 4 +- .../controls/__tests__/jog_buttons_test.tsx | 4 +- webpack/devices/__tests__/actions_test.ts | 42 +++++++++---------- .../__tests__/board_type_test.tsx | 7 ++-- .../__tests__/camera_selection_test.tsx | 8 ++-- .../__tests__/os_update_button_test.tsx | 4 +- .../__tests__/homing_and_calibration_test.tsx | 10 ++--- .../farm_designer/__tests__/actions_test.ts | 12 +++--- .../__tests__/edit_fe_form_test.tsx | 3 +- .../map/__tests__/garden_map_test.tsx | 8 ++-- .../layers/__tests__/tool_slot_layer_test.tsx | 10 ++--- .../plants/__tests__/crop_info_test.tsx | 10 ++--- .../plants/__tests__/edit_plant_info_test.tsx | 3 +- .../__tests__/plant_inventory_item_test.tsx | 11 ++--- .../plants/__tests__/plant_panel_test.tsx | 16 ++++--- .../farmware/images/__tests__/photos_test.tsx | 3 +- .../editor/__tests__/copy_button_test.tsx | 8 ++-- .../list/__tests__/add_button_test.tsx | 6 +-- 19 files changed, 78 insertions(+), 99 deletions(-) diff --git a/webpack/__tests__/routes_test.tsx b/webpack/__tests__/routes_test.tsx index 499c0cb70..402da4bb7 100644 --- a/webpack/__tests__/routes_test.tsx +++ b/webpack/__tests__/routes_test.tsx @@ -3,14 +3,13 @@ jest.mock("fastclick", () => ({ })); let mockAuth: AuthState | undefined = undefined; -const mockClear = jest.fn(); jest.mock("../session", () => ({ Session: { fetchStoredToken: jest.fn(() => mockAuth), deprecatedGetNum: () => undefined, deprecatedGetBool: () => undefined, getAll: () => undefined, - clear: mockClear + clear: jest.fn() } })); @@ -27,6 +26,7 @@ import { RootComponent } from "../routes"; import { store } from "../redux/store"; import { AuthState } from "../auth/interfaces"; import { auth } from "../__test_support__/fake_state/token"; +import { Session } from "../session"; describe("", () => { beforeEach(function () { @@ -37,13 +37,13 @@ describe("", () => { mockAuth = undefined; mockPathname = "/app/account"; shallow(); - expect(mockClear).toHaveBeenCalled(); + expect(Session.clear).toHaveBeenCalled(); }); it("authorized", () => { mockAuth = auth; mockPathname = "/app/account"; shallow(); - expect(mockClear).not.toHaveBeenCalled(); + expect(Session.clear).not.toHaveBeenCalled(); }); }); diff --git a/webpack/controls/__tests__/direction_button_test.tsx b/webpack/controls/__tests__/direction_button_test.tsx index aaa2a2ca1..710eed40c 100644 --- a/webpack/controls/__tests__/direction_button_test.tsx +++ b/webpack/controls/__tests__/direction_button_test.tsx @@ -5,8 +5,8 @@ const mockDevice = { jest.mock("../../device", () => ({ getDevice: () => (mockDevice) })); -const mockOk = jest.fn(); -jest.mock("farmbot-toastr", () => ({ success: mockOk })); + +jest.mock("farmbot-toastr", () => ({ success: jest.fn() })); import * as React from "react"; import { mount } from "enzyme"; diff --git a/webpack/controls/__tests__/jog_buttons_test.tsx b/webpack/controls/__tests__/jog_buttons_test.tsx index 4ae049f5d..a1197e1ca 100644 --- a/webpack/controls/__tests__/jog_buttons_test.tsx +++ b/webpack/controls/__tests__/jog_buttons_test.tsx @@ -8,8 +8,8 @@ const mockDevice = { jest.mock("../../device", () => ({ getDevice: () => (mockDevice) })); -const mockOk = jest.fn(); -jest.mock("farmbot-toastr", () => ({ success: mockOk })); + +jest.mock("farmbot-toastr", () => ({ success: jest.fn() })); import * as React from "react"; import { mount } from "enzyme"; diff --git a/webpack/devices/__tests__/actions_test.ts b/webpack/devices/__tests__/actions_test.ts index 100dd7df3..ac1d13e9a 100644 --- a/webpack/devices/__tests__/actions_test.ts +++ b/webpack/devices/__tests__/actions_test.ts @@ -21,15 +21,12 @@ jest.mock("../../device", () => ({ return mockDevice; } })); -const mockOk = jest.fn(); -const mockInfo = jest.fn(); -const mockError = jest.fn(); -const mockWarning = jest.fn(); + jest.mock("farmbot-toastr", () => ({ - success: mockOk, - info: mockInfo, - error: mockError, - warning: mockWarning, + success: jest.fn(), + info: jest.fn(), + error: jest.fn(), + warning: jest.fn(), })); let mockGetRelease: Promise<{}> = Promise.resolve({}); @@ -52,6 +49,7 @@ import axios from "axios"; import { SpecialStatus } from "../../resources/tagged_resources"; import { McuParamName } from "farmbot"; import { bot } from "../../__test_support__/fake_state/bot"; +import { success, error, warning, info } from "farmbot-toastr"; describe("checkControllerUpdates()", function () { beforeEach(function () { @@ -61,7 +59,7 @@ describe("checkControllerUpdates()", function () { it("calls checkUpdates", async () => { await actions.checkControllerUpdates(); expect(mockDevice.checkUpdates).toHaveBeenCalled(); - expect(mockOk).toHaveBeenCalled(); + expect(success).toHaveBeenCalled(); }); }); @@ -73,7 +71,7 @@ describe("powerOff()", function () { it("calls powerOff", async () => { await actions.powerOff(); expect(mockDevice.powerOff).toHaveBeenCalled(); - expect(mockOk).toHaveBeenCalled(); + expect(success).toHaveBeenCalled(); }); }); @@ -103,7 +101,7 @@ describe("reboot()", function () { it("calls reboot", async () => { await actions.reboot(); expect(mockDevice.reboot).toHaveBeenCalled(); - expect(mockOk).toHaveBeenCalled(); + expect(success).toHaveBeenCalled(); }); }); @@ -134,7 +132,7 @@ describe("sync()", function () { actions.sync()(jest.fn(), getState); expect(mockDevice.sync).not.toHaveBeenCalled(); const expectedMessage = ["FarmBot is not connected.", "Disconnected", "red"]; - expect(mockInfo).toBeCalledWith(...expectedMessage); + expect(info).toBeCalledWith(...expectedMessage); }); }); @@ -147,7 +145,7 @@ describe("execSequence()", function () { const s = fakeSequence().body; await actions.execSequence(s); expect(mockDevice.execSequence).toHaveBeenCalledWith(s.id); - expect(mockOk).toHaveBeenCalled(); + expect(success).toHaveBeenCalled(); }); it("implodes when executing unsaved sequences", () => { @@ -264,7 +262,7 @@ describe("updateMCU()", () => { await actions.updateMCU( "movement_min_spd_x", "100")(jest.fn(), () => state); expect(mockDevice.updateMcu).not.toHaveBeenCalled(); - expect(mockWarning).toHaveBeenCalledWith( + expect(warning).toHaveBeenCalledWith( "Minimum speed should always be lower than maximum"); }); }); @@ -277,7 +275,7 @@ describe("pinToggle()", function () { it("calls togglePin", async () => { await actions.pinToggle(5); expect(mockDevice.togglePin).toHaveBeenCalledWith({ pin_number: 5 }); - expect(mockOk).not.toHaveBeenCalled(); + expect(success).not.toHaveBeenCalled(); }); }); @@ -290,7 +288,7 @@ describe("homeAll()", function () { await actions.homeAll(100); expect(mockDevice.home) .toHaveBeenCalledWith({ axis: "all", speed: 100 }); - expect(mockOk).not.toHaveBeenCalled(); + expect(success).not.toHaveBeenCalled(); }); }); @@ -346,7 +344,7 @@ describe("fetchReleases()", () => { const dispatch = jest.fn(); await actions.fetchReleases("url")(dispatch); expect(axios.get).toHaveBeenCalledWith("url"); - expect(mockError).not.toHaveBeenCalled(); + expect(error).not.toHaveBeenCalled(); expect(dispatch).toHaveBeenCalledWith({ payload: { version: "1.0.0", commit: undefined }, type: Actions.FETCH_OS_UPDATE_INFO_OK @@ -360,7 +358,7 @@ describe("fetchReleases()", () => { const dispatch = jest.fn(); await actions.fetchReleases("url", { beta: true })(dispatch); expect(axios.get).toHaveBeenCalledWith("url"); - expect(mockError).not.toHaveBeenCalled(); + expect(error).not.toHaveBeenCalled(); expect(dispatch).toHaveBeenCalledWith({ payload: { version: "1.0.0-beta", commit: "commit" }, type: Actions.FETCH_BETA_OS_UPDATE_INFO_OK @@ -372,7 +370,7 @@ describe("fetchReleases()", () => { const dispatch = jest.fn(); await actions.fetchReleases("url")(dispatch); await expect(axios.get).toHaveBeenCalledWith("url"); - expect(mockError).toHaveBeenCalledWith( + expect(error).toHaveBeenCalledWith( "Could not download FarmBot OS update information."); expect(dispatch).toHaveBeenCalledWith({ payload: "error", @@ -385,7 +383,7 @@ describe("fetchReleases()", () => { const dispatch = jest.fn(); await actions.fetchReleases("url", { beta: true })(dispatch); await expect(axios.get).toHaveBeenCalledWith("url"); - expect(mockError).not.toHaveBeenCalled(); + expect(error).not.toHaveBeenCalled(); expect(dispatch).toHaveBeenCalledWith({ payload: "error", type: "FETCH_BETA_OS_UPDATE_INFO_ERROR" @@ -448,7 +446,7 @@ describe("fetchMinOsFeatureData()", () => { const dispatch = jest.fn(); await actions.fetchMinOsFeatureData("url")(dispatch); await expect(axios.get).toHaveBeenCalledWith("url"); - expect(mockError).not.toHaveBeenCalled(); + expect(error).not.toHaveBeenCalled(); expect(dispatch).toHaveBeenCalledWith({ payload: "error", type: "FETCH_MIN_OS_FEATURE_INFO_ERROR" @@ -492,7 +490,7 @@ describe("updateConfig()", () => { describe("badVersion()", () => { it("warns of old FBOS version", () => { actions.badVersion(); - expect(mockInfo).toHaveBeenCalledWith( + expect(info).toHaveBeenCalledWith( expect.stringContaining("old version"), "Please Update", "red"); }); }); diff --git a/webpack/devices/components/fbos_settings/__tests__/board_type_test.tsx b/webpack/devices/components/fbos_settings/__tests__/board_type_test.tsx index 34460767d..199defd3f 100644 --- a/webpack/devices/components/fbos_settings/__tests__/board_type_test.tsx +++ b/webpack/devices/components/fbos_settings/__tests__/board_type_test.tsx @@ -5,11 +5,10 @@ const mockDevice = { jest.mock("../../../../device", () => ({ getDevice: () => (mockDevice) })); -const mockToast = jest.fn(); jest.mock("farmbot-toastr", () => ({ - success: mockToast, - info: mockToast, - error: mockToast + success: jest.fn(), + info: jest.fn(), + error: jest.fn() })); import * as React from "react"; diff --git a/webpack/devices/components/fbos_settings/__tests__/camera_selection_test.tsx b/webpack/devices/components/fbos_settings/__tests__/camera_selection_test.tsx index 86cd0461b..7b05693f4 100644 --- a/webpack/devices/components/fbos_settings/__tests__/camera_selection_test.tsx +++ b/webpack/devices/components/fbos_settings/__tests__/camera_selection_test.tsx @@ -4,14 +4,14 @@ const mockDevice = { jest.mock("../../../../device", () => ({ getDevice: () => (mockDevice) })); -const mockInfo = jest.fn(); -const mockError = jest.fn(); -jest.mock("farmbot-toastr", () => ({ info: mockInfo, error: mockError })); + +jest.mock("farmbot-toastr", () => ({ info: jest.fn(), error: jest.fn() })); import * as React from "react"; import { mount, shallow } from "enzyme"; import { CameraSelection } from "../camera_selection"; import { CameraSelectionProps } from "../interfaces"; +import { info } from "farmbot-toastr"; describe("", () => { beforeEach(function () { @@ -41,7 +41,7 @@ describe("", () => { const cameraSelection = shallow(); cameraSelection.find("FBSelect") .simulate("change", { label: "My Camera", value: "mycamera" }); - expect(mockInfo) + expect(info) .toHaveBeenCalledWith("Sending camera configuration...", "Sending"); expect(mockDevice.setUserEnv) .toHaveBeenCalledWith({ camera: "\"mycamera\"" }); diff --git a/webpack/devices/components/fbos_settings/__tests__/os_update_button_test.tsx b/webpack/devices/components/fbos_settings/__tests__/os_update_button_test.tsx index 4c33691e9..878b1609d 100644 --- a/webpack/devices/components/fbos_settings/__tests__/os_update_button_test.tsx +++ b/webpack/devices/components/fbos_settings/__tests__/os_update_button_test.tsx @@ -5,8 +5,8 @@ const mockDevice = { jest.mock("../../../../device", () => ({ getDevice: () => (mockDevice) })); -const mockOk = jest.fn(); -jest.mock("farmbot-toastr", () => ({ success: mockOk })); + +jest.mock("farmbot-toastr", () => ({ success: jest.fn() })); import * as React from "react"; import { mount } from "enzyme"; diff --git a/webpack/devices/components/hardware_settings/__tests__/homing_and_calibration_test.tsx b/webpack/devices/components/hardware_settings/__tests__/homing_and_calibration_test.tsx index 3929e96d0..3863a313b 100644 --- a/webpack/devices/components/hardware_settings/__tests__/homing_and_calibration_test.tsx +++ b/webpack/devices/components/hardware_settings/__tests__/homing_and_calibration_test.tsx @@ -2,8 +2,7 @@ jest.mock("../../../actions", () => ({ updateMCU: jest.fn() })); -const mockWarn = jest.fn(); -jest.mock("farmbot-toastr", () => ({ warning: mockWarn })); +jest.mock("farmbot-toastr", () => ({ warning: jest.fn() })); import * as React from "react"; import { mount } from "enzyme"; @@ -13,6 +12,7 @@ import { updateMCU } from "../../../actions"; import { fakeFirmwareConfig } from "../../../../__test_support__/fake_state/resources"; +import { warning } from "farmbot-toastr"; describe("", () => { beforeEach(function () { @@ -42,18 +42,18 @@ describe("", () => { } it("short int", () => { testAxisLengthInput("5.0.0", "100000", "32000"); - expect(mockWarn) + expect(warning) .toHaveBeenCalledWith("Maximum input is 32,000. Rounding down."); }); it("long int: too long", () => { testAxisLengthInput("6.0.0", "10000000000", "2000000000"); - expect(mockWarn) + expect(warning) .toHaveBeenCalledWith("Maximum input is 2,000,000,000. Rounding down."); }); it("long int: ok", () => { testAxisLengthInput("6.0.0", "100000", "100000"); - expect(mockWarn).not.toHaveBeenCalled(); + expect(warning).not.toHaveBeenCalled(); }); }); diff --git a/webpack/farm_designer/__tests__/actions_test.ts b/webpack/farm_designer/__tests__/actions_test.ts index d41f82813..2eafb83db 100644 --- a/webpack/farm_designer/__tests__/actions_test.ts +++ b/webpack/farm_designer/__tests__/actions_test.ts @@ -1,9 +1,6 @@ -const mockHistory = jest.fn(); let mockPath = "/app/designer/plants"; jest.mock("../../history", () => ({ - history: { - push: mockHistory - }, + history: { push: jest.fn() }, getPathArray: jest.fn(() => { return mockPath.split("/"); }) })); @@ -17,6 +14,7 @@ import { fakePlant } from "../../__test_support__/fake_state/resources"; import { edit } from "../../api/crud"; import { Actions } from "../../constants"; import { DEFAULT_ICON } from "../../open_farm/icons"; +import { history } from "../../history"; describe("movePlant", () => { beforeEach(() => { @@ -59,7 +57,7 @@ describe("closePlantInfo()", () => { mockPath = "/app/designer/plants"; const dispatch = jest.fn(); closePlantInfo(dispatch)(); - expect(mockHistory).not.toHaveBeenCalled(); + expect(history.push).not.toHaveBeenCalled(); expect(dispatch).not.toHaveBeenCalled(); }); @@ -67,7 +65,7 @@ describe("closePlantInfo()", () => { mockPath = "/app/designer/plants/1/edit"; const dispatch = jest.fn(); closePlantInfo(dispatch)(); - expect(mockHistory).not.toHaveBeenCalled(); + expect(history.push).not.toHaveBeenCalled(); expect(dispatch).not.toHaveBeenCalled(); }); @@ -75,7 +73,7 @@ describe("closePlantInfo()", () => { mockPath = "/app/designer/plants/1"; const dispatch = jest.fn(); closePlantInfo(dispatch)(); - expect(mockHistory).toHaveBeenCalledWith("/app/designer/plants"); + expect(history.push).toHaveBeenCalledWith("/app/designer/plants"); expect(dispatch).toHaveBeenCalledWith({ payload: undefined, type: Actions.SELECT_PLANT }); diff --git a/webpack/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx b/webpack/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx index 4cc7bb855..3f64d89e4 100644 --- a/webpack/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx +++ b/webpack/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx @@ -1,7 +1,6 @@ -const mockHistory = jest.fn(); jest.mock("../../../history", () => ({ history: { - push: mockHistory + push: jest.fn() } })); diff --git a/webpack/farm_designer/map/__tests__/garden_map_test.tsx b/webpack/farm_designer/map/__tests__/garden_map_test.tsx index c46d0f6b2..8b159244b 100644 --- a/webpack/farm_designer/map/__tests__/garden_map_test.tsx +++ b/webpack/farm_designer/map/__tests__/garden_map_test.tsx @@ -2,10 +2,7 @@ jest.mock("../../../open_farm/icons", () => ({ cachedCrop: jest.fn(() => { return Promise.resolve({ spread: 100 }); }) })); -const mockError = jest.fn(); -jest.mock("farmbot-toastr", () => ({ - error: mockError -})); +jest.mock("farmbot-toastr", () => ({ error: jest.fn() })); jest.mock("../../actions", () => ({ closePlantInfo: jest.fn(), @@ -33,6 +30,7 @@ import { Actions } from "../../../constants"; import { initSave } from "../../../api/crud"; import { setEggStatus, EggKeys } from "../easter_eggs/status"; import { movePlant, unselectPlant } from "../../actions"; +import { error } from "farmbot-toastr"; function fakeProps(): GardenMapProps { return { @@ -143,7 +141,7 @@ describe("", () => { wrapper.find("#drop-area-svg").simulate("click", { preventDefault: jest.fn(), pageX: -100, pageY: -100 }); - expect(mockError).toHaveBeenCalledWith( + expect(error).toHaveBeenCalledWith( expect.stringContaining("Outside of planting area")); }); diff --git a/webpack/farm_designer/map/layers/__tests__/tool_slot_layer_test.tsx b/webpack/farm_designer/map/layers/__tests__/tool_slot_layer_test.tsx index 1c1d6a375..ef6247741 100644 --- a/webpack/farm_designer/map/layers/__tests__/tool_slot_layer_test.tsx +++ b/webpack/farm_designer/map/layers/__tests__/tool_slot_layer_test.tsx @@ -1,9 +1,6 @@ -const mockHistory = jest.fn(); let mockPath = "/app/designer/plants"; jest.mock("../../../../history", () => ({ - history: { - push: mockHistory - }, + history: { push: jest.fn() }, getPathArray: jest.fn(() => { return mockPath.split("/"); }) })); @@ -13,6 +10,7 @@ import { fakeMapTransformProps } from "../../../../__test_support__/map_transfor import { fakeResource } from "../../../../__test_support__/fake_resource"; import { ToolSlotPointer } from "../../../../interfaces"; import { shallow } from "enzyme"; +import { history } from "../../../../history"; describe("", () => { beforeEach(function () { @@ -56,7 +54,7 @@ describe("", () => { const wrapper = shallow(); const tools = wrapper.find("g").first(); await tools.simulate("click"); - expect(mockHistory).toHaveBeenCalledWith("/app/tools"); + expect(history.push).toHaveBeenCalledWith("/app/tools"); }); it("doesn't navigate to tools page", async () => { @@ -65,7 +63,7 @@ describe("", () => { const wrapper = shallow(); const tools = wrapper.find("g").first(); await tools.simulate("click"); - expect(mockHistory).not.toHaveBeenCalled(); + expect(history.push).not.toHaveBeenCalled(); }); it("is in non-clickable mode", () => { diff --git a/webpack/farm_designer/plants/__tests__/crop_info_test.tsx b/webpack/farm_designer/plants/__tests__/crop_info_test.tsx index 0686b5b9f..46990a7cb 100644 --- a/webpack/farm_designer/plants/__tests__/crop_info_test.tsx +++ b/webpack/farm_designer/plants/__tests__/crop_info_test.tsx @@ -3,12 +3,9 @@ jest.mock("react-redux", () => ({ })); let mockPath = ""; -const mockHistory = jest.fn(); jest.mock("../../../history", () => ({ getPathArray: jest.fn(() => { return mockPath.split("/"); }), - history: { - push: mockHistory - } + history: { push: jest.fn() } })); jest.mock("../../../api/crud", () => ({ @@ -20,6 +17,7 @@ import { CropInfo } from "../crop_info"; import { shallow, mount } from "enzyme"; import { CropInfoProps } from "../../interfaces"; import { initSave } from "../../../api/crud"; +import { history } from "../../../history"; describe("", () => { const fakeProps = (): CropInfoProps => { @@ -59,7 +57,7 @@ describe("", () => { mockPath = "/app/designer/plants/crop_search/mint"; const wrapper = shallow(); wrapper.find(".right-button").simulate("click"); - expect(mockHistory).toHaveBeenCalledWith( + expect(history.push).toHaveBeenCalledWith( "/app/designer/plants/crop_search/mint/add"); }); @@ -67,7 +65,7 @@ describe("", () => { mockPath = "/app/designer/plants/crop_search/mint"; const wrapper = shallow(); wrapper.find(".plant-panel-back-arrow").simulate("click"); - expect(mockHistory).toHaveBeenCalledWith( + expect(history.push).toHaveBeenCalledWith( "/app/designer/plants/crop_search/"); }); diff --git a/webpack/farm_designer/plants/__tests__/edit_plant_info_test.tsx b/webpack/farm_designer/plants/__tests__/edit_plant_info_test.tsx index 61a484ded..3500452d0 100644 --- a/webpack/farm_designer/plants/__tests__/edit_plant_info_test.tsx +++ b/webpack/farm_designer/plants/__tests__/edit_plant_info_test.tsx @@ -9,8 +9,7 @@ jest.mock("../../../history", () => ({ getPathArray: () => "" })); -const mockErr = jest.fn(); -jest.mock("farmbot-toastr", () => ({ error: mockErr })); +jest.mock("farmbot-toastr", () => ({ error: jest.fn() })); import * as React from "react"; import { EditPlantInfo } from "../edit_plant_info"; diff --git a/webpack/farm_designer/plants/__tests__/plant_inventory_item_test.tsx b/webpack/farm_designer/plants/__tests__/plant_inventory_item_test.tsx index 9dd901154..4a6e09758 100644 --- a/webpack/farm_designer/plants/__tests__/plant_inventory_item_test.tsx +++ b/webpack/farm_designer/plants/__tests__/plant_inventory_item_test.tsx @@ -1,13 +1,11 @@ -const mockHistory = jest.fn(); -jest.mock("../../../history", () => ({ - push: mockHistory -})); +jest.mock("../../../history", () => ({ push: jest.fn() })); import * as React from "react"; import { PlantInventoryItem } from "../plant_inventory_item"; import { shallow } from "enzyme"; import { fakePlant } from "../../../__test_support__/fake_state/resources"; import { Actions } from "../../../constants"; +import { push } from "../../../history"; describe("", () => { const fakeProps = () => { @@ -19,7 +17,7 @@ describe("", () => { }; it("renders", () => { - const wrapper = shallow(); + const wrapper = shallow(); expect(wrapper.text()).toEqual("Strawberry Plant 11 days old"); expect(wrapper.find("div").first().hasClass("hovered")).toBeFalsy(); }); @@ -65,7 +63,6 @@ describe("", () => { payload: [p.tpp.uuid], type: Actions.SELECT_PLANT }); - expect(mockHistory) - .toHaveBeenCalledWith("/app/designer/plants/" + p.tpp.body.id); + expect(push).toHaveBeenCalledWith("/app/designer/plants/" + p.tpp.body.id); }); }); diff --git a/webpack/farm_designer/plants/__tests__/plant_panel_test.tsx b/webpack/farm_designer/plants/__tests__/plant_panel_test.tsx index 20719dad6..52824620b 100644 --- a/webpack/farm_designer/plants/__tests__/plant_panel_test.tsx +++ b/webpack/farm_designer/plants/__tests__/plant_panel_test.tsx @@ -1,16 +1,14 @@ -const mockHistory = jest.fn(); -jest.mock("../../../history", () => ({ - history: { - push: mockHistory - } -})); +jest.mock("../../../history", () => ({ history: { push: jest.fn() } })); import * as React from "react"; -import { PlantPanel, PlantPanelProps, EditPlantStatus, EditPlantStatusProps } from "../plant_panel"; +import { + PlantPanel, PlantPanelProps, EditPlantStatus, EditPlantStatusProps +} from "../plant_panel"; import { shallow } from "enzyme"; import { FormattedPlantInfo } from "../map_state_to_props"; import { Actions } from "../../../constants"; import { clickButton } from "../../../__test_support__/helpers"; +import { history } from "../../../history"; describe("", () => { beforeEach(function () { @@ -63,14 +61,14 @@ describe("", () => { it("enters select mode", () => { const wrapper = shallow(); clickButton(wrapper, 2, "Delete multiple"); - expect(mockHistory).toHaveBeenCalledWith("/app/designer/plants/select"); + expect(history.push).toHaveBeenCalledWith("/app/designer/plants/select"); }); it("navigates to 'move to' mode", () => { const dispatch = jest.fn(); const wrapper = shallow(); clickButton(wrapper, 0, "Move FarmBot to this plant"); - expect(mockHistory).toHaveBeenCalledWith("/app/designer/plants/move_to"); + expect(history.push).toHaveBeenCalledWith("/app/designer/plants/move_to"); expect(dispatch).toHaveBeenCalledWith({ payload: { "x": 12, "y": 34, "z": undefined }, type: Actions.CHOOSE_LOCATION diff --git a/webpack/farmware/images/__tests__/photos_test.tsx b/webpack/farmware/images/__tests__/photos_test.tsx index 696c872b1..285d21e7f 100644 --- a/webpack/farmware/images/__tests__/photos_test.tsx +++ b/webpack/farmware/images/__tests__/photos_test.tsx @@ -2,8 +2,7 @@ jest.mock("../../../api/crud", () => ({ destroy: jest.fn(), })); -const mockOk = jest.fn(); -jest.mock("farmbot-toastr", () => ({ success: mockOk })); +jest.mock("farmbot-toastr", () => ({ success: jest.fn() })); import * as React from "react"; import { mount } from "enzyme"; diff --git a/webpack/regimens/editor/__tests__/copy_button_test.tsx b/webpack/regimens/editor/__tests__/copy_button_test.tsx index 17432e541..139d6603b 100644 --- a/webpack/regimens/editor/__tests__/copy_button_test.tsx +++ b/webpack/regimens/editor/__tests__/copy_button_test.tsx @@ -1,7 +1,4 @@ -const mockPush = jest.fn(); -jest.mock("../../../history", () => ({ - push: (url: string) => mockPush(url) -})); +jest.mock("../../../history", () => ({ push: jest.fn() })); jest.unmock("../../../api/crud"); import * as React from "react"; @@ -10,6 +7,7 @@ import { CopyButton } from "../copy_button"; import { fakeRegimen } from "../../../__test_support__/fake_state/resources"; import { SpecialStatus } from "../../../resources/tagged_resources"; import { Actions } from "../../../constants"; +import { push } from "../../../history"; describe("Copy button", () => { @@ -30,7 +28,7 @@ describe("Copy button", () => { }), type: Actions.INIT_RESOURCE }); - expect(mockPush).toHaveBeenCalledWith("/app/regimens/foo_copy_1"); + expect(push).toHaveBeenCalledWith("/app/regimens/foo_copy_1"); }); it("Render a button when given a regimen", () => { diff --git a/webpack/regimens/list/__tests__/add_button_test.tsx b/webpack/regimens/list/__tests__/add_button_test.tsx index 4ede53d55..f2877d8b6 100644 --- a/webpack/regimens/list/__tests__/add_button_test.tsx +++ b/webpack/regimens/list/__tests__/add_button_test.tsx @@ -1,11 +1,11 @@ jest.unmock("../../actions"); -const mockPush = jest.fn(); -jest.mock("../../../history", () => ({ push: mockPush })); +jest.mock("../../../history", () => ({ push: jest.fn() })); import * as React from "react"; import { AddRegimen } from "../add_button"; import { AddRegimenProps } from "../../interfaces"; import { shallow } from "enzyme"; import { Actions } from "../../../constants"; +import { push } from "../../../history"; describe("", () => { function btn(props: AddRegimenProps) { @@ -22,7 +22,7 @@ describe("", () => { it("dispatches a new regimen onclick", () => { const dispatch = jest.fn(); const b = btn({ dispatch, length }); - expect(mockPush).not.toHaveBeenCalled(); + expect(push).not.toHaveBeenCalled(); b.find("button").simulate("click"); expect(dispatch).toHaveBeenCalledTimes(1); expect(dispatch).toHaveBeenCalledWith({ From bffbbf69d961df8666ba6bd01e84451bedfe6943 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 15 Jun 2018 19:02:29 -0700 Subject: [PATCH 3/4] api crud destroy tests --- webpack/api/__tests__/destroy_tests.ts | 101 +++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 webpack/api/__tests__/destroy_tests.ts diff --git a/webpack/api/__tests__/destroy_tests.ts b/webpack/api/__tests__/destroy_tests.ts new file mode 100644 index 000000000..c553dba25 --- /dev/null +++ b/webpack/api/__tests__/destroy_tests.ts @@ -0,0 +1,101 @@ +const mockResource: { kind: string, body: { id: number | undefined } } + = { kind: "Regimen", body: { id: 1 } }; +jest.mock("../../resources/reducer", () => ({ + findByUuid: () => (mockResource) +})); + +jest.mock("../../resources/actions", () => ({ + destroyOK: jest.fn(), + destroyNO: jest.fn() +})); + +jest.mock("../maybe_start_tracking", () => ({ + maybeStartTracking: jest.fn() +})); + +let mockDelete: Promise<{}> = Promise.resolve({}); +jest.mock("axios", () => ({ + default: { + delete: jest.fn(() => mockDelete) + } +})); + +import { destroy } from "../crud"; +import { API } from "../api"; +import axios from "axios"; +import { destroyOK, destroyNO } from "../../resources/actions"; + +describe("destroy", () => { + beforeEach(() => { + jest.clearAllMocks(); + mockResource.body.id = 1; + mockResource.kind = "Regimen"; + }); + + API.setBaseUrl("http://localhost:3000"); + // tslint:disable-next-line:no-any + const fakeGetState = () => ({ resources: { index: {} } } as any); + const fakeDestroy = () => destroy("fakeResource")(jest.fn(), fakeGetState); + + const expectDestroyed = () => { + const kind = mockResource.kind.toLowerCase() + "s"; + expect(axios.delete) + .toHaveBeenCalledWith(`http://localhost:3000/api/${kind}/1`); + expect(destroyOK).toHaveBeenCalledWith(mockResource); + }; + + const expectNotDestroyed = () => { + expect(axios.delete).not.toHaveBeenCalled(); + }; + + it("not confirmed", () => { + expect(fakeDestroy()).rejects.toEqual("User pressed cancel"); + expectNotDestroyed(); + }); + + it("id: 0", () => { + mockResource.body.id = 0; + window.confirm = () => true; + expect(fakeDestroy()).resolves.toEqual(""); + expect(destroyOK).toHaveBeenCalledWith(mockResource); + }); + + it("id: undefined", () => { + mockResource.body.id = undefined; + window.confirm = () => true; + expect(fakeDestroy()).resolves.toEqual(""); + expect(destroyOK).toHaveBeenCalledWith(mockResource); + }); + + it("confirmed", async () => { + window.confirm = () => true; + await expect(fakeDestroy()).resolves.toEqual(undefined); + expectDestroyed(); + }); + + it("confirmation overridden", async () => { + window.confirm = () => false; + const forceDestroy = () => + destroy("fakeResource", true)(jest.fn(), fakeGetState); + await expect(forceDestroy()).resolves.toEqual(undefined); + expectDestroyed(); + }); + + it("confirmation not required", async () => { + mockResource.kind = "Sensor"; + window.confirm = () => false; + await expect(fakeDestroy()).resolves.toEqual(undefined); + expectDestroyed(); + }); + + it("rejected", async () => { + window.confirm = () => true; + mockDelete = Promise.reject("error"); + await expect(fakeDestroy()).rejects.toEqual("error"); + expect(destroyNO).toHaveBeenCalledWith({ + err: "error", + statusBeforeError: undefined, + uuid: "fakeResource" + }); + }); +}); From b87390e069cbe9f355b6d36aea7c4069a6da92a5 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 15 Jun 2018 19:40:00 -0700 Subject: [PATCH 4/4] more test cleanup --- webpack/__test_support__/wrapper.tsx | 7 ------- .../inputs/__tests__/input_default_test.tsx | 15 ++++++--------- 2 files changed, 6 insertions(+), 16 deletions(-) delete mode 100644 webpack/__test_support__/wrapper.tsx diff --git a/webpack/__test_support__/wrapper.tsx b/webpack/__test_support__/wrapper.tsx deleted file mode 100644 index ceb01c087..000000000 --- a/webpack/__test_support__/wrapper.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import * as React from "react"; - -export class Wrapper extends React.Component<{}, {}> { - render() { - return
{this.props.children}
; - } -} diff --git a/webpack/sequences/inputs/__tests__/input_default_test.tsx b/webpack/sequences/inputs/__tests__/input_default_test.tsx index 30cb7e0ad..077a2134f 100644 --- a/webpack/sequences/inputs/__tests__/input_default_test.tsx +++ b/webpack/sequences/inputs/__tests__/input_default_test.tsx @@ -4,7 +4,6 @@ import { InputDefault } from "../input_default"; import { mount } from "enzyme"; import { TaggedSequence, SpecialStatus } from "../../../resources/tagged_resources"; import { MoveAbsolute } from "farmbot/dist"; -import { Wrapper } from "../../../__test_support__/wrapper"; import { Actions } from "../../../constants"; describe("", () => { @@ -49,14 +48,12 @@ describe("", () => { }, "uuid": "Sequence.74.145" }; - const c = mount( - - ); + const c = mount(); const input = c.find("input").first(); input.simulate("change"); input.simulate("blur");