diff --git a/ui/src/Components/SilenceModal/SilenceForm.test.js b/ui/src/Components/SilenceModal/SilenceForm.test.js
new file mode 100644
index 000000000..5db5e0f64
--- /dev/null
+++ b/ui/src/Components/SilenceModal/SilenceForm.test.js
@@ -0,0 +1,109 @@
+import React from "react";
+
+import { mount, shallow } from "enzyme";
+
+import { AlertStore } from "Stores/AlertStore";
+import { SilenceFormStore } from "Stores/SilenceFormStore";
+import { SilenceForm } from "./SilenceForm";
+
+let alertStore;
+let silenceFormStore;
+
+beforeEach(() => {
+ alertStore = new AlertStore([]);
+ silenceFormStore = new SilenceFormStore();
+});
+
+const ShallowSilenceForm = () => {
+ return shallow(
+
+ );
+};
+
+const MountedSilenceForm = () => {
+ return mount(
+
+ );
+};
+
+describe(" matchers", () => {
+ it("has an empty matcher selects on default render", () => {
+ const tree = ShallowSilenceForm();
+ const matchers = tree.find("SilenceMatch");
+ expect(matchers).toHaveLength(1);
+ expect(silenceFormStore.data.matchers).toHaveLength(1);
+ });
+
+ it("clicking 'Add more' button adds another matcher", () => {
+ const tree = ShallowSilenceForm();
+ const button = tree.find("button[type='button']");
+ button.simulate("click", { preventDefault: jest.fn() });
+ const matchers = tree.find("SilenceMatch");
+ expect(matchers).toHaveLength(2);
+ expect(silenceFormStore.data.matchers).toHaveLength(2);
+ });
+
+ it("clicking trash icon on a matcher select removes it", () => {
+ silenceFormStore.data.addEmptyMatcher();
+ silenceFormStore.data.addEmptyMatcher();
+ silenceFormStore.data.addEmptyMatcher();
+ const tree = MountedSilenceForm();
+ expect(silenceFormStore.data.matchers).toHaveLength(3);
+
+ const matchers = tree.find("SilenceMatch");
+ const toDelete = matchers.at(1);
+ const button = toDelete.find("button");
+ button.simulate("click");
+ expect(silenceFormStore.data.matchers).toHaveLength(2);
+ });
+});
+
+describe(" preview", () => {
+ it("doesn't render SilencePreview when previewCollapse.hidden is true", () => {
+ const tree = ShallowSilenceForm();
+ const instance = tree.instance();
+ instance.previewCollapse.hidden = true;
+ expect(tree.find("SilencePreview")).toHaveLength(0);
+ });
+
+ it("renders SilencePreview when previewCollapse.hidden is false", () => {
+ const tree = ShallowSilenceForm();
+ const instance = tree.instance();
+ instance.previewCollapse.hidden = false;
+ expect(tree.find("SilencePreview")).toHaveLength(1);
+ });
+
+ it("clicking on the toggle icon toggles SilencePreview", () => {
+ const tree = ShallowSilenceForm();
+ const button = tree.find("a.btn.cursor-pointer.text-muted");
+ expect(tree.find("SilencePreview")).toHaveLength(0);
+ button.simulate("click");
+ expect(tree.find("SilencePreview")).toHaveLength(1);
+ button.simulate("click");
+ expect(tree.find("SilencePreview")).toHaveLength(0);
+ });
+});
+
+describe(" inputs", () => {
+ it("changing author input updates SilenceFormStore", () => {
+ const tree = MountedSilenceForm();
+ const input = tree.find("input[placeholder='Author email']");
+ input.simulate("change", { target: { value: "me@example.com" } });
+ expect(silenceFormStore.data.author).toBe("me@example.com");
+ });
+
+ it("changing comment input updates SilenceFormStore", () => {
+ const tree = MountedSilenceForm();
+ const input = tree.find("input[placeholder='Comment']");
+ input.simulate("change", { target: { value: "fake comment" } });
+ expect(silenceFormStore.data.comment).toBe("fake comment");
+ });
+});
+
+describe("", () => {
+ it("calling submit marks form as in progress", () => {
+ const tree = ShallowSilenceForm();
+ tree.simulate("submit", { preventDefault: jest.fn() });
+ expect(silenceFormStore.data.inProgress).toBe(true);
+ });
+});
diff --git a/ui/src/Components/SilenceModal/SilenceModalContent.test.js b/ui/src/Components/SilenceModal/SilenceModalContent.test.js
new file mode 100644
index 000000000..5d570f8fe
--- /dev/null
+++ b/ui/src/Components/SilenceModal/SilenceModalContent.test.js
@@ -0,0 +1,40 @@
+import React from "react";
+
+import { shallow } from "enzyme";
+
+import { AlertStore } from "Stores/AlertStore";
+import { SilenceFormStore } from "Stores/SilenceFormStore";
+import { SilenceModalContent } from "./SilenceModalContent";
+
+let alertStore;
+let silenceFormStore;
+
+beforeEach(() => {
+ alertStore = new AlertStore([]);
+ silenceFormStore = new SilenceFormStore();
+});
+
+const ShallowSilenceModalContent = () => {
+ return shallow(
+
+ );
+};
+
+describe("", () => {
+ it("renders SilenceForm when silenceFormStore.data.inProgress is false", () => {
+ silenceFormStore.data.inProgress = false;
+ const tree = ShallowSilenceModalContent();
+ const form = tree.find("SilenceForm");
+ expect(form).toHaveLength(1);
+ });
+
+ it("renders SilenceSubmitController when silenceFormStore.data.inProgress is true", () => {
+ silenceFormStore.data.inProgress = true;
+ const tree = ShallowSilenceModalContent();
+ const ctrl = tree.find("SilenceSubmitController");
+ expect(ctrl).toHaveLength(1);
+ });
+});