167 lines
5.7 KiB
JavaScript
167 lines
5.7 KiB
JavaScript
|
|
import assert from 'node:assert/strict'
|
|||
|
|
import test from 'node:test'
|
|||
|
|
|
|||
|
|
import { useWorkbenchAiApplicationPreviewFlow } from '../src/composables/workbenchAiMode/useWorkbenchAiApplicationPreviewFlow.js'
|
|||
|
|
|
|||
|
|
function createRef(value) {
|
|||
|
|
return { value }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createInlineMessage(role, content, options = {}) {
|
|||
|
|
return {
|
|||
|
|
id: options.id || `msg-${Math.random().toString(16).slice(2)}`,
|
|||
|
|
role,
|
|||
|
|
content,
|
|||
|
|
text: content,
|
|||
|
|
paragraphs: String(content || '').split(/\n+/).filter(Boolean),
|
|||
|
|
pending: Boolean(options.pending),
|
|||
|
|
...options
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function buildApplicationPreviewFlowHarness(messages) {
|
|||
|
|
const conversationMessages = createRef(messages)
|
|||
|
|
const applicationSubmitConfirmOpen = createRef(false)
|
|||
|
|
const applicationSubmitConfirmContext = createRef(null)
|
|||
|
|
const persisted = createRef(0)
|
|||
|
|
|
|||
|
|
const flow = useWorkbenchAiApplicationPreviewFlow({
|
|||
|
|
activateInlineConversation: () => {},
|
|||
|
|
applicationPreviewEditor: createRef({}),
|
|||
|
|
applicationSubmitConfirmContext,
|
|||
|
|
applicationSubmitConfirmOpen,
|
|||
|
|
assistantDraft: createRef(''),
|
|||
|
|
cancelApplicationPreviewEditor: () => {},
|
|||
|
|
clearAiModeFiles: () => {},
|
|||
|
|
closeWorkbenchDatePicker: () => {},
|
|||
|
|
commitApplicationPreviewEditor: async () => true,
|
|||
|
|
conversationId: createRef('conversation-context-submit'),
|
|||
|
|
conversationMessages,
|
|||
|
|
conversationStarted: createRef(true),
|
|||
|
|
createInlineMessage,
|
|||
|
|
currentUser: createRef({ username: 'zhangsan@example.com', name: '张三' }),
|
|||
|
|
handleApplicationPreviewEditorKeydown: () => {},
|
|||
|
|
inlineConversationAutoScrollPinned: createRef(true),
|
|||
|
|
isApplicationPreviewEditing: createRef(false),
|
|||
|
|
openApplicationPreviewEditor: () => {},
|
|||
|
|
persistCurrentConversation: () => { persisted.value += 1 },
|
|||
|
|
pushInlineApplicationActionUserMessage: (text) => {
|
|||
|
|
conversationMessages.value.push(createInlineMessage('user', text))
|
|||
|
|
},
|
|||
|
|
pushInlineUserMessage: (text) => {
|
|||
|
|
conversationMessages.value.push(createInlineMessage('user', text))
|
|||
|
|
},
|
|||
|
|
refreshApplicationPreviewEstimate: async (preview) => preview,
|
|||
|
|
removeWorkbenchDateTag: () => {},
|
|||
|
|
replaceInlineMessage: (id, nextMessage) => {
|
|||
|
|
const index = conversationMessages.value.findIndex((item) => item.id === id)
|
|||
|
|
if (index >= 0) {
|
|||
|
|
conversationMessages.value.splice(index, 1, nextMessage)
|
|||
|
|
} else {
|
|||
|
|
conversationMessages.value.push(nextMessage)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
resolveApplicationPreviewEditorDateMax: () => '',
|
|||
|
|
resolveApplicationPreviewEditorDateMin: () => '',
|
|||
|
|
resolveApplicationPreviewEditorControl: () => null,
|
|||
|
|
resolveApplicationPreviewEditorOptions: () => [],
|
|||
|
|
resolveInlineThinkingEvents: (message) => message?.stewardPlan?.thinkingEvents || [],
|
|||
|
|
resolveLatestInlineUserPrompt: () => '2026-02-20 至 2026-02-23,去上海出差,交通火车,保存草稿',
|
|||
|
|
scrollInlineConversationToBottom: () => {},
|
|||
|
|
sending: createRef(false),
|
|||
|
|
toast: () => {}
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
applicationSubmitConfirmOpen,
|
|||
|
|
conversationMessages,
|
|||
|
|
flow,
|
|||
|
|
persisted
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
test('workbench saved application draft can be submitted by contextual text without re-planning', async () => {
|
|||
|
|
const originalFetch = globalThis.fetch
|
|||
|
|
const requests = []
|
|||
|
|
globalThis.fetch = async (url, options = {}) => {
|
|||
|
|
const normalizedUrl = String(url)
|
|||
|
|
if (normalizedUrl.includes('/reimbursements/claims')) {
|
|||
|
|
return {
|
|||
|
|
ok: true,
|
|||
|
|
async json() {
|
|||
|
|
return { items: [] }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (normalizedUrl.includes('/reimbursements/application-preview-action')) {
|
|||
|
|
const body = JSON.parse(String(options.body || '{}'))
|
|||
|
|
requests.push({ url: normalizedUrl, body })
|
|||
|
|
return {
|
|||
|
|
ok: true,
|
|||
|
|
async json() {
|
|||
|
|
return {
|
|||
|
|
status: 'succeeded',
|
|||
|
|
result: {
|
|||
|
|
draft_payload: {
|
|||
|
|
claim_id: 'claim-saved-draft',
|
|||
|
|
claim_no: 'A20260220',
|
|||
|
|
status: 'submitted',
|
|||
|
|
approval_stage: '直属领导审批'
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
throw new Error(`unexpected request: ${normalizedUrl}`)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try {
|
|||
|
|
const previewMessage = createInlineMessage('assistant', '申请核对表', {
|
|||
|
|
id: 'application-preview-1',
|
|||
|
|
applicationPreview: {
|
|||
|
|
readyToSubmit: true,
|
|||
|
|
fields: {
|
|||
|
|
applicationType: '差旅费用申请',
|
|||
|
|
time: '2026-02-20 至 2026-02-23',
|
|||
|
|
location: '上海',
|
|||
|
|
reason: '辅助国网仿生产服务器部署',
|
|||
|
|
days: '4天',
|
|||
|
|
transportMode: '火车',
|
|||
|
|
amount: '1200元'
|
|||
|
|
},
|
|||
|
|
missingFields: [],
|
|||
|
|
validationIssues: []
|
|||
|
|
},
|
|||
|
|
draftPayload: {
|
|||
|
|
claim_id: 'claim-saved-draft',
|
|||
|
|
claim_no: 'A20260220',
|
|||
|
|
status: 'draft'
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
const harness = buildApplicationPreviewFlowHarness([
|
|||
|
|
createInlineMessage('user', '2026-02-20 至 2026-02-23,去上海出差,交通火车,保存草稿'),
|
|||
|
|
previewMessage,
|
|||
|
|
createInlineMessage('assistant', '### 申请草稿已保存', {
|
|||
|
|
draftPayload: previewMessage.draftPayload
|
|||
|
|
})
|
|||
|
|
])
|
|||
|
|
|
|||
|
|
const handled = harness.flow.handleInlineApplicationPreviewTextAction(
|
|||
|
|
'提交这个单据',
|
|||
|
|
createRef(false)
|
|||
|
|
)
|
|||
|
|
assert.equal(handled, true)
|
|||
|
|
await new Promise((resolve) => setTimeout(resolve, 0))
|
|||
|
|
|
|||
|
|
assert.equal(harness.applicationSubmitConfirmOpen.value, false)
|
|||
|
|
assert.equal(requests.length, 1)
|
|||
|
|
assert.equal(requests[0].body.context_json.application_edit_claim_id, 'claim-saved-draft')
|
|||
|
|
assert.equal(requests[0].body.context_json.application_edit_mode, true)
|
|||
|
|
assert.match(harness.conversationMessages.value.at(-1).content, /申请单据已生成/)
|
|||
|
|
assert.ok(harness.persisted.value > 0)
|
|||
|
|
} finally {
|
|||
|
|
globalThis.fetch = originalFetch
|
|||
|
|
}
|
|||
|
|
})
|