From fbdea793549a8ccaeea4826f2c81eff444b74ff8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 16:45:40 +0100
Subject: [PATCH 01/17] fix(tests): add test coverage for missed branches in
AppBoot
---
ui/src/AppBoot.test.js | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/ui/src/AppBoot.test.js b/ui/src/AppBoot.test.js
index 705301c97..0f390bf58 100644
--- a/ui/src/AppBoot.test.js
+++ b/ui/src/AppBoot.test.js
@@ -87,4 +87,14 @@ describe("ParseDefaultFilters()", () => {
expect(filters).toContain("foo=bar");
expect(filters).toContain("bar=~baz");
});
+
+ it("returns [] on filters attr that decodes to an object instead of an array", () => {
+ const filters = FiltersSetting({ foo: "bar" });
+ expect(filters).toHaveLength(0);
+ });
+
+ it("returns [] on filters attr that decodes to a string instead of an array", () => {
+ const filters = FiltersSetting("foo=bar");
+ expect(filters).toHaveLength(0);
+ });
});
From ba6ed7f9ff2a1d1e0608f752a901382156478901 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 16:50:50 +0100
Subject: [PATCH 02/17] fix(tests): add test coverage for missed branches in
AlertGrid
---
ui/src/Components/Grid/AlertGrid/index.test.js | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/ui/src/Components/Grid/AlertGrid/index.test.js b/ui/src/Components/Grid/AlertGrid/index.test.js
index 4f3f7f3e6..8e7e5dd6e 100644
--- a/ui/src/Components/Grid/AlertGrid/index.test.js
+++ b/ui/src/Components/Grid/AlertGrid/index.test.js
@@ -89,6 +89,15 @@ describe("", () => {
expect(instance.masonryComponentReference.ref.forcePack).toHaveBeenCalled();
});
+ it("masonryRepack() doesn't crash when masonryComponentReference.ref=false`", () => {
+ const tree = ShallowAlertGrid();
+ const instance = tree.instance();
+ const repackSpy = jest.spyOn(instance, "masonryRepack");
+ instance.masonryComponentReference.ref = false;
+ instance.componentDidUpdate();
+ expect(repackSpy).toHaveBeenCalled();
+ });
+
it("calling storeMasonryRef() saves the ref in local store", () => {
const tree = ShallowAlertGrid();
const instance = tree.instance();
From 2bb0f2ffb09f63275a409f7592821876b88d62b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 17:49:43 +0100
Subject: [PATCH 03/17] fix(ui): fix the logic for deciding when to show
@alertmanager labels in the footer, add a test
---
.../Grid/AlertGrid/AlertGroup/index.js | 13 +++++++++---
.../Grid/AlertGrid/AlertGroup/index.test.js | 21 +++++++++++++++++++
2 files changed, 31 insertions(+), 3 deletions(-)
diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.js
index 815ddf9d5..a85aed849 100644
--- a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.js
+++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.js
@@ -32,6 +32,15 @@ LoadButton.propTypes = {
action: PropTypes.func.isRequired
};
+const AllAlertsAreUsingSameAlertmanagers = alerts => {
+ const usedAMs = alerts.map(alert =>
+ alert.alertmanager.map(am => am.name).sort()
+ );
+ return usedAMs.every(
+ listOfAMs => JSON.stringify(listOfAMs) === JSON.stringify(usedAMs[0])
+ );
+};
+
const AlertGroup = observer(
class AlertGroup extends Component {
static propTypes = {
@@ -137,9 +146,7 @@ const AlertGroup = observer(
// alertmanagers (and there's > 1 alert to show, there's no footer for 1)
showAlertmanagersInFooter =
group.alerts.length > 1 &&
- Object.values(group.alertmanagerCount).every(
- elem => elem === Object.values(group.alertmanagerCount)[0]
- );
+ AllAlertsAreUsingSameAlertmanagers(group.alerts);
if (showAlertmanagersInFooter) {
footerAlertmanagers = group.alerts[0].alertmanager.map(am => am.name);
}
diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.js
index 9c71d5cac..3739ac412 100644
--- a/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.js
+++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/index.test.js
@@ -65,6 +65,27 @@ describe("", () => {
expect(tree.find("GroupFooter").html()).toMatch(/@alertmanager: default/);
});
+ it("doesn't render alertmanager labels in footer when they are unique", () => {
+ MockAlerts(5);
+ for (let i = 0; i < group.alerts.length; i++) {
+ group.alerts[i].alertmanager[0].name = `fakeAlertmanager${i}`;
+ }
+ group.alertmanagerCount = {
+ fakeAlertmanager0: 1,
+ fakeAlertmanager1: 1,
+ fakeAlertmanager2: 1,
+ fakeAlertmanager3: 1,
+ fakeAlertmanager4: 1
+ };
+ const tree = MountedAlertGroup(jest.fn(), true);
+
+ const alerts = tree.find("ul.list-group");
+ expect(alerts.html()).toMatch(/@alertmanager:/);
+
+ const footer = tree.find("GroupFooter");
+ expect(footer.html()).not.toMatch(/@alertmanager:/);
+ });
+
it("only renders titlebar when collapsed", () => {
MockAlerts(10);
const tree = MountedAlertGroup(jest.fn(), false);
From a95b919872138837cc7726afe0c1bb563c352c90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 17:59:51 +0100
Subject: [PATCH 04/17] fix(tests): add missing linkify test coverage
---
.../AlertGroup/Annotation/index.test.js | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Annotation/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Annotation/index.test.js
index ed1edbbad..31a3bfa67 100644
--- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Annotation/index.test.js
+++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Annotation/index.test.js
@@ -59,6 +59,18 @@ const MountedNonLinkAnnotation = visible => {
);
};
+const MountedNonLinkAnnotationContainingLink = visible => {
+ return mount(
+
+ );
+};
+
describe("", () => {
it("matches snapshot when visible=true", () => {
const tree = ShallowNonLinkAnnotation(true);
@@ -80,6 +92,12 @@ describe("", () => {
expect(tree.html()).not.toMatch(/some long text/);
});
+ it("links inside annotation are rendered as a.href", () => {
+ const tree = MountedNonLinkAnnotationContainingLink(true);
+ const link = tree.find("a[href='http://example.com']");
+ expect(link.text()).toBe("http://example.com");
+ });
+
it("clicking on + icon hides the value", () => {
const tree = MountedNonLinkAnnotation(true);
expect(tree.html()).toMatch(/fa-search-minus/);
@@ -89,6 +107,13 @@ describe("", () => {
expect(tree.html()).not.toMatch(/some long text/);
});
+ it("clicking on a link inside annotation doesn't hide the value", () => {
+ const tree = MountedNonLinkAnnotationContainingLink(true);
+ expect(tree.html()).toMatch(/fa-search-minus/);
+ tree.find("a").simulate("click");
+ expect(tree.html()).toMatch(/fa-search-minus/);
+ });
+
it("clicking on - icon shows the value", () => {
const tree = MountedNonLinkAnnotation(false);
expect(tree.html()).toMatch(/fa-search-plus/);
From bd4e549b270d968082278d906a66d44643af24d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 18:02:58 +0100
Subject: [PATCH 05/17] fix(tests): cover regex matches in silence tests
---
.../AlertGroup/Silence/__snapshots__/index.test.js.snap | 3 +++
.../Grid/AlertGrid/AlertGroup/Silence/index.test.js | 5 +++++
2 files changed, 8 insertions(+)
diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/__snapshots__/index.test.js.snap b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/__snapshots__/index.test.js.snap
index 2c7daac4d..fe7c57330 100644
--- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/__snapshots__/index.test.js.snap
+++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/__snapshots__/index.test.js.snap
@@ -112,6 +112,9 @@ exports[` matches snapshot with expaned details 1`] = `
alertname=MockAlert
+
+ instance=~foo[0-9]+
+
"
diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js
index 56ddd651b..4eb9b29de 100644
--- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js
+++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Silence/index.test.js
@@ -30,6 +30,11 @@ const silence = {
name: "alertname",
value: "MockAlert",
isRegex: false
+ },
+ {
+ name: "instance",
+ value: "foo[0-9]+",
+ isRegex: true
}
],
startsAt: "2000-01-01T10:00:00Z",
From 2ee69f9c0862a4b54f5cddb6fd7de7a8f8c79d3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 18:09:46 +0100
Subject: [PATCH 06/17] fix(tests): add missing HistoryLabels tests
---
.../Labels/HistoryLabel/index.test.js | 34 +++++++++++++++++++
1 file changed, 34 insertions(+)
create mode 100644 ui/src/Components/Labels/HistoryLabel/index.test.js
diff --git a/ui/src/Components/Labels/HistoryLabel/index.test.js b/ui/src/Components/Labels/HistoryLabel/index.test.js
new file mode 100644
index 000000000..fb64c67ae
--- /dev/null
+++ b/ui/src/Components/Labels/HistoryLabel/index.test.js
@@ -0,0 +1,34 @@
+import React from "react";
+
+import { shallow } from "enzyme";
+
+import { AlertStore } from "Stores/AlertStore";
+
+import { HistoryLabel } from ".";
+
+let alertStore;
+
+beforeEach(() => {
+ alertStore = new AlertStore([]);
+});
+
+describe("", () => {
+ it("renders name, matcher and value if all are set", () => {
+ const tree = shallow(
+
+ );
+ expect(tree.text()).toBe("foo=bar");
+ });
+
+ it("renders only value if name is falsey", () => {
+ const tree = shallow(
+
+ );
+ expect(tree.text()).toBe("bar");
+ });
+});
From 5e0c766f4477fc856c041918698b61dcf5a61c19 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 18:14:00 +0100
Subject: [PATCH 07/17] fix(tests): use diffable html instead tree snapshots
---
.../__snapshots__/index.test.js.snap | 1222 ++++-------------
ui/src/Components/MultiSelect/index.test.js | 12 +-
2 files changed, 281 insertions(+), 953 deletions(-)
diff --git a/ui/src/Components/MultiSelect/__snapshots__/index.test.js.snap b/ui/src/Components/MultiSelect/__snapshots__/index.test.js.snap
index 318800f69..edee4f5ad 100644
--- a/ui/src/Components/MultiSelect/__snapshots__/index.test.js.snap
+++ b/ui/src/Components/MultiSelect/__snapshots__/index.test.js.snap
@@ -1,968 +1,294 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[` matches snapshot when focused 1`] = `
-
-
+
-
-
+
+ 0 results available. Select is focused ,type to refine list, press Down to open the menu,
+
+
+
+"
`;
exports[` matches snapshot with a value 1`] = `
-
+"
+
+"
`;
exports[` matches snapshot with defaults 1`] = `
-
+"
+
+"
`;
exports[` matches snapshot with isMulti=true 1`] = `
-
+"
+
+"
`;
exports[` matches snapshot with isMulti=true and a value 1`] = `
-
+"
+
+"
`;
diff --git a/ui/src/Components/MultiSelect/index.test.js b/ui/src/Components/MultiSelect/index.test.js
index b575edef4..a60fe54d5 100644
--- a/ui/src/Components/MultiSelect/index.test.js
+++ b/ui/src/Components/MultiSelect/index.test.js
@@ -2,6 +2,8 @@ import React from "react";
import { shallow, mount } from "enzyme";
+import toDiffableHtml from "diffable-html";
+
import { MultiSelect } from ".";
const Option = value => ({ label: value, value: value });
@@ -25,19 +27,19 @@ class CustomMultiSelect extends MultiSelect {
describe("", () => {
it("matches snapshot with defaults", () => {
const tree = shallow();
- expect(tree).toMatchSnapshot();
+ expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
it("matches snapshot with isMulti=true", () => {
const tree = shallow();
- expect(tree).toMatchSnapshot();
+ expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
it("matches snapshot when focused", () => {
// this test is to cover styles state.isFocused conditions
const tree = mount();
tree.find("input").simulate("focus");
- expect(tree).toMatchSnapshot();
+ expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
it("matches snapshot with a value", () => {
@@ -47,7 +49,7 @@ describe("", () => {
options={[Option("foo", Option("bar"))]}
/>
);
- expect(tree).toMatchSnapshot();
+ expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
it("matches snapshot with isMulti=true and a value", () => {
@@ -58,6 +60,6 @@ describe("", () => {
options={[Option("foo", Option("bar"))]}
/>
);
- expect(tree).toMatchSnapshot();
+ expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
});
From bbbcb497a5c4f3322a3c6dc96ea586fbe8fca7b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 18:21:22 +0100
Subject: [PATCH 08/17] fix(tests): format options correctly
---
ui/src/Components/MultiSelect/index.test.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/ui/src/Components/MultiSelect/index.test.js b/ui/src/Components/MultiSelect/index.test.js
index a60fe54d5..59b0d236d 100644
--- a/ui/src/Components/MultiSelect/index.test.js
+++ b/ui/src/Components/MultiSelect/index.test.js
@@ -46,7 +46,7 @@ describe("", () => {
const tree = shallow(
);
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
@@ -57,7 +57,7 @@ describe("", () => {
);
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
From e0d49175664f70f7a831a57e0f108cbef3192b65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 18:27:36 +0100
Subject: [PATCH 09/17] fix(ui): remove dead code
isSelected doesn't seem to get trigger in any way
---
ui/src/Components/MultiSelect/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/src/Components/MultiSelect/index.js b/ui/src/Components/MultiSelect/index.js
index d8a528d52..3b4b82dc3 100644
--- a/ui/src/Components/MultiSelect/index.js
+++ b/ui/src/Components/MultiSelect/index.js
@@ -78,7 +78,7 @@ const ReactSelectStyles = {
}),
option: (base, state) => ({
...base,
- color: state.isSelected ? "#95a5a6" : "inherit",
+ color: "inherit",
backgroundColor: "inherit",
"&:hover": { color: "#fff", backgroundColor: "#455a64", cursor: "pointer" }
})
From 96448090543caef2b57358e2202cf72278545003 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 18:57:44 +0100
Subject: [PATCH 10/17] fix(tests): add missing coverage cases for FilerInput
---
.../NavBar/FilterInput/index.test.js | 36 ++++++++++++++++++-
1 file changed, 35 insertions(+), 1 deletion(-)
diff --git a/ui/src/Components/NavBar/FilterInput/index.test.js b/ui/src/Components/NavBar/FilterInput/index.test.js
index 996e56193..296835244 100644
--- a/ui/src/Components/NavBar/FilterInput/index.test.js
+++ b/ui/src/Components/NavBar/FilterInput/index.test.js
@@ -63,7 +63,16 @@ describe("", () => {
);
});
- it("Clicking on form-control div focuses input", () => {
+ it("submit should be no-op if input value is empty", () => {
+ const tree = MountedInput();
+ const instance = tree.instance();
+ instance.inputStore.value = "";
+ expect(alertStore.filters.values).toHaveLength(0);
+ tree.find("form").simulate("submit");
+ expect(alertStore.filters.values).toHaveLength(0);
+ });
+
+ it("clicking on form-control div focuses input", () => {
const tree = MountedInput();
const instance = tree.instance();
const inputSpy = jest.spyOn(instance.inputStore.ref.input, "focus");
@@ -71,6 +80,22 @@ describe("", () => {
formControl.simulate("click");
expect(inputSpy).toHaveBeenCalledTimes(1);
});
+
+ it("clicking on a label doesn't trigger input focus", () => {
+ alertStore.filters.values = [NewUnappliedFilter("foo=bar")];
+ const tree = MountedInput();
+ const instance = tree.instance();
+ const inputSpy = jest.spyOn(instance.inputStore.ref.input, "focus");
+ tree.find("FilterInputLabel").simulate("click");
+ expect(inputSpy).not.toHaveBeenCalled();
+ });
+
+ it("componentDidMount executes even when inputStore.ref=null", () => {
+ const tree = MountedInput();
+ const instance = tree.instance();
+ instance.inputStore.ref = null;
+ instance.componentDidMount();
+ });
});
describe("", () => {
@@ -89,6 +114,15 @@ describe("", () => {
expect(instance.inputStore.suggestions).toContain("foo=~bar");
});
+ it("doesn't fetch any suggestion if the input value is empty", () => {
+ fetch.mockResponseOnce(JSON.stringify(["foo=bar", "foo=~bar"]));
+
+ const tree = MountedInput();
+ const instance = tree.instance();
+ instance.onSuggestionsFetchRequested({ value: "" });
+ expect(fetch.mock.calls).toHaveLength(0);
+ });
+
it("clicking on a suggestion adds it to filters", async () => {
fetch.mockResponse(JSON.stringify(["foo=bar", "foo=~bar"]));
From 48f9176cf9593404c47ba9bb90e160f6136a233d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 19:02:23 +0100
Subject: [PATCH 11/17] fix(tests): add missing coverage cases for
AlertManagerInput
---
ui/src/Components/SilenceModal/AlertManagerInput.test.js | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/ui/src/Components/SilenceModal/AlertManagerInput.test.js b/ui/src/Components/SilenceModal/AlertManagerInput.test.js
index 1e7257fb9..75c42bb1b 100644
--- a/ui/src/Components/SilenceModal/AlertManagerInput.test.js
+++ b/ui/src/Components/SilenceModal/AlertManagerInput.test.js
@@ -70,6 +70,15 @@ describe("", () => {
}
});
+ it("doesn't override last selected Alertmanager instances on mount", () => {
+ silenceFormStore.data.alertmanagers = [AlertmanagerOption(1)];
+ ShallowAlertManagerInput();
+ expect(silenceFormStore.data.alertmanagers).toHaveLength(1);
+ expect(silenceFormStore.data.alertmanagers).toContainEqual(
+ AlertmanagerOption(1)
+ );
+ });
+
it("renders all 3 suggestions", () => {
const tree = ValidateSuggestions();
const options = tree.find("[role='option']");
From b5112880a59ec4cb38328a4b3196cb52a0ffbee2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 19:12:59 +0100
Subject: [PATCH 12/17] fix(tests): add missing coverage cases for
LabelNameInput
---
ui/src/Components/SilenceModal/LabelNameInput.test.js | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/ui/src/Components/SilenceModal/LabelNameInput.test.js b/ui/src/Components/SilenceModal/LabelNameInput.test.js
index dbcc8934e..6af967fd4 100644
--- a/ui/src/Components/SilenceModal/LabelNameInput.test.js
+++ b/ui/src/Components/SilenceModal/LabelNameInput.test.js
@@ -77,7 +77,7 @@ describe("", () => {
}, 100);
});
- it("suggestions are empited on failed fetch", done => {
+ it("suggestions are emptied on failed fetch", done => {
fetch.mockReject(new Error("fake error message"));
ShallowLabelNameInput();
// use timeout since mount will call fetch
@@ -86,4 +86,12 @@ describe("", () => {
done();
}, 100);
});
+
+ it("doesn't fetch suggestions if value is changed to empty string", () => {
+ const tree = MountedLabelNameInput();
+ const instance = tree.instance();
+ const fetchSpy = jest.spyOn(instance, "populateValueSuggestions");
+ instance.onChange("");
+ expect(fetchSpy).not.toHaveBeenCalled();
+ });
});
From 38b0cb15570c8e33ca4f1092250b882be45854d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 19:21:50 +0100
Subject: [PATCH 13/17] fix(ui): remove dead code
---
ui/src/Components/SilenceModal/DateTimeSelect/index.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/src/Components/SilenceModal/DateTimeSelect/index.js b/ui/src/Components/SilenceModal/DateTimeSelect/index.js
index 650f0192c..e8f902ec8 100644
--- a/ui/src/Components/SilenceModal/DateTimeSelect/index.js
+++ b/ui/src/Components/SilenceModal/DateTimeSelect/index.js
@@ -114,7 +114,7 @@ const CalculateChangeValueUp = (currentValue, step) => {
return 1;
}
// otherwise use step or a value that moves current value to the next step
- return step - (currentValue % step) || step;
+ return step - (currentValue % step);
};
// calculate value for duration decrease button using a goal step
From 617895e4716b10c0239363ac912510ac7ff4d69f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 19:23:50 +0100
Subject: [PATCH 14/17] fix(tests): add missing coverage cases for
SilenceFormStore
---
ui/src/Stores/SilenceFormStore.test.js | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/ui/src/Stores/SilenceFormStore.test.js b/ui/src/Stores/SilenceFormStore.test.js
index bac6d3287..8568e3389 100644
--- a/ui/src/Stores/SilenceFormStore.test.js
+++ b/ui/src/Stores/SilenceFormStore.test.js
@@ -70,6 +70,11 @@ describe("SilenceFormStore.data", () => {
);
});
+ it("deleteMatcher() is a no-op when matcher list is empty", () => {
+ store.data.deleteMatcher(1);
+ expect(store.data.matchers).toHaveLength(0);
+ });
+
it("fillMatchersFromGroup() creates correct matcher object for a group", () => {
const group = MockGroup();
store.data.fillMatchersFromGroup(group);
From 852dcfbdc66d43b952615da8998c523ad8076a95 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 19:47:39 +0100
Subject: [PATCH 15/17] fix(ui): compare correct attributes
---
ui/src/Stores/AlertStore.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ui/src/Stores/AlertStore.js b/ui/src/Stores/AlertStore.js
index 21e03792d..f89262e49 100644
--- a/ui/src/Stores/AlertStore.js
+++ b/ui/src/Stores/AlertStore.js
@@ -280,7 +280,7 @@ class AlertStore {
}
// settings exported via API
- if (!equal(this.settings, result.settings)) {
+ if (!equal(this.settings.values, result.settings)) {
this.settings.values = result.settings;
}
From 87c8d6e071a91de0c0f9059640d80c9293555cc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 19:56:31 +0100
Subject: [PATCH 16/17] fix(tests): add missing coverage cases for AlertStore
---
ui/src/Stores/AlertStore.js | 7 ++---
ui/src/Stores/AlertStore.test.js | 52 ++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 4 deletions(-)
diff --git a/ui/src/Stores/AlertStore.js b/ui/src/Stores/AlertStore.js
index f89262e49..130e5ec73 100644
--- a/ui/src/Stores/AlertStore.js
+++ b/ui/src/Stores/AlertStore.js
@@ -294,10 +294,8 @@ class AlertStore {
this.info.totalAlerts = 0;
// all unapplied filters should be marked applied to reset progress indicator
- for (const [index, filter] of this.filters.values.entries()) {
- if (!filter.applied) {
- this.filters.values[index].applied = true;
- }
+ for (let i = 0; i < this.filters.values.length; i++) {
+ this.filters.values[i].applied = true;
}
return { error: err };
@@ -310,5 +308,6 @@ export {
FormatUnseeBackendURI,
FormatAPIFilterQuery,
DecodeLocationSearch,
+ UpdateLocationSearch,
NewUnappliedFilter
};
diff --git a/ui/src/Stores/AlertStore.test.js b/ui/src/Stores/AlertStore.test.js
index b8958bd1e..56cd6216a 100644
--- a/ui/src/Stores/AlertStore.test.js
+++ b/ui/src/Stores/AlertStore.test.js
@@ -5,6 +5,7 @@ import {
AlertStoreStatuses,
FormatUnseeBackendURI,
DecodeLocationSearch,
+ UpdateLocationSearch,
NewUnappliedFilter
} from "Stores/AlertStore";
@@ -63,6 +64,13 @@ describe("AlertStore.filters", () => {
expect(store.filters.values[0]).toMatchObject(NewUnappliedFilter("foo"));
});
+ it("addFilter should not allow duplicates", () => {
+ const store = new AlertStore([]);
+ store.filters.addFilter("foo");
+ store.filters.addFilter("foo");
+ expect(store.filters.values).toHaveLength(1);
+ });
+
it("removeFilter('foo') should remove passed filter if it's defined", () => {
const store = new AlertStore([]);
store.filters.addFilter("foo");
@@ -180,6 +188,23 @@ describe("DecodeLocationSearch", () => {
});
});
+describe("UpdateLocationSearch", () => {
+ it("{q: foo} is pushed to location.search", () => {
+ UpdateLocationSearch({ q: "foo" });
+ expect(window.location.search).toBe("?q=foo");
+ });
+
+ it("{a: foo} is not pushed to location.search", () => {
+ UpdateLocationSearch({ a: "foo" });
+ expect(window.location.search).toBe("");
+ });
+
+ it("{a: foo, q: bar} is pushed to location.search", () => {
+ UpdateLocationSearch({ a: "foo", q: "bar" });
+ expect(window.location.search).toBe("?q=bar");
+ });
+});
+
describe("AlertStore.fetch", () => {
it("parseAPIResponse() rejects a response with mismatched filters", () => {
const consoleSpy = jest.spyOn(console, "info");
@@ -247,7 +272,34 @@ describe("AlertStore.fetch", () => {
it("unapplied filters are marked as applied on fetch error", async () => {
fetch.mockReject("Fetch error");
const store = new AlertStore([NewUnappliedFilter("foo")]);
+ store.filters.values[0].applied = false;
await expect(store.fetch()).resolves.toHaveProperty("error");
expect(store.filters.values[0].applied).toBe(true);
});
+
+ it("stored settings are updated if needed after fetch", async () => {
+ const response = EmptyAPIResponse();
+ fetch.mockResponse(JSON.stringify(response));
+
+ const store = new AlertStore(["label=value"]);
+
+ // initial fetch, should update settings
+ store.settings.values = { foo: "bar" };
+ await expect(store.fetch()).resolves.toBeUndefined();
+ expect(store.settings.values).toMatchObject({
+ staticColorLabels: ["job"],
+ annotationsDefaultHidden: false,
+ annotationsHidden: [],
+ annotationsVisible: []
+ });
+
+ // second fetch, should keep same settings
+ await expect(store.fetch()).resolves.toBeUndefined();
+ expect(store.settings.values).toMatchObject({
+ staticColorLabels: ["job"],
+ annotationsDefaultHidden: false,
+ annotationsHidden: [],
+ annotationsVisible: []
+ });
+ });
});
From e286cf2f1c4fef57d45b6166ba57d89b739c2500 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=C5=81ukasz=20Mierzwa?=
Date: Sun, 2 Sep 2018 19:58:36 +0100
Subject: [PATCH 17/17] fix(ui): remove dead check
---
.../Components/Grid/AlertGrid/AlertGroup/Annotation/index.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/ui/src/Components/Grid/AlertGrid/AlertGroup/Annotation/index.js b/ui/src/Components/Grid/AlertGrid/AlertGroup/Annotation/index.js
index 70eae7ec5..92819de8b 100644
--- a/ui/src/Components/Grid/AlertGrid/AlertGroup/Annotation/index.js
+++ b/ui/src/Components/Grid/AlertGrid/AlertGroup/Annotation/index.js
@@ -29,8 +29,9 @@ const RenderNonLinkAnnotation = inject("alertStore")(
{
visible: true,
show(e) {
- // don't action link clicks inside Linkify
- if (e.target.nodeName !== "A") this.visible = true;
+ // Linkify only handles value, no need to check for links of
+ // collapsed annotation
+ this.visible = true;
},
hide(e) {
// don't action link clicks inside Linkify