68 lines
2.8 KiB
TypeScript
68 lines
2.8 KiB
TypeScript
import { describe, expect, it, beforeAll, afterAll, beforeEach } from "@jest/globals";
|
|
import mongoose from "mongoose";
|
|
import { MongoMemoryServer } from "mongodb-memory-server";
|
|
import { MonitorModel } from "../../src/domain/monitors/monitor.model.ts";
|
|
import { backfillMonitorLastEvaluatedAt } from "../../src/db/migration/0008_backfillMonitorLastEvaluatedAt.ts";
|
|
import { createMockLogger } from "../helpers/createMockLogger.ts";
|
|
|
|
const logger = createMockLogger();
|
|
|
|
// ── Real-Mongo harness ─────────────────────────────────────────────────────────
|
|
// Legacy monitors are inserted through the raw driver, NOT MonitorModel.create — the
|
|
// schema default (lastEvaluatedAt: 0) would otherwise stamp the field and the migration's
|
|
// { $exists: false } filter would skip it, defeating the test.
|
|
|
|
let mongod: MongoMemoryServer;
|
|
|
|
beforeAll(async () => {
|
|
mongod = await MongoMemoryServer.create();
|
|
await mongoose.connect(mongod.getUri());
|
|
}, 120_000);
|
|
|
|
afterAll(async () => {
|
|
await mongoose.disconnect();
|
|
await mongod.stop();
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await MonitorModel.collection.deleteMany({});
|
|
});
|
|
|
|
describe("0008_backfillMonitorLastEvaluatedAt", () => {
|
|
it("stamps the upgrade moment (not 0) on monitors missing lastEvaluatedAt", async () => {
|
|
await MonitorModel.collection.insertOne({ name: "legacy" }); // pre-upgrade doc, no lastEvaluatedAt
|
|
|
|
const before = Date.now();
|
|
await backfillMonitorLastEvaluatedAt(logger);
|
|
|
|
const doc = await MonitorModel.collection.findOne({ name: "legacy" });
|
|
// Must be a recent timestamp — backfilling 0 would replay the whole check history on the first evaluate.
|
|
expect(doc?.lastEvaluatedAt).not.toBe(0);
|
|
expect(doc?.lastEvaluatedAt).toBeGreaterThanOrEqual(before);
|
|
expect(doc?.lastEvaluatedAt).toBeLessThanOrEqual(Date.now());
|
|
});
|
|
|
|
it("leaves monitors that already have lastEvaluatedAt untouched (idempotent)", async () => {
|
|
await MonitorModel.collection.insertOne({ name: "current", lastEvaluatedAt: 12345 });
|
|
|
|
await backfillMonitorLastEvaluatedAt(logger);
|
|
|
|
const doc = await MonitorModel.collection.findOne({ name: "current" });
|
|
expect(doc?.lastEvaluatedAt).toBe(12345);
|
|
});
|
|
|
|
it("drops the legacy jobs collection left behind by the old scheduler", async () => {
|
|
const db = mongoose.connection.db!;
|
|
await db.collection("jobs").insertOne({ id: "legacy-job", template: "monitor-job" }); // old-scheduler row
|
|
|
|
await backfillMonitorLastEvaluatedAt(logger);
|
|
|
|
const exists = await db.listCollections({ name: "jobs" }).toArray();
|
|
expect(exists).toHaveLength(0);
|
|
});
|
|
|
|
it("does not throw when there is no jobs collection to drop", async () => {
|
|
await expect(backfillMonitorLastEvaluatedAt(logger)).resolves.toBeUndefined();
|
|
});
|
|
});
|