diff --git a/config/jest-backend.config.js b/config/jest-backend.config.js
index 1a88d9a..db39512 100644
--- a/config/jest-backend.config.js
+++ b/config/jest-backend.config.js
@@ -1,5 +1,5 @@
module.exports = {
"rootDir": "..",
- "testRegex": "./test/backend.spec.js",
+ "testRegex": ["./test/backend.spec.js", "./server/.*.spec.js"],
};
diff --git a/server/notification-providers/aliyun-sms.js b/server/notification-providers/aliyun-sms.js
index 6a20632..952efec 100644
--- a/server/notification-providers/aliyun-sms.js
+++ b/server/notification-providers/aliyun-sms.js
@@ -8,7 +8,6 @@ class AliyunSMS extends NotificationProvider {
name = "AliyunSMS";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
if (heartbeatJSON != null) {
@@ -18,8 +17,9 @@ class AliyunSMS extends NotificationProvider {
status: this.statusToString(heartbeatJSON["status"]),
msg: heartbeatJSON["msg"],
});
- if (this.sendSms(notification, msgBody)) {
- return okMsg;
+ if (await this.sendSms(notification, msgBody)) {
+ return this.sendSuccess;
+ //TODO account for cases where sendSMS returns false.
}
} else {
let msgBody = JSON.stringify({
@@ -28,8 +28,8 @@ class AliyunSMS extends NotificationProvider {
status: "",
msg: msg,
});
- if (this.sendSms(notification, msgBody)) {
- return okMsg;
+ if (await this.sendSms(notification, msgBody)) {
+ return this.sendSuccess;
}
}
} catch (error) {
@@ -48,7 +48,7 @@ class AliyunSMS extends NotificationProvider {
SignatureMethod: "HMAC-SHA1",
SignatureVersion: "1.0",
SignatureNonce: Math.random().toString(),
- Timestamp: new Date().toISOString(),
+ Timestamp: new Date(Date.now()).toISOString(),
Action: "SendSms",
Version: "2017-05-25",
};
diff --git a/server/notification-providers/aliyun-sms.spec.js b/server/notification-providers/aliyun-sms.spec.js
new file mode 100644
index 0000000..c58a765
--- /dev/null
+++ b/server/notification-providers/aliyun-sms.spec.js
@@ -0,0 +1,243 @@
+jest.mock("axios");
+
+const axios = require("axios");
+
+const { UP } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const AliyunSMS = require("./aliyun-sms");
+
+beforeEach(() => {
+ axios.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new AliyunSMS();
+ expect(notification.name).toBe("AliyunSMS");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ jest.spyOn(global.Date, "now")
+ .mockImplementation(() =>
+ new Date("2019-05-14T11:01:58.135Z")
+ );
+
+ jest.spyOn(global.Math, "random")
+ .mockImplementation(() =>
+ 0.0000111010100
+ );
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.mockResolvedValueOnce(response);
+
+ let notif = new AliyunSMS();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios).toHaveBeenCalledWith({
+ data: "TemplateParam=%7B%22name%22%3A%22testing%22%2C%22time%22%3A%22example%20time%22%2C%22status%22%3A%22UP%22%2C%22msg%22%3A%22some%20message%22%7D&Format=JSON&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&SignatureNonce=0.00001110101&Timestamp=2019-05-14T11%3A01%3A58.135Z&Action=SendSms&Version=2017-05-25&Signature=73QTXvIaPHJIEo%2BCV1bzaZ5rzh4%3D",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ method: "POST",
+ url: "http://dysmsapi.aliyuncs.com/",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+
+ jest.spyOn(global.Date, "now")
+ .mockImplementation(() =>
+ new Date("2019-05-14T11:01:58.135Z")
+ );
+
+ jest.spyOn(global.Math, "random")
+ .mockImplementation(() =>
+ 0.0000111010100
+ );
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.mockResolvedValueOnce(response);
+
+ let notif = new AliyunSMS();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage";
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios).toHaveBeenCalledWith({
+ data: "TemplateParam=%7B%22name%22%3A%22%22%2C%22time%22%3A%22%22%2C%22status%22%3A%22%22%2C%22msg%22%3A%22PassedInMessage%22%7D&Format=JSON&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&SignatureNonce=0.00001110101&Timestamp=2019-05-14T11%3A01%3A58.135Z&Action=SendSms&Version=2017-05-25&Signature=bXj4C8u60n6Xfiqf3VhtyqtW6Fk%3D",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ method: "POST",
+ url: "http://dysmsapi.aliyuncs.com/",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+
+ jest.spyOn(global.Date, "now")
+ .mockImplementation(() =>
+ new Date("2019-05-14T11:01:58.135Z")
+ );
+
+ jest.spyOn(global.Math, "random")
+ .mockImplementation(() =>
+ 0.0000111010100
+ );
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.mockResolvedValueOnce(response);
+
+ let notif = new AliyunSMS();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage";
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios).toHaveBeenCalledWith({
+ data: "TemplateParam=%7B%22name%22%3A%22%22%2C%22time%22%3A%22%22%2C%22status%22%3A%22%22%2C%22msg%22%3A%22PassedInMessage%22%7D&Format=JSON&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&SignatureNonce=0.00001110101&Timestamp=2019-05-14T11%3A01%3A58.135Z&Action=SendSms&Version=2017-05-25&Signature=bXj4C8u60n6Xfiqf3VhtyqtW6Fk%3D",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ method: "POST",
+ url: "http://dysmsapi.aliyuncs.com/",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+ jest.spyOn(global.Date, "now")
+ .mockImplementation(() =>
+ new Date("2019-05-14T11:01:58.135Z")
+ );
+
+ jest.spyOn(global.Math, "random")
+ .mockImplementation(() =>
+ 0.0000111010100
+ );
+
+ axios.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage";
+ let notif = new AliyunSMS();
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ //axios general error on catching another error is not the cleanest, but works.
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios).toHaveBeenCalledWith({
+ data: "TemplateParam=%7B%22name%22%3A%22%22%2C%22time%22%3A%22%22%2C%22status%22%3A%22%22%2C%22msg%22%3A%22PassedInMessage%22%7D&Format=JSON&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&SignatureNonce=0.00001110101&Timestamp=2019-05-14T11%3A01%3A58.135Z&Action=SendSms&Version=2017-05-25&Signature=bXj4C8u60n6Xfiqf3VhtyqtW6Fk%3D",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ method: "POST",
+ url: "http://dysmsapi.aliyuncs.com/",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call sendMail with proper data", async () => {
+ jest.spyOn(global.Date, "now")
+ .mockImplementation(() =>
+ new Date("2019-05-14T11:01:58.135Z")
+ );
+
+ jest.spyOn(global.Math, "random")
+ .mockImplementation(() =>
+ 0.0000111010100
+ );
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "AliyunSMS",
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+ expect(axios).toHaveBeenCalledWith({
+ data: "TemplateParam=%7B%22name%22%3A%22testing%22%2C%22time%22%3A%22example%20time%22%2C%22status%22%3A%22UP%22%2C%22msg%22%3A%22some%20message%22%7D&Format=JSON&SignatureMethod=HMAC-SHA1&SignatureVersion=1.0&SignatureNonce=0.00001110101&Timestamp=2019-05-14T11%3A01%3A58.135Z&Action=SendSms&Version=2017-05-25&Signature=73QTXvIaPHJIEo%2BCV1bzaZ5rzh4%3D",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ method: "POST",
+ url: "http://dysmsapi.aliyuncs.com/",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/apprise.js b/server/notification-providers/apprise.js
index fdcd8d6..90cefac 100644
--- a/server/notification-providers/apprise.js
+++ b/server/notification-providers/apprise.js
@@ -1,22 +1,22 @@
const NotificationProvider = require("./notification-provider");
-const child_process = require("child_process");
+const childProcess = require("child_process");
class Apprise extends NotificationProvider {
name = "apprise";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let s = child_process.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL])
+ let s = childProcess.spawnSync("apprise", [ "-vv", "-b", msg, notification.appriseURL]);
let output = (s.stdout) ? s.stdout.toString() : "ERROR: maybe apprise not found";
if (output) {
if (! output.includes("ERROR")) {
- return "Sent Successfully";
+ return this.sendSuccess;
}
- throw new Error(output)
+ throw new Error(output);
} else {
return "No output from apprise";
}
diff --git a/server/notification-providers/apprise.spec.js b/server/notification-providers/apprise.spec.js
new file mode 100644
index 0000000..148521a
--- /dev/null
+++ b/server/notification-providers/apprise.spec.js
@@ -0,0 +1,112 @@
+jest.mock("child_process", () => ({
+ spawnSync: jest.fn(),
+}));
+
+const childProcess = require("child_process");
+const { UP } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const Apprise = require("./apprise");
+
+beforeEach(() => {
+ childProcess.spawnSync.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Apprise();
+ expect(notification.name).toBe("apprise");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call apprise with the proper default data", async () => {
+
+ childProcess.spawnSync.mockImplementationOnce(() => {
+ return { stdout: "response" };
+ });
+
+ let notif = new Apprise();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ };
+ let msg = "PassedInMessage";
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(childProcess.spawnSync).toHaveBeenCalledWith("apprise", ["-vv", "-b", "PassedInMessage", "appriseURL"]);
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ //TODO code under test unreachable. Remove or resolve.
+ // it("should call output no data when no data", async () => {
+
+ // childProcess.spawnSync.mockImplementationOnce(() => {
+ // return { stdout: "" };
+ // });
+
+ // let notif = new Apprise();
+ // let notificationConf = {
+ // appriseURL: "appriseURL",
+ // };
+ // let msg = "PassedInMessage";
+ // let res = await notif.send(notificationConf, msg, null, null);
+
+ // expect(childProcess.spawnSync).toHaveBeenCalledWith("apprise", ["-vv", "-b", "PassedInMessage", "appriseURL"]);
+ // expect(res).toBe("No output from apprise");
+ // });
+
+});
+
+describe("notification to act properly on errors from apprise", () => {
+ it("should call apprise with the proper default data", async () => {
+
+ childProcess.spawnSync.mockImplementationOnce(() => {
+ return { stdout: "ERROR FROM APPRISE" };
+ });
+
+ let notif = new Apprise();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ };
+ let msg = "PassedInMessage";
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("not reached").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("ERROR FROM APPRISE");
+ }
+
+ expect(childProcess.spawnSync).toHaveBeenCalledWith("apprise", ["-vv", "-b", "PassedInMessage", "appriseURL"]);
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call sendMail with proper data", async () => {
+ childProcess.spawnSync.mockImplementationOnce(() => {
+ return { stdout: "response" };
+ });
+
+ let notificationConf = {
+ type: "apprise",
+ appriseURL: "appriseURL",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+
+ expect(res).toBe("Sent Successfully.");
+
+ expect(childProcess.spawnSync).toHaveBeenCalledWith("apprise", ["-vv", "-b", "PassedInMessage", "appriseURL"]);
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/dingding.js b/server/notification-providers/dingding.js
index f099192..db52b0a 100644
--- a/server/notification-providers/dingding.js
+++ b/server/notification-providers/dingding.js
@@ -7,7 +7,6 @@ class DingDing extends NotificationProvider {
name = "DingDing";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
if (heartbeatJSON != null) {
@@ -15,11 +14,11 @@ class DingDing extends NotificationProvider {
msgtype: "markdown",
markdown: {
title: monitorJSON["name"],
- text: `## [${this.statusToString(heartbeatJSON["status"])}] \n > ${heartbeatJSON["msg"]} \n > Time(UTC):${heartbeatJSON["time"]}`,
+ text: `## [${this.statusToString(heartbeatJSON["status"])}] ${monitorJSON["name"]}\n > ${heartbeatJSON["msg"]} \n > Time(UTC):${heartbeatJSON["time"]}`,
}
};
- if (this.sendToDingDing(notification, params)) {
- return okMsg;
+ if (await this.sendToDingDing(notification, params)) {
+ return this.sendSuccess;
}
} else {
let params = {
@@ -28,8 +27,8 @@ class DingDing extends NotificationProvider {
content: msg
}
};
- if (this.sendToDingDing(notification, params)) {
- return okMsg;
+ if (await this.sendToDingDing(notification, params)) {
+ return this.sendSuccess;
}
}
} catch (error) {
diff --git a/server/notification-providers/dingding.spec.js b/server/notification-providers/dingding.spec.js
new file mode 100644
index 0000000..b6307ac
--- /dev/null
+++ b/server/notification-providers/dingding.spec.js
@@ -0,0 +1,208 @@
+jest.mock("axios");
+
+const { UP } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const DingDing = require("./dingding");
+
+const axios = require("axios");
+
+beforeEach(() => {
+ axios.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new DingDing();
+ expect(notification.name).toBe("DingDing");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ jest.spyOn(global.Date, "now")
+ .mockImplementationOnce(() =>
+ new Date("2019-05-14T11:01:58.135Z").valueOf()
+ );
+
+ let response = {
+ data: {
+ errmsg: "ok"
+ }
+ };
+ axios.mockResolvedValueOnce(response);
+
+ let notif = new DingDing();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios).toHaveBeenCalledWith({
+ data: "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"testing\",\"text\":\"## [UP] testing\\n > some message \\n > Time(UTC):example time\"}}",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ method: "POST",
+ url: "https://example.com/webhook×tamp=1557831718135&sign=lCTIn3sYpAYFAw3B2LeTLr7BvcOMAcmZu%2F6rb7kC8Io%3D",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when missing heartbeat", async () => {
+
+ jest.spyOn(global.Date, "now")
+ .mockImplementationOnce(() =>
+ new Date("2019-05-14T11:01:58.135Z").valueOf()
+ );
+
+ let response = {
+ data: {
+ errmsg: "ok"
+ }
+ };
+ axios.mockResolvedValueOnce(response);
+
+ let notif = new DingDing();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, null);
+
+ expect(axios).toHaveBeenCalledWith({
+ data: "{\"msgtype\":\"text\",\"text\":{\"content\":\"PassedInMessage\"}}",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ method: "POST",
+ url: "https://example.com/webhook×tamp=1557831718135&sign=lCTIn3sYpAYFAw3B2LeTLr7BvcOMAcmZu%2F6rb7kC8Io%3D",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ //TODO need to get correct response when sendToDingDing fails, but no axios error.
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ jest.spyOn(global.Date, "now")
+ .mockImplementationOnce(() =>
+ new Date("2019-05-14T11:01:58.135Z").valueOf()
+ );
+
+ axios.mockImplementationOnce(() => {
+ throw new Error("Test Error");
+ });
+
+ let notif = new DingDing();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+
+ try {
+ await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+ console.log("fail");
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ //axios general error on catching another error is not the cleanest, but works.
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios).toHaveBeenCalledWith({
+ data: "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"testing\",\"text\":\"## [UP] testing\\n > some message \\n > Time(UTC):example time\"}}",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ method: "POST",
+ url: "https://example.com/webhook×tamp=1557831718135&sign=lCTIn3sYpAYFAw3B2LeTLr7BvcOMAcmZu%2F6rb7kC8Io%3D",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call sendMail with proper data", async () => {
+ jest.spyOn(global.Date, "now")
+ .mockImplementationOnce(() =>
+ new Date("2019-05-14T11:01:58.135Z").valueOf()
+ );
+
+ let response = {
+ data: {
+ errmsg: "ok"
+ }
+ };
+ axios.mockResolvedValueOnce(response);
+
+ let notif = new DingDing();
+ let notificationConf = {
+ type: "DingDing",
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ webHookUrl: "https://example.com/webhook",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+
+ expect(res).toBe("Sent Successfully.");
+
+ expect(axios).toHaveBeenCalledWith({
+ data: "{\"msgtype\":\"markdown\",\"markdown\":{\"title\":\"testing\",\"text\":\"## [UP] testing\\n > some message \\n > Time(UTC):example time\"}}",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ method: "POST",
+ url: "https://example.com/webhook×tamp=1557831718135&sign=lCTIn3sYpAYFAw3B2LeTLr7BvcOMAcmZu%2F6rb7kC8Io%3D",
+
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/discord.js b/server/notification-providers/discord.js
index 881ad21..06b0273 100644
--- a/server/notification-providers/discord.js
+++ b/server/notification-providers/discord.js
@@ -7,7 +7,6 @@ class Discord extends NotificationProvider {
name = "discord";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
const discordDisplayName = notification.discordUsername || "Uptime Kuma";
@@ -17,9 +16,9 @@ class Discord extends NotificationProvider {
let discordtestdata = {
username: discordDisplayName,
content: msg,
- }
- await axios.post(notification.discordWebhookUrl, discordtestdata)
- return okMsg;
+ };
+ await axios.post(notification.discordWebhookUrl, discordtestdata);
+ return this.sendSuccess;
}
let url;
@@ -49,7 +48,7 @@ class Discord extends NotificationProvider {
},
{
name: "Service URL",
- value: url,
+ value: url.startsWith("http") ? "[Visit Service](" + url + ")" : url,
},
{
name: "Time (UTC)",
@@ -61,14 +60,14 @@ class Discord extends NotificationProvider {
},
],
}],
- }
+ };
if (notification.discordPrefixMessage) {
discorddowndata.content = notification.discordPrefixMessage;
}
- await axios.post(notification.discordWebhookUrl, discorddowndata)
- return okMsg;
+ await axios.post(notification.discordWebhookUrl, discorddowndata);
+ return this.sendSuccess;
} else if (heartbeatJSON["status"] == UP) {
let discordupdata = {
@@ -96,17 +95,17 @@ class Discord extends NotificationProvider {
},
],
}],
- }
+ };
if (notification.discordPrefixMessage) {
discordupdata.content = notification.discordPrefixMessage;
}
- await axios.post(notification.discordWebhookUrl, discordupdata)
- return okMsg;
+ await axios.post(notification.discordWebhookUrl, discordupdata);
+ return this.sendSuccess;
}
} catch (error) {
- this.throwGeneralAxiosError(error)
+ this.throwGeneralAxiosError(error);
}
}
diff --git a/server/notification-providers/discord.spec.js b/server/notification-providers/discord.spec.js
new file mode 100644
index 0000000..1583005
--- /dev/null
+++ b/server/notification-providers/discord.spec.js
@@ -0,0 +1,260 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const Discord = require("./discord");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Discord();
+ expect(notification.name).toBe("discord");
+ });
+});
+
+describe("notification to act properly on send", () => {
+
+ it("should call axios with the proper data when missing heartbeat/monitor", async () => {
+
+ let response = {};
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Discord();
+ let url = "https://example.com/webhook";
+ let notificationConf = {
+ discordUsername: "username",
+ discordWebhookUrl: url,
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith(url, {
+ content: "PassedInMessage",
+ username: "username"
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when having heartbeat & monitor & service up", async () => {
+
+ jest.spyOn(global.Date, "now")
+ .mockImplementationOnce(() =>
+ new Date("2019-05-14T11:01:58.135Z").valueOf()
+ );
+
+ let response = {};
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Discord();
+ let url = "https://example.com/webhook";
+ let notificationConf = {
+ discordUsername: "username",
+ discordWebhookUrl: url,
+ discordPrefixMessage: "prefix",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing monitor",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ ping: "111"
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith(url, {
+ content: "prefix",
+ embeds: [
+ {
+ color: 65280,
+ fields: [
+ {
+ name: "Service Name",
+ value: "testing monitor",
+ },
+ {
+ name: "Service URL",
+ value: "[Visit Service](https://www.google.com)",
+ },
+ {
+ name: "Time (UTC)",
+ value: "example time",
+ },
+ {
+ name: "Ping",
+ value: "111ms",
+ },
+ ],
+ timestamp: "example time",
+ title: "✅ Your service testing monitor is up! ✅",
+ },
+ ],
+ username: "username"
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when having heartbeat & monitor & service down", async () => {
+
+ let response = {};
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Discord();
+ let url = "https://example.com/webhook";
+ let notificationConf = {
+ discordUsername: "username",
+ discordWebhookUrl: url,
+ discordPrefixMessage: "prefix",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing monitor",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "some message",
+ time: "example time",
+ ping: "111"
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith(url, {
+ content: "prefix",
+ embeds: [
+ {
+ color: 16711680,
+ fields: [
+ {
+ name: "Service Name",
+ value: "testing monitor",
+ },
+ {
+ name: "Service URL",
+ value: "[Visit Service](https://www.google.com)",
+ },
+ {
+ name: "Time (UTC)",
+ value: "example time",
+ },
+ {
+ name: "Error",
+ value: "some message",
+ },
+ ],
+ timestamp: "example time",
+ title: "❌ Your service testing monitor went down. ❌",
+ },
+ ],
+ username: "username"
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+
+ let notif = new Discord();
+ let notificationConf = {
+ appriseURL: "appriseURL",
+ secretKey: "abc",
+ discordWebhookUrl: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ console.log("fail");
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ //axios general error on catching another error is not the cleanest, but works.
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://example.com/webhook", {
+ content: "PassedInMessage",
+ username: "Uptime Kuma"
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call sendMail with proper data", async () => {
+
+ let response = {};
+ axios.post.mockResolvedValueOnce(response);
+
+ let url = "https://example.com/webhook";
+ let notificationConf = {
+ type: "discord",
+ discordUsername: "username",
+ discordWebhookUrl: url,
+ discordPrefixMessage: "prefix",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing monitor",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ ping: "111"
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith(url, {
+ content: "prefix",
+ embeds: [
+ {
+ color: 65280,
+ fields: [
+ {
+ name: "Service Name",
+ value: "testing monitor",
+ },
+ {
+ name: "Service URL",
+ value: "[Visit Service](https://www.google.com)",
+ },
+ {
+ name: "Time (UTC)",
+ value: "example time",
+ },
+ {
+ name: "Ping",
+ value: "111ms",
+ },
+ ],
+ timestamp: "example time",
+ title: "✅ Your service testing monitor is up! ✅",
+ },
+ ],
+ username: "username"
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/feishu.js b/server/notification-providers/feishu.js
index a3e3403..5ab8ca7 100644
--- a/server/notification-providers/feishu.js
+++ b/server/notification-providers/feishu.js
@@ -6,7 +6,6 @@ class Feishu extends NotificationProvider {
name = "Feishu";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
let feishuWebHookUrl = notification.feishuWebHookUrl;
try {
@@ -18,7 +17,7 @@ class Feishu extends NotificationProvider {
},
};
await axios.post(feishuWebHookUrl, testdata);
- return okMsg;
+ return this.sendSuccess;
}
if (heartbeatJSON["status"] == DOWN) {
@@ -45,7 +44,7 @@ class Feishu extends NotificationProvider {
},
};
await axios.post(feishuWebHookUrl, downdata);
- return okMsg;
+ return this.sendSuccess;
}
if (heartbeatJSON["status"] == UP) {
@@ -72,7 +71,7 @@ class Feishu extends NotificationProvider {
},
};
await axios.post(feishuWebHookUrl, updata);
- return okMsg;
+ return this.sendSuccess;
}
} catch (error) {
this.throwGeneralAxiosError(error);
diff --git a/server/notification-providers/feishu.spec.js b/server/notification-providers/feishu.spec.js
new file mode 100644
index 0000000..cb152f3
--- /dev/null
+++ b/server/notification-providers/feishu.spec.js
@@ -0,0 +1,174 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const Feishu = require("./feishu");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Feishu();
+ expect(notification.name).toBe("Feishu");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Feishu();
+ let notificationConf = {
+ feishuWebHookUrl: "feishuWebHookUrl"
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("feishuWebHookUrl", {
+ content: {
+ post: {
+ zh_cn: {
+ content: [
+ [
+ {
+ tag: "text",
+ text: "[Up] some message\nTime (UTC): example time",
+ },
+ ],
+ ],
+ title: "UptimeKuma Alert: testing",
+ },
+ },
+ },
+ msg_type: "post",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Feishu();
+ let notificationConf = {
+ feishuWebHookUrl: "feishuWebHookUrl"
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("feishuWebHookUrl", {
+ "content": {
+ "text": "PassedInMessage"
+ },
+ "msg_type": "text"
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+
+ let notificationConf = {
+ feishuWebHookUrl: "feishuWebHookUrl"
+
+ };
+ let msg = "PassedInMessage";
+ let notif = new Feishu();
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("feishuWebHookUrl", {
+ content: {
+ text: "PassedInMessage",
+ },
+ msg_type: "text",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "Feishu",
+ feishuWebHookUrl: "feishuWebHookUrl"
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("feishuWebHookUrl", {
+ content: {
+ post: {
+ zh_cn: {
+ content: [
+ [
+ {
+ tag: "text",
+ text: "[Up] some message\nTime (UTC): example time",
+ },
+ ],
+ ],
+ title: "UptimeKuma Alert: testing",
+ },
+ },
+ },
+ msg_type: "post",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/gotify.js b/server/notification-providers/gotify.js
index 0852618..dba6dea 100644
--- a/server/notification-providers/gotify.js
+++ b/server/notification-providers/gotify.js
@@ -6,7 +6,6 @@ class Gotify extends NotificationProvider {
name = "gotify";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
if (notification.gotifyserverurl && notification.gotifyserverurl.endsWith("/")) {
notification.gotifyserverurl = notification.gotifyserverurl.slice(0, -1);
@@ -15,9 +14,9 @@ class Gotify extends NotificationProvider {
"message": msg,
"priority": notification.gotifyPriority || 8,
"title": "Uptime-Kuma",
- })
+ });
- return okMsg;
+ return this.sendSuccess;
} catch (error) {
this.throwGeneralAxiosError(error);
diff --git a/server/notification-providers/gotify.spec.js b/server/notification-providers/gotify.spec.js
new file mode 100644
index 0000000..c88058d
--- /dev/null
+++ b/server/notification-providers/gotify.spec.js
@@ -0,0 +1,152 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const Gotify = require("./gotify");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Gotify();
+ expect(notification.name).toBe("gotify");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Gotify();
+ let notificationConf = {
+ gotifyserverurl: "url/",
+ gotifyPriority: 4,
+ gotifyapplicationToken: "token"
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("url/message?token=token", {
+ message: "PassedInMessage",
+ priority: 4,
+ title: "Uptime-Kuma",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Gotify();
+ let notificationConf = {
+ gotifyserverurl: "url",
+ gotifyPriority: 4,
+ gotifyapplicationToken: "token"
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("url/message?token=token", {
+ message: "PassedInMessage",
+ priority: 4,
+ title: "Uptime-Kuma",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+
+ let notificationConf = {
+ gotifyserverurl: "url",
+ gotifyPriority: 4,
+ gotifyapplicationToken: "token"
+ };
+ let msg = "PassedInMessage";
+ let notif = new Gotify();
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("url/message?token=token", {
+ message: "PassedInMessage",
+ priority: 4,
+ title: "Uptime-Kuma",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "gotify",
+ gotifyserverurl: "url",
+ gotifyPriority: 4,
+ gotifyapplicationToken: "token"
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("url/message?token=token", {
+ message: "PassedInMessage",
+ priority: 4,
+ title: "Uptime-Kuma",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/line.js b/server/notification-providers/line.js
index 327696e..a9c2f58 100644
--- a/server/notification-providers/line.js
+++ b/server/notification-providers/line.js
@@ -7,7 +7,6 @@ class Line extends NotificationProvider {
name = "line";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
let lineAPIUrl = "https://api.line.me/v2/bot/message/push";
let config = {
@@ -25,34 +24,34 @@ class Line extends NotificationProvider {
"text": "Test Successful!"
}
]
- }
- await axios.post(lineAPIUrl, testMessage, config)
+ };
+ await axios.post(lineAPIUrl, testMessage, config);
} else if (heartbeatJSON["status"] == DOWN) {
let downMessage = {
"to": notification.lineUserID,
"messages": [
{
"type": "text",
- "text": "UptimeKuma Alert: [🔴 Down]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"]
+ "text": "UptimeKuma Alert: [🔴 Down]\n" + "Name: " + monitorJSON["name"] + "\n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"]
}
]
- }
- await axios.post(lineAPIUrl, downMessage, config)
+ };
+ await axios.post(lineAPIUrl, downMessage, config);
} else if (heartbeatJSON["status"] == UP) {
let upMessage = {
"to": notification.lineUserID,
"messages": [
{
"type": "text",
- "text": "UptimeKuma Alert: [✅ Up]\n" + "Name: " + monitorJSON["name"] + " \n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"]
+ "text": "UptimeKuma Alert: [✅ Up]\n" + "Name: " + monitorJSON["name"] + "\n" + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"]
}
]
- }
- await axios.post(lineAPIUrl, upMessage, config)
+ };
+ await axios.post(lineAPIUrl, upMessage, config);
}
- return okMsg;
+ return this.sendSuccess;
} catch (error) {
- this.throwGeneralAxiosError(error)
+ this.throwGeneralAxiosError(error);
}
}
}
diff --git a/server/notification-providers/line.spec.js b/server/notification-providers/line.spec.js
new file mode 100644
index 0000000..97b8631
--- /dev/null
+++ b/server/notification-providers/line.spec.js
@@ -0,0 +1,232 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const Line = require("./line");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Line();
+ expect(notification.name).toBe("line");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data when UP", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Line();
+ let notificationConf = {
+ type: "line",
+ lineUserID: "1234",
+ lineChannelAccessToken: "token"
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.line.me/v2/bot/message/push", {
+ messages: [
+ {
+ text: "UptimeKuma Alert: [✅ Up]\nName: testing\nsome message\nTime (UTC): example time",
+ type: "text",
+ },
+ ],
+ to: "1234",
+ }, {
+ headers: {
+ "Authorization": "Bearer token",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+ it("should call axios with the proper default data when DOWN", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Line();
+ let notificationConf = {
+ type: "line",
+ lineUserID: "1234",
+ lineChannelAccessToken: "token"
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "some message",
+ time: "example time",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.line.me/v2/bot/message/push", {
+ messages: [
+ {
+ text: "UptimeKuma Alert: [🔴 Down]\nName: testing\nsome message\nTime (UTC): example time",
+ type: "text",
+ },
+ ],
+ to: "1234",
+ }, {
+ headers: {
+ "Authorization": "Bearer token",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Line();
+ let notificationConf = {
+ type: "line",
+ lineUserID: "1234",
+ lineChannelAccessToken: "token"
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.line.me/v2/bot/message/push", {
+ messages: [
+ {
+ text: "Test Successful!",
+ type: "text",
+ },
+ ],
+ to: "1234",
+ }, {
+ headers: {
+ "Authorization": "Bearer token",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+
+ let notificationConf = {
+ type: "line",
+ lineUserID: "1234",
+ lineChannelAccessToken: "token"
+ };
+ let msg = "PassedInMessage";
+ let notif = new Line();
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.line.me/v2/bot/message/push", {
+ messages: [
+ {
+ text: "Test Successful!",
+ type: "text",
+ },
+ ],
+ to: "1234",
+ }, {
+ headers: {
+ "Authorization": "Bearer token",
+ "Content-Type": "application/json",
+ },
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "line",
+ lineUserID: "1234",
+ lineChannelAccessToken: "token"
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("https://api.line.me/v2/bot/message/push", {
+ messages: [
+ {
+ text: "UptimeKuma Alert: [✅ Up]\nName: testing\nsome message\nTime (UTC): example time",
+ type: "text",
+ },
+ ],
+ to: "1234",
+ }, {
+ headers: {
+ "Authorization": "Bearer token",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/lunasea.js b/server/notification-providers/lunasea.js
index c41f400..6b7ccb4 100644
--- a/server/notification-providers/lunasea.js
+++ b/server/notification-providers/lunasea.js
@@ -7,39 +7,38 @@ class LunaSea extends NotificationProvider {
name = "lunasea";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
- let lunaseadevice = "https://notify.lunasea.app/v1/custom/device/" + notification.lunaseaDevice
+ let lunaseadevice = "https://notify.lunasea.app/v1/custom/device/" + notification.lunaseaDevice;
try {
if (heartbeatJSON == null) {
let testdata = {
"title": "Uptime Kuma Alert",
"body": "Testing Successful.",
- }
- await axios.post(lunaseadevice, testdata)
- return okMsg;
+ };
+ await axios.post(lunaseadevice, testdata);
+ return this.sendSuccess;
}
if (heartbeatJSON["status"] == DOWN) {
let downdata = {
"title": "UptimeKuma Alert: " + monitorJSON["name"],
"body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"],
- }
- await axios.post(lunaseadevice, downdata)
- return okMsg;
+ };
+ await axios.post(lunaseadevice, downdata);
+ return this.sendSuccess;
}
if (heartbeatJSON["status"] == UP) {
let updata = {
"title": "UptimeKuma Alert: " + monitorJSON["name"],
"body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"],
- }
- await axios.post(lunaseadevice, updata)
- return okMsg;
+ };
+ await axios.post(lunaseadevice, updata);
+ return this.sendSuccess;
}
} catch (error) {
- this.throwGeneralAxiosError(error)
+ this.throwGeneralAxiosError(error);
}
}
diff --git a/server/notification-providers/lunasea.spec.js b/server/notification-providers/lunasea.spec.js
new file mode 100644
index 0000000..fd9639d
--- /dev/null
+++ b/server/notification-providers/lunasea.spec.js
@@ -0,0 +1,176 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const LunaSea = require("./lunasea");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new LunaSea();
+ expect(notification.name).toBe("lunasea");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data when UP", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new LunaSea();
+ let notificationConf = {
+ type: "lunasea",
+ lunaseaDevice: "1234",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://notify.lunasea.app/v1/custom/device/1234", {
+ "body": "[✅ Up] some message\nTime (UTC): example time",
+ "title": "UptimeKuma Alert: testing",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+ it("should call axios with the proper default data when DOWN", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new LunaSea();
+ let notificationConf = {
+ type: "lunasea",
+ lunaseaDevice: "1234",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "some message",
+ time: "example time",
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://notify.lunasea.app/v1/custom/device/1234", {
+ "body": "[🔴 Down] some message\nTime (UTC): example time",
+ "title": "UptimeKuma Alert: testing",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new LunaSea();
+ let notificationConf = {
+ type: "lunasea",
+ lunaseaDevice: "1234",
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("https://notify.lunasea.app/v1/custom/device/1234", {
+ "body": "Testing Successful.",
+ "title": "Uptime Kuma Alert",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new LunaSea();
+ let notificationConf = {
+ type: "lunasea",
+ lunaseaDevice: "1234",
+ };
+ let msg = "PassedInMessage";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://notify.lunasea.app/v1/custom/device/1234", {
+
+ "body": "Testing Successful.",
+ "title": "Uptime Kuma Alert" });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "lunasea",
+ lunaseaDevice: "1234",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("https://notify.lunasea.app/v1/custom/device/1234", {
+ "body": "[✅ Up] some message\nTime (UTC): example time",
+ "title": "UptimeKuma Alert: testing",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/matrix.js b/server/notification-providers/matrix.js
index c1054fc..26a85ff 100644
--- a/server/notification-providers/matrix.js
+++ b/server/notification-providers/matrix.js
@@ -7,7 +7,6 @@ class Matrix extends NotificationProvider {
name = "matrix";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
const size = 20;
const randomString = encodeURIComponent(
@@ -35,7 +34,7 @@ class Matrix extends NotificationProvider {
};
await axios.put(`${notification.homeserverUrl}/_matrix/client/r0/rooms/${roomId}/send/m.room.message/${randomString}`, data, config);
- return okMsg;
+ return this.sendSuccess;
} catch (error) {
this.throwGeneralAxiosError(error);
}
diff --git a/server/notification-providers/matrix.spec.js b/server/notification-providers/matrix.spec.js
new file mode 100644
index 0000000..b70c569
--- /dev/null
+++ b/server/notification-providers/matrix.spec.js
@@ -0,0 +1,171 @@
+jest.mock("axios", () => ({
+ put: jest.fn(),
+}));
+jest.mock("crypto", () => ({
+ randomBytes: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const Matrix = require("./matrix");
+const Crypto = require("crypto");
+
+beforeEach(() => {
+ axios.put.mockReset();
+ Crypto.randomBytes.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Matrix();
+ expect(notification.name).toBe("matrix");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.put.mockResolvedValueOnce(response);
+ Crypto.randomBytes.mockReturnValueOnce(Buffer.from("abcd"));
+
+ let notif = new Matrix();
+
+ let msg = "PassedInMessage";
+ let notificationConf = {
+ type: "matrix",
+ internalRoomId: "1234",
+ accessToken: "abcd",
+ homeserverUrl: "www.example.com",
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.put).toHaveBeenCalledWith("www.example.com/_matrix/client/r0/rooms/1234/send/m.room.message/YWJjZA%3D%3D", {
+ body: "PassedInMessage",
+ msgtype: "m.text"
+ }, {
+ headers: {
+ "Authorization": "Bearer abcd"
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.put.mockResolvedValueOnce(response);
+ Crypto.randomBytes.mockReturnValueOnce(Buffer.from("abcd"));
+
+ let notif = new Matrix();
+ let notificationConf = {
+ type: "matrix",
+ internalRoomId: "1234",
+ accessToken: "abcd",
+ homeserverUrl: "www.example.com",
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.put).toHaveBeenCalledWith("www.example.com/_matrix/client/r0/rooms/1234/send/m.room.message/YWJjZA%3D%3D", {
+ body: "PassedInMessage",
+ msgtype: "m.text"
+ }, {
+ headers: {
+ "Authorization": "Bearer abcd"
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.put.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ Crypto.randomBytes.mockReturnValueOnce(Buffer.from("abcd"));
+
+ let notif = new Matrix();
+ let notificationConf = {
+ type: "matrix",
+ internalRoomId: "1234",
+ accessToken: "abcd",
+ homeserverUrl: "www.example.com",
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.put).toHaveBeenCalledWith("www.example.com/_matrix/client/r0/rooms/1234/send/m.room.message/YWJjZA%3D%3D", {
+ body: "PassedInMessage",
+ msgtype: "m.text"
+ }, {
+ headers: {
+ "Authorization": "Bearer abcd"
+ }
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.put.mockResolvedValueOnce(response);
+ Crypto.randomBytes.mockReturnValueOnce(Buffer.from("abcd"));
+
+ let notificationConf = {
+ type: "matrix",
+ internalRoomId: "1234",
+ accessToken: "abcd",
+ homeserverUrl: "www.example.com",
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+ expect(axios.put).toHaveBeenCalledWith("www.example.com/_matrix/client/r0/rooms/1234/send/m.room.message/YWJjZA%3D%3D", {
+ body: "PassedInMessage",
+ msgtype: "m.text"
+ }, {
+ headers: {
+ "Authorization": "Bearer abcd"
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/mattermost.js b/server/notification-providers/mattermost.js
index d776284..1d25811 100644
--- a/server/notification-providers/mattermost.js
+++ b/server/notification-providers/mattermost.js
@@ -7,7 +7,6 @@ class Mattermost extends NotificationProvider {
name = "mattermost";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
const mattermostUserName = notification.mattermostusername || "Uptime Kuma";
// If heartbeatJSON is null, assume we're testing.
@@ -15,9 +14,9 @@ class Mattermost extends NotificationProvider {
let mattermostTestData = {
username: mattermostUserName,
text: msg,
- }
- await axios.post(notification.mattermostWebhookUrl, mattermostTestData)
- return okMsg;
+ };
+ await axios.post(notification.mattermostWebhookUrl, mattermostTestData);
+ return this.sendSuccess;
}
const mattermostChannel = notification.mattermostchannel;
@@ -36,12 +35,12 @@ class Mattermost extends NotificationProvider {
fallback:
"Your " +
monitorJSON["name"] +
- " service went down.",
+ " service went down!",
color: "#FF0000",
title:
"❌ " +
monitorJSON["name"] +
- " service went down. ❌",
+ " service went down! ❌",
title_link: monitorJSON["url"],
fields: [
{
@@ -67,7 +66,7 @@ class Mattermost extends NotificationProvider {
notification.mattermostWebhookUrl,
mattermostdowndata
);
- return okMsg;
+ return this.sendSuccess;
} else if (heartbeatJSON["status"] == UP) {
let mattermostupdata = {
username: mattermostUserName,
@@ -111,7 +110,7 @@ class Mattermost extends NotificationProvider {
notification.mattermostWebhookUrl,
mattermostupdata
);
- return okMsg;
+ return this.sendSuccess;
}
} catch (error) {
this.throwGeneralAxiosError(error);
diff --git a/server/notification-providers/mattermost.spec.js b/server/notification-providers/mattermost.spec.js
new file mode 100644
index 0000000..fa3979b
--- /dev/null
+++ b/server/notification-providers/mattermost.spec.js
@@ -0,0 +1,297 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const Mattermost = require("./mattermost");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Mattermost();
+ expect(notification.name).toBe("mattermost");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data when UP", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Mattermost();
+ let notificationConf = {
+ type: "mattermost",
+ mattermostchannel: "1234",
+ mattermosticonemo: "😀",
+ mattermosticonurl: "www.testing.com",
+ mattermostWebhookUrl: "www.example.com/webhook",
+ mattermostusername: "username",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ ping: "123",
+ time: "example time",
+ };
+ let msg = "PassedInMessage";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("www.example.com/webhook", {
+ "attachments": [
+ {
+ "color": "#32CD32",
+ "fallback": "Your testing service went up!",
+ "fields": [
+ {
+ "short": true,
+ "title": "Service Name",
+ "value": "testing",
+ },
+ {
+ "short": true,
+ "title": "Time (UTC)",
+ "value": "example time",
+ },
+ {
+ "short": false,
+ "title": "Ping",
+ "value": "123ms",
+ },
+ ],
+ "title": "✅ testing service went up! ✅",
+ "title_link": "https://www.google.com",
+ },
+ ],
+ "channel": "1234",
+ "icon_emoji": "😀",
+ "icon_url": "www.testing.com",
+ "text": "Uptime Kuma Alert",
+ "username": "username",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+ it("should call axios with the proper default data when DOWN", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Mattermost();
+ let notificationConf = {
+ type: "mattermost",
+ mattermostchannel: "1234",
+ mattermosticonemo: "😀",
+ mattermosticonurl: "www.testing.com",
+ mattermostWebhookUrl: "www.example.com/webhook",
+ mattermostusername: "username",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "some message",
+ ping: "123",
+ time: "example time",
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("www.example.com/webhook", {
+ "attachments": [
+ {
+ "color": "#FF0000",
+ "fallback": "Your testing service went down!",
+ "fields": [
+ {
+ "short": true,
+ "title": "Service Name",
+ "value": "testing",
+ },
+ {
+ "short": true,
+ "title": "Time (UTC)",
+ "value": "example time",
+ },
+ {
+ "short": false,
+ "title": "Error",
+ "value": "some message",
+ },
+ ],
+ "title": "❌ testing service went down! ❌",
+ "title_link": "https://www.google.com",
+ },
+ ],
+ "channel": "1234",
+ "icon_emoji": "😀",
+ "icon_url": "www.testing.com",
+ "text": "Uptime Kuma Alert",
+ "username": "username",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Mattermost();
+ let notificationConf = {
+ type: "mattermost",
+ mattermostchannel: "1234",
+ mattermosticonemo: "😀",
+ mattermosticonurl: "www.testing.com",
+ mattermostWebhookUrl: "www.example.com/webhook",
+ mattermostusername: "username",
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("www.example.com/webhook", {
+
+ "text": "PassedInMessage",
+ "username": "username"
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Mattermost();
+ let notificationConf = {
+ type: "mattermost",
+ mattermostchannel: "1234",
+ mattermosticonemo: "😀",
+ mattermosticonurl: "www.testing.com",
+ mattermostWebhookUrl: "www.example.com/webhook",
+ mattermostusername: "username",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ ping: "123",
+ time: "example time",
+ };
+ let msg = "PassedInMessage";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("www.example.com/webhook", {
+
+ "text": "PassedInMessage",
+ "username": "username"
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "mattermost",
+ mattermostchannel: "1234",
+ mattermosticonemo: "😀",
+ mattermosticonurl: "www.testing.com",
+ mattermostWebhookUrl: "www.example.com/webhook",
+ mattermostusername: "username",
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ ping: "123",
+ time: "example time",
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "PassedInMessage", monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("www.example.com/webhook", {
+ "attachments": [
+ {
+ "color": "#32CD32",
+ "fallback": "Your testing service went up!",
+ "fields": [
+ {
+ "short": true,
+ "title": "Service Name",
+ "value": "testing",
+ },
+ {
+ "short": true,
+ "title": "Time (UTC)",
+ "value": "example time",
+ },
+ {
+ "short": false,
+ "title": "Ping",
+ "value": "123ms",
+ },
+ ],
+ "title": "✅ testing service went up! ✅",
+ "title_link": "https://www.google.com",
+ },
+ ],
+ "channel": "1234",
+ "icon_emoji": "😀",
+ "icon_url": "www.testing.com",
+ "text": "Uptime Kuma Alert",
+ "username": "username",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/notification-provider.js b/server/notification-providers/notification-provider.js
index 61c6242..3ccff04 100644
--- a/server/notification-providers/notification-provider.js
+++ b/server/notification-providers/notification-provider.js
@@ -6,6 +6,8 @@ class NotificationProvider {
*/
name = undefined;
+ sendSuccess = "Sent Successfully.";
+
/**
* @param notification : BeanModel
* @param msg : string General Message
@@ -25,11 +27,11 @@ class NotificationProvider {
if (typeof error.response.data === "string") {
msg += error.response.data;
} else {
- msg += JSON.stringify(error.response.data)
+ msg += JSON.stringify(error.response.data);
}
}
- throw new Error(msg)
+ throw new Error(msg);
}
}
diff --git a/server/notification-providers/notification-provider.spec.js b/server/notification-providers/notification-provider.spec.js
new file mode 100644
index 0000000..1f6f037
--- /dev/null
+++ b/server/notification-providers/notification-provider.spec.js
@@ -0,0 +1,40 @@
+// jest.mock("nodemailer", () => ({
+// createTransport: jest.fn(),
+// }));
+
+// const mockNodeMailer = require("nodemailer");
+
+const NotificationProvider = require("./notification-provider");
+
+beforeEach(() => {
+ // mockNodeMailer.createTransport.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new NotificationProvider();
+ expect(notification.name).toBe(undefined);
+ });
+});
+
+describe("notification to error if blank notification called", () => {
+ it("should respond with an error if just called.", async () => {
+
+ let notif = new NotificationProvider();
+ let notificationConf = {
+ type: "telegram",
+ telegramBotToken: "abc",
+ telegramChatID: "123",
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Have to override Notification.send(...)");
+ }
+
+ });
+
+});
diff --git a/server/notification-providers/octopush.js b/server/notification-providers/octopush.js
index 9d77aa5..6ef8e39 100644
--- a/server/notification-providers/octopush.js
+++ b/server/notification-providers/octopush.js
@@ -6,7 +6,6 @@ class Octopush extends NotificationProvider {
name = "octopush";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
// Default - V2
@@ -30,7 +29,7 @@ class Octopush extends NotificationProvider {
"purpose": "alert",
"sender": notification.octopushSenderName
};
- await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config)
+ await axios.post("https://api.octopush.com/v1/public/sms-campaign/send", data, config);
} else if (notification.octopushVersion == 1) {
let data = {
"user_login": notification.octopushDMLogin,
@@ -49,12 +48,12 @@ class Octopush extends NotificationProvider {
},
params: data
};
- await axios.post("https://www.octopush-dm.com/api/sms/json", {}, config)
+ await axios.post("https://www.octopush-dm.com/api/sms/json", {}, config);
} else {
throw new Error("Unknown Octopush version!");
}
- return okMsg;
+ return this.sendSuccess;
} catch (error) {
this.throwGeneralAxiosError(error);
}
diff --git a/server/notification-providers/octopush.spec.js b/server/notification-providers/octopush.spec.js
new file mode 100644
index 0000000..75ac667
--- /dev/null
+++ b/server/notification-providers/octopush.spec.js
@@ -0,0 +1,245 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const Octopush = require("./octopush");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Octopush();
+ expect(notification.name).toBe("octopush");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data when version 2", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Octopush();
+ let notificationConf = {
+ type: "octopush",
+ octopushVersion: 2,
+ octopushAPIKey: "key",
+ octopushLogin: "login",
+ octopushPhoneNumber: "number",
+ octopushSMSType: "type",
+ octopushSenderName: "sender"
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.octopush.com/v1/public/sms-campaign/send", {
+ "purpose": "alert",
+ "recipients": [{ "phone_number": "number" }],
+ "sender": "sender",
+ "text": "PassedInMessage",
+ "type": "type"
+ }, {
+ "headers": {
+ "api-key": "key",
+ "api-login": "login",
+ "cache-control": "no-cache"
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+ it("should call axios with the proper default data when version 1", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Octopush();
+ let notificationConf = {
+ type: "octopush",
+ octopushVersion: 1,
+ octopushDMAPIKey: "key",
+ octopushDMLogin: "login",
+ octopushDMPhoneNumber: "number",
+ octopushDMSMSType: "sms_premium",
+ octopushDMSenderName: "sender"
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://www.octopush-dm.com/api/sms/json", {
+
+ }, {
+ "headers": {
+ "cache-control": "no-cache"
+ },
+ "params": {
+ "api_key": "key",
+ "sms_recipients": "number",
+ "sms_sender": "sender",
+ "sms_text": "PassedInMessage",
+ "sms_type": "FR",
+ "transactional": "1",
+ "user_login": "login"
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Octopush();
+ let notificationConf = {
+ type: "lunasea",
+ lunaseaDevice: "1234",
+ };
+ let msg = "PassedInMessage";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.octopush.com/v1/public/sms-campaign/send", {
+ "purpose": "alert",
+ "recipients": [{ "phone_number": undefined }],
+ "sender": undefined,
+ "text": "PassedInMessage",
+ "type": undefined
+ }, {
+ "headers": {
+ "api-key": undefined,
+ "api-login": undefined,
+ "cache-control": "no-cache"
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Octopush();
+ let notificationConf = {
+ type: "octopush",
+ octopushVersion: 2,
+ octopushAPIKey: "key",
+ octopushLogin: "login",
+ octopushPhoneNumber: "number",
+ octopushSMSType: "type",
+ octopushSenderName: "sender"
+ };
+ let msg = "PassedInMessage";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.octopush.com/v1/public/sms-campaign/send", {
+ "purpose": "alert",
+ "recipients": [{ "phone_number": "number" }],
+ "sender": "sender",
+ "text": "PassedInMessage",
+ "type": "type"
+ }, {
+ "headers": {
+ "api-key": "key",
+ "api-login": "login",
+ "cache-control": "no-cache"
+ }
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "octopush",
+ octopushVersion: 2,
+ octopushAPIKey: "key",
+ octopushLogin: "login",
+ octopushPhoneNumber: "number",
+ octopushSMSType: "type",
+ octopushSenderName: "sender"
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "Passed😀InMessage", monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("https://api.octopush.com/v1/public/sms-campaign/send", {
+ "purpose": "alert",
+ "recipients": [{ "phone_number": "number" }],
+ "sender": "sender",
+ "text": "PassedInMessage",
+ "type": "type"
+ }, {
+ "headers": {
+ "api-key": "key",
+ "api-login": "login",
+ "cache-control": "no-cache"
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/promosms.js b/server/notification-providers/promosms.js
index 362ef71..4f0e526 100644
--- a/server/notification-providers/promosms.js
+++ b/server/notification-providers/promosms.js
@@ -6,13 +6,12 @@ class PromoSMS extends NotificationProvider {
name = "promosms";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
let config = {
headers: {
"Content-Type": "application/json",
- "Authorization": "Basic " + Buffer.from(notification.promosmsLogin + ":" + notification.promosmsPassword).toString('base64'),
+ "Authorization": "Basic " + Buffer.from(notification.promosmsLogin + ":" + notification.promosmsPassword).toString("base64"),
"Accept": "text/json",
}
};
@@ -30,8 +29,8 @@ class PromoSMS extends NotificationProvider {
let error = "Something gone wrong. Api returned " + resp.data.response.status + ".";
this.throwGeneralAxiosError(error);
}
-
- return okMsg;
+
+ return this.sendSuccess;
} catch (error) {
this.throwGeneralAxiosError(error);
}
diff --git a/server/notification-providers/promosms.spec.js b/server/notification-providers/promosms.spec.js
new file mode 100644
index 0000000..6802341
--- /dev/null
+++ b/server/notification-providers/promosms.spec.js
@@ -0,0 +1,193 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+const PromoSMS = require("./promosms");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new PromoSMS();
+ expect(notification.name).toBe("promosms");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ response: {
+ status: 0
+ },
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new PromoSMS();
+ let notificationConf = {
+ type: "promosms",
+ promosmsLogin: "login",
+ promosmsPassword: "password",
+ promosmsPhoneNumber: "number",
+ promosmsSMSType: 1,
+ promosmsSenderName: "sender"
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://promosms.com/api/rest/v3_2/sms", {
+ "recipients": [
+ "number",
+ ],
+ "sender": "sender",
+ "text": "PassedInMessage",
+ "type": 1,
+ }, {
+ "headers": {
+ "Accept": "text/json",
+ "Authorization": "Basic bG9naW46cGFzc3dvcmQ=",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ response: {
+ status: 0
+ },
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new PromoSMS();
+ let notificationConf = {
+ type: "promosms",
+ promosmsLogin: "login",
+ promosmsPassword: "password",
+ promosmsPhoneNumber: "number",
+ promosmsSMSType: 1,
+ promosmsSenderName: "sender"
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("https://promosms.com/api/rest/v3_2/sms", {
+ "recipients": [
+ "number",
+ ],
+ "sender": "sender",
+ "text": "PassedInMessage",
+ "type": 1,
+ }, {
+ "headers": {
+ "Accept": "text/json",
+ "Authorization": "Basic bG9naW46cGFzc3dvcmQ=",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new PromoSMS();
+ let notificationConf = {
+ type: "promosms",
+ promosmsLogin: "login",
+ promosmsPassword: "password",
+ promosmsPhoneNumber: "number",
+ promosmsSMSType: 1,
+ promosmsSenderName: "sender"
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://promosms.com/api/rest/v3_2/sms", {
+ "recipients": [
+ "number",
+ ],
+ "sender": "sender",
+ "text": "PassedInMessage",
+ "type": 1,
+ }, {
+ "headers": {
+ "Accept": "text/json",
+ "Authorization": "Basic bG9naW46cGFzc3dvcmQ=",
+ "Content-Type": "application/json",
+ },
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ response: {
+ status: 0
+ },
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "promosms",
+ promosmsLogin: "login",
+ promosmsPassword: "password",
+ promosmsPhoneNumber: "number",
+ promosmsSMSType: 1,
+ promosmsSenderName: "sender"
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("https://promosms.com/api/rest/v3_2/sms", {
+ "recipients": [
+ "number",
+ ],
+ "sender": "sender",
+ "text": "PassedInMessage",
+ "type": 1,
+ }, {
+ "headers": {
+ "Accept": "text/json",
+ "Authorization": "Basic bG9naW46cGFzc3dvcmQ=",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/pushbullet.js b/server/notification-providers/pushbullet.js
index c7b824a..9de5b61 100644
--- a/server/notification-providers/pushbullet.js
+++ b/server/notification-providers/pushbullet.js
@@ -8,7 +8,6 @@ class Pushbullet extends NotificationProvider {
name = "pushbullet";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
let pushbulletUrl = "https://api.pushbullet.com/v2/pushes";
@@ -23,26 +22,26 @@ class Pushbullet extends NotificationProvider {
"type": "note",
"title": "Uptime Kuma Alert",
"body": "Testing Successful.",
- }
- await axios.post(pushbulletUrl, testdata, config)
+ };
+ await axios.post(pushbulletUrl, testdata, config);
} else if (heartbeatJSON["status"] == DOWN) {
let downdata = {
"type": "note",
"title": "UptimeKuma Alert: " + monitorJSON["name"],
"body": "[🔴 Down] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"],
- }
- await axios.post(pushbulletUrl, downdata, config)
+ };
+ await axios.post(pushbulletUrl, downdata, config);
} else if (heartbeatJSON["status"] == UP) {
let updata = {
"type": "note",
"title": "UptimeKuma Alert: " + monitorJSON["name"],
"body": "[✅ Up] " + heartbeatJSON["msg"] + "\nTime (UTC): " + heartbeatJSON["time"],
- }
- await axios.post(pushbulletUrl, updata, config)
+ };
+ await axios.post(pushbulletUrl, updata, config);
}
- return okMsg;
+ return this.sendSuccess;
} catch (error) {
- this.throwGeneralAxiosError(error)
+ this.throwGeneralAxiosError(error);
}
}
}
diff --git a/server/notification-providers/pushbullet.spec.js b/server/notification-providers/pushbullet.spec.js
new file mode 100644
index 0000000..8958b5e
--- /dev/null
+++ b/server/notification-providers/pushbullet.spec.js
@@ -0,0 +1,201 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+const Pushbullet = require("./pushbullet");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Pushbullet();
+ expect(notification.name).toBe("pushbullet");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data when UP", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Pushbullet();
+ let notificationConf = {
+ type: "pushbullet",
+ pushbulletAccessToken: "token",
+ };
+ let monitorConf = {
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushbullet.com/v2/pushes", {
+ "body": "[✅ Up] some message\nTime (UTC): example time",
+ "title": "UptimeKuma Alert: testing",
+ "type": "note",
+ }, {
+ "headers": {
+ "Access-Token": "token",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+ it("should call axios with the proper default data when UP", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Pushbullet();
+ let notificationConf = {
+ type: "pushbullet",
+ pushbulletAccessToken: "token",
+ };
+ let monitorConf = {
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "some message",
+ time: "example time",
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushbullet.com/v2/pushes", {
+ "body": "[🔴 Down] some message\nTime (UTC): example time",
+ "title": "UptimeKuma Alert: testing",
+ "type": "note",
+ }, {
+ "headers": {
+ "Access-Token": "token",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Pushbullet();
+ let notificationConf = {
+ type: "pushbullet",
+ pushbulletAccessToken: "token",
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushbullet.com/v2/pushes", {
+ "body": "Testing Successful.",
+ "title": "Uptime Kuma Alert",
+ "type": "note",
+ }, {
+ "headers": {
+ "Access-Token": "token",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Pushbullet();
+ let notificationConf = {
+ type: "pushbullet",
+ pushbulletAccessToken: "token",
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushbullet.com/v2/pushes", {
+ "body": "Testing Successful.",
+ "title": "Uptime Kuma Alert",
+ "type": "note",
+ }, {
+ "headers": {
+ "Access-Token": "token",
+ "Content-Type": "application/json",
+ },
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "pushbullet",
+ pushbulletAccessToken: "token",
+ };
+ let monitorConf = {
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "some message",
+ time: "example time",
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushbullet.com/v2/pushes", {
+ "body": "[✅ Up] some message\nTime (UTC): example time",
+ "title": "UptimeKuma Alert: testing",
+ "type": "note",
+ }, {
+ "headers": {
+ "Access-Token": "token",
+ "Content-Type": "application/json",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/pushover.js b/server/notification-providers/pushover.js
index 77ef1a3..76aa059 100644
--- a/server/notification-providers/pushover.js
+++ b/server/notification-providers/pushover.js
@@ -6,8 +6,7 @@ class Pushover extends NotificationProvider {
name = "pushover";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
- let pushoverlink = "https://api.pushover.net/1/messages.json"
+ let pushoverlink = "https://api.pushover.net/1/messages.json";
try {
if (heartbeatJSON == null) {
@@ -21,9 +20,9 @@ class Pushover extends NotificationProvider {
"retry": "30",
"expire": "3600",
"html": 1,
- }
- await axios.post(pushoverlink, data)
- return okMsg;
+ };
+ await axios.post(pushoverlink, data);
+ return this.sendSuccess;
}
let data = {
@@ -36,11 +35,11 @@ class Pushover extends NotificationProvider {
"retry": "30",
"expire": "3600",
"html": 1,
- }
- await axios.post(pushoverlink, data)
- return okMsg;
+ };
+ await axios.post(pushoverlink, data);
+ return this.sendSuccess;
} catch (error) {
- this.throwGeneralAxiosError(error)
+ this.throwGeneralAxiosError(error);
}
}
diff --git a/server/notification-providers/pushover.spec.js b/server/notification-providers/pushover.spec.js
new file mode 100644
index 0000000..d6ee4f7
--- /dev/null
+++ b/server/notification-providers/pushover.spec.js
@@ -0,0 +1,177 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+const Pushover = require("./pushover");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Pushover();
+ expect(notification.name).toBe("pushover");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Pushover();
+ let notificationConf = {
+ type: "octopush",
+ pushoveruserkey: "123",
+ pushoverapptoken: "token",
+ pushoversounds: "ding",
+ pushoverpriority: "6",
+ pushovertitle: "Important Title!",
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ time: "example time",
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushover.net/1/messages.json", {
+ "expire": "3600",
+ "html": 1,
+ "message": "Uptime Kuma Alert\n\nMessage:PassedInMessage😀\nTime (UTC):example time",
+ "priority": "6",
+ "retry": "30",
+ "sound": "ding",
+ "title": "Important Title!",
+ "token": "token",
+ "user": "123",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Pushover();
+ let notificationConf = {
+ type: "octopush",
+ pushoveruserkey: "123",
+ pushoverapptoken: "token",
+ pushoversounds: "ding",
+ pushoverpriority: "6",
+ pushovertitle: "Important Title!",
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushover.net/1/messages.json", {
+ "expire": "3600",
+ "html": 1,
+ "message": "Uptime Kuma Pushover testing successful.",
+ "priority": "6",
+ "retry": "30",
+ "sound": "ding",
+ "title": "Important Title!",
+ "token": "token",
+ "user": "123",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Pushover();
+ let notificationConf = {
+ type: "octopush",
+ pushoveruserkey: "123",
+ pushoverapptoken: "token",
+ pushoversounds: "ding",
+ pushoverpriority: "6",
+ pushovertitle: "Important Title!",
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushover.net/1/messages.json", {
+ "expire": "3600",
+ "html": 1,
+ "message": "Uptime Kuma Pushover testing successful.",
+ "priority": "6",
+ "retry": "30",
+ "sound": "ding",
+ "title": "Important Title!",
+ "token": "token",
+ "user": "123",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "pushover",
+ pushoveruserkey: "123",
+ pushoverapptoken: "token",
+ pushoversounds: "ding",
+ pushoverpriority: "6",
+ pushovertitle: "Important Title!",
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ time: "example time",
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushover.net/1/messages.json", {
+ "expire": "3600",
+ "html": 1,
+ "message": "Uptime Kuma Alert\n\nMessage:PassedInMessage😀\nTime (UTC):example time",
+ "priority": "6",
+ "retry": "30",
+ "sound": "ding",
+ "title": "Important Title!",
+ "token": "token",
+ "user": "123",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/pushy.js b/server/notification-providers/pushy.js
index 2bb8993..f18c915 100644
--- a/server/notification-providers/pushy.js
+++ b/server/notification-providers/pushy.js
@@ -6,7 +6,6 @@ class Pushy extends NotificationProvider {
name = "pushy";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
await axios.post(`https://api.pushy.me/push?api_key=${notification.pushyAPIKey}`, {
@@ -19,10 +18,10 @@ class Pushy extends NotificationProvider {
"badge": 1,
"sound": "ping.aiff"
}
- })
- return okMsg;
+ });
+ return this.sendSuccess;
} catch (error) {
- this.throwGeneralAxiosError(error)
+ this.throwGeneralAxiosError(error);
}
}
}
diff --git a/server/notification-providers/pushy.spec.js b/server/notification-providers/pushy.spec.js
new file mode 100644
index 0000000..4fada3d
--- /dev/null
+++ b/server/notification-providers/pushy.spec.js
@@ -0,0 +1,161 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+const Pushy = require("./pushy");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Pushy();
+ expect(notification.name).toBe("pushy");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Pushy();
+ let notificationConf = {
+ pushyAPIKey: "key",
+ pushyToken: "token"
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushy.me/push?api_key=key", {
+ "data": {
+ "message": "Uptime-Kuma",
+ },
+ "notification": {
+ "badge": 1,
+ "body": "PassedInMessage😀",
+ "sound": "ping.aiff",
+ },
+ "to": "token",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Pushy();
+ let notificationConf = {
+ pushyAPIKey: "key",
+ pushyToken: "token"
+ };
+
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushy.me/push?api_key=key", {
+ "data": {
+ "message": "Uptime-Kuma",
+ },
+ "notification": {
+ "badge": 1,
+ "body": "PassedInMessage😀",
+ "sound": "ping.aiff",
+ },
+ "to": "token",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Pushy();
+ let notificationConf = {
+ pushyAPIKey: "key",
+ pushyToken: "token"
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushy.me/push?api_key=key", {
+ "data": {
+ "message": "Uptime-Kuma",
+ },
+ "notification": {
+ "badge": 1,
+ "body": "PassedInMessage😀",
+ "sound": "ping.aiff",
+ },
+ "to": "token",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "pushy",
+ pushyAPIKey: "key",
+ pushyToken: "token"
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("https://api.pushy.me/push?api_key=key", {
+ "data": {
+ "message": "Uptime-Kuma",
+ },
+ "notification": {
+ "badge": 1,
+ "body": "PassedInMessage😀",
+ "sound": "ping.aiff",
+ },
+ "to": "token",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/rocket-chat.js b/server/notification-providers/rocket-chat.js
index 25b0b94..28327b0 100644
--- a/server/notification-providers/rocket-chat.js
+++ b/server/notification-providers/rocket-chat.js
@@ -9,7 +9,6 @@ class RocketChat extends NotificationProvider {
name = "rocket.chat";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
if (heartbeatJSON == null) {
let data = {
@@ -19,7 +18,7 @@ class RocketChat extends NotificationProvider {
"icon_emoji": notification.rocketiconemo,
};
await axios.post(notification.rocketwebhookURL, data);
- return okMsg;
+ return this.sendSuccess;
}
const time = heartbeatJSON["time"];
@@ -55,7 +54,7 @@ class RocketChat extends NotificationProvider {
}
await axios.post(notification.rocketwebhookURL, data);
- return okMsg;
+ return this.sendSuccess;
} catch (error) {
this.throwGeneralAxiosError(error);
}
diff --git a/server/notification-providers/rocket-chat.spec.js b/server/notification-providers/rocket-chat.spec.js
new file mode 100644
index 0000000..a039571
--- /dev/null
+++ b/server/notification-providers/rocket-chat.spec.js
@@ -0,0 +1,221 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+jest.mock("../util-server");
+
+const axios = require("axios");
+const { setting } = require("../util-server");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.post.mockReset();
+ setting.mockReset();
+});
+const RocketChat = require("./rocket-chat");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new RocketChat();
+ expect(notification.name).toBe("rocket.chat");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data when UP", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ setting.mockResolvedValueOnce("base.com");
+ let notif = new RocketChat();
+ let notificationConf = {
+ rocketchannel: "channel",
+ rocketusername: "user",
+ rocketiconemo: "😀",
+ rocketwebhookURL: "example.com",
+ };
+ let monitorConf = {
+ id: "123"
+ };
+ let heartbeatConf = {
+ status: UP,
+ time: "some time"
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("example.com", {
+ "attachments": [
+ {
+ "color": "#32cd32",
+ "text": "*Message*\nPassedInMessage😀",
+ "title": "Uptime Kuma Alert *Time (UTC)*\nsome time",
+ "title_link": "base.com/dashboard/123",
+ },
+ ],
+ "channel": "channel",
+ "icon_emoji": "😀",
+ "text": "Uptime Kuma Alert",
+ "username": "user",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper default data when DOWN", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ setting.mockResolvedValueOnce("base.com");
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new RocketChat();
+ let notificationConf = {
+ rocketchannel: "channel",
+ rocketusername: "user",
+ rocketiconemo: "😀",
+ rocketwebhookURL: "example.com",
+ };
+ let monitorConf = {
+ id: "123"
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ time: "some time"
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("example.com", {
+ "attachments": [
+ {
+ "color": "#ff0000",
+ "text": "*Message*\nPassedInMessage😀",
+ "title": "Uptime Kuma Alert *Time (UTC)*\nsome time",
+ "title_link": "base.com/dashboard/123",
+ },
+ ],
+ "channel": "channel",
+ "icon_emoji": "😀",
+ "text": "Uptime Kuma Alert",
+ "username": "user",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ setting.mockResolvedValueOnce("base.com");
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new RocketChat();
+ let notificationConf = {
+ rocketchannel: "channel",
+ rocketusername: "user",
+ rocketiconemo: "😀",
+ rocketwebhookURL: "example.com",
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("example.com", {
+ "channel": "channel",
+ "icon_emoji": "😀",
+ "text": "PassedInMessage😀",
+ "username": "user",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ setting.mockResolvedValueOnce("base.com");
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new RocketChat();
+ let notificationConf = {
+ rocketchannel: "channel",
+ rocketusername: "user",
+ rocketiconemo: "😀",
+ rocketwebhookURL: "example.com",
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("example.com", {
+ "channel": "channel",
+ "icon_emoji": "😀",
+ "text": "PassedInMessage😀",
+ "username": "user",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ setting.mockResolvedValueOnce("base.com");
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "rocket.chat",
+ rocketchannel: "channel",
+ rocketusername: "user",
+ rocketiconemo: "😀",
+ rocketwebhookURL: "example.com",
+ };
+ let monitorConf = {
+ id: "123"
+ };
+ let heartbeatConf = {
+ status: UP,
+ time: "some time"
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("example.com", {
+ "attachments": [
+ {
+ "color": "#32cd32",
+ "text": "*Message*\nPassedInMessage😀",
+ "title": "Uptime Kuma Alert *Time (UTC)*\nsome time",
+ "title_link": "base.com/dashboard/123",
+ },
+ ],
+ "channel": "channel",
+ "icon_emoji": "😀",
+ "text": "Uptime Kuma Alert",
+ "username": "user",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/signal.js b/server/notification-providers/signal.js
index fee6575..eb58eb2 100644
--- a/server/notification-providers/signal.js
+++ b/server/notification-providers/signal.js
@@ -6,7 +6,6 @@ class Signal extends NotificationProvider {
name = "signal";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
let data = {
@@ -16,10 +15,10 @@ class Signal extends NotificationProvider {
};
let config = {};
- await axios.post(notification.signalURL, data, config)
- return okMsg;
+ await axios.post(notification.signalURL, data, config);
+ return this.sendSuccess;
} catch (error) {
- this.throwGeneralAxiosError(error)
+ this.throwGeneralAxiosError(error);
}
}
}
diff --git a/server/notification-providers/signal.spec.js b/server/notification-providers/signal.spec.js
new file mode 100644
index 0000000..6b8fd71
--- /dev/null
+++ b/server/notification-providers/signal.spec.js
@@ -0,0 +1,175 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+const Signal = require("./signal");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Signal();
+ expect(notification.name).toBe("signal");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Signal();
+ let notificationConf = {
+ type: "signal",
+ signalNumber: "appriseURL",
+ signalRecipients: "asd asd, age, ge, wrh werh ,werh ,er h,as",
+ signalURL: "https://example.com/webhook",
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("https://example.com/webhook", {
+ "message": "PassedInMessage😀",
+ "number": "appriseURL",
+ "recipients": [
+ "asdasd",
+ "age",
+ "ge",
+ "wrhwerh",
+ "werh",
+ "erh",
+ "as",
+ ],
+ }, {});
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Signal();
+ let notificationConf = {
+ type: "signal",
+ signalNumber: "appriseURL",
+ signalRecipients: "asd asd, age, ge, wrh werh ,werh ,er h,as",
+ signalURL: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("https://example.com/webhook", {
+ "message": "PassedInMessage😀",
+ "number": "appriseURL",
+ "recipients": [
+ "asdasd",
+ "age",
+ "ge",
+ "wrhwerh",
+ "werh",
+ "erh",
+ "as",
+ ],
+ }, {});
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Signal();
+ let notificationConf = {
+ type: "signal",
+ signalNumber: "appriseURL",
+ signalRecipients: "asd asd, age, ge, wrh werh ,werh ,er h,as",
+ signalURL: "https://example.com/webhook",
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("https://example.com/webhook", {
+ "message": "PassedInMessage😀",
+ "number": "appriseURL",
+ "recipients": [
+ "asdasd",
+ "age",
+ "ge",
+ "wrhwerh",
+ "werh",
+ "erh",
+ "as",
+ ],
+ }, {});
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "signal",
+ signalNumber: "appriseURL",
+ signalRecipients: "asd asd, age, ge, wrh werh ,werh ,er h,as",
+ signalURL: "https://example.com/webhook",
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("https://example.com/webhook", {
+ "message": "PassedInMessage😀",
+ "number": "appriseURL",
+ "recipients": [
+ "asdasd",
+ "age",
+ "ge",
+ "wrhwerh",
+ "werh",
+ "erh",
+ "as",
+ ],
+ }, {});
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/slack.js b/server/notification-providers/slack.js
index b4dad6f..d7ef721 100644
--- a/server/notification-providers/slack.js
+++ b/server/notification-providers/slack.js
@@ -25,7 +25,6 @@ class Slack extends NotificationProvider {
}
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
if (heartbeatJSON == null) {
let data = {
@@ -35,7 +34,7 @@ class Slack extends NotificationProvider {
"icon_emoji": notification.slackiconemo,
};
await axios.post(notification.slackwebhookURL, data);
- return okMsg;
+ return this.sendSuccess;
}
const time = heartbeatJSON["time"];
@@ -88,7 +87,7 @@ class Slack extends NotificationProvider {
}
await axios.post(notification.slackwebhookURL, data);
- return okMsg;
+ return this.sendSuccess;
} catch (error) {
this.throwGeneralAxiosError(error);
}
diff --git a/server/notification-providers/slack.spec.js b/server/notification-providers/slack.spec.js
new file mode 100644
index 0000000..a360704
--- /dev/null
+++ b/server/notification-providers/slack.spec.js
@@ -0,0 +1,252 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+jest.mock("../util-server");
+const { setting } = require("../util-server");
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ setting.mockReset();
+ axios.post.mockReset();
+});
+const Slack = require("./slack");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Slack();
+ expect(notification.name).toBe("slack");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ setting.mockResolvedValueOnce("base.com");
+
+ let notif = new Slack();
+
+ let notificationConf = {
+ type: "slack",
+ slackchannel: "chan",
+ slackusername: "name",
+ slackiconemo: "😀",
+ slackwebhookURL: "www.slack.com/webhook"
+ };
+ let monitorConf = {
+ name: "testing monitor",
+ id: "123",
+ };
+ let heartbeatConf = {
+ time: "test time"
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("www.slack.com/webhook", {
+
+ "blocks": [
+ {
+ "text": {
+ "text": "Uptime Kuma Alert",
+ "type": "plain_text",
+ },
+ "type": "header",
+ },
+ {
+ "fields": [
+ {
+ "text": "*Message*\nPassedInMessage😀",
+ "type": "mrkdwn",
+ },
+ {
+ "text": "*Time (UTC)*\ntest time",
+ "type": "mrkdwn",
+ },
+ ],
+ "type": "section",
+ },
+ {
+ "elements": [
+ {
+ "text": {
+ "text": "Visit Uptime Kuma",
+ "type": "plain_text",
+ },
+ "type": "button",
+ "url": "base.com/dashboard/123",
+ "value": "Uptime-Kuma",
+ },
+ ],
+ "type": "actions",
+ },
+ ],
+ "channel": "chan",
+ "icon_emoji": "😀",
+ "text": "Uptime Kuma Alert: testing monitor",
+ "username": "name",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ setting.mockResolvedValueOnce("base.com");
+
+ let notif = new Slack();
+
+ let notificationConf = {
+ type: "slack",
+ slackchannel: "chan",
+ slackusername: "name",
+ slackiconemo: "😀",
+ slackwebhookURL: "www.slack.com/webhook"
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("www.slack.com/webhook", {
+
+ "channel": "chan",
+ "icon_emoji": "😀",
+ "text": "PassedInMessage😀",
+ "username": "name",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ setting.mockResolvedValueOnce("base.com");
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Slack();
+
+ let notificationConf = {
+ type: "slack",
+ slackchannel: "chan",
+ slackusername: "name",
+ slackiconemo: "😀",
+ slackwebhookURL: "www.slack.com/webhook"
+ };
+ let monitorConf = {
+ name: "testing monitor",
+ id: "123",
+ };
+ let heartbeatConf = {
+ time: "test time"
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("www.slack.com/webhook", {
+
+ "channel": "chan",
+ "icon_emoji": "😀",
+ "text": "PassedInMessage😀",
+ "username": "name",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ setting.mockResolvedValueOnce("base.com");
+
+ let notificationConf = {
+ type: "slack",
+ slackchannel: "chan",
+ slackusername: "name",
+ slackiconemo: "😀",
+ slackwebhookURL: "www.slack.com/webhook"
+ };
+ let monitorConf = {
+ name: "testing monitor",
+ id: "123",
+ };
+ let heartbeatConf = {
+ time: "test time"
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("www.slack.com/webhook", {
+
+ "blocks": [
+ {
+ "text": {
+ "text": "Uptime Kuma Alert",
+ "type": "plain_text",
+ },
+ "type": "header",
+ },
+ {
+ "fields": [
+ {
+ "text": "*Message*\nPassedInMessage😀",
+ "type": "mrkdwn",
+ },
+ {
+ "text": "*Time (UTC)*\ntest time",
+ "type": "mrkdwn",
+ },
+ ],
+ "type": "section",
+ },
+ {
+ "elements": [
+ {
+ "text": {
+ "text": "Visit Uptime Kuma",
+ "type": "plain_text",
+ },
+ "type": "button",
+ "url": "base.com/dashboard/123",
+ "value": "Uptime-Kuma",
+ },
+ ],
+ "type": "actions",
+ },
+ ],
+ "channel": "chan",
+ "icon_emoji": "😀",
+ "text": "Uptime Kuma Alert: testing monitor",
+ "username": "name",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/smtp.js b/server/notification-providers/smtp.js
index 14429bc..31a0bc5 100644
--- a/server/notification-providers/smtp.js
+++ b/server/notification-providers/smtp.js
@@ -92,7 +92,7 @@ class SMTP extends NotificationProvider {
text: bodyTextContent,
});
- return "Sent Successfully.";
+ return this.sendSuccess;
}
}
diff --git a/server/notification-providers/smtp.spec.js b/server/notification-providers/smtp.spec.js
new file mode 100644
index 0000000..b3ffb42
--- /dev/null
+++ b/server/notification-providers/smtp.spec.js
@@ -0,0 +1,250 @@
+jest.mock("nodemailer", () => ({
+ createTransport: jest.fn(),
+}));
+const mockNodeMailer = require("nodemailer");
+const { UP } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+const SMTP = require("./smtp");
+
+beforeEach(() => {
+ mockNodeMailer.createTransport.mockReset();
+});
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new SMTP();
+ expect(notification.name).toBe("smtp");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call transport with the proper default data", async () => {
+ let sender = jest.fn()
+ .mockResolvedValue(() => {
+ return;
+ });
+ mockNodeMailer.createTransport.mockImplementationOnce(() => {
+ return { sendMail: sender };
+ });
+
+ let notif = new SMTP();
+ let notificationConf = {
+ smtpHost: "host",
+ smtpPort: "port",
+ smtpSecure: "secure",
+ smtpUsername: "username",
+ smtpPassword: "password",
+ customSubject: "",
+ smtpFrom: "From",
+ smtpCC: "CC",
+ smtpBCC: "BCC",
+ smtpTo: "To",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = { };
+ let heartbeatConf = { };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(mockNodeMailer.createTransport).toHaveBeenCalledWith({
+ auth: {
+ pass: "password",
+ user: "username",
+ },
+ host: "host",
+ port: "port",
+ secure: "secure",
+ tls: {
+ "rejectUnauthorized": false,
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ expect(sender).toHaveBeenCalledWith({
+ bcc: "BCC",
+ cc: "CC",
+ from: "From",
+ subject: "PassedInMessage",
+ text: "PassedInMessage\nTime (UTC): undefined",
+
+ to: "To",
+
+ });
+ });
+
+ it("should use the proper email subject", async () => {
+ let sender = jest.fn()
+ .mockResolvedValue(() => {
+ return;
+ });
+ mockNodeMailer.createTransport.mockImplementationOnce(() => {
+ return { sendMail: sender };
+ });
+
+ let notif = new SMTP();
+ let notificationConf = {
+ smtpHost: "host",
+ smtpPort: "port",
+ smtpSecure: "secure",
+ smtpUsername: "username",
+ smtpPassword: "password",
+ customSubject: "Name: {{NAME}} | Status: {{STATUS}} | Hostname: {{HOSTNAME_OR_URL}}",
+ smtpFrom: "From",
+ smtpCC: "CC",
+ smtpBCC: "BCC",
+ smtpTo: "To",
+ };
+ let msg = "PassedInMessage";
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+
+ };
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(mockNodeMailer.createTransport).toHaveBeenCalledWith({
+ auth: {
+ pass: "password",
+ user: "username",
+ },
+ host: "host",
+ port: "port",
+ secure: "secure",
+ tls: {
+ "rejectUnauthorized": false,
+ }
+ });
+ expect(res).toBe("Sent Successfully.");
+ expect(sender).toHaveBeenCalledWith({
+ bcc: "BCC",
+ cc: "CC",
+ from: "From",
+ subject: "Name: testing | Status: ✅ Up | Hostname: https://www.google.com",
+ text: "PassedInMessage\nTime (UTC): undefined",
+ to: "To",
+ });
+ });
+});
+
+describe("notification to act properly on error from transport", () => {
+ it("should pass a createTransport error on", async () => {
+ let sender = jest.fn()
+ .mockResolvedValue(() => {
+ return;
+ });
+ mockNodeMailer.createTransport.mockImplementationOnce(() => {
+ throw new Error("Test Error");
+ });
+
+ let notif = new SMTP();
+ let notificationConf = { };
+ let msg = "PassedInMessage";
+ let monitorConf = { };
+ let heartbeatConf = { };
+ let res = "";
+ try {
+ res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(true).toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Test Error");
+ }
+
+ expect(mockNodeMailer.createTransport).toHaveBeenCalledTimes(1);
+ expect(res).toBe("");
+ expect(sender).toHaveBeenCalledTimes(0);
+ });
+
+ it("should pass a send mail error on", async () => {
+ let sender = jest.fn()
+ .mockRejectedValue(new Error("Test Error"));
+ mockNodeMailer.createTransport.mockImplementationOnce(() => {
+ return { sendMail: sender };
+
+ });
+
+ let notif = new SMTP();
+ let notificationConf = { };
+ let msg = "PassedInMessage";
+ let monitorConf = { };
+ let heartbeatConf = { };
+ let res = "";
+ try {
+ res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect("threw error").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Test Error");
+ }
+
+ expect(mockNodeMailer.createTransport).toHaveBeenCalledTimes(1);
+ expect(res).toBe("");
+ expect(sender).toHaveBeenCalledTimes(1);
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call sendMail with proper data", async () => {
+ let sender = jest.fn()
+ .mockResolvedValue(() => {
+ return;
+ });
+ mockNodeMailer.createTransport.mockImplementationOnce(() => {
+ return { sendMail: sender };
+ });
+
+ let notificationConf = {
+ type: "smtp",
+ smtpHost: "host",
+ smtpPort: "port",
+ smtpSecure: "secure",
+ smtpUsername: "username",
+ smtpPassword: "password",
+ customSubject: "",
+ smtpFrom: "From",
+ smtpCC: "CC",
+ smtpBCC: "BCC",
+ smtpTo: "To",
+ smtpIgnoreTLSError: true,
+ };
+ let monitorConf = {
+ type: "http",
+ url: "https://www.google.com",
+ name: "testing",
+ };
+ let heartbeatConf = {
+ status: UP,
+ };
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, "simple message", monitorConf, heartbeatConf);
+
+ expect(res).toBe("Sent Successfully.");
+
+ expect(mockNodeMailer.createTransport).toHaveBeenCalledTimes(1);
+ expect(mockNodeMailer.createTransport).toHaveBeenCalledWith({
+ auth: {
+ pass: "password",
+ user: "username",
+ },
+ host: "host",
+ port: "port",
+ secure: "secure",
+ tls: {
+ "rejectUnauthorized": true,
+ }
+ });
+ expect(sender).toHaveBeenCalledTimes(1);
+ expect(sender).toHaveBeenCalledWith({
+ bcc: "BCC",
+ cc: "CC",
+ from: "From",
+ subject: "simple message",
+ text: "simple message\nTime (UTC): undefined",
+ to: "To",
+ });
+ });
+
+});
diff --git a/server/notification-providers/teams.js b/server/notification-providers/teams.js
index 859af56..edaa605 100644
--- a/server/notification-providers/teams.js
+++ b/server/notification-providers/teams.js
@@ -87,12 +87,11 @@ class Teams extends NotificationProvider {
};
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
if (heartbeatJSON == null) {
await this._handleGeneralNotification(notification.webhookUrl, msg);
- return okMsg;
+ return this.sendSuccess;
}
let url;
@@ -114,7 +113,7 @@ class Teams extends NotificationProvider {
});
await this._sendNotification(notification.webhookUrl, payload);
- return okMsg;
+ return this.sendSuccess;
} catch (error) {
this.throwGeneralAxiosError(error);
}
diff --git a/server/notification-providers/teams.spec.js b/server/notification-providers/teams.spec.js
new file mode 100644
index 0000000..2f39ec9
--- /dev/null
+++ b/server/notification-providers/teams.spec.js
@@ -0,0 +1,283 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+const Teams = require("./teams");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Teams();
+ expect(notification.name).toBe("teams");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data when up", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Teams();
+ let notificationConf = {
+ webhookUrl: "teams.com/webhook"
+ };
+ let monitorConf = {
+ type: "port",
+ hostname: "abc.com",
+ port: "1234",
+ url: "https://www.abc.com",
+ name: "name",
+ };
+ let heartbeatConf = {
+ status: UP,
+ msg: "heart beating"
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("teams.com/webhook", {
+ "@context": "https://schema.org/extensions",
+ "@type": "MessageCard",
+ "sections": [
+ {
+ "activityImage": "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png",
+ "activityTitle": "**Uptime Kuma**",
+ },
+ {
+ "activityTitle": "✅ Application [name] is back online",
+ },
+ {
+ "activityTitle": "**Description**",
+ "facts": [
+ {
+ "name": "Monitor",
+ "value": "name"
+ },
+ {
+ "name": "URL",
+ "value": "abc.com:1234",
+ },
+ ],
+ "text": "heart beating",
+ },
+ ],
+ "summary": "✅ Application [name] is back online",
+ "themeColor": "00e804",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper default data when DOWN", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Teams();
+ let notificationConf = {
+ webhookUrl: "teams.com/webhook"
+ };
+ let monitorConf = {
+ type: "port",
+ hostname: "abc.com",
+ port: "1234",
+ url: "https://www.abc.com",
+ name: "name",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "heart beating"
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("teams.com/webhook", {
+ "@context": "https://schema.org/extensions",
+ "@type": "MessageCard",
+ "sections": [
+ {
+ "activityImage": "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png",
+ "activityTitle": "**Uptime Kuma**",
+ },
+ {
+ "activityTitle": "🔴 Application [name] went down",
+ },
+ {
+ "activityTitle": "**Description**",
+ "facts": [
+ {
+ "name": "Monitor",
+ "value": "name"
+ },
+ {
+ "name": "URL",
+ "value": "abc.com:1234",
+ },
+ ],
+ "text": "heart beating",
+ },
+ ],
+ "summary": "🔴 Application [name] went down",
+ "themeColor": "ff0000",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Teams();
+ let notificationConf = {
+ webhookUrl: "teams.com/webhook"
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("teams.com/webhook", {
+ "@context": "https://schema.org/extensions",
+ "@type": "MessageCard",
+ "sections": [
+ {
+ "activityImage": "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png",
+ "activityTitle": "**Uptime Kuma**",
+ },
+ {
+ "activityTitle": "Notification",
+ },
+ {
+ "activityTitle": "**Description**",
+ "facts": [ ],
+ "text": "PassedInMessage😀",
+ },
+ ],
+ "summary": "Notification",
+ "themeColor": "008cff",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Teams();
+ let notificationConf = {
+ webhookUrl: "teams.com/webhook"
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("teams.com/webhook", {
+ "@context": "https://schema.org/extensions",
+ "@type": "MessageCard",
+ "sections": [
+ {
+ "activityImage": "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png",
+ "activityTitle": "**Uptime Kuma**",
+ },
+ {
+ "activityTitle": "Notification",
+ },
+ {
+ "activityTitle": "**Description**",
+ "facts": [ ],
+ "text": "PassedInMessage😀",
+ },
+ ],
+ "summary": "Notification",
+ "themeColor": "008cff",
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "teams",
+ webhookUrl: "teams.com/webhook"
+ };
+ let monitorConf = {
+ type: "port",
+ hostname: "abc.com",
+ port: "1234",
+ url: "https://www.abc.com",
+ name: "name",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "heart beating"
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("teams.com/webhook", {
+ "@context": "https://schema.org/extensions",
+ "@type": "MessageCard",
+ "sections": [
+ {
+ "activityImage": "https://raw.githubusercontent.com/louislam/uptime-kuma/master/public/icon.png",
+ "activityTitle": "**Uptime Kuma**",
+ },
+ {
+ "activityTitle": "🔴 Application [name] went down",
+ },
+ {
+ "activityTitle": "**Description**",
+ "facts": [
+ {
+ "name": "Monitor",
+ "value": "name"
+ },
+ {
+ "name": "URL",
+ "value": "abc.com:1234",
+ },
+ ],
+ "text": "heart beating",
+ },
+ ],
+ "summary": "🔴 Application [name] went down",
+ "themeColor": "ff0000",
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/telegram.js b/server/notification-providers/telegram.js
index 54d33bf..4caef56 100644
--- a/server/notification-providers/telegram.js
+++ b/server/notification-providers/telegram.js
@@ -6,7 +6,6 @@ class Telegram extends NotificationProvider {
name = "telegram";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
await axios.get(`https://api.telegram.org/bot${notification.telegramBotToken}/sendMessage`, {
@@ -14,12 +13,11 @@ class Telegram extends NotificationProvider {
chat_id: notification.telegramChatID,
text: msg,
},
- })
- return okMsg;
-
+ });
+ return this.sendSuccess;
} catch (error) {
- let msg = (error.response.data.description) ? error.response.data.description : "Error without description"
- throw new Error(msg)
+ let msg = (error.response.data.description) ? error.response.data.description : "Error without description";
+ throw new Error(msg);
}
}
}
diff --git a/server/notification-providers/telegram.spec.js b/server/notification-providers/telegram.spec.js
new file mode 100644
index 0000000..ef6e14d
--- /dev/null
+++ b/server/notification-providers/telegram.spec.js
@@ -0,0 +1,155 @@
+jest.mock("axios", () => ({
+ get: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.get.mockReset();
+});
+const Telegram = require("./telegram");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Telegram();
+ expect(notification.name).toBe("telegram");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.get.mockResolvedValueOnce(response);
+
+ let notif = new Telegram();
+ let notificationConf = {
+ type: "telegram",
+ telegramBotToken: "abc",
+ telegramChatID: "123",
+
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.get).toHaveBeenCalledWith("https://api.telegram.org/botabc/sendMessage", {
+ "params": {
+ "chat_id": "123",
+ "text": "PassedInMessage😀",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.get.mockResolvedValueOnce(response);
+
+ let notif = new Telegram();
+ let notificationConf = {
+ type: "telegram",
+ telegramBotToken: "abc",
+ telegramChatID: "123",
+
+ };
+
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.get).toHaveBeenCalledWith("https://api.telegram.org/botabc/sendMessage", {
+ "params": {
+ "chat_id": "123",
+ "text": "PassedInMessage😀",
+ },
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.get.mockImplementation(() => {
+ throw {
+ response: {
+ data: {
+ description: "Error Description"
+ }
+ }
+ };
+ });
+ let notif = new Telegram();
+ let notificationConf = {
+ type: "telegram",
+ telegramBotToken: "abc",
+ telegramChatID: "123",
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error Description");
+ }
+
+ expect(axios.get).toHaveBeenCalledWith("https://api.telegram.org/botabc/sendMessage", {
+ "params": {
+ "chat_id": "123",
+ "text": "PassedInMessage😀",
+ },
+ });
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.get.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "telegram",
+ telegramBotToken: "abc",
+ telegramChatID: "123",
+
+ };
+ let monitorConf = {
+ };
+ let heartbeatConf = {
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.get).toHaveBeenCalledWith("https://api.telegram.org/botabc/sendMessage", {
+
+ "params": {
+ "chat_id": "123",
+ "text": "PassedInMessage😀",
+ },
+
+ });
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
diff --git a/server/notification-providers/webhook.js b/server/notification-providers/webhook.js
index 9cb361f..1f7e368 100644
--- a/server/notification-providers/webhook.js
+++ b/server/notification-providers/webhook.js
@@ -7,7 +7,6 @@ class Webhook extends NotificationProvider {
name = "webhook";
async send(notification, msg, monitorJSON = null, heartbeatJSON = null) {
- let okMsg = "Sent Successfully.";
try {
let data = {
@@ -24,17 +23,16 @@ class Webhook extends NotificationProvider {
config = {
headers: finalData.getHeaders(),
- }
+ };
} else {
finalData = data;
}
- await axios.post(notification.webhookURL, finalData, config)
- return okMsg;
-
+ await axios.post(notification.webhookURL, finalData, config);
+ return this.sendSuccess;
} catch (error) {
- this.throwGeneralAxiosError(error)
+ this.throwGeneralAxiosError(error);
}
}
diff --git a/server/notification-providers/webhook.spec.js b/server/notification-providers/webhook.spec.js
new file mode 100644
index 0000000..232c436
--- /dev/null
+++ b/server/notification-providers/webhook.spec.js
@@ -0,0 +1,207 @@
+jest.mock("axios", () => ({
+ post: jest.fn(),
+}));
+
+const axios = require("axios");
+const { UP, DOWN } = require("../../src/util");
+const NotificationSend = require("../notification");
+
+beforeEach(() => {
+ axios.post.mockReset();
+});
+const Webhook = require("./webhook");
+
+describe("notification default information", () => {
+ it("should have the correct name", () => {
+ let notification = new Webhook();
+ expect(notification.name).toBe("webhook");
+ });
+});
+
+describe("notification to act properly on send", () => {
+ it("should call axios with the proper default data as not form-data", async () => {
+
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Webhook();
+ let notificationConf = {
+ type: "webhook",
+ webhookURL: "abc.com/webhook",
+ webhookContentType: "JSON"
+ };
+ let monitorConf = {
+ type: "port",
+ hostname: "abc.com",
+ port: "1234",
+ url: "https://www.abc.com",
+ name: "name",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "heart beating"
+ };
+ let msg = "PassedInMessage😀";
+ let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ expect(axios.post).toHaveBeenCalledWith("abc.com/webhook", {
+ "heartbeat": {
+ "msg": "heart beating",
+ "status": 0,
+ },
+ "monitor": {
+ "hostname": "abc.com",
+ "name": "name",
+ "port": "1234",
+ "type": "port",
+ "url": "https://www.abc.com",
+ },
+ "msg": "PassedInMessage😀",
+ }, {});
+ expect(res).toBe("Sent Successfully.");
+ });
+
+ //TODO finish headers test.
+ // it("should call axios with the proper default data as form-data", async () => {
+
+ // let response = {
+ // data: {
+ // Message: "OK"
+ // }
+ // };
+ // axios.post.mockResolvedValueOnce(response);
+
+ // let notif = new Webhook();
+ // let notificationConf = {
+ // type: "webhook",
+ // webhookURL: "abc.com/webhook",
+ // webhookContentType: "form-data"
+ // };
+ // let monitorConf = {
+ // type: "port",
+ // hostname: "abc.com",
+ // port: "1234",
+ // url: "https://www.abc.com",
+ // name: "name",
+ // };
+ // let heartbeatConf = {
+ // status: DOWN,
+ // msg: "heart beating"
+ // };
+ // let msg = "PassedInMessage😀";
+ // let res = await notif.send(notificationConf, msg, monitorConf, heartbeatConf);
+
+ // expect(axios.post).toHaveBeenCalledWith("abc.com/webhook", {}, {
+ // "headers": {
+ // "content-type": "multipart/form-data; boundary=--------------------------219451039202311711580332",
+ // },
+ // });
+ // expect(res).toBe("Sent Successfully.");
+ // });
+
+ it("should call axios with the proper data when monitor nil", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+
+ let notif = new Webhook();
+ let notificationConf = {
+ type: "webhook",
+ webhookURL: "abc.com/webhook"
+ };
+ let msg = "PassedInMessage😀";
+
+ let res = await notif.send(notificationConf, msg, null, null);
+
+ expect(axios.post).toHaveBeenCalledWith("abc.com/webhook", {
+ "heartbeat": null,
+ "monitor": null,
+
+ "msg": "PassedInMessage😀",
+ }, {});
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});
+
+describe("notification to act properly on error", () => {
+ it("should respond with an axios error on error", async () => {
+
+ axios.post.mockImplementation(() => {
+ throw new Error("Test Error");
+ });
+ let notif = new Webhook();
+ let notificationConf = {
+ type: "webhook",
+ webhookURL: "abc.com/webhook"
+ };
+ let msg = "PassedInMessage😀";
+
+ try {
+ await notif.send(notificationConf, msg, null, null);
+ expect("Error thrown").toBe(false);
+ } catch (e) {
+ expect(e.message).toBe("Error: Error: Test Error ");
+ }
+
+ expect(axios.post).toHaveBeenCalledWith("abc.com/webhook", {
+ "heartbeat": null,
+ "monitor": null,
+ "msg": "PassedInMessage😀",
+ }, {});
+ });
+
+});
+
+describe("notification to get proper data from Notification.send", () => {
+ it("should call axios with proper data", async () => {
+ let response = {
+ data: {
+ Message: "OK"
+ }
+ };
+ axios.post.mockResolvedValueOnce(response);
+ let notificationConf = {
+ type: "webhook",
+ webhookURL: "abc.com/webhook"
+ };
+ let monitorConf = {
+ type: "port",
+ hostname: "abc.com",
+ port: "1234",
+ url: "https://www.abc.com",
+ name: "name",
+ };
+ let heartbeatConf = {
+ status: DOWN,
+ msg: "heart beating"
+ };
+ let msg = "PassedInMessage😀";
+
+ NotificationSend.Notification.init();
+ let res = await NotificationSend.Notification.send(notificationConf, msg, monitorConf, heartbeatConf);
+ expect(axios.post).toHaveBeenCalledWith("abc.com/webhook", {
+ "heartbeat": {
+ "msg": "heart beating",
+ "status": 0,
+ },
+ "monitor": {
+ "hostname": "abc.com",
+ "name": "name",
+ "port": "1234",
+ "type": "port",
+ "url": "https://www.abc.com",
+ },
+ "msg": "PassedInMessage😀",
+ }, {});
+ expect(res).toBe("Sent Successfully.");
+ });
+
+});