Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/openstatusHQ/openstatus. ๐ซ Status page with uptime monitoring & API monitoring as code ๐ซ openstatus.dev
bun drizzle-orm monitoring monitoring-as-code nextjs observability on-call open-source shadcn-ui status-page statuspage synthetic-monitoring tinybird turso uptime uptime-checker uptime-monitor
Something went wrong. Try again.
5.7 kB ยท 201 lines
TypeScript
at incident-api
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202import "./test-preload.ts";import { selectNotificationSchema } from "@openstatus/db/src/schema";import { EmailClient } from "@openstatus/emails/src/client";import { afterEach, assertSpyCalls, beforeEach, describe, expect, type Stub, stub, test,} from "@openstatus/test-utils";
import { sendAlert, sendDegraded, sendRecovery } from "./index";
// biome-ignore lint/suspicious/noExplicitAny: stub over the EmailClient methodlet sendMonitorAlertMock: Stub<any>;
describe("Email Notifications", () => { beforeEach(() => { sendMonitorAlertMock = stub(EmailClient.prototype, "sendMonitorAlert", () => Promise.resolve(), ); });
afterEach(() => { sendMonitorAlertMock.restore(); });
const createMockMonitor = () => ({ id: "monitor-1", name: "API Health Check", url: "https://api.example.com/health", jobType: "http" as const, periodicity: "5m" as const, status: "active" as const, createdAt: new Date(), updatedAt: new Date(), region: "iad", });
const createMockNotification = () => ({ id: 1, name: "Email Notification", provider: "email", workspaceId: 1, createdAt: new Date(), updatedAt: new Date(), data: '{"email":"ping@openstatus.dev"}', });
test("Send Alert", async () => { const monitor = createMockMonitor(); const notification = selectNotificationSchema.parse( createMockNotification(), );
await sendAlert({ // @ts-expect-error monitor, notification, statusCode: 500, message: "Something went wrong", latency: 1500, regions: ["iad"], cronTimestamp: Date.now(), });
assertSpyCalls(sendMonitorAlertMock, 1); const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.name).toBe("API Health Check"); expect(callArgs.type).toBe("alert"); expect(callArgs.to).toBe("ping@openstatus.dev"); expect(callArgs.url).toBe("https://api.example.com/health"); expect(callArgs.status).toBe("500"); expect(callArgs.latency).toBe("1500 ms"); expect(callArgs.monitorId).toBe("monitor-1"); expect(callArgs.region).toBe("Ashburn, Virginia, USA"); expect(callArgs.message).toBe("Something went wrong"); expect(callArgs.timestamp).toBeDefined(); });
test("Send Alert without optional fields", async () => { const monitor = createMockMonitor(); const notification = selectNotificationSchema.parse( createMockNotification(), );
await sendAlert({ // @ts-expect-error monitor, notification, cronTimestamp: Date.now(), });
assertSpyCalls(sendMonitorAlertMock, 1); const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.status).toBeUndefined(); expect(callArgs.latency).toBe("N/A"); expect(callArgs.region).toBe("N/A"); });
test("Send Recovery", async () => { const monitor = createMockMonitor(); const notification = selectNotificationSchema.parse( createMockNotification(), );
await sendRecovery({ // @ts-expect-error monitor, notification, statusCode: 200, latency: 100, regions: ["ams"], cronTimestamp: Date.now(), });
assertSpyCalls(sendMonitorAlertMock, 1); const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.type).toBe("recovery"); expect(callArgs.name).toBe("API Health Check"); expect(callArgs.to).toBe("ping@openstatus.dev"); expect(callArgs.status).toBe("200"); expect(callArgs.latency).toBe("100 ms"); expect(callArgs.region).toBe("Amsterdam, Netherlands"); });
test("Send Degraded", async () => { const monitor = createMockMonitor(); const notification = selectNotificationSchema.parse( createMockNotification(), );
await sendDegraded({ // @ts-expect-error monitor, notification, statusCode: 503, latency: 2000, regions: ["lax"], cronTimestamp: Date.now(), });
assertSpyCalls(sendMonitorAlertMock, 1); const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.type).toBe("degraded"); expect(callArgs.name).toBe("API Health Check"); expect(callArgs.status).toBe("503"); expect(callArgs.latency).toBe("2000 ms"); expect(callArgs.region).toBe("Los Angeles, California, USA"); });
test("Send Degraded passes the threshold and incident start", async () => { const monitor = { ...createMockMonitor(), degradedAfter: 250 }; const notification = selectNotificationSchema.parse( createMockNotification(), ); const startedAt = new Date("2026-10-13T17:29:00Z");
await sendDegraded({ // @ts-expect-error monitor, notification, latency: 300, regions: ["ams"], cronTimestamp: Date.now(), // @ts-expect-error incident: { startedAt }, });
assertSpyCalls(sendMonitorAlertMock, 1); const callArgs = sendMonitorAlertMock.calls[0].args[0]; expect(callArgs.degradedAfter).toBe(250); expect(callArgs.firstSeen).toBe(startedAt.toISOString()); });
test("Handles invalid notification data gracefully", async () => { const monitor = createMockMonitor(); const invalidNotification = selectNotificationSchema.parse({ id: 1, name: "Email Notification", provider: "email", workspaceId: 1, createdAt: new Date(), updatedAt: new Date(), data: '{"invalid":"data"}', });
await sendAlert({ // @ts-expect-error monitor, notification: invalidNotification, cronTimestamp: Date.now(), });
// Should not call sendMonitorAlert when data is invalid assertSpyCalls(sendMonitorAlertMock, 0); });});