From c994b3cee4b464c087222cda47d01514ba7088ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?= Date: Sun, 19 Jul 2020 13:37:00 +0100 Subject: [PATCH] fix(ui): don't render silence fallback on alert group unmount --- .../AlertGrid/AlertGroup/Silences.test.js | 109 ++++++++++++++++++ .../Grid/AlertGrid/AlertGroup/Silences.tsx | 59 ++++++---- .../__snapshots__/Silences.test.js.snap | 70 +++++++++++ 3 files changed, 217 insertions(+), 21 deletions(-) create mode 100644 ui/src/Components/Grid/AlertGrid/AlertGroup/Silences.test.js create mode 100644 ui/src/Components/Grid/AlertGrid/AlertGroup/__snapshots__/Silences.test.js.snap diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silences.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silences.test.js new file mode 100644 index 000000000..d3a83f38e --- /dev/null +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silences.test.js @@ -0,0 +1,109 @@ +import React from "react"; + +import { mount } from "enzyme"; + +import toDiffableHtml from "diffable-html"; + +import { MockSilence } from "__mocks__/Alerts"; +import { AlertStore } from "Stores/AlertStore"; +import { SilenceFormStore } from "Stores/SilenceFormStore"; +import { RenderSilence } from "./Silences"; + +describe("", () => { + let alertStore; + let silenceFormStore; + + beforeEach(() => { + alertStore = new AlertStore([]); + silenceFormStore = new SilenceFormStore(); + }); + + it("renders fallback text if silence is not present in AlertStore", () => { + const tree = mount( + + ); + expect(tree.text()).toBe("Silenced by 1234567890"); + expect(toDiffableHtml(tree.html())).toMatchSnapshot(); + }); + + it("renders ManagedSilence if silence is present in AlertStore", () => { + const silence = MockSilence(); + + alertStore.data.silences = { fakeCluster: { [silence.id]: silence } }; + + const tree = mount( + + ); + expect(tree.find("ManagedSilence")).toHaveLength(1); + expect(tree.text()).toMatch(/Mocked Silence/); + expect(toDiffableHtml(tree.html())).toMatchSnapshot(); + }); + + it("re-render when silence was removed AlertStore is a no-op", () => { + const silence = MockSilence(); + + alertStore.data.silences = { fakeCluster: { [silence.id]: silence } }; + + const tree = mount( + + ); + expect(tree.find("ManagedSilence")).toHaveLength(1); + const snapshot = toDiffableHtml(tree.html()); + + alertStore.data.silences = {}; + + tree.setProps({}); + expect(tree.find("ManagedSilence")).toHaveLength(1); + expect(toDiffableHtml(tree.html())).toBe(snapshot); + }); + + it("re-render when silence ID was changed updates it", () => { + const tree = mount( + + ); + expect(tree.text()).toBe("Silenced by silence1"); + + tree.setProps({ silenceID: "silence2" }); + expect(tree.text()).toBe("Silenced by silence2"); + }); + + it("re-render when cluster name was changed updates it", () => { + const tree = mount( + + ); + expect(tree.text()).toBe("Silenced by 1234567890"); + + tree.setProps({ cluster: "cluster2" }); + expect(tree.text()).toBe("Silenced by 1234567890"); + }); +}); diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silences.tsx b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silences.tsx index b2053296b..2a2e2d8e4 100644 --- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silences.tsx +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silences.tsx @@ -1,4 +1,4 @@ -import React, { FC } from "react"; +import React, { FC, memo } from "react"; import { APISilenceT } from "Models/APITypes"; import { AlertStore } from "Stores/AlertStore"; @@ -36,30 +36,47 @@ const RenderSilence: FC<{ afterUpdate: () => void; cluster: string; silenceID: string; -}> = ({ alertStore, silenceFormStore, afterUpdate, cluster, silenceID }) => { - const silence = GetSilenceFromStore(alertStore, cluster, silenceID); +}> = memo( + ({ alertStore, silenceFormStore, afterUpdate, cluster, silenceID }) => { + const silence = GetSilenceFromStore(alertStore, cluster, silenceID); + + if (silence === null) { + return ( + + ); + } - if (silence === null) { return ( - + cluster={cluster} + alertCount={0} + alertCountAlwaysVisible={false} + silence={silence} + alertStore={alertStore} + silenceFormStore={silenceFormStore} + onDidUpdate={afterUpdate} + /> ); + }, + (prevProps, nextProps) => { + if ( + prevProps.cluster == nextProps.cluster && + prevProps.silenceID === nextProps.silenceID + ) { + return ( + GetSilenceFromStore( + nextProps.alertStore, + nextProps.cluster, + nextProps.silenceID + ) === null + ); + } + return false; } - - return ( - - ); -}; +); export { RenderSilence }; diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/__snapshots__/Silences.test.js.snap b/ui/src/Components/Grid/AlertGrid/AlertGroup/__snapshots__/Silences.test.js.snap new file mode 100644 index 000000000..6afe305c9 --- /dev/null +++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/__snapshots__/Silences.test.js.snap @@ -0,0 +1,70 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders ManagedSilence if silence is present in AlertStore 1`] = ` +" +
+
+
+
+ + + + +
+
+
+ Mocked Silence +
+
+ + — me@example.com + + + Expired 21 years ago + +
+
+
+
+ + + + +
+
+
+
+
+" +`; + +exports[` renders fallback text if silence is not present in AlertStore 1`] = ` +" +
+ + Silenced by 1234567890 + +
+" +`;