diff --git a/frontend/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx b/frontend/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx
index 46ea654af..8b601b4a8 100644
--- a/frontend/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx
+++ b/frontend/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx
@@ -23,16 +23,15 @@ import { isString, isFunction } from "lodash";
import { repeatOptions } from "../map_state_to_props_add_edit";
import { SpecialStatus, ParameterApplication } from "farmbot";
import moment from "moment";
-import { fakeState } from "../../../__test_support__/fake_state";
import { history } from "../../../history";
import {
buildResourceIndex
} from "../../../__test_support__/resource_index_builder";
import { fakeVariableNameSet } from "../../../__test_support__/fake_variables";
import { clickButton } from "../../../__test_support__/helpers";
-import { destroy } from "../../../api/crud";
+import { destroy, save } from "../../../api/crud";
import { fakeTimeSettings } from "../../../__test_support__/fake_time_settings";
-import { error, success, warning } from "../../../toast/toast";
+import { error, success } from "../../../toast/toast";
const mockSequence = fakeSequence();
@@ -275,10 +274,14 @@ describe("", () => {
it("warns about missed regimen items", async () => {
const p = props();
- const state = fakeState();
- state.resources.index.references = { [p.farmEvent.uuid]: p.farmEvent };
- p.dispatch = jest.fn(x => { isFunction(x) && x(); return Promise.resolve(); });
p.farmEvent.body.executable_type = "Regimen";
+ const regimen = fakeRegimen();
+ regimen.body.regimen_items = [
+ { sequence_id: -1, time_offset: 0 },
+ { sequence_id: -1, time_offset: 1000000000 },
+ ];
+ p.findExecutable = () => regimen;
+ p.dispatch = jest.fn(x => { isFunction(x) && x(); return Promise.resolve(); });
p.farmEvent.body.start_time = "2017-05-22T05:00:00.000Z";
p.farmEvent.body.end_time = "2017-05-22T06:00:00.000Z";
const i = instance(p);
@@ -334,14 +337,15 @@ describe("", () => {
expectStartTimeToBeRejected();
});
- it("doesn't display error message on edit: start time has passed", () => {
+ it("displays error message on edit: start time has passed", () => {
const p = props();
p.title = "edit";
p.farmEvent.body.start_time = "2017-05-22T05:00:00.000Z";
p.farmEvent.body.end_time = "2017-05-22T06:00:00.000Z";
const i = instance(p);
i.commitViewModel(moment("2017-06-22T05:00:00.000Z"));
- expect(error).not.toHaveBeenCalled();
+ expect(error).toHaveBeenCalledWith(expect.stringContaining(
+ "Nothing to run."), "Unable to save event.");
});
it("displays error message on save: no items", async () => {
@@ -351,8 +355,22 @@ describe("", () => {
p.farmEvent.body.end_time = "2017-05-22T06:00:00.000Z";
const i = instance(p);
await i.commitViewModel(moment("2017-06-22T05:00:00.000Z"));
- expect(warning).toHaveBeenCalledWith(expect.stringContaining(
- "Nothing to run."));
+ expect(error).toHaveBeenCalledWith(expect.stringContaining(
+ "Nothing to run."), "Unable to save event.");
+ });
+
+ it("displays error message on save: save error", async () => {
+ const p = props();
+ p.dispatch = jest.fn()
+ .mockResolvedValueOnce("")
+ .mockRejectedValueOnce("error");
+ p.shouldDisplay = () => true;
+ p.farmEvent.body.start_time = "2017-07-22T05:00:00.000Z";
+ p.farmEvent.body.end_time = "2017-07-22T06:00:00.000Z";
+ const i = instance(p);
+ await i.commitViewModel(moment("2017-06-22T05:00:00.000Z"));
+ await expect(save).toHaveBeenCalled();
+ expect(error).toHaveBeenCalledWith("Unable to save event.");
});
it("allows start time: edit with unsupported OS", () => {
diff --git a/frontend/farm_designer/farm_events/__tests__/util_test.ts b/frontend/farm_designer/farm_events/__tests__/util_test.ts
index 2803dd650..46177d50e 100644
--- a/frontend/farm_designer/farm_events/__tests__/util_test.ts
+++ b/frontend/farm_designer/farm_events/__tests__/util_test.ts
@@ -1,11 +1,14 @@
import { maybeWarnAboutMissedTasks } from "../util";
import { fakeFarmEvent } from "../../../__test_support__/fake_state/resources";
import moment from "moment";
+import { ExecutableType } from "farmbot/dist/resources/api_resources";
describe("maybeWarnAboutMissedTasks()", () => {
- function testWarn(time: string): () => void {
+ function testWarn(
+ time: string, executableType: ExecutableType = "Regimen"
+ ): () => void {
const callback = jest.fn();
- const fe = fakeFarmEvent("Regimen", 1);
+ const fe = fakeFarmEvent(executableType, 1);
fe.body.start_time = "2017-05-21T22:00:00.000";
maybeWarnAboutMissedTasks(fe,
() => callback("missed event warning"),
@@ -21,4 +24,9 @@ describe("maybeWarnAboutMissedTasks()", () => {
const cb = testWarn("2017-05-01T22:00:00.000");
expect(cb).not.toHaveBeenCalled();
});
+
+ it("doesn't warn when not a regimen", () => {
+ const cb = testWarn("2017-05-21T22:00:00.000", "Sequence");
+ expect(cb).not.toHaveBeenCalled();
+ });
});
diff --git a/frontend/farm_designer/farm_events/edit_fe_form.tsx b/frontend/farm_designer/farm_events/edit_fe_form.tsx
index 7b8dc3f9e..6185e57da 100644
--- a/frontend/farm_designer/farm_events/edit_fe_form.tsx
+++ b/frontend/farm_designer/farm_events/edit_fe_form.tsx
@@ -1,6 +1,6 @@
import * as React from "react";
import moment from "moment";
-import { success, error, warning } from "../../toast/toast";
+import { success, error } from "../../toast/toast";
import {
TaggedFarmEvent, SpecialStatus, TaggedSequence, TaggedRegimen,
ParameterApplication
@@ -94,6 +94,13 @@ const startTimeWarning = () => {
error(message, title);
};
+const nothingToRunWarning = () => {
+ const message =
+ t("All items scheduled before the start time. Nothing to run.");
+ const title = t("Unable to save event.");
+ error(message, title);
+};
+
type RecombineOptions = { forceRegimensToMidnight: boolean };
/** Take a FormViewModel and recombine the fields into a FarmEvent
@@ -323,9 +330,8 @@ export class EditFEForm extends React.Component {
return recombine(vm, opts);
}
- /** Use the next item run time to display toast messages and return to
- * the form if necessary. */
- nextRunTimeActions = (now = moment()): boolean => {
+ /** Use the next item run time to display toast messages. */
+ nextRunTimeActions = (now = moment()) => {
const nextRun = this.nextItemTime(this.props.farmEvent.body, now);
if (nextRun) {
const nextRunText = this.props.autoSyncEnabled
@@ -335,10 +341,6 @@ export class EditFEForm extends React.Component {
you must first SYNC YOUR DEVICE. If you do not sync, the event will
not run.`.replace(/\s+/g, " "), { timeFromNow: nextRun.from(now) });
success(nextRunText);
- return true;
- } else {
- warning(t("All items scheduled before the start time. Nothing to run."));
- return false;
}
}
@@ -346,24 +348,27 @@ export class EditFEForm extends React.Component {
* - Regimen Farm Event:
* * If scheduled for today, warn about the possibility of missing tasks.
* * Display the start time difference from now and maybe prompt to sync.
- * * Return to calendar view if items exist to be run past the start time.
+ * * Return to calendar view.
* - Sequence Farm Event:
* * Determine the time for the next item to be run.
* * If auto-sync is disabled, prompt the user to sync.
- * * Return to calendar view only if more items exist to be run.
+ * * Return to calendar view.
*/
commitViewModel = (now = moment()) => {
if (this.maybeRejectStartTime(this.updatedFarmEvent)) {
return startTimeWarning();
}
+ if (!this.nextItemTime(this.updatedFarmEvent, now)) {
+ return nothingToRunWarning();
+ }
this.dispatch(overwrite(this.props.farmEvent, this.updatedFarmEvent));
this.dispatch(save(this.props.farmEvent.uuid))
.then(() => {
this.setState({ specialStatusLocal: SpecialStatus.SAVED });
this.dispatch(maybeWarnAboutMissedTasks(this.props.farmEvent,
() => alert(t(Content.REGIMEN_TODAY_SKIPPED_ITEM_RISK)), now));
- const itemsScheduled = this.nextRunTimeActions(now);
- if (itemsScheduled) { history.push("/app/designer/events"); }
+ this.nextRunTimeActions(now);
+ history.push("/app/designer/events");
})
.catch(() => {
error(t("Unable to save event."));