hermes-agent/apps/desktop/electron/link-title-window.test.cjs
Brooklyn Nicholson 42bc07d107 fix(desktop): cancel downloads triggered by link-title fetch window
The hidden BrowserWindow used by fetchLinkTitle to scrape page titles
had no will-download handler on its session.  When a link artifact URL
responds with Content-Disposition: attachment, Electron fires will-download
and the file is saved for real — explaining the spurious download on the
Artifacts page.

Add guardLinkTitleSession() (parallel to the existing audio-mute guard for
#49505) that installs a will-download handler which immediately cancels
every download item on the hermes:link-titles session.  Call it from
getLinkTitleSession() right after the request-type blocklist is wired up.
2026-07-03 01:46:27 -05:00

68 lines
2.3 KiB
JavaScript

const assert = require('node:assert/strict')
const test = require('node:test')
const { createLinkTitleWindow, guardLinkTitleSession, linkTitleWindowOptions } = require('./link-title-window.cjs')
function makeFakeBrowserWindow() {
const calls = { audioMuted: [] }
const FakeBrowserWindow = function (options) {
this.options = options
this.webContents = {
setAudioMuted(value) {
calls.audioMuted.push(value)
}
}
}
return { FakeBrowserWindow, calls }
}
test('linkTitleWindowOptions keeps the offscreen, hardened defaults', () => {
const session = { id: 'link-titles' }
const options = linkTitleWindowOptions(session)
assert.equal(options.show, false)
assert.equal(options.webPreferences.session, session)
assert.equal(options.webPreferences.contextIsolation, true)
assert.equal(options.webPreferences.sandbox, true)
assert.equal(options.webPreferences.nodeIntegration, false)
})
test('createLinkTitleWindow mutes audio so historical links never autoplay sound', () => {
// Regression for #49505: the hidden title-fetch window loaded YouTube/watch
// URLs (to read their <title>) without muting, leaking ~2s of audio on every
// history re-render.
const { FakeBrowserWindow, calls } = makeFakeBrowserWindow()
const window = createLinkTitleWindow(FakeBrowserWindow, { id: 'link-titles' })
assert.ok(window instanceof FakeBrowserWindow)
assert.deepEqual(calls.audioMuted, [true])
})
test('createLinkTitleWindow still returns the window if muting throws', () => {
const ThrowingBrowserWindow = function (options) {
this.options = options
this.webContents = {
setAudioMuted() {
throw new Error('webContents unavailable')
}
}
}
const window = createLinkTitleWindow(ThrowingBrowserWindow, { id: 'link-titles' })
assert.ok(window instanceof ThrowingBrowserWindow)
})
test('guardLinkTitleSession cancels downloads triggered by the title-fetch window', () => {
let cancelled = false
const handlers = {}
guardLinkTitleSession({ on: (e, h) => { handlers[e] = h } })
handlers['will-download'](null, { cancel: () => { cancelled = true } })
assert.ok(cancelled)
})
test('guardLinkTitleSession is a no-op when session.on throws', () => {
assert.doesNotThrow(() => guardLinkTitleSession({ on() { throw new Error() } }))
})