import { describe, expect, it, jest } from "@jest/globals"; import { CheckProducer } from "../../../src/worker/worker.check-producer.ts"; import type { Monitor } from "../../../src/domain/monitors/monitor.type.ts"; import { createMockLogger } from "../../helpers/createMockLogger.ts"; const makeMonitor = (overrides?: Partial): Monitor => ({ id: "m1", teamId: "team", type: "http", interval: 60000, status: "up", ...overrides, }) as Monitor; // A maintenance window straddling "now" — active per isWindowActive. const activeWindow = () => { const now = Date.now(); return { active: true, start: new Date(now - 1000).toISOString(), end: new Date(now + 1000).toISOString(), repeat: 0 }; }; const createProducer = (overrides?: Record) => { const defaults = { logger: createMockLogger(), monitorsRepository: { updateById: jest.fn().mockResolvedValue({}), findDockerTlsKeyById: jest.fn().mockResolvedValue(null) }, maintenanceWindowsRepository: { findByMonitorId: jest.fn().mockResolvedValue([]) }, checkService: { toCheck: jest.fn().mockReturnValue({ id: "check-1" }) }, networkService: { requestStatus: jest.fn().mockResolvedValue({ monitorId: "m1", status: true, code: 200, message: "OK" }) }, proxyResolver: { resolve: jest.fn().mockResolvedValue(undefined) }, buffer: { addToBuffer: jest.fn() }, dockerLogsService: { buildDockerLogs: jest.fn().mockResolvedValue([]) }, ...overrides, }; const producer = new CheckProducer( defaults.monitorsRepository as any, defaults.maintenanceWindowsRepository as any, defaults.checkService as any, defaults.networkService as any, defaults.proxyResolver as any, defaults.buffer as any, defaults.dockerLogsService as any, defaults.logger as any ); return { producer, defaults }; }; describe("CheckProducer", () => { it("throws when monitor id is missing", async () => { const { producer } = createProducer(); await expect(producer.produce({} as Monitor)).rejects.toThrow("No monitor id"); }); // ── maintenance gate ────────────────────────────────────────────────────── it("skips the check and flips status to 'maintenance' when in a maintenance window", async () => { const { producer, defaults } = createProducer({ maintenanceWindowsRepository: { findByMonitorId: jest.fn().mockResolvedValue([activeWindow()]) }, }); const result = await producer.produce(makeMonitor({ status: "up" })); expect(result).toBeNull(); expect(defaults.monitorsRepository.updateById).toHaveBeenCalledWith("m1", "team", { status: "maintenance", statusWindow: [] }); expect(defaults.networkService.requestStatus).not.toHaveBeenCalled(); expect(defaults.buffer.addToBuffer).not.toHaveBeenCalled(); }); it("does not re-write status when already in maintenance", async () => { const { producer, defaults } = createProducer({ maintenanceWindowsRepository: { findByMonitorId: jest.fn().mockResolvedValue([activeWindow()]) }, }); const result = await producer.produce(makeMonitor({ status: "maintenance" })); expect(result).toBeNull(); expect(defaults.monitorsRepository.updateById).not.toHaveBeenCalled(); }); it("proceeds with the check when the maintenance window is inactive", async () => { const { producer, defaults } = createProducer({ maintenanceWindowsRepository: { findByMonitorId: jest.fn().mockResolvedValue([{ ...activeWindow(), active: false }]) }, }); await producer.produce(makeMonitor()); expect(defaults.networkService.requestStatus).toHaveBeenCalled(); }); // ── proxy resolution ────────────────────────────────────────────────────── it("passes the resolved proxy url into requestStatus", async () => { const { producer, defaults } = createProducer({ proxyResolver: { resolve: jest.fn().mockResolvedValue("http://proxy.example.com:8080") }, }); const monitor = makeMonitor(); await producer.produce(monitor); expect(defaults.networkService.requestStatus).toHaveBeenCalledWith(monitor, { proxyUrl: "http://proxy.example.com:8080" }); }); it("still produces a check when the resolver returns undefined", async () => { const { producer, defaults } = createProducer(); const monitor = makeMonitor(); const result = await producer.produce(monitor); expect(defaults.networkService.requestStatus).toHaveBeenCalledWith(monitor, { proxyUrl: undefined }); expect(result).toEqual({ status: expect.objectContaining({ monitorId: "m1" }), check: { id: "check-1" } }); }); // ── acquire / record ────────────────────────────────────────────────────── // ── docker tls key resolution ───────────────────────────────────────────── it("fetches the stored key for a docker monitor with a key set and passes it in the context", async () => { const { producer, defaults } = createProducer({ monitorsRepository: { updateById: jest.fn(), findDockerTlsKeyById: jest.fn().mockResolvedValue("v1.abc123.iv.tag.data") }, }); const monitor = makeMonitor({ type: "docker", url: "tcp://host", dockerTlsKeySet: true }); await producer.produce(monitor); expect(defaults.monitorsRepository.findDockerTlsKeyById).toHaveBeenCalledWith("m1"); expect(defaults.networkService.requestStatus).toHaveBeenCalledWith(monitor, { proxyUrl: undefined, dockerTlsKey: "v1.abc123.iv.tag.data" }); }); it("does not fetch a key for a docker monitor without one set", async () => { const { producer, defaults } = createProducer(); const monitor = makeMonitor({ type: "docker", url: "unix:///var/run/docker.sock", dockerTlsKeySet: false }); await producer.produce(monitor); expect(defaults.monitorsRepository.findDockerTlsKeyById).not.toHaveBeenCalled(); expect(defaults.networkService.requestStatus).toHaveBeenCalledWith(monitor, { proxyUrl: undefined, dockerTlsKey: undefined }); }); it("does not fetch a key for non-docker monitors even if the flag is set", async () => { const { producer, defaults } = createProducer(); await producer.produce(makeMonitor({ type: "http", dockerTlsKeySet: true })); expect(defaults.monitorsRepository.findDockerTlsKeyById).not.toHaveBeenCalled(); }); it("passes undefined when the flag is set but the repository has no key", async () => { const { producer, defaults } = createProducer(); const monitor = makeMonitor({ type: "docker", url: "tcp://host", dockerTlsKeySet: true }); await producer.produce(monitor); expect(defaults.monitorsRepository.findDockerTlsKeyById).toHaveBeenCalledWith("m1"); expect(defaults.networkService.requestStatus).toHaveBeenCalledWith(monitor, { proxyUrl: undefined, dockerTlsKey: undefined }); }); it("throws when the network response is null", async () => { const { producer } = createProducer({ networkService: { requestStatus: jest.fn().mockResolvedValue(null) }, }); await expect(producer.produce(makeMonitor())).rejects.toThrow("No network response"); }); it("returns null, warns, and does not buffer when toCheck yields nothing", async () => { const { producer, defaults } = createProducer({ checkService: { toCheck: jest.fn().mockReturnValue(null) }, }); const result = await producer.produce(makeMonitor()); expect(result).toBeNull(); expect(defaults.logger.warn).toHaveBeenCalledWith(expect.objectContaining({ message: expect.stringContaining("No check could be built") })); expect(defaults.buffer.addToBuffer).not.toHaveBeenCalled(); }); it("buffers the built check and returns the status and check on success", async () => { const status = { monitorId: "m1", status: false, code: 500, message: "Error" }; const check = { id: "check-1" }; const { producer, defaults } = createProducer({ networkService: { requestStatus: jest.fn().mockResolvedValue(status) }, checkService: { toCheck: jest.fn().mockReturnValue(check) }, }); const result = await producer.produce(makeMonitor()); expect(defaults.buffer.addToBuffer).toHaveBeenCalledWith(check); expect(result).toEqual({ status, check }); }); it("builds and buffers docker logs for a docker status", async () => { const status = { type: "docker", monitorId: "m1", teamId: "team", status: true, code: 200, message: "OK", payload: {} }; const dockerLogs = [{ id: "docker-log-1" }, { id: "docker-log-2" }]; const { producer, defaults } = createProducer({ networkService: { requestStatus: jest.fn().mockResolvedValue(status) }, buffer: { addToBuffer: jest.fn(), addDockerLogToBuffer: jest.fn() }, dockerLogsService: { buildDockerLogs: jest.fn().mockResolvedValue(dockerLogs) }, }); await producer.produce(makeMonitor({ type: "docker" })); expect(defaults.dockerLogsService.buildDockerLogs).toHaveBeenCalledWith(status); expect(defaults.buffer.addDockerLogToBuffer).toHaveBeenNthCalledWith(1, dockerLogs[0]); expect(defaults.buffer.addDockerLogToBuffer).toHaveBeenNthCalledWith(2, dockerLogs[1]); }); it("does not build docker logs for a non-docker status", async () => { const { producer, defaults } = createProducer(); await producer.produce(makeMonitor()); expect(defaults.dockerLogsService.buildDockerLogs).not.toHaveBeenCalled(); }); });