fix(support): expose notification health aggregates

This commit is contained in:
Sucukdeluxe
2026-08-22 08:00:25 +02:00
parent 16679e73b5
commit 1b8f6fe4b6
7 changed files with 219 additions and 47 deletions
+42 -7
View File
@@ -2,9 +2,11 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import AdmZip from "adm-zip";
import { afterEach, describe, expect, it } from "vitest";
import { buildSupportBundle } from "../src/main/support-bundle";
import type { DownloadManager } from "../src/main/download-manager";
import { afterEach, describe, expect, it } from "vitest";
import { buildSupportBundle } from "../src/main/support-bundle";
import { createStoragePaths } from "../src/main/storage";
import type { DownloadManager } from "../src/main/download-manager";
import type { NotificationSupportPayload } from "../src/main/support-data";
const tempDirs: string[] = [];
const legacyManifestFile = ["debug_", "a", "i", "_manifest.json"].join("");
@@ -60,7 +62,7 @@ describe("buildSupportBundle (async, non-blocking)", () => {
expect(hostEntry?.getData().toString("utf8")).toBe("host-info-test");
});
it("does not block the event loop while building (a concurrent timer still fires)", async () => {
it("does not block the event loop while building (a concurrent timer still fires)", async () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rd-bundle-"));
tempDirs.push(root);
@@ -69,6 +71,39 @@ describe("buildSupportBundle (async, non-blocking)", () => {
await buildSupportBundle(fakeManager(), root, { hostDiagnosticsMode: "none" });
clearTimeout(timer);
await new Promise((resolve) => setTimeout(resolve, 0));
expect(timerFired).toBe(true);
});
});
expect(timerFired).toBe(true);
});
it("writes only the safe notification aggregate and excludes its runtime files", async () => {
const root = fs.mkdtempSync(path.join(os.tmpdir(), "rd-bundle-notifications-"));
tempDirs.push(root);
const paths = createStoragePaths(root);
fs.writeFileSync(paths.notificationOutboxFile, "PRIVATE_OUTBOX_RUNTIME_PAYLOAD", "utf8");
fs.writeFileSync(paths.notificationHealthFile, "PRIVATE_HEALTH_RUNTIME_PAYLOAD", "utf8");
const notificationStatus: NotificationSupportPayload & Record<string, unknown> = {
queued: 7,
lastSuccessAt: 1_700_000_000_000,
incidentType: "scheduler",
incidentAgeMs: 45_000,
events: [{ payload: "PRIVATE_EVENT_PAYLOAD" }],
url: "https://private.example.test/webhook",
mention: "@private"
};
const buffer = await buildSupportBundle(fakeManager(), root, { hostDiagnosticsMode: "none", notificationStatus });
const zip = new AdmZip(buffer);
const entry = zip.getEntry("overview/notifications.json");
const payload = JSON.parse(entry?.getData().toString("utf8") || "null");
const serialized = buffer.toString("utf8");
expect(payload).toEqual({
queued: 7,
lastSuccessAt: 1_700_000_000_000,
incidentType: "scheduler",
incidentAgeMs: 45_000
});
expect(zip.getEntries().map((item) => item.entryName)).not.toContain(path.basename(paths.notificationOutboxFile));
expect(zip.getEntries().map((item) => item.entryName)).not.toContain(path.basename(paths.notificationHealthFile));
expect(serialized).not.toMatch(/PRIVATE_|https:\/\/private|@private/);
});
});