add missing seq/reg select

pull/1068/head
gabrielburnworth 2018-12-14 16:35:50 -08:00
parent 6253e2e11d
commit aace6d66f5
7 changed files with 82 additions and 110 deletions

View File

@ -8,20 +8,6 @@ SET check_function_bodies = false;
SET client_min_messages = warning;
SET row_security = off;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
--
-- Name: hstore; Type: EXTENSION; Schema: -; Owner: -
--
@ -1265,7 +1251,8 @@ CREATE TABLE public.web_app_configs (
home_button_homing boolean DEFAULT false,
show_motor_plot boolean DEFAULT false,
show_historic_points boolean DEFAULT false,
show_sensor_readings boolean DEFAULT false
show_sensor_readings boolean DEFAULT false,
show_dev_menu boolean DEFAULT false
);
@ -2217,6 +2204,14 @@ ALTER TABLE ONLY public.points
ADD CONSTRAINT fk_rails_a62cbb8aca FOREIGN KEY (tool_id) REFERENCES public.tools(id);
--
-- Name: farmware_envs fk_rails_ab55c3a1d1; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.farmware_envs
ADD CONSTRAINT fk_rails_ab55c3a1d1 FOREIGN KEY (device_id) REFERENCES public.devices(id);
--
-- Name: primary_nodes fk_rails_bca7fee3b9; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -2225,14 +2220,6 @@ ALTER TABLE ONLY public.primary_nodes
ADD CONSTRAINT fk_rails_bca7fee3b9 FOREIGN KEY (sequence_id) REFERENCES public.sequences(id);
--
-- Name: farmware_envs fk_rails_bdadc396eb; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.farmware_envs
ADD CONSTRAINT fk_rails_bdadc396eb FOREIGN KEY (device_id) REFERENCES public.devices(id);
--
-- Name: diagnostic_dumps fk_rails_c5df7fdc83; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -2406,10 +2393,10 @@ INSERT INTO "schema_migrations" (version) VALUES
('20180925203846'),
('20180926161918'),
('20181014221342'),
('20181014231010'),
('20181019023351'),
('20181025182807'),
('20181112010427'),
('20181126175951');
('20181126175951'),
('20181204005038');

View File

@ -1,51 +1,42 @@
jest.mock("../../../history", () => ({ push: jest.fn() }));
jest.mock("../../../history", () => ({
push: jest.fn(),
history: { getCurrentLocation: () => ({ pathname: "" }) }
}));
jest.mock("../../../api/crud", () => ({ init: jest.fn() }));
jest.mock("../../set_active_regimen_by_name", () => ({
setActiveRegimenByName: jest.fn()
}));
jest.unmock("../../../api/crud");
import * as React from "react";
import { mount } from "enzyme";
import { CopyButton } from "../copy_button";
import { fakeRegimen } from "../../../__test_support__/fake_state/resources";
import { SpecialStatus } from "farmbot";
import { Actions } from "../../../constants";
import { push } from "../../../history";
import { setActiveRegimenByName } from "../../set_active_regimen_by_name";
import { init } from "../../../api/crud";
import { CopyButtnProps } from "../interfaces";
describe("Copy button", () => {
describe("<CopyButton />", () => {
const fakeProps = (): CopyButtnProps => ({
dispatch: jest.fn(x => x(jest.fn())),
regimen: fakeRegimen(),
});
it("Initializes a new regimen on click", () => {
const dispatch = jest.fn();
const regimen = fakeRegimen();
const el = mount(<CopyButton dispatch={dispatch} regimen={regimen} />);
expect(el.find("button").length).toBe(1);
el.simulate("click");
expect(dispatch).toHaveBeenCalledTimes(1);
expect(dispatch).toHaveBeenCalledWith({
payload: expect.objectContaining({
body: expect.objectContaining({
name: expect.stringContaining("Foo copy")
}),
specialStatus: SpecialStatus.DIRTY,
kind: "Regimen"
}),
type: Actions.INIT_RESOURCE
it("initializes a new regimen on click", () => {
const p = fakeProps();
p.regimen.body.regimen_items = [{
regimen_id: 1, sequence_id: 1, time_offset: 1
}];
const { regimen_items } = p.regimen.body;
const wrapper = mount(<CopyButton {...p} />);
wrapper.simulate("click");
expect(p.dispatch).toHaveBeenCalled();
expect(init).toHaveBeenCalledWith("Regimen", {
color: "red", name: "Foo copy 1", regimen_items
});
expect(push).toHaveBeenCalledWith("/app/regimens/foo_copy_1");
expect(setActiveRegimenByName).toHaveBeenCalled();
});
it("Render a button when given a regimen", () => {
const dispatch = jest.fn();
const regimen = fakeRegimen();
const el = mount(<CopyButton dispatch={dispatch} regimen={regimen} />);
expect(el.find("button").length).toBe(1);
el.simulate("click");
expect(dispatch).toHaveBeenCalledTimes(1);
});
it("renders nothing if not given a regimen", () => {
const dispatch = jest.fn();
const el = mount(<CopyButton dispatch={dispatch} />);
expect(el.find("button").length).toBe(0);
el.simulate("click");
expect(dispatch).not.toHaveBeenCalled();
});
});

View File

@ -5,26 +5,23 @@ import { init } from "../../api/crud";
import { TaggedRegimen } from "farmbot";
import { defensiveClone, urlFriendly } from "../../util";
import { push } from "../../history";
import { setActiveRegimenByName } from "../set_active_regimen_by_name";
export function CopyButton({ dispatch, regimen }: CopyButtnProps) {
if (regimen) {
return <button
className="fb-button yellow"
onClick={() => dispatch(copy(regimen))}>
{t("Copy")}
</button>;
} else {
return <span />;
}
}
export const CopyButton = ({ dispatch, regimen }: CopyButtnProps) =>
<button
className="fb-button yellow"
onClick={() => dispatch(copyRegimen(regimen))}>
{t("Copy")}
</button>;
let count = 1;
function copy(regimen: TaggedRegimen | undefined) {
if (regimen) {
const r = defensiveClone(regimen);
r.body.name = r.body.name + t(" copy ") + (count++);
push("/app/regimens/" + urlFriendly(r.body.name));
r.body.id = undefined;
return regimen && init(r.kind, r.body);
}
}
export const copyRegimen = (payload: TaggedRegimen) =>
(dispatch: Function) => {
const copy = defensiveClone(payload);
copy.body.id = undefined;
copy.body.name = copy.body.name + t(" copy ") + (count++);
dispatch(init(copy.kind, copy.body));
push("/app/regimens/" + urlFriendly(copy.body.name));
setActiveRegimenByName();
};

View File

@ -35,7 +35,7 @@ export interface RegimenEditorProps {
export interface CopyButtnProps {
dispatch: Function;
regimen?: TaggedRegimen;
regimen: TaggedRegimen;
}
export interface DeleteButtonProps extends RegimenProps {

View File

@ -2,12 +2,8 @@ import * as React from "react";
import { RegimenListItemProps } from "../interfaces";
import { lastUrlChunk, urlFriendly } from "../../util";
import { selectRegimen } from "../actions";
import {
isTaggedRegimen
} from "../../resources/tagged_resources";
import { t } from "i18next";
import { Content } from "../../constants";
import { TaggedRegimen } from "farmbot";
import { Link } from "../../link";
export function RegimenListItem({ regimen, dispatch, inUse }: RegimenListItemProps) {
@ -16,21 +12,13 @@ export function RegimenListItem({ regimen, dispatch, inUse }: RegimenListItemPro
const style = [`block`, `full-width`, `fb-button`, `${color}`];
lastUrlChunk() === urlFriendly(regimen.body.name) && style.push("active");
return <Link
to={`/app/regimens/${urlFriendly(name)}`}
to={`/app/regimens/${urlFriendly(regimen.body.name)}`}
key={regimen.uuid}>
<button
className={style.join(" ")}
onClick={select(dispatch, regimen)}>
onClick={() => dispatch(selectRegimen(regimen.uuid))}>
<label>{name}</label>
{inUse && <i className="in-use fa fa-hdd-o" title={t(Content.IN_USE)} />}
</button>
</Link>;
}
function select(dispatch: Function, regimen: TaggedRegimen) {
return function () {
if (regimen && isTaggedRegimen(regimen)) {
dispatch(selectRegimen(regimen.uuid));
}
};
}

View File

@ -1,12 +1,14 @@
jest.mock("../../history", () => ({
push: jest.fn()
}));
jest.mock("../../history", () => ({ push: jest.fn() }));
jest.mock("../../api/crud", () => ({
init: jest.fn(),
edit: jest.fn()
}));
jest.mock("../set_active_sequence_by_name", () => ({
setActiveSequenceByName: jest.fn()
}));
import {
copySequence, editCurrentSequence, selectSequence
} from "../actions";
@ -14,21 +16,27 @@ import { fakeSequence } from "../../__test_support__/fake_state/resources";
import { init, edit } from "../../api/crud";
import { push } from "../../history";
import { Actions } from "../../constants";
import { setActiveSequenceByName } from "../set_active_sequence_by_name";
describe("copySequence()", () => {
it("copies sequence", () => {
const sequence = fakeSequence();
const copy = copySequence(sequence);
copy(jest.fn());
sequence.body.body = [{ kind: "wait", args: { milliseconds: 100 } }];
const { body } = sequence.body;
copySequence(sequence)(jest.fn());
expect(init).toHaveBeenCalledWith("Sequence",
expect.objectContaining({ name: "fake copy 1" }));
expect.objectContaining({ name: "fake copy 1", body }));
});
it("updates current path", () => {
const copy = copySequence(fakeSequence());
copy(jest.fn());
copySequence(fakeSequence())(jest.fn());
expect(push).toHaveBeenCalledWith("/app/sequences/fake_copy_2");
});
it("selcts sequence", () => {
copySequence(fakeSequence())(jest.fn());
expect(setActiveSequenceByName).toHaveBeenCalled();
});
});
describe("editCurrentSequence()", () => {

View File

@ -6,6 +6,7 @@ import { push } from "../history";
import { urlFriendly } from "../util";
import { Actions } from "../constants";
import { t } from "i18next";
import { setActiveSequenceByName } from "./set_active_sequence_by_name";
export function pushStep(step: SequenceBodyItem,
dispatch: Function,
@ -23,15 +24,15 @@ export function editCurrentSequence(dispatch: Function, seq: TaggedSequence,
let count = 1;
export function copySequence(payload: TaggedSequence) {
return function (dispatch: Function) {
export const copySequence = (payload: TaggedSequence) =>
(dispatch: Function) => {
const copy = defensiveClone(payload);
copy.body.id = undefined;
copy.body.name = copy.body.name + t(" copy ") + (count++);
dispatch(init(copy.kind, copy.body));
push("/app/sequences/" + urlFriendly(copy.body.name));
setActiveSequenceByName();
};
}
export function selectSequence(uuid: string): SelectSequence {
return {