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.
7.1 kB ยท 227 lines
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228import { eq } from "@openstatus/db";import { monitor, monitorRun, notification, page, pageComponent, workspace,} from "@openstatus/db/src/schema";import { expect } from "@std/expect";import { beforeAll, describe, test } from "@std/testing/bdd";
import { createWorkspaceFixture, withTestTransaction,} from "../../test/helpers";import type { DrizzleTx } from "../context";import { LimitExceededError } from "../errors";import { LIMIT_KEYS, type LimitKey, assertWithinLimit } from "../limits";
const TEST_PREFIX = "svc-limits-test";
let workspaceId: number;let seq = 0;const unique = () => `${TEST_PREFIX}-${workspaceId}-${seq++}`;
beforeAll(async () => { workspaceId = (await createWorkspaceFixture("team")).workspace.id;});
/** Pin one limit for the workspace so a case controls its own ceiling. */async function setLimit(tx: DrizzleTx, limit: LimitKey, max: number) { await tx .update(workspace) .set({ limits: JSON.stringify({ [limit]: max }) }) .where(eq(workspace.id, workspaceId));}
function within(limit: LimitKey, delta?: number) { return (tx: DrizzleTx) => assertWithinLimit({ tx, workspaceId, limit, delta });}
async function addMonitor(tx: DrizzleTx, overrides: { deletedAt?: Date } = {}) { return tx .insert(monitor) .values({ workspaceId, url: "https://example.openstatus.dev", name: unique(), ...overrides, }) .returning() .get();}
async function addPage(tx: DrizzleTx) { return tx .insert(page) .values({ workspaceId, title: unique(), description: "", // `slug` is globally unique, not per-workspace. slug: unique(), customDomain: "", }) .returning() .get();}
async function addRun(tx: DrizzleTx, monitorId: number, createdAt: Date) { await tx .insert(monitorRun) .values({ workspaceId, monitorId, runnedAt: new Date(), createdAt });}
describe("countCurrent coverage", () => { // The real guard is the `never` in countCurrent's default branch, which // makes an uncounted LimitKey a type error. This is its runtime twin: it // fails if a key is listed but its case never runs a query. for (const limit of LIMIT_KEYS) { test(`counts "${limit}" instead of throwing not-implemented`, async () => { await withTestTransaction(async (tx) => { await setLimit(tx, limit, 1_000_000); await expect(within(limit)(tx)).resolves.toBeUndefined(); }); }); }
test("every LimitKey resolves to a numeric plan limit", async () => { const { limits } = (await createWorkspaceFixture("free")).workspace; for (const limit of LIMIT_KEYS) { expect(typeof limits[limit]).toBe("number"); } });});
describe("assertWithinLimit boundaries", () => { test("monitors: counts live rows, ignores soft-deleted ones", async () => { await withTestTransaction(async (tx) => { await setLimit(tx, "monitors", 2); await addMonitor(tx); await addMonitor(tx, { deletedAt: new Date() });
// 1 live + 1 tombstoned: the tombstone must not consume quota. await expect(within("monitors")(tx)).resolves.toBeUndefined();
await addMonitor(tx); await expect(within("monitors")(tx)).rejects.toBeInstanceOf( LimitExceededError, ); }); });
test("status-pages: trips once the workspace is full", async () => { await withTestTransaction(async (tx) => { await setLimit(tx, "status-pages", 1); await expect(within("status-pages")(tx)).resolves.toBeUndefined();
await addPage(tx); await expect(within("status-pages")(tx)).rejects.toBeInstanceOf( LimitExceededError, ); }); });
test("page-components: counts across every page in the workspace", async () => { await withTestTransaction(async (tx) => { await setLimit(tx, "page-components", 2); const pageA = await addPage(tx); const pageB = await addPage(tx); const values = (pageId: number) => ({ workspaceId, pageId, type: "static" as const, name: unique(), order: 0, });
await tx.insert(pageComponent).values(values(pageA.id)); await expect(within("page-components")(tx)).resolves.toBeUndefined();
// The second component sits on a different page โ a per-page count // would still see room here. await tx.insert(pageComponent).values(values(pageB.id)); await expect(within("page-components")(tx)).rejects.toBeInstanceOf( LimitExceededError, ); }); });
test("notification-channels: trips once the workspace is full", async () => { await withTestTransaction(async (tx) => { await setLimit(tx, "notification-channels", 1); await expect( within("notification-channels")(tx), ).resolves.toBeUndefined();
await tx.insert(notification).values({ workspaceId, name: unique(), provider: "email", data: JSON.stringify({ email: "limits@openstatus.dev" }), }); await expect(within("notification-channels")(tx)).rejects.toBeInstanceOf( LimitExceededError, ); }); });
test("synthetic-checks: meters the rolling month, not all history", async () => { await withTestTransaction(async (tx) => { await setLimit(tx, "synthetic-checks", 1); const mon = await addMonitor(tx); const stale = new Date(); stale.setMonth(stale.getMonth() - 2);
// Older than the window: spent quota, but not this month's. await addRun(tx, mon.id, stale); await expect(within("synthetic-checks")(tx)).resolves.toBeUndefined();
await addRun(tx, mon.id, new Date()); await expect(within("synthetic-checks")(tx)).rejects.toBeInstanceOf( LimitExceededError, ); }); });
test("delta reserves more than one slot at a time", async () => { await withTestTransaction(async (tx) => { await setLimit(tx, "monitors", 3); await addMonitor(tx);
await expect(within("monitors", 2)(tx)).resolves.toBeUndefined(); await expect(within("monitors", 3)(tx)).rejects.toBeInstanceOf( LimitExceededError, ); }); });
test("the error carries both the ceiling and the current usage", async () => { await withTestTransaction(async (tx) => { await setLimit(tx, "monitors", 1); await addMonitor(tx);
const err = await within("monitors")(tx).catch((e) => e); expect(err).toBeInstanceOf(LimitExceededError); expect(err.max).toBe(1); expect(err.current).toBe(1); }); });
test("reads limits from the db, not a stale caller snapshot", async () => { await withTestTransaction(async (tx) => { await setLimit(tx, "monitors", 1); await addMonitor(tx); await expect(within("monitors")(tx)).rejects.toBeInstanceOf( LimitExceededError, );
// An add-on purchased mid-request lands as a workspace-row override. await setLimit(tx, "monitors", 5); await expect(within("monitors")(tx)).resolves.toBeUndefined(); }); });});