420 lines
14 KiB
TypeScript
420 lines
14 KiB
TypeScript
jest.mock("../../../open_farm/icons", () => ({
|
|
cachedCrop: jest.fn(() => { return Promise.resolve({ spread: 100 }); })
|
|
}));
|
|
|
|
jest.mock("farmbot-toastr", () => ({ error: jest.fn() }));
|
|
|
|
jest.mock("../../actions", () => ({
|
|
closePlantInfo: jest.fn(),
|
|
movePlant: jest.fn(),
|
|
unselectPlant: jest.fn(() => jest.fn()),
|
|
}));
|
|
|
|
jest.mock("../../../api/crud", () => ({
|
|
initSave: jest.fn(),
|
|
edit: () => "edit resource",
|
|
save: () => "save resource",
|
|
}));
|
|
|
|
let mockPath = "";
|
|
jest.mock("../../../history", () => ({
|
|
getPathArray: jest.fn(() => { return mockPath.split("/"); })
|
|
}));
|
|
|
|
import * as React from "react";
|
|
import { GardenMap } from "../garden_map";
|
|
import { shallow } from "enzyme";
|
|
import { GardenMapProps } from "../../interfaces";
|
|
import { fakePlant } from "../../../__test_support__/fake_state/resources";
|
|
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 {
|
|
showPoints: true,
|
|
showPlants: true,
|
|
showSpread: false,
|
|
showFarmbot: false,
|
|
showImages: false,
|
|
selectedPlant: fakePlant(),
|
|
crops: [],
|
|
dispatch: jest.fn(),
|
|
designer: {
|
|
selectedPlants: undefined,
|
|
hoveredPlant: {
|
|
plantUUID: "",
|
|
icon: ""
|
|
},
|
|
hoveredPlantListItem: undefined,
|
|
cropSearchQuery: "",
|
|
cropSearchResults: [{
|
|
crop: {
|
|
name: "strawberry",
|
|
slug: "strawberry",
|
|
binomial_name: "",
|
|
common_names: [],
|
|
description: "",
|
|
sun_requirements: "",
|
|
sowing_method: "",
|
|
processing_pictures: 0
|
|
}, image: ""
|
|
}],
|
|
chosenLocation: { x: undefined, y: undefined, z: undefined },
|
|
currentPoint: undefined,
|
|
},
|
|
plants: [fakePlant(), fakePlant()],
|
|
points: [],
|
|
toolSlots: [],
|
|
botLocationData: {
|
|
position: { x: 0, y: 0, z: 0 },
|
|
scaled_encoders: { x: undefined, y: undefined, z: undefined },
|
|
raw_encoders: { x: undefined, y: undefined, z: undefined },
|
|
},
|
|
botSize: {
|
|
x: { value: 3000, isDefault: true },
|
|
y: { value: 1500, isDefault: true }
|
|
},
|
|
stopAtHome: { x: true, y: true },
|
|
hoveredPlant: fakePlant(),
|
|
zoomLvl: 1,
|
|
botOriginQuadrant: 2,
|
|
gridSize: { x: 1000, y: 1000 },
|
|
gridOffset: { x: 100, y: 100 },
|
|
peripherals: [],
|
|
eStopStatus: false,
|
|
latestImages: [],
|
|
cameraCalibrationData: {
|
|
scale: undefined, rotation: undefined,
|
|
offset: { x: undefined, y: undefined },
|
|
origin: undefined,
|
|
calibrationZ: undefined
|
|
},
|
|
getConfigValue: jest.fn(),
|
|
};
|
|
}
|
|
|
|
describe("<GardenPlant/>", () => {
|
|
beforeEach(function () {
|
|
jest.clearAllMocks();
|
|
Object.defineProperty(document, "querySelector", {
|
|
value: () => { return { scrollLeft: 1, scrollTop: 2 }; },
|
|
configurable: true
|
|
});
|
|
Object.defineProperty(window, "getComputedStyle", {
|
|
value: () => { return { zoom: 1 }; }, configurable: true
|
|
});
|
|
});
|
|
|
|
it("drops plant", () => {
|
|
const p = fakeProps();
|
|
const dispatch = jest.fn();
|
|
p.dispatch = dispatch;
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
mockPath = "/app/designer/plants/crop_search/strawberry/add";
|
|
wrapper.find("#drop-area-svg").simulate("click", {
|
|
preventDefault: jest.fn()
|
|
});
|
|
expect(initSave).toHaveBeenCalledWith(expect.objectContaining({
|
|
body: expect.objectContaining({ name: "strawberry" })
|
|
}));
|
|
});
|
|
|
|
it("doesn't drop plant: error", () => {
|
|
const wrapper = shallow(<GardenMap {...fakeProps()} />);
|
|
mockPath = "/app/designer/plants/crop_search/aplant/add";
|
|
Object.defineProperty(document, "querySelector", {
|
|
value: () => { }, configurable: true
|
|
});
|
|
const add = () =>
|
|
wrapper.find("#drop-area-svg").simulate("click", {
|
|
preventDefault: jest.fn()
|
|
});
|
|
expect(add).toThrow(/while trying to add a plant./);
|
|
});
|
|
|
|
it("doesn't drop plant: outside planting area", () => {
|
|
const wrapper = shallow(<GardenMap {...fakeProps()} />);
|
|
mockPath = "/app/designer/plants/crop_search/aplant/add";
|
|
wrapper.find("#drop-area-svg").simulate("click", {
|
|
preventDefault: jest.fn(), pageX: -100, pageY: -100
|
|
});
|
|
expect(error).toHaveBeenCalledWith(
|
|
expect.stringContaining("Outside of planting area"));
|
|
});
|
|
|
|
it("starts drag and sets activeSpread", async () => {
|
|
const wrapper = shallow(<GardenMap {...fakeProps()} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
mockPath = "/app/designer/plants/1/edit/";
|
|
await wrapper.find("#drop-area-svg").simulate("mouseDown");
|
|
expect(wrapper.state()).toEqual({
|
|
activeDragSpread: 1000,
|
|
isDragging: true
|
|
});
|
|
});
|
|
|
|
it("ends drag", () => {
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.find("#drop-area-svg").simulate("mouseUp");
|
|
expect(p.dispatch).not.toHaveBeenCalled();
|
|
expect(wrapper.state()).toEqual({
|
|
activeDragSpread: undefined,
|
|
activeDragXY: { x: undefined, y: undefined, z: undefined },
|
|
isDragging: false,
|
|
pageX: 0,
|
|
pageY: 0
|
|
});
|
|
wrapper.setState({ isDragging: true });
|
|
wrapper.find("#drop-area-svg").simulate("mouseUp");
|
|
expect(p.dispatch).toHaveBeenCalled();
|
|
expect(wrapper.state().isDragging).toBeFalsy();
|
|
});
|
|
|
|
it("drags: editing", () => {
|
|
mockPath = "/app/designer/plants/1/edit";
|
|
Object.defineProperty(window, "getComputedStyle", {
|
|
value: () => { return { zoom: 0.5 }; }, configurable: true
|
|
});
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.find("#drop-area-svg").simulate("mouseMove");
|
|
expect(p.dispatch).not.toHaveBeenCalled();
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.setState({ isDragging: true, pageX: 200, pageY: 300 });
|
|
wrapper.find("#drop-area-svg").simulate("mouseMove", {
|
|
pageX: 400, pageY: 500
|
|
});
|
|
expect(wrapper.state()).toEqual({
|
|
activeDragXY: { x: 500, y: 600, z: 0 },
|
|
isDragging: true,
|
|
pageX: 400,
|
|
pageY: 500
|
|
});
|
|
expect(movePlant).toHaveBeenCalledWith(expect.objectContaining({
|
|
deltaX: 400, deltaY: 400
|
|
}));
|
|
});
|
|
|
|
it("drags: editing, zoom undefined", () => {
|
|
mockPath = "/app/designer/plants/1/edit";
|
|
Object.defineProperty(window, "getComputedStyle", {
|
|
value: () => { return { zoom: undefined }; }, configurable: true
|
|
});
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.find("#drop-area-svg").simulate("mouseMove");
|
|
expect(p.dispatch).not.toHaveBeenCalled();
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.setState({ isDragging: true, pageX: 300, pageY: 400 });
|
|
wrapper.find("#drop-area-svg").simulate("mouseMove", {
|
|
pageX: 400, pageY: 500
|
|
});
|
|
expect(wrapper.state()).toEqual({
|
|
activeDragXY: { x: 200, y: 300, z: 0 },
|
|
isDragging: true,
|
|
pageX: 400,
|
|
pageY: 500
|
|
});
|
|
expect(movePlant).toHaveBeenCalledWith(expect.objectContaining({
|
|
deltaX: 100, deltaY: 100
|
|
}));
|
|
});
|
|
|
|
it("drags: editing, X&Y swapped", () => {
|
|
mockPath = "/app/designer/plants/1/edit";
|
|
const p = fakeProps();
|
|
p.getConfigValue = () => true;
|
|
p.botOriginQuadrant = 1;
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.find("#drop-area-svg").simulate("mouseMove");
|
|
expect(p.dispatch).not.toHaveBeenCalled();
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.setState({ isDragging: true, pageX: 300, pageY: 500 });
|
|
wrapper.find("#drop-area-svg").simulate("mouseMove", {
|
|
pageX: 400, pageY: 500
|
|
});
|
|
expect(wrapper.state()).toEqual({
|
|
activeDragXY: { x: -100, y: 300, z: 0 },
|
|
isDragging: true,
|
|
pageX: 500,
|
|
pageY: 400
|
|
});
|
|
expect(movePlant).toHaveBeenCalledWith(expect.objectContaining({
|
|
deltaX: -200, deltaY: 100
|
|
}));
|
|
});
|
|
|
|
it("starts drag: selecting", async () => {
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
mockPath = "/app/designer/plants/select";
|
|
await wrapper.find("#drop-area-svg").simulate("mouseDown", {
|
|
pageX: 1000, pageY: 2000
|
|
});
|
|
expect(wrapper.state()).toEqual({
|
|
selectionBox: {
|
|
x0: 580, y0: 1790, x1: undefined, y1: undefined
|
|
}
|
|
});
|
|
expect(p.dispatch).toHaveBeenCalledWith({
|
|
payload: undefined,
|
|
type: Actions.SELECT_PLANT
|
|
});
|
|
});
|
|
|
|
it("drags: selecting", () => {
|
|
mockPath = "/app/designer/plants/select";
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.find("#drop-area-svg").simulate("mouseMove");
|
|
expect(p.dispatch).not.toHaveBeenCalled();
|
|
expect(wrapper.state()).toEqual({});
|
|
wrapper.setState({
|
|
selectionBox: {
|
|
x0: 0, y0: 0, x1: undefined, y1: undefined
|
|
}
|
|
});
|
|
wrapper.find("#drop-area-svg").simulate("mouseMove", {
|
|
pageX: 2000, pageY: 2000
|
|
});
|
|
expect(wrapper.state()).toEqual({
|
|
selectionBox: {
|
|
x0: 0, y0: 0, x1: 1580, y1: 1790
|
|
}
|
|
});
|
|
expect(p.dispatch).toHaveBeenCalledWith(expect.objectContaining({
|
|
type: Actions.SELECT_PLANT,
|
|
payload: [expect.any(String), expect.any(String)]
|
|
}));
|
|
});
|
|
|
|
it("selects location", async () => {
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
mockPath = "/app/designer/plants/move_to";
|
|
await wrapper.find("#drop-area-svg").simulate("click", {
|
|
pageX: 1000, pageY: 2000, preventDefault: jest.fn()
|
|
});
|
|
expect(p.dispatch).toHaveBeenCalledWith({
|
|
payload: { x: 580, y: 1790, z: 0 },
|
|
type: Actions.CHOOSE_LOCATION
|
|
});
|
|
});
|
|
|
|
it("selects location: zoom undefined", async () => {
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
Object.defineProperty(window, "getComputedStyle", {
|
|
value: () => { return { zoom: undefined }; }, configurable: true
|
|
});
|
|
expect(wrapper.state()).toEqual({});
|
|
mockPath = "/app/designer/plants/move_to";
|
|
await wrapper.find("#drop-area-svg").simulate("click", {
|
|
pageX: 1000, pageY: 2000, preventDefault: jest.fn()
|
|
});
|
|
expect(p.dispatch).toHaveBeenCalledWith({
|
|
payload: { x: 580, y: 1790, z: 0 },
|
|
type: Actions.CHOOSE_LOCATION
|
|
});
|
|
});
|
|
|
|
it("starts drawing point", async () => {
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
mockPath = "/app/designer/plants/create_point/";
|
|
await wrapper.find("#drop-area-svg").simulate("mouseDown", {
|
|
pageX: 1, pageY: 2
|
|
});
|
|
expect(wrapper.state()).toEqual({ isDragging: true });
|
|
expect(p.dispatch).toHaveBeenCalledWith({
|
|
payload: { cx: -420, cy: -210, r: 0 },
|
|
type: Actions.SET_CURRENT_POINT_DATA
|
|
});
|
|
});
|
|
|
|
it("sets drawn point radius", async () => {
|
|
const p = fakeProps();
|
|
p.designer.currentPoint = { cx: -420, cy: -210, r: 0 };
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
expect(wrapper.state()).toEqual({});
|
|
mockPath = "/app/designer/plants/create_point/";
|
|
wrapper.setState({ isDragging: true });
|
|
await wrapper.find("#drop-area-svg").simulate("mouseMove", {
|
|
pageX: 10, pageY: 20
|
|
});
|
|
expect(p.dispatch).toHaveBeenCalledWith({
|
|
payload: { cx: -420, cy: -210, r: 22 },
|
|
type: Actions.SET_CURRENT_POINT_DATA
|
|
});
|
|
});
|
|
|
|
it("lays eggs", () => {
|
|
setEggStatus(EggKeys.BRING_ON_THE_BUGS, "");
|
|
setEggStatus(EggKeys.BUGS_ARE_STILL_ALIVE, "");
|
|
const noEggs = shallow(<GardenMap {...fakeProps()} />);
|
|
expect(noEggs.find("Bugs").length).toEqual(0);
|
|
setEggStatus(EggKeys.BRING_ON_THE_BUGS, "true");
|
|
setEggStatus(EggKeys.BUGS_ARE_STILL_ALIVE, "");
|
|
const eggs = shallow(<GardenMap {...fakeProps()} />);
|
|
expect(eggs.find("Bugs").length).toEqual(1);
|
|
});
|
|
|
|
const expectHandledDragOver = () => {
|
|
const wrapper = shallow(<GardenMap {...fakeProps()} />);
|
|
const e = {
|
|
dataTransfer: { dropEffect: undefined },
|
|
preventDefault: jest.fn()
|
|
};
|
|
wrapper.find(".drop-area").simulate("dragOver", e);
|
|
expect(e.dataTransfer.dropEffect).toEqual("move");
|
|
expect(e.preventDefault).toHaveBeenCalled();
|
|
};
|
|
|
|
it(".drop-area: handles drag over (crop page)", () => {
|
|
mockPath = "/app/designer/plants/crop_search/mint";
|
|
expectHandledDragOver();
|
|
});
|
|
|
|
it(".drop-area: handles drag over (click-to-add mode)", () => {
|
|
mockPath = "/app/designer/plants/crop_search/mint/add";
|
|
expectHandledDragOver();
|
|
});
|
|
|
|
it(".drop-area: handles drag start", () => {
|
|
mockPath = "/app/designer/plants";
|
|
const wrapper = shallow(<GardenMap {...fakeProps()} />);
|
|
const e = { preventDefault: jest.fn() };
|
|
wrapper.find(".drop-area").simulate("dragStart", e);
|
|
expect(e.preventDefault).toHaveBeenCalled();
|
|
});
|
|
|
|
it(".drop-area: handles drag enter", () => {
|
|
mockPath = "/app/designer/plants/crop_search";
|
|
const wrapper = shallow(<GardenMap {...fakeProps()} />);
|
|
const e = { preventDefault: jest.fn() };
|
|
wrapper.find(".drop-area").simulate("dragEnter", e);
|
|
expect(e.preventDefault).toHaveBeenCalled();
|
|
});
|
|
|
|
it("calls unselectPlant on unmount", () => {
|
|
const p = fakeProps();
|
|
const wrapper = shallow(<GardenMap {...p} />);
|
|
// tslint:disable-next-line:no-any
|
|
const instance = wrapper.instance() as any;
|
|
instance.componentWillUnmount();
|
|
expect(unselectPlant).toHaveBeenCalled();
|
|
});
|
|
});
|