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 client_min_messages = warning;
SET row_security = off; 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: - -- Name: hstore; Type: EXTENSION; Schema: -; Owner: -
-- --
@ -1265,7 +1251,8 @@ CREATE TABLE public.web_app_configs (
home_button_homing boolean DEFAULT false, home_button_homing boolean DEFAULT false,
show_motor_plot boolean DEFAULT false, show_motor_plot boolean DEFAULT false,
show_historic_points 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); 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: - -- 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); 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: - -- Name: diagnostic_dumps fk_rails_c5df7fdc83; Type: FK CONSTRAINT; Schema: public; Owner: -
-- --
@ -2406,10 +2393,10 @@ INSERT INTO "schema_migrations" (version) VALUES
('20180925203846'), ('20180925203846'),
('20180926161918'), ('20180926161918'),
('20181014221342'), ('20181014221342'),
('20181014231010'),
('20181019023351'), ('20181019023351'),
('20181025182807'), ('20181025182807'),
('20181112010427'), ('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 * as React from "react";
import { mount } from "enzyme"; import { mount } from "enzyme";
import { CopyButton } from "../copy_button"; import { CopyButton } from "../copy_button";
import { fakeRegimen } from "../../../__test_support__/fake_state/resources"; import { fakeRegimen } from "../../../__test_support__/fake_state/resources";
import { SpecialStatus } from "farmbot";
import { Actions } from "../../../constants";
import { push } from "../../../history"; 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", () => { it("initializes a new regimen on click", () => {
const dispatch = jest.fn(); const p = fakeProps();
const regimen = fakeRegimen(); p.regimen.body.regimen_items = [{
const el = mount(<CopyButton dispatch={dispatch} regimen={regimen} />); regimen_id: 1, sequence_id: 1, time_offset: 1
expect(el.find("button").length).toBe(1); }];
el.simulate("click"); const { regimen_items } = p.regimen.body;
expect(dispatch).toHaveBeenCalledTimes(1); const wrapper = mount(<CopyButton {...p} />);
expect(dispatch).toHaveBeenCalledWith({ wrapper.simulate("click");
payload: expect.objectContaining({ expect(p.dispatch).toHaveBeenCalled();
body: expect.objectContaining({ expect(init).toHaveBeenCalledWith("Regimen", {
name: expect.stringContaining("Foo copy") color: "red", name: "Foo copy 1", regimen_items
}),
specialStatus: SpecialStatus.DIRTY,
kind: "Regimen"
}),
type: Actions.INIT_RESOURCE
}); });
expect(push).toHaveBeenCalledWith("/app/regimens/foo_copy_1"); 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 { TaggedRegimen } from "farmbot";
import { defensiveClone, urlFriendly } from "../../util"; import { defensiveClone, urlFriendly } from "../../util";
import { push } from "../../history"; import { push } from "../../history";
import { setActiveRegimenByName } from "../set_active_regimen_by_name";
export function CopyButton({ dispatch, regimen }: CopyButtnProps) { export const CopyButton = ({ dispatch, regimen }: CopyButtnProps) =>
if (regimen) { <button
return <button className="fb-button yellow"
className="fb-button yellow" onClick={() => dispatch(copyRegimen(regimen))}>
onClick={() => dispatch(copy(regimen))}> {t("Copy")}
{t("Copy")} </button>;
</button>;
} else {
return <span />;
}
}
let count = 1; let count = 1;
function copy(regimen: TaggedRegimen | undefined) {
if (regimen) { export const copyRegimen = (payload: TaggedRegimen) =>
const r = defensiveClone(regimen); (dispatch: Function) => {
r.body.name = r.body.name + t(" copy ") + (count++); const copy = defensiveClone(payload);
push("/app/regimens/" + urlFriendly(r.body.name)); copy.body.id = undefined;
r.body.id = undefined; copy.body.name = copy.body.name + t(" copy ") + (count++);
return regimen && init(r.kind, r.body); 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 { export interface CopyButtnProps {
dispatch: Function; dispatch: Function;
regimen?: TaggedRegimen; regimen: TaggedRegimen;
} }
export interface DeleteButtonProps extends RegimenProps { export interface DeleteButtonProps extends RegimenProps {

View File

@ -2,12 +2,8 @@ import * as React from "react";
import { RegimenListItemProps } from "../interfaces"; import { RegimenListItemProps } from "../interfaces";
import { lastUrlChunk, urlFriendly } from "../../util"; import { lastUrlChunk, urlFriendly } from "../../util";
import { selectRegimen } from "../actions"; import { selectRegimen } from "../actions";
import {
isTaggedRegimen
} from "../../resources/tagged_resources";
import { t } from "i18next"; import { t } from "i18next";
import { Content } from "../../constants"; import { Content } from "../../constants";
import { TaggedRegimen } from "farmbot";
import { Link } from "../../link"; import { Link } from "../../link";
export function RegimenListItem({ regimen, dispatch, inUse }: RegimenListItemProps) { 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}`]; const style = [`block`, `full-width`, `fb-button`, `${color}`];
lastUrlChunk() === urlFriendly(regimen.body.name) && style.push("active"); lastUrlChunk() === urlFriendly(regimen.body.name) && style.push("active");
return <Link return <Link
to={`/app/regimens/${urlFriendly(name)}`} to={`/app/regimens/${urlFriendly(regimen.body.name)}`}
key={regimen.uuid}> key={regimen.uuid}>
<button <button
className={style.join(" ")} className={style.join(" ")}
onClick={select(dispatch, regimen)}> onClick={() => dispatch(selectRegimen(regimen.uuid))}>
<label>{name}</label> <label>{name}</label>
{inUse && <i className="in-use fa fa-hdd-o" title={t(Content.IN_USE)} />} {inUse && <i className="in-use fa fa-hdd-o" title={t(Content.IN_USE)} />}
</button> </button>
</Link>; </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", () => ({ jest.mock("../../history", () => ({ push: jest.fn() }));
push: jest.fn()
}));
jest.mock("../../api/crud", () => ({ jest.mock("../../api/crud", () => ({
init: jest.fn(), init: jest.fn(),
edit: jest.fn() edit: jest.fn()
})); }));
jest.mock("../set_active_sequence_by_name", () => ({
setActiveSequenceByName: jest.fn()
}));
import { import {
copySequence, editCurrentSequence, selectSequence copySequence, editCurrentSequence, selectSequence
} from "../actions"; } from "../actions";
@ -14,21 +16,27 @@ import { fakeSequence } from "../../__test_support__/fake_state/resources";
import { init, edit } from "../../api/crud"; import { init, edit } from "../../api/crud";
import { push } from "../../history"; import { push } from "../../history";
import { Actions } from "../../constants"; import { Actions } from "../../constants";
import { setActiveSequenceByName } from "../set_active_sequence_by_name";
describe("copySequence()", () => { describe("copySequence()", () => {
it("copies sequence", () => { it("copies sequence", () => {
const sequence = fakeSequence(); const sequence = fakeSequence();
const copy = copySequence(sequence); sequence.body.body = [{ kind: "wait", args: { milliseconds: 100 } }];
copy(jest.fn()); const { body } = sequence.body;
copySequence(sequence)(jest.fn());
expect(init).toHaveBeenCalledWith("Sequence", expect(init).toHaveBeenCalledWith("Sequence",
expect.objectContaining({ name: "fake copy 1" })); expect.objectContaining({ name: "fake copy 1", body }));
}); });
it("updates current path", () => { it("updates current path", () => {
const copy = copySequence(fakeSequence()); copySequence(fakeSequence())(jest.fn());
copy(jest.fn());
expect(push).toHaveBeenCalledWith("/app/sequences/fake_copy_2"); expect(push).toHaveBeenCalledWith("/app/sequences/fake_copy_2");
}); });
it("selcts sequence", () => {
copySequence(fakeSequence())(jest.fn());
expect(setActiveSequenceByName).toHaveBeenCalled();
});
}); });
describe("editCurrentSequence()", () => { describe("editCurrentSequence()", () => {

View File

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