hermes-agent/apps/desktop/electron/fs-ipc.test.cjs
Brooklyn Nicholson f3ce17bf9e refactor(desktop): extract filesystem IPC handlers from main.cjs into fs-ipc.cjs
Second main.cjs cluster peel (after git-ipc). The six hermes:fs:* handlers
(readDir, gitRoot, reveal, rename, writeText, trash) move verbatim into
electron/fs-ipc.cjs behind a registerFsIpc({ ipcMain, directoryExists,
expandUserPath }) registrar — same injection pattern as registerGitIpc. Path
hardening / read-dir / git-root come from their sibling modules directly; the
two main-process path helpers are injected so the module stays side-effect free.

Channel names are unchanged, so preload + renderer are untouched. main.cjs drops
~85 lines; the now-dead fs-read-dir / git-root requires in main.cjs are removed.
Adds electron/fs-ipc.test.cjs asserting the hermes:fs:* surface by invariant.
2026-06-30 13:26:53 -05:00

49 lines
1.5 KiB
JavaScript

'use strict'
const assert = require('node:assert/strict')
const test = require('node:test')
const { registerFsIpc } = require('./fs-ipc.cjs')
function fakeIpcMain() {
const handlers = new Map()
return {
handlers,
handle(channel, handler) {
assert.ok(!handlers.has(channel), `duplicate registration for ${channel}`)
handlers.set(channel, handler)
}
}
}
test('registerFsIpc wires only hermes:fs:* channels, each to a handler fn', () => {
const ipcMain = fakeIpcMain()
registerFsIpc({ ipcMain, directoryExists: () => true, expandUserPath: p => p })
assert.ok(ipcMain.handlers.size >= 6, `expected the full fs surface, got ${ipcMain.handlers.size}`)
for (const [channel, handler] of ipcMain.handlers) {
assert.match(channel, /^hermes:fs:/, `${channel} is not an fs channel`)
assert.equal(typeof handler, 'function', `${channel} should register a handler`)
}
for (const channel of ['hermes:fs:readDir', 'hermes:fs:rename', 'hermes:fs:trash']) {
assert.ok(ipcMain.handlers.has(channel), `missing ${channel}`)
}
})
test('rename rejects names that traverse out of the parent dir', async () => {
const ipcMain = fakeIpcMain()
registerFsIpc({ ipcMain, directoryExists: () => true, expandUserPath: p => p })
for (const bad of ['..', '.', 'a/b', 'a\\b']) {
await assert.rejects(
() => ipcMain.handlers.get('hermes:fs:rename')({}, '/tmp/x', bad),
/Invalid rename/,
`"${bad}" should be rejected`
)
}
})