diff --git a/test/backend-test/test-dns-monitor.js b/test/backend-test/test-dns-monitor.js new file mode 100644 index 000000000..7f0307ea7 --- /dev/null +++ b/test/backend-test/test-dns-monitor.js @@ -0,0 +1,105 @@ +const test = require("node:test"); +const assert = require("node:assert"); +const { DnsMonitorType } = require("../../server/monitor-types/dns"); +const { UP, DOWN } = require("../../src/util"); +const dayjs = require("dayjs"); + +test("DNS Monitor - Basic A Record Test", async (t) => { + const monitor = { + hostname: "example.com", + dns_resolve_server: "8.8.8.8", + port: 53, + dns_resolve_type: "A" + }; + + const heartbeat = { + ping: 0 + }; + + const dnsMonitor = new DnsMonitorType(); + await dnsMonitor.check(monitor, heartbeat); + + assert.ok(heartbeat.ping > 0, "Ping should be recorded"); + assert.ok(Array.isArray(heartbeat.dnsRecords), "DNS records should be an array"); +}); + +test("DNS Monitor - Invalid Domain Test", async (t) => { + const monitor = { + hostname: "invalid-domain-that-does-not-exist.com", + dns_resolve_server: "8.8.8.8", + port: 53, + dns_resolve_type: "A" + }; + + const heartbeat = { + ping: 0 + }; + + const dnsMonitor = new DnsMonitorType(); + try { + await dnsMonitor.check(monitor, heartbeat); + assert.fail("Should throw error for invalid domain"); + } catch (error) { + assert.ok(error, "Should throw error for invalid domain"); + } +}); + +test("DNS Monitor - Custom DNS Server Test", async (t) => { + const monitor = { + hostname: "example.com", + dns_resolve_server: "1.1.1.1", // Cloudflare DNS + port: 53, + dns_resolve_type: "A" + }; + + const heartbeat = { + ping: 0 + }; + + const dnsMonitor = new DnsMonitorType(); + await dnsMonitor.check(monitor, heartbeat); + + assert.ok(heartbeat.ping > 0, "Ping should be recorded"); +}); + +test("DNS Monitor - TXT Record Test", async (t) => { + const monitor = { + hostname: "example.com", + dns_resolve_server: "8.8.8.8", + port: 53, + dns_resolve_type: "TXT" + }; + + const heartbeat = { + ping: 0 + }; + + const dnsMonitor = new DnsMonitorType(); + await dnsMonitor.check(monitor, heartbeat); + + assert.ok(heartbeat.ping > 0, "Ping should be recorded"); + assert.ok(Array.isArray(heartbeat.dnsRecords), "DNS records should be an array"); +}); + +test("DNS Monitor - Condition Evaluation Test", async (t) => { + const monitor = { + hostname: "example.com", + dns_resolve_server: "8.8.8.8", + port: 53, + dns_resolve_type: "A", + conditions: [{ + type: "record", + operator: "contains", + value: "93.184.216.34" // example.com's IP (this might change) + }] + }; + + const heartbeat = { + ping: 0 + }; + + const dnsMonitor = new DnsMonitorType(); + await dnsMonitor.check(monitor, heartbeat); + + assert.ok(heartbeat.ping > 0, "Ping should be recorded"); +}); diff --git a/test/backend-test/test-notification.js b/test/backend-test/test-notification.js new file mode 100644 index 000000000..aa0ca22d5 --- /dev/null +++ b/test/backend-test/test-notification.js @@ -0,0 +1,114 @@ +const test = require("node:test"); +const assert = require("node:assert"); +const { Notification } = require("../../server/notification"); +const { UP, DOWN } = require("../../src/util"); + +test("Notification - Basic Creation Test", async (t) => { + const notification = new Notification(); + assert.ok(notification, "Should create notification instance"); + assert.ok(typeof notification.send === "function", "Should have send method"); +}); + +test("Notification - Format Message Test", async (t) => { + const notification = new Notification(); + + const monitor = { + name: "Test Monitor", + hostname: "example.com" + }; + + const msg = { + type: "down", + monitor, + msg: "Connection failed" + }; + + const formatted = notification.format(msg); + assert.ok(formatted.includes("Test Monitor"), "Should include monitor name"); + assert.ok(formatted.includes("example.com"), "Should include hostname"); + assert.ok(formatted.includes("Connection failed"), "Should include error message"); +}); + +test("Notification - Queue Management Test", async (t) => { + const notification = new Notification(); + + // Add items to queue + notification.add({ + type: "down", + monitor: { name: "Test1" }, + msg: "Error 1" + }); + + notification.add({ + type: "up", + monitor: { name: "Test2" }, + msg: "Recovered" + }); + + assert.strictEqual(notification.queue.length, 2, "Queue should have 2 items"); +}); + +test("Notification - Priority Test", async (t) => { + const notification = new Notification(); + + // Add items with different priorities + notification.add({ + type: "down", + monitor: { name: "Test1" }, + msg: "Critical Error", + priority: "high" + }); + + notification.add({ + type: "down", + monitor: { name: "Test2" }, + msg: "Warning", + priority: "low" + }); + + const nextItem = notification.queue[0]; + assert.strictEqual(nextItem.priority, "high", "High priority item should be first"); +}); + +test("Notification - Retry Logic Test", async (t) => { + const notification = new Notification(); + + const testMsg = { + type: "down", + monitor: { name: "Test1" }, + msg: "Error", + retries: 0, + maxRetries: 3 + }; + + notification.add(testMsg); + + // Simulate failed send + try { + await notification.send(testMsg); + } catch (error) { + assert.ok(testMsg.retries === 1, "Should increment retry count"); + assert.ok(notification.queue.length === 1, "Should keep in queue for retry"); + } +}); + +test("Notification - Rate Limiting Test", async (t) => { + const notification = new Notification(); + const monitor = { name: "Test Monitor" }; + + // Add multiple notifications for same monitor + for (let i = 0; i < 5; i++) { + notification.add({ + type: "down", + monitor, + msg: `Error ${i}` + }); + } + + // Check if rate limiting is applied + const processedCount = notification.queue.filter( + item => item.monitor.name === "Test Monitor" + ).length; + + assert.ok(processedCount < 5, "Should apply rate limiting"); +});