mirror of
https://github.com/prymitive/karma
synced 2026-05-09 03:36:44 +00:00
Merge pull request #176 from cloudflare/jest-coverage
Add tests for (un)silence.js
This commit is contained in:
12
assets/static/__mocks__/ajaxMock.js
Normal file
12
assets/static/__mocks__/ajaxMock.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const mockXHR = require("mock-xhr");
|
||||
|
||||
function createServer(status, payload) {
|
||||
var server = new mockXHR.server();
|
||||
server.handle = function (request) {
|
||||
request.setResponseHeader("Content-Type", "application/json");
|
||||
request.receive(status, JSON.stringify(payload));
|
||||
};
|
||||
return server;
|
||||
}
|
||||
|
||||
exports.createServer = createServer;
|
||||
280
assets/static/__snapshots__/silence.test.js.snap
Normal file
280
assets/static/__snapshots__/silence.test.js.snap
Normal file
File diff suppressed because one or more lines are too long
@@ -328,3 +328,4 @@ function setupSilenceForm() {
|
||||
}
|
||||
|
||||
exports.setupSilenceForm = setupSilenceForm;
|
||||
exports.sendSilencePOST = sendSilencePOST;
|
||||
|
||||
@@ -1,5 +1,173 @@
|
||||
test("silence setupSilenceForm()", () => {
|
||||
window.jQuery = require("jquery");
|
||||
const $ = window.jQuery = require("jquery");
|
||||
const moment = require("moment");
|
||||
const templatesMock = require("./__mocks__/templatesMock");
|
||||
const ajaxMock = require("./__mocks__/ajaxMock");
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
test("silence form", () => {
|
||||
let body = templatesMock.loadTemplates();
|
||||
body.push(
|
||||
"<div class='modal' id='silenceModal' role='dialog'>" +
|
||||
" <div class='modal-dialog' role='document'>" +
|
||||
" <div class='modal-content'>" +
|
||||
" <div class='modal-body'></div>" +
|
||||
" </div>" +
|
||||
" </div>" +
|
||||
"</div>" +
|
||||
"<span type='button' id='silenceButton'" +
|
||||
" data-labels='@state=active,foo=bar'" +
|
||||
" data-alertmanagers='mock'" +
|
||||
" data-alertname='fakeAlert'" +
|
||||
" data-toggle='modal'" +
|
||||
" data-target='#silenceModal'>" +
|
||||
"</span>"
|
||||
);
|
||||
document.body.innerHTML = body;
|
||||
|
||||
const templates = require("./templates");
|
||||
templates.init();
|
||||
|
||||
const config = require("./config");
|
||||
config.init({
|
||||
CopySelector: "#copy-settings-with-filter",
|
||||
SaveSelector: "#save-default-filter",
|
||||
ResetSelector: "#reset-settings"
|
||||
});
|
||||
|
||||
const silence = require("./silence");
|
||||
silence.setupSilenceForm();
|
||||
|
||||
require("bootstrap/js/tooltip.js");
|
||||
require("bootstrap/js/modal.js");
|
||||
|
||||
// rendering silence form requires AJAX call to pull data
|
||||
// first check failed request
|
||||
let ajaxServer = ajaxMock.createServer(500, {
|
||||
"status": "error",
|
||||
"errorType": "server_error",
|
||||
"error": "request failed"
|
||||
});
|
||||
ajaxServer.start();
|
||||
// click on the button, modal should show and render via ajax call
|
||||
$("#silenceButton").click();
|
||||
jest.runOnlyPendingTimers();
|
||||
let silenceModal = $("#silenceModal").html().trim();
|
||||
expect(silenceModal).toMatchSnapshot();
|
||||
ajaxServer.stop();
|
||||
|
||||
// hide the form
|
||||
$("#silenceModal").modal("hide");
|
||||
|
||||
// next try successful request
|
||||
ajaxServer = ajaxMock.createServer(200, {
|
||||
"groups": [ {
|
||||
"receiver": "default",
|
||||
"labels": {"alertname": "fakeAlert"},
|
||||
"alerts": [ {
|
||||
"annotations": {},
|
||||
"labels": {
|
||||
"alertname": "fakeAlert",
|
||||
"cluster": "prod",
|
||||
"foo": "bar"
|
||||
},
|
||||
"startsAt": "2017-07-22T01:07:54.32189391Z",
|
||||
"endsAt": "0001-01-01T00:00:00Z",
|
||||
"state": "active",
|
||||
"alertmanager": [ {
|
||||
"name": "mock",
|
||||
"uri": "http://localhost",
|
||||
"state": "active",
|
||||
"startsAt": "2017-07-22T01:07:54.32189391Z",
|
||||
"endsAt": "0001-01-01T00:00:00Z",
|
||||
"source": "localhost/prometheus",
|
||||
"silences": {}
|
||||
} ],
|
||||
"receiver": "default",
|
||||
"links": {}
|
||||
} ],
|
||||
"id": "12345",
|
||||
"hash": "abcdef",
|
||||
"stateCount": {"active": 1, "suppressed": 0, "unprocessed": 0}
|
||||
} ]
|
||||
});
|
||||
ajaxServer.start();
|
||||
// click on the button, modal should show and render via ajax call
|
||||
$("#silenceButton").click();
|
||||
jest.runOnlyPendingTimers();
|
||||
// default times are relative to current time, use fixed values
|
||||
let startsAt = moment("2050-01-01T01:00:00.000Z").utc();
|
||||
let endsAt = moment("2050-01-01T02:00:00.000Z").utc();
|
||||
$("#endsAt").data("DateTimePicker").date(endsAt);
|
||||
$("#startsAt").data("DateTimePicker").date(startsAt);
|
||||
// compare html to a snapshot
|
||||
silenceModal = $("#silenceModal").html().trim();
|
||||
expect(silenceModal).toMatchSnapshot();
|
||||
ajaxServer.stop();
|
||||
|
||||
// submit silence
|
||||
ajaxServer = ajaxMock.createServer(200, {
|
||||
"status": "success",
|
||||
"data": {"silenceId": "abcdef"}
|
||||
});
|
||||
ajaxServer.start();
|
||||
$("#newSilenceForm").submit();
|
||||
ajaxServer.stop();
|
||||
silenceModal = $("#silenceModal").html().trim();
|
||||
expect(silenceModal).toMatchSnapshot();
|
||||
});
|
||||
|
||||
test("successful sendSilencePOST()", () => {
|
||||
var body = templatesMock.loadTemplates();
|
||||
body.push(
|
||||
"<span class='silence-post-result' " +
|
||||
" data-uri='http://localhost'>" +
|
||||
"</span>"
|
||||
);
|
||||
document.body.innerHTML = body;
|
||||
|
||||
const templates = require("./templates");
|
||||
templates.init();
|
||||
|
||||
const ajaxServer = ajaxMock.createServer(200, {
|
||||
"status": "success",
|
||||
"data": {"silenceId": "abcdef"}
|
||||
});
|
||||
ajaxServer.start();
|
||||
|
||||
const silence = require("./silence");
|
||||
silence.sendSilencePOST("http://localhost", {});
|
||||
|
||||
let resultElem = $(".silence-post-result").html().trim();
|
||||
expect(resultElem).toMatchSnapshot();
|
||||
|
||||
ajaxServer.stop();
|
||||
});
|
||||
|
||||
test("failed sendSilencePOST()", () => {
|
||||
var body = templatesMock.loadTemplates();
|
||||
body.push(
|
||||
"<span class='silence-post-result' " +
|
||||
" data-uri='http://localhost'>" +
|
||||
"</span>"
|
||||
);
|
||||
document.body.innerHTML = body;
|
||||
|
||||
const templates = require("./templates");
|
||||
templates.init();
|
||||
|
||||
const ajaxServer = ajaxMock.createServer(500, {
|
||||
"status": "error",
|
||||
"errorType": "server_error",
|
||||
"error": "request failed"
|
||||
});
|
||||
ajaxServer.start();
|
||||
|
||||
const silence = require("./silence");
|
||||
silence.sendSilencePOST("http://localhost", {});
|
||||
|
||||
let resultElem = $(".silence-post-result").html().trim();
|
||||
expect(resultElem).toMatchSnapshot();
|
||||
|
||||
ajaxServer.stop();
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ function markInProgress(alertmanagerURI, silenceID) {
|
||||
var elem = unsilenceButtonByID(alertmanagerURI, silenceID);
|
||||
elem.attr("title", "Silence is being deleted from Alertmanager");
|
||||
elem.tooltip("fixTitle");
|
||||
elem.find(".fa").removeClass("fa-times").addClass("fa-refresh fa-spin");
|
||||
elem.find(".fa").removeClass("fa-trash-o").addClass("fa-refresh fa-spin");
|
||||
}
|
||||
|
||||
function markFailed(alertmanagerURI, silenceID, xhr) {
|
||||
@@ -26,12 +26,12 @@ function markFailed(alertmanagerURI, silenceID, xhr) {
|
||||
var elem = unsilenceButtonByID(alertmanagerURI, silenceID);
|
||||
elem.attr("title", err);
|
||||
elem.tooltip("fixTitle");
|
||||
elem.find(".fa").removeClass("fa-times fa-refresh fa-spin").addClass("fa-exclamation-circle text-danger");
|
||||
elem.find(".fa").removeClass("fa-trash-o fa-refresh fa-spin").addClass("fa-exclamation-circle text-danger");
|
||||
|
||||
// Disable button, wait 5s and reset button to the original state
|
||||
elem.data("disabled", "true");
|
||||
setTimeout(function() {
|
||||
elem.find(".fa").removeClass("fa-exclamation-circle text-danger").addClass("fa-times");
|
||||
elem.find(".fa").removeClass("fa-exclamation-circle text-danger").addClass("fa-trash-o");
|
||||
elem.removeData("disabled");
|
||||
elem.attr("title", "Delete this silence");
|
||||
elem.tooltip("fixTitle");
|
||||
@@ -42,7 +42,7 @@ function markSuccess(alertmanagerURI, silenceID) {
|
||||
var elem = unsilenceButtonByID(alertmanagerURI, silenceID);
|
||||
elem.attr("title", "Silence deleted from Alertmanager");
|
||||
elem.tooltip("fixTitle");
|
||||
elem.find(".fa").removeClass("fa-times fa-refresh fa-spin").addClass("fa-check-circle text-success");
|
||||
elem.find(".fa").removeClass("fa-trash-o fa-refresh fa-spin").addClass("fa-check-circle text-success");
|
||||
// disable button so it's no longer clickable
|
||||
elem.data("disabled", "true");
|
||||
}
|
||||
|
||||
@@ -1,5 +1,66 @@
|
||||
test("silence setupSilenceForm()", () => {
|
||||
window.jQuery = require("jquery");
|
||||
const $ = window.jQuery = require("jquery");
|
||||
const templatesMock = require("./__mocks__/templatesMock");
|
||||
const ajaxMock = require("./__mocks__/ajaxMock");
|
||||
|
||||
const unsilenceButtonHTML =
|
||||
"<button class='silence-delete'" +
|
||||
" data-alertmanager-uri='http://localhost'" +
|
||||
" data-silence-id='abcd'>" +
|
||||
" <span class='fa fa-trash-o'></span>" +
|
||||
"</button>";
|
||||
|
||||
jest.useFakeTimers();
|
||||
|
||||
test("unsilence button icons after success", () => {
|
||||
var body = templatesMock.loadTemplates();
|
||||
body.push(unsilenceButtonHTML);
|
||||
document.body.innerHTML = body;
|
||||
|
||||
require("bootstrap/js/tooltip.js");
|
||||
const unsilence = require("./unsilence");
|
||||
|
||||
const ajaxServer = ajaxMock.createServer(200, {"status":"success"});
|
||||
ajaxServer.start();
|
||||
|
||||
unsilence.init();
|
||||
// icon should be trash-o before clicking
|
||||
expect($("button > span.fa").hasClass("fa-trash-o")).toBe(true);
|
||||
$("button.silence-delete").click();
|
||||
// and switch to green check mark in circle after
|
||||
expect($("button > span.fa").hasClass("fa-trash-o")).toBe(false);
|
||||
expect($("button > span.fa").hasClass("fa-check-circle")).toBe(true);
|
||||
expect($("button > span.fa").hasClass("text-success")).toBe(true);
|
||||
|
||||
ajaxServer.stop();
|
||||
});
|
||||
|
||||
test("unsilence button icons after failed delete", () => {
|
||||
var body = templatesMock.loadTemplates();
|
||||
body.push(unsilenceButtonHTML);
|
||||
document.body.innerHTML = body;
|
||||
|
||||
require("bootstrap/js/tooltip.js");
|
||||
const unsilence = require("./unsilence");
|
||||
|
||||
const ajaxServer = ajaxMock.createServer(500, {
|
||||
"status": "error",
|
||||
"errorType": "server_error",
|
||||
"error": "end time must not be modified for elapsed silence"
|
||||
});
|
||||
ajaxServer.start();
|
||||
|
||||
unsilence.init();
|
||||
// icon should be trash-o before clicking
|
||||
expect($("button > span.fa").hasClass("fa-trash-o")).toBe(true);
|
||||
$("button.silence-delete").click();
|
||||
// and switch to green check mark in circle after
|
||||
expect($("button > span.fa").hasClass("fa-trash-o")).toBe(false);
|
||||
expect($("button > span.fa").hasClass("fa-exclamation-circle")).toBe(true);
|
||||
expect($("button > span.fa").hasClass("text-danger")).toBe(true);
|
||||
|
||||
// run timers, it should reset the icon back to trash-o
|
||||
jest.runOnlyPendingTimers();
|
||||
expect($("button > span.fa").hasClass("fa-trash-o")).toBe(true);
|
||||
|
||||
ajaxServer.stop();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user