feat(tests): add Silence component tests

This commit is contained in:
Łukasz Mierzwa
2018-09-01 19:36:01 +01:00
parent 1550025336
commit 4dfd044cc3
6 changed files with 358 additions and 1 deletions

View File

@@ -0,0 +1,118 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<Silence /> matches snapshot when data is not present in alertStore 1`] = `
"
<div>
<small class=\\"text-muted\\">
Silenced by default/4cf5fd82-1edd-4169-99d1-ff8415e72179
</small>
</div>
"
`;
exports[`<Silence /> matches snapshot when data is present in alertStore 1`] = `
"
<div class=\\"card mt-1 border-0 p-1\\">
<div class=\\"card-text mb-0\\">
<span class=\\"text-muted my-1\\">
Fake silence
<span class=\\"blockquote-footer pt-1\\">
<a class=\\"float-right cursor-pointer\\">
<svg aria-hidden=\\"true\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-up\\"
class=\\"svg-inline--fa fa-chevron-up fa-w-14 \\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M240.971 130.524l194.343 194.343c9.373 9.373 9.373 24.569 0 33.941l-22.667 22.667c-9.357 9.357-24.522 9.375-33.901.04L224 227.495 69.255 381.516c-9.379 9.335-24.544 9.317-33.901-.04l-22.667-22.667c-9.373-9.373-9.373-24.569 0-33.941L207.03 130.525c9.372-9.373 24.568-9.373 33.941-.001z\\"
>
</path>
</svg>
</a>
<cite class=\\"components-grid-alertgroup-silences mr-2\\">
me@example.com
</cite>
<span class=\\"badge badge-light nmb-05 text-nowrap text-truncate mw-100 align-bottom\\">
Expires
<time datetime=\\"946756800000\\">
in 5 hours
</time>
<div class=\\"progress silence-progress bg-white\\">
<div class=\\"progress-bar bg-success\\"
role=\\"progressbar\\"
style=\\"width: 50%;\\"
aria-valuenow=\\"50\\"
aria-valuemin=\\"0\\"
aria-valuemax=\\"100\\"
>
</div>
</div>
</span>
</span>
</span>
</div>
</div>
"
`;
exports[`<Silence /> matches snapshot with expaned details 1`] = `
"
<div class=\\"card mt-1 border-0 p-1\\">
<div class=\\"card-text mb-0\\">
<span class=\\"text-muted my-1\\">
Fake silence
<span class=\\"blockquote-footer pt-1\\">
<a class=\\"float-right cursor-pointer\\">
<svg aria-hidden=\\"true\\"
data-prefix=\\"fas\\"
data-icon=\\"chevron-down\\"
class=\\"svg-inline--fa fa-chevron-down fa-w-14 \\"
role=\\"img\\"
xmlns=\\"http://www.w3.org/2000/svg\\"
viewbox=\\"0 0 448 512\\"
>
<path fill=\\"currentColor\\"
d=\\"M207.029 381.476L12.686 187.132c-9.373-9.373-9.373-24.569 0-33.941l22.667-22.667c9.357-9.357 24.522-9.375 33.901-.04L224 284.505l154.745-154.021c9.379-9.335 24.544-9.317 33.901.04l22.667 22.667c9.373 9.373 9.373 24.569 0 33.941L240.971 381.476c-9.373 9.372-24.569 9.372-33.942 0z\\"
>
</path>
</svg>
</a>
<cite class=\\"components-grid-alertgroup-silences mr-2\\">
me@example.com
</cite>
</span>
</span>
</div>
<div class=\\"mt-1\\">
<span class=\\"components-label components-label-with-hover text-nowrap text-truncate badge badge-warning mw-100\\">
@alertmanager: default
</span>
<a class=\\"badge badge-secondary text-nowrap text-truncate px-1 mr-1\\"
href=\\"file:///mock/#/silences/4cf5fd82-1edd-4169-99d1-ff8415e72179\\"
target=\\"_blank\\"
rel=\\"noopener noreferrer\\"
>
4cf5fd82-1edd-4169-99d1-ff8415e72179
</a>
<span class=\\"badge badge-secondary text-nowrap text-truncate px-1 mr-1\\">
Silenced
<time datetime=\\"946720800000\\">
5 hours ago
</time>
</span>
<span class=\\"badge badge-secondary text-nowrap text-truncate px-1 mr-1\\">
Expires
<time datetime=\\"946756800000\\">
in 5 hours
</time>
</span>
<span class=\\"badge badge-success text-nowrap text-truncate px-1 mr-1\\">
alertname=MockAlert
</span>
</div>
</div>
"
`;

View File

@@ -228,4 +228,4 @@ const Silence = inject("alertStore")(
)
);
export { Silence };
export { Silence, SilenceDetails, SilenceExpiryBadgeWithProgress };

View File

@@ -0,0 +1,194 @@
import React from "react";
import { Provider } from "mobx-react";
import { mount, shallow } from "enzyme";
import toDiffableHtml from "diffable-html";
import { advanceTo, clear } from "jest-date-mock";
import { AlertStore } from "Stores/AlertStore";
import { Silence, SilenceDetails, SilenceExpiryBadgeWithProgress } from ".";
const mockAfterUpdate = jest.fn();
const alertmanager = {
name: "default",
uri: "file:///mock",
state: "suppressed",
startsAt: "2000-01-01T10:00:00Z",
endsAt: "0001-01-01T00:00:00Z",
source: "localhost/prometheus",
silencedBy: ["4cf5fd82-1edd-4169-99d1-ff8415e72179"]
};
const silence = {
id: "4cf5fd82-1edd-4169-99d1-ff8415e72179",
matchers: [
{
name: "alertname",
value: "MockAlert",
isRegex: false
}
],
startsAt: "2000-01-01T10:00:00Z",
endsAt: "2000-01-01T20:00:00Z",
createdAt: "0001-01-01T00:00:00Z",
createdBy: "me@example.com",
comment: "Fake silence",
jiraID: "",
jiraURL: ""
};
let alertStore;
beforeEach(() => {
advanceTo(new Date(2000, 0, 1, 15, 0, 0));
alertStore = new AlertStore([]);
alertStore.data.upstreams = {
counters: {
total: 1,
healthy: 1,
failed: 0
},
instances: [
{
name: "default",
uri: "file:///mock",
error: ""
}
]
};
alertStore.data.silences = {
default: {
"4cf5fd82-1edd-4169-99d1-ff8415e72179": silence
}
};
});
afterEach(() => {
// reset Date() to current time
clear();
});
const MountedSilence = () => {
return mount(
<Provider alertStore={alertStore}>
<Silence
alertStore={alertStore}
alertmanager={alertmanager}
silenceID="4cf5fd82-1edd-4169-99d1-ff8415e72179"
afterUpdate={mockAfterUpdate}
/>
</Provider>
);
};
describe("<Silence />", () => {
it("matches snapshot when data is present in alertStore", () => {
const tree = MountedSilence().find("Silence");
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
it("renders full silence when data is present in alertStore", () => {
const tree = MountedSilence().find("Silence");
const fallback = tree.find("FallbackSilenceDesciption");
expect(fallback).toHaveLength(0);
});
it("matches snapshot when data is not present in alertStore", () => {
alertStore.data.silences = {};
const tree = MountedSilence().find("Silence");
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
it("renders FallbackSilenceDesciption when Alertmanager data is not present in alertStore", () => {
alertStore.data.silences = {};
const tree = MountedSilence();
const fallback = tree.find("FallbackSilenceDesciption");
expect(fallback).toHaveLength(1);
expect(tree.text()).toBe(
"Silenced by default/4cf5fd82-1edd-4169-99d1-ff8415e72179"
);
});
it("renders FallbackSilenceDesciption when silence data is not present in alertStore", () => {
alertStore.data.silences.default = {};
const tree = MountedSilence();
const fallback = tree.find("FallbackSilenceDesciption");
expect(fallback).toHaveLength(1);
expect(tree.text()).toBe(
"Silenced by default/4cf5fd82-1edd-4169-99d1-ff8415e72179"
);
});
it("clicking on expand toggle shows silence details", () => {
const tree = MountedSilence();
const toggle = tree.find("a.float-right.cursor-pointer");
toggle.simulate("click");
const details = tree.find("SilenceDetails");
expect(details).toHaveLength(1);
});
it("matches snapshot with expaned details", () => {
const tree = MountedSilence().find("Silence");
tree.instance().collapse.toggle();
expect(toDiffableHtml(tree.html())).toMatchSnapshot();
});
it("renders comment as link when jiraURL is set", () => {
alertStore.data.silences.default[silence.id].jiraURL =
"http://jira.example.com";
const tree = MountedSilence().find("Silence");
const link = tree.find("a[href='http://jira.example.com']");
expect(link).toHaveLength(1);
expect(link.text()).toBe("Fake silence");
});
});
const ShallowSilenceDetails = () => {
return shallow(
<SilenceDetails alertmanager={alertmanager} silence={silence} />
);
};
describe("<SilenceDetails />", () => {
it("unexpired silence endsAt label uses 'secondary' class", () => {
const tree = ShallowSilenceDetails();
const endsAt = tree.find("span.badge").at(1);
expect(endsAt.html()).toMatch(/badge-secondary/);
});
it("expired silence endsAt label uses 'danger' class", () => {
advanceTo(new Date(2000, 0, 1, 23, 0, 0));
const tree = ShallowSilenceDetails();
const endsAt = tree.find("span.badge").at(1);
expect(endsAt.html()).toMatch(/badge-danger/);
});
});
const ShallowSilenceExpiryBadgeWithProgress = () => {
return shallow(<SilenceExpiryBadgeWithProgress silence={silence} />);
};
describe("<SilenceExpiryBadgeWithProgress />", () => {
it("renders with class 'danger' and no progressbar when expired", () => {
advanceTo(new Date(2001, 0, 1, 23, 0, 0));
const tree = ShallowSilenceExpiryBadgeWithProgress();
expect(tree.html()).toMatch(/badge-danger/);
expect(tree.text()).toBe("Expired <t />");
});
it("progressbar uses class 'danger' when > 90%", () => {
advanceTo(new Date(2000, 0, 1, 19, 30, 0));
const tree = ShallowSilenceExpiryBadgeWithProgress();
expect(tree.html()).toMatch(/progress-bar bg-danger/);
});
it("progressbar uses class 'danger' when > 75%", () => {
advanceTo(new Date(2000, 0, 1, 17, 45, 0));
const tree = ShallowSilenceExpiryBadgeWithProgress();
expect(tree.html()).toMatch(/progress-bar bg-warning/);
});
});

View File

@@ -15,6 +15,9 @@ require("jest-localstorage-mock");
// favico.js needs canvas
require("jest-canvas-mock");
// used to mock current time since we render moment.fromNow() in some places
require("jest-date-mock");
// fetch is used in multiple places to interact with Go backend
// or upstream Alertmanager API
global.fetch = require("jest-fetch-mock");