openpencil/packages/harness/tests/session-store.test.ts
Danila Poyarkov 83a5ea1b42
feat(ai): add HarnessAgent sidecar foundation (#560)
* feat(ai): add HarnessAgent sidecar foundation

* feat(ai): integrate Pi as a Harness provider

* fix(ai): harden Harness provider integration

* fix(ai): address Harness integration review

* fix(ai): align Harness code with project conventions

* fix(ai): preserve Harness sessions on cancellation

* test(ai): cover Harness JSONL framing

* refactor(ai): generalize Harness sidecar adapters

* fix(ci): build Harness sidecar for native checks
2026-08-19 17:41:10 +03:00

54 lines
1.8 KiB
TypeScript

import { describe, expect, test } from 'bun:test'
import { mkdtemp, readFile, rm } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import type { HarnessResumeState } from '../src/backends/types'
import { FileResumeStateStore } from '../src/session-store'
const state: HarnessResumeState = {
type: 'resume-session',
harnessId: 'fake',
specificationVersion: 'harness-v1',
data: { opaque: 'state' }
}
describe('FileResumeStateStore', () => {
test('atomically persists and removes opaque state', async () => {
const root = await mkdtemp(join(tmpdir(), 'open-pencil-harness-'))
try {
const store = new FileResumeStateStore(root)
expect(await store.load('session-1')).toBeUndefined()
await store.save('session-1', state)
expect(await store.load('session-1')).toEqual(state)
expect(JSON.parse(await readFile(join(root, 'session-1.json'), 'utf8'))).toEqual(state)
await store.remove('session-1')
expect(await store.load('session-1')).toBeUndefined()
} finally {
await rm(root, { recursive: true, force: true })
}
})
test('concurrent saves leave valid state', async () => {
const root = await mkdtemp(join(tmpdir(), 'open-pencil-harness-'))
try {
const store = new FileResumeStateStore(root)
await Promise.all([
store.save('session-1', state),
store.save('session-1', { ...state, data: { opaque: 'newer' } })
])
expect(await store.load('session-1')).toMatchObject({
type: 'resume-session',
harnessId: 'fake'
})
} finally {
await rm(root, { recursive: true, force: true })
}
})
test('rejects path traversal session IDs', async () => {
const store = new FileResumeStateStore(tmpdir())
await expect(store.save('../escape', state)).rejects.toThrow('Invalid harness session ID')
})
})