From 241cd2fa087d31128a24f94b27f048322f1620ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Mon, 27 Aug 2018 23:22:49 +0100 Subject: [PATCH] feat(tests): add test coverage for AlertManagerInput --- .../SilenceModal/AlertManagerInput.test.js | 110 +++++++++++++ .../AlertManagerInput.test.js.snap | 155 ++++++++++++++++++ 2 files changed, 265 insertions(+) create mode 100644 ui/src/Components/SilenceModal/AlertManagerInput.test.js create mode 100644 ui/src/Components/SilenceModal/__snapshots__/AlertManagerInput.test.js.snap diff --git a/ui/src/Components/SilenceModal/AlertManagerInput.test.js b/ui/src/Components/SilenceModal/AlertManagerInput.test.js new file mode 100644 index 000000000..1e7257fb9 --- /dev/null +++ b/ui/src/Components/SilenceModal/AlertManagerInput.test.js @@ -0,0 +1,110 @@ +import React from "react"; + +import { shallow, mount } from "enzyme"; + +import { AlertStore } from "Stores/AlertStore"; +import { SilenceFormStore } from "Stores/SilenceFormStore"; +import { AlertManagerInput } from "./AlertManagerInput"; + +let alertStore; +let silenceFormStore; + +const AlertmanagerOption = index => ({ + label: `am${index}`, + value: `http://am${index}.example.com` +}); + +beforeEach(() => { + alertStore = new AlertStore([]); + alertStore.data.upstreams.instances = [ + { name: "am1", uri: "http://am1.example.com", error: "" }, + { name: "am2", uri: "http://am2.example.com", error: "" }, + { name: "am3", uri: "http://am3.example.com", error: "" } + ]; + silenceFormStore = new SilenceFormStore(); +}); + +const ShallowAlertManagerInput = () => { + return shallow( + + ); +}; + +const MountedAlertManagerInput = () => { + return mount( + + ); +}; + +const ValidateSuggestions = () => { + const tree = MountedAlertManagerInput(); + // clear all selected instances, they are selected by default + const clear = tree.find("ClearIndicator"); + // https://github.com/JedWatson/react-select/blob/c22d296d50917e210836fb011ae3e565895e6440/src/__tests__/Select.test.js#L1873 + clear.simulate("mousedown", { button: 0 }); + // click on the react-select component doesn't seem to trigger options + // rendering in tests, so change the input instead + tree.find("input").simulate("change", { target: { value: "am" } }); + return tree; +}; + +describe("", () => { + it("matches snapshot", () => { + const tree = ShallowAlertManagerInput(); + expect(tree).toMatchSnapshot(); + }); + + it("all available Alertmanager instances are selected by default", () => { + ShallowAlertManagerInput(); + expect(silenceFormStore.data.alertmanagers).toHaveLength(3); + for (let i = 1; i <= 3; i++) { + expect(silenceFormStore.data.alertmanagers).toContainEqual( + AlertmanagerOption(i) + ); + } + }); + + it("renders all 3 suggestions", () => { + const tree = ValidateSuggestions(); + const options = tree.find("[role='option']"); + expect(options).toHaveLength(3); + expect(options.at(0).text()).toBe("am1"); + expect(options.at(1).text()).toBe("am2"); + expect(options.at(2).text()).toBe("am3"); + }); + + it("clicking on options appends them to silenceFormStore.data.alertmanagers", () => { + const tree = ValidateSuggestions(); + const options = tree.find("[role='option']"); + options.at(0).simulate("click"); + options.at(2).simulate("click"); + expect(silenceFormStore.data.alertmanagers).toHaveLength(2); + expect(silenceFormStore.data.alertmanagers).toContainEqual( + AlertmanagerOption(1) + ); + expect(silenceFormStore.data.alertmanagers).toContainEqual( + AlertmanagerOption(3) + ); + }); + + it("silenceFormStore.data.alertmanagers gets updated from alertStore.data.upstreams.instances on mismatch", () => { + const tree = ShallowAlertManagerInput(); + alertStore.data.upstreams.instances[0] = { + name: "am1", + uri: "http://am1.example.com/new", + error: "" + }; + // force update since this is where the mismatch check lives + tree.instance().componentDidUpdate(); + expect(silenceFormStore.data.alertmanagers).toContainEqual({ + label: "am1", + value: "http://am1.example.com/new" + }); + }); +}); diff --git a/ui/src/Components/SilenceModal/__snapshots__/AlertManagerInput.test.js.snap b/ui/src/Components/SilenceModal/__snapshots__/AlertManagerInput.test.js.snap new file mode 100644 index 000000000..0a6937c7b --- /dev/null +++ b/ui/src/Components/SilenceModal/__snapshots__/AlertManagerInput.test.js.snap @@ -0,0 +1,155 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` matches snapshot 1`] = ` + false, + "nodeType" => false, + "$$typeof" => false, + "@@__IMMUTABLE_LIST__@@" => false, + "@@__IMMUTABLE_SET__@@" => false, + "@@__IMMUTABLE_MAP__@@" => false, + "@@__IMMUTABLE_STACK__@@" => false, + "toJSON" => false, + }, + "proxy": [Circular], + "target": Object { + "label": "am1", + "value": "http://am1.example.com", + Symbol(mobx administration): [Circular], + }, + "values": Map { + "label" => "am1", + "value" => "http://am1.example.com", + }, + }, + }, + Object { + "label": "am2", + "value": "http://am2.example.com", + Symbol(mobx administration): ObservableObjectAdministration$$1 { + "defaultEnhancer": [Function], + "keysAtom": Atom$$1 { + "diffValue": 0, + "isBeingObserved": false, + "isPendingUnobservation": false, + "lastAccessedBy": 0, + "lowestObserverState": 2, + "name": "Silence form store.alertmanagers[..].keys", + "observers": Set {}, + }, + "name": "Silence form store.alertmanagers[..]", + "pendingKeys": Map { + "cheerio" => false, + "nodeType" => false, + "$$typeof" => false, + "@@__IMMUTABLE_LIST__@@" => false, + "@@__IMMUTABLE_SET__@@" => false, + "@@__IMMUTABLE_MAP__@@" => false, + "@@__IMMUTABLE_STACK__@@" => false, + "toJSON" => false, + }, + "proxy": [Circular], + "target": Object { + "label": "am2", + "value": "http://am2.example.com", + Symbol(mobx administration): [Circular], + }, + "values": Map { + "label" => "am2", + "value" => "http://am2.example.com", + }, + }, + }, + Object { + "label": "am3", + "value": "http://am3.example.com", + Symbol(mobx administration): ObservableObjectAdministration$$1 { + "defaultEnhancer": [Function], + "keysAtom": Atom$$1 { + "diffValue": 0, + "isBeingObserved": false, + "isPendingUnobservation": false, + "lastAccessedBy": 0, + "lowestObserverState": 2, + "name": "Silence form store.alertmanagers[..].keys", + "observers": Set {}, + }, + "name": "Silence form store.alertmanagers[..]", + "pendingKeys": Map { + "cheerio" => false, + "nodeType" => false, + "$$typeof" => false, + "@@__IMMUTABLE_LIST__@@" => false, + "@@__IMMUTABLE_SET__@@" => false, + "@@__IMMUTABLE_MAP__@@" => false, + "@@__IMMUTABLE_STACK__@@" => false, + "toJSON" => false, + }, + "proxy": [Circular], + "target": Object { + "label": "am3", + "value": "http://am3.example.com", + Symbol(mobx administration): [Circular], + }, + "values": Map { + "label" => "am3", + "value" => "http://am3.example.com", + }, + }, + }, + ] + } + instanceId="silence-input-alertmanagers" + isMulti={true} + onChange={[Function]} + options={ + Array [ + Object { + "label": "am1", + "value": "http://am1.example.com", + }, + Object { + "label": "am2", + "value": "http://am2.example.com", + }, + Object { + "label": "am3", + "value": "http://am3.example.com", + }, + ] + } + placeholder="Alertmanager" + styles={ + Object { + "control": [Function], + "indicatorsContainer": [Function], + "multiValue": [Function], + "multiValueLabel": [Function], + "multiValueRemove": [Function], + "option": [Function], + "valueContainer": [Function], + "valueLabel": [Function], + } + } +/> +`;