fix: preserve notifier routing fallbacks (#1958)
This commit is contained in:
parent
71e8151f6e
commit
9ab18c6846
|
|
@ -159,6 +159,41 @@ describe("startup notifier defaults", () => {
|
|||
expect(parsed.notificationRouting?.urgent).toEqual(["desktop", "dashboard"]);
|
||||
});
|
||||
|
||||
it("preserves defaults.notifiers fallback semantics when writing startup routes", () => {
|
||||
writeFileSync(
|
||||
configPath,
|
||||
[
|
||||
"port: 3000",
|
||||
"defaults:",
|
||||
" notifiers:",
|
||||
" - slack",
|
||||
"notifiers:",
|
||||
" slack:",
|
||||
" plugin: slack",
|
||||
" webhookUrl: https://hooks.slack.com/services/T/B/C",
|
||||
"projects: {}",
|
||||
"",
|
||||
].join("\n"),
|
||||
);
|
||||
|
||||
expect(
|
||||
ensureStartupNotifierDefaults({
|
||||
configPath,
|
||||
dashboardUrl: "http://localhost:3000",
|
||||
desktopMode: "enable",
|
||||
}),
|
||||
).toBe(true);
|
||||
|
||||
const parsed = readConfig();
|
||||
expect(parsed.defaults?.notifiers).toEqual(["slack"]);
|
||||
expect(parsed.notificationRouting).toEqual({
|
||||
urgent: ["slack", "desktop", "dashboard"],
|
||||
action: ["slack", "dashboard"],
|
||||
warning: ["slack", "dashboard"],
|
||||
info: ["slack", "dashboard"],
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves configured manual opt-in notifiers while removing only implicit manual defaults", () => {
|
||||
writeFileSync(
|
||||
configPath,
|
||||
|
|
|
|||
|
|
@ -44,6 +44,10 @@ function arraysEqual(left: string[], right: string[]): boolean {
|
|||
return left.length === right.length && left.every((value, index) => value === right[index]);
|
||||
}
|
||||
|
||||
function hasOwn(record: Record<string, unknown>, key: string): boolean {
|
||||
return Object.prototype.hasOwnProperty.call(record, key);
|
||||
}
|
||||
|
||||
function hasNotifierConfig(notifiers: Record<string, unknown>, notifierName: string): boolean {
|
||||
return isRecord(notifiers[notifierName]);
|
||||
}
|
||||
|
|
@ -227,7 +231,12 @@ export function ensureStartupNotifierDefaults(options: StartupNotifierDefaultsOp
|
|||
const shouldRemoveDefaultDesktopRouting = desktopMode === "disable-default" && !desktopConfigured;
|
||||
|
||||
for (const priority of NOTIFICATION_PRIORITIES) {
|
||||
const existingRoute = sanitizeNotifierReferences(notifiers, routing[priority]);
|
||||
const hasExplicitRoute = hasOwn(routing, priority);
|
||||
const existingRoute = sanitizeNotifierReferences(
|
||||
notifiers,
|
||||
hasExplicitRoute ? routing[priority] : defaults["notifiers"],
|
||||
);
|
||||
const previousRoute = hasExplicitRoute ? asStringArray(routing[priority]) : existingRoute;
|
||||
let nextRoute = existingRoute;
|
||||
|
||||
if (shouldRemoveDefaultDesktopRouting) {
|
||||
|
|
@ -245,7 +254,7 @@ export function ensureStartupNotifierDefaults(options: StartupNotifierDefaultsOp
|
|||
}
|
||||
|
||||
nextRoute = unique(nextRoute);
|
||||
if (!arraysEqual(asStringArray(routing[priority]), nextRoute)) {
|
||||
if (!arraysEqual(previousRoute, nextRoute)) {
|
||||
routing[priority] = nextRoute;
|
||||
changed = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -483,6 +483,18 @@ describe("notifier-desktop", () => {
|
|||
expect(mockExecFile.mock.calls[0][0]).toBe("notify-send");
|
||||
});
|
||||
|
||||
it("keeps action labels on non-macOS even when backend is ao-app", async () => {
|
||||
mockPlatform.mockReturnValue("linux");
|
||||
setProcessPlatform("linux");
|
||||
const notifier = create({ backend: "ao-app", dashboardUrl: "http://localhost:3000" });
|
||||
const actions: NotifyAction[] = [{ label: "Open PR", url: "https://example.com/pr/1" }];
|
||||
await notifier.notifyWithActions!(makeEvent(), actions);
|
||||
|
||||
expect(mockExecFile.mock.calls[0][0]).toBe("notify-send");
|
||||
const args = mockExecFile.mock.calls[0][1] as string[];
|
||||
expect(args.join("\n")).toContain("Open PR");
|
||||
});
|
||||
|
||||
it("uses terminal-notifier for notifyWithActions too", async () => {
|
||||
const notifier = create({ dashboardUrl: "http://localhost:3000" });
|
||||
const actions: NotifyAction[] = [{ label: "View", url: "https://example.com" }];
|
||||
|
|
|
|||
|
|
@ -388,6 +388,10 @@ function detectTerminalNotifier(): boolean {
|
|||
}
|
||||
}
|
||||
|
||||
function usesAoNotifierNativeActions(backend: DesktopBackend, appPath: string): boolean {
|
||||
return isMac() && (backend === "ao-app" || (backend === "auto" && detectAoNotifierApp(appPath)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a desktop notification using terminal-notifier / osascript (macOS) or
|
||||
* notify-send (Linux). Falls back gracefully if neither is available.
|
||||
|
|
@ -568,10 +572,9 @@ export function create(config?: Record<string, unknown>): Notifier {
|
|||
async notifyWithActions(event: OrchestratorEvent, actions: NotifyAction[]): Promise<void> {
|
||||
const nativeActions = nativeActionPayloads(actions, dashboardUrl);
|
||||
const content = formatContent(event, actions, {
|
||||
hiddenActionIndexes:
|
||||
backend === "ao-app" || (backend === "auto" && detectAoNotifierApp(appPath))
|
||||
? nativeActionIndexes(actions, dashboardUrl)
|
||||
: undefined,
|
||||
hiddenActionIndexes: usesAoNotifierNativeActions(backend, appPath)
|
||||
? nativeActionIndexes(actions, dashboardUrl)
|
||||
: undefined,
|
||||
});
|
||||
const fallbackContent = formatContent(event, actions);
|
||||
const sound = shouldPlaySound(event.priority, soundEnabled);
|
||||
|
|
|
|||
Loading…
Reference in New Issue