feat(ui): validate silence form data before submiting

This commit is contained in:
Łukasz Mierzwa
2018-09-04 13:35:35 +01:00
parent 823d9de765
commit 3cb3ed6990
4 changed files with 115 additions and 4 deletions

View File

@@ -102,7 +102,8 @@ const SilenceForm = observer(
event.preventDefault();
silenceFormStore.data.inProgress = true;
if (silenceFormStore.data.isValid)
silenceFormStore.data.inProgress = true;
});
render() {

View File

@@ -3,7 +3,7 @@ import React from "react";
import { mount, shallow } from "enzyme";
import { AlertStore } from "Stores/AlertStore";
import { SilenceFormStore } from "Stores/SilenceFormStore";
import { SilenceFormStore, NewEmptyMatcher } from "Stores/SilenceFormStore";
import { SilenceForm } from "./SilenceForm";
let alertStore;
@@ -121,7 +121,22 @@ describe("<SilenceForm /> inputs", () => {
});
describe("<SilenceForm />", () => {
it("calling submit marks form as in progress", () => {
it("calling submit doesn't mark form as in progress when form is invalid", () => {
const tree = ShallowSilenceForm();
tree.simulate("submit", { preventDefault: jest.fn() });
expect(silenceFormStore.data.inProgress).toBe(false);
});
it("calling submit marks form as in progress when form is valid", () => {
const matcher = NewEmptyMatcher();
matcher.name = "job";
matcher.values = ["node_exporter"];
silenceFormStore.data.matchers = [matcher];
silenceFormStore.data.alertmanagers = [
{ label: "am1", value: "http://example.com" }
];
silenceFormStore.data.author = "me@example.com";
silenceFormStore.data.comment = "fake silence";
const tree = ShallowSilenceForm();
tree.simulate("submit", { preventDefault: jest.fn() });
expect(silenceFormStore.data.inProgress).toBe(true);

View File

@@ -51,6 +51,23 @@ class SilenceFormStore {
comment: "",
author: "",
get isValid() {
if (this.alertmanagers.length === 0) return false;
if (this.matchers.length === 0) return false;
if (
this.matchers.filter(
m =>
m.name === "" ||
m.values.length === 0 ||
m.values.filter(v => v === "").length > 0
).length > 0
)
return false;
if (this.comment === "") return false;
if (this.author === "") return false;
return true;
},
resetProgress() {
this.inProgress = false;
},
@@ -181,6 +198,7 @@ class SilenceFormStore {
decStart: action.bound,
incEnd: action.bound,
decEnd: action.bound,
isValid: computed,
toAlertmanagerPayload: computed,
toDuration: computed
},

View File

@@ -1,7 +1,7 @@
import moment from "moment";
import { MockAlert, MockAlertGroup } from "__mocks__/Alerts.js";
import { SilenceFormStore } from "./SilenceFormStore";
import { SilenceFormStore, NewEmptyMatcher } from "./SilenceFormStore";
let store;
beforeEach(() => {
@@ -129,6 +129,83 @@ describe("SilenceFormStore.data", () => {
});
});
const MockAlertmanager = () => ({
label: "default",
value: "http://localhost"
});
const MockMatcher = (name, values) => {
const matcher = NewEmptyMatcher();
matcher.name = name;
matcher.values = values;
return matcher;
};
describe("SilenceFormStore.data.isValid", () => {
it("isValid returns 'false' if alertmanagers list is empty", () => {
store.data.matchers = [MockMatcher("foo", ["bar"])];
store.data.author = "me@example.com";
store.data.comment = "fake silence";
expect(store.data.isValid).toBe(false);
});
it("isValid returns 'false' if matchers list is empty", () => {
store.data.alertmanagers = [MockAlertmanager];
store.data.matchers = [];
store.data.author = "me@example.com";
store.data.comment = "fake silence";
expect(store.data.isValid).toBe(false);
});
it("isValid returns 'false' if matchers list is pupulated when a matcher without any name", () => {
store.data.alertmanagers = [MockAlertmanager];
store.data.matchers = [MockMatcher("", ["bar"])];
store.data.author = "me@example.com";
store.data.comment = "fake silence";
expect(store.data.isValid).toBe(false);
});
it("isValid returns 'false' if matchers list is pupulated when a matcher without any value ([])", () => {
store.data.alertmanagers = [MockAlertmanager];
store.data.matchers = [MockMatcher("foo", [])];
store.data.author = "me@example.com";
store.data.comment = "fake silence";
expect(store.data.isValid).toBe(false);
});
it("isValid returns 'false' if matchers list is pupulated when a matcher with empty value ([''])", () => {
store.data.alertmanagers = [MockAlertmanager];
store.data.matchers = [MockMatcher("foo", [])];
store.data.author = "me@example.com";
store.data.comment = "fake silence";
expect(store.data.isValid).toBe(false);
});
it("isValid returns 'false' if author is empty", () => {
store.data.alertmanagers = [MockAlertmanager];
store.data.matchers = [MockMatcher("foo", ["bar"])];
store.data.author = "";
store.data.comment = "fake silence";
expect(store.data.isValid).toBe(false);
});
it("isValid returns 'false' if comment is empty", () => {
store.data.alertmanagers = [MockAlertmanager];
store.data.matchers = [MockMatcher("foo", ["bar"])];
store.data.author = "me@example.com";
store.data.comment = "";
expect(store.data.isValid).toBe(false);
});
it("isValid returns 'true' if all fileds are set", () => {
store.data.alertmanagers = [MockAlertmanager];
store.data.matchers = [MockMatcher("foo", ["bar"])];
store.data.author = "me@example.com";
store.data.comment = "fake silence";
expect(store.data.isValid).toBe(true);
});
});
describe("SilenceFormStore.data startsAt & endsAt validation", () => {
it("toDuration returns correct duration for 5d 0h 1m", () => {
store.data.startsAt = moment([2000, 1, 1, 0, 0, 0]);