diff --git a/apps/desktop/electron/notification-actions.test.ts b/apps/desktop/electron/notification-actions.test.ts new file mode 100644 index 0000000000..733632bc0b --- /dev/null +++ b/apps/desktop/electron/notification-actions.test.ts @@ -0,0 +1,22 @@ +import assert from 'node:assert/strict' + +import { test } from 'vitest' + +import { resolveNotificationAction } from './notification-actions' + +const actions = [ + { id: 'approve', text: 'Approve' }, + { id: 'reject', text: 'Reject' } +] + +test('prefers Electron event details and supports the legacy positional index', () => { + assert.deepEqual(resolveNotificationAction(actions, { actionIndex: 1 }, undefined), actions[1]) + assert.deepEqual(resolveNotificationAction(actions, {}, 0), actions[0]) + assert.deepEqual(resolveNotificationAction(actions, { actionIndex: 1 }, 0), actions[1]) +}) + +test('ignores missing and out-of-range action indexes', () => { + assert.equal(resolveNotificationAction(actions, {}, undefined), null) + assert.equal(resolveNotificationAction(actions, { actionIndex: -1 }, undefined), null) + assert.equal(resolveNotificationAction(actions, { actionIndex: 2 }, undefined), null) +}) diff --git a/apps/desktop/electron/notification-actions.ts b/apps/desktop/electron/notification-actions.ts new file mode 100644 index 0000000000..7a3693b160 --- /dev/null +++ b/apps/desktop/electron/notification-actions.ts @@ -0,0 +1,29 @@ +function isActionIndex(value: unknown): value is number { + return typeof value === 'number' && Number.isInteger(value) +} + +function notificationActionIndex(actionEvent: unknown, legacyIndex: unknown): number | null { + if (actionEvent && typeof actionEvent === 'object' && 'actionIndex' in actionEvent) { + const { actionIndex } = actionEvent as { actionIndex?: unknown } + + if (isActionIndex(actionIndex)) { + return actionIndex + } + } + + return isActionIndex(legacyIndex) ? legacyIndex : null +} + +export function resolveNotificationAction( + actions: readonly T[], + actionEvent: unknown, + legacyIndex: unknown +): T | null { + const index = notificationActionIndex(actionEvent, legacyIndex) + + if (index === null || index < 0 || index >= actions.length) { + return null + } + + return actions[index] ?? null +}