✅ test: 补上待处理请求与页面结构的回归用例

This commit is contained in:
pyh
2026-10-04 19:24:03 +08:00
parent ec8661b317
commit 302e0a8bf5
4 changed files with 153 additions and 69 deletions
+39 -11
View File
@@ -9,11 +9,14 @@ import {
preview,
questionText,
servedPendingKind,
stillWorth,
stillOwed,
titleOf,
} from '../../src/client/core/session.js'
test('only the three interaction kinds the Harness renders are served', () => {
test('only the three interaction kinds the domains publish are served', () => {
// The literals the shipped domains publish: dsh-client-ui-approval sets
// `kind = "approval"`, dsh-client-ui-user-questions picks between `"question"`
// and `"plan-review"` for one batch.
assert.equal(servedPendingKind({ kind: 'approval' }), 'approval')
assert.equal(servedPendingKind({ kind: 'question' }), 'question')
assert.equal(servedPendingKind({ kind: 'plan-review' }), 'plan-review')
@@ -58,17 +61,42 @@ test('the conversation on screen is the one the main view retains', () => {
assert.equal(isOnScreen('a', undefined), false)
})
test('a queued alert is dropped when its conversation resumed inside the settle window', () => {
const candidate = { kind: 'completion', sessionId: 'a', test: false }
test('a pending interaction stays owed while it waits, even though the run is still running', () => {
// The session is `running` whenever the agent loop is active, and a pending
// approval or question is exactly that: the loop is waiting for the human. The
// run state must therefore not gate these alerts — it used to drop every one
// of them, which is why only completions ever reached the user.
const candidate = { kind: 'approval', sessionId: 'a', pendingKind: 'approval', test: false }
const status = (pendingInteraction, running) => new Map([['a', { pendingInteraction, running }]])
assert.equal(stillOwed(candidate, { list: { byId: { a: { running: true } } }, status: status({ kind: 'approval' }, true) }), true)
assert.equal(stillOwed(candidate, { list: { byId: { a: { running: false } } }, status: status({ kind: 'approval' }, false) }), true)
// Answered inside the settle window: the request is gone, so nothing is owed.
assert.equal(stillOwed(candidate, { list: { byId: { a: { running: true } } }, status: status(undefined, true) }), false)
// Replaced by a different request of the same kind: a new request is a new alert.
assert.equal(stillOwed({ ...candidate, kind: 'question', pendingKind: 'question' }, { list: { byId: {} }, status: status({ kind: 'approval' }, true) }), false)
// A plan review is owed on its own discriminator.
assert.equal(stillOwed({ ...candidate, kind: 'question', pendingKind: 'plan-review' }, { list: { byId: {} }, status: status({ kind: 'plan-review' }, true) }), true)
// Nothing contradicts the request, so it is still the user's move.
assert.equal(stillOwed(candidate, { list: { byId: {} }, status: new Map() }), true)
assert.equal(stillOwed(candidate, { list: undefined, status: undefined }), true)
})
test('a completion is owed only while the conversation stayed idle', () => {
const candidate = { kind: 'completion', sessionId: 'a', pendingKind: '', test: false }
const live = (byId, status) => ({ list: { byId }, status })
assert.equal(stillWorth(candidate, { list: undefined, status: undefined }), true)
assert.equal(stillWorth(candidate, live({ a: { running: false } })), true)
assert.equal(stillWorth(candidate, live({})), true)
assert.equal(stillWorth(candidate, live({ a: { running: true } })), false)
assert.equal(stillOwed(candidate, { list: undefined, status: undefined }), true)
assert.equal(stillOwed(candidate, live({ a: { running: false } })), true)
assert.equal(stillOwed(candidate, live({})), true)
assert.equal(stillOwed(candidate, live({ a: { running: true } })), false)
// The per-session selector wins over the list summary, which still carries the
// pre-transition flag.
assert.equal(stillWorth(candidate, { list: { byId: { a: { running: true } } }, status: new Map([['a', { running: false }]]) }), true)
// A test alert is owed no matter what the live state says.
assert.equal(stillWorth({ ...candidate, test: true }, live({ a: { running: true } })), true)
assert.equal(stillOwed(candidate, { list: { byId: { a: { running: true } } }, status: new Map([['a', { running: false }]]) }), true)
})
test('a test alert is always owed', () => {
const live = { list: { byId: { a: { running: true } } }, status: new Map([['a', { running: true }]]) }
assert.equal(stillOwed({ kind: 'completion', sessionId: 'a', pendingKind: '', test: true }, live), true)
assert.equal(stillOwed({ kind: 'approval', sessionId: 'a', pendingKind: 'approval', test: true }, live), true)
})