mirror of
https://github.com/langgenius/dify.git
synced 2026-05-15 13:02:19 -04:00
148 lines
4.4 KiB
TypeScript
148 lines
4.4 KiB
TypeScript
import type { Node } from '@/app/components/workflow/types'
|
|
import { BlockEnum, SupportUploadFileTypes } from '@/app/components/workflow/types'
|
|
import { TransferMethod } from '@/types/app'
|
|
import {
|
|
buildInitialFeatures,
|
|
buildTriggerStatusMap,
|
|
coerceReplayUserInputs,
|
|
normalizeWorkflowNodesForBackend,
|
|
normalizeWorkflowNodesForFrontend,
|
|
} from '../utils'
|
|
|
|
type HumanInputTestField = {
|
|
type: string
|
|
output_variable_name: string
|
|
}
|
|
|
|
type HumanInputTestNode = Node<{
|
|
inputs: HumanInputTestField[]
|
|
}>
|
|
|
|
describe('workflow-app utils', () => {
|
|
it('should map trigger statuses to enabled and disabled states', () => {
|
|
expect(buildTriggerStatusMap([
|
|
{ node_id: 'node-1', status: 'enabled' },
|
|
{ node_id: 'node-2', status: 'disabled' },
|
|
{ node_id: 'node-3', status: 'paused' },
|
|
])).toEqual({
|
|
'node-1': 'enabled',
|
|
'node-2': 'disabled',
|
|
'node-3': 'disabled',
|
|
})
|
|
})
|
|
|
|
it('should coerce replay run inputs, omit sys keys, and stringify complex values', () => {
|
|
expect(coerceReplayUserInputs({
|
|
'sys.query': 'hidden',
|
|
'query': 'hello',
|
|
'count': 3,
|
|
'enabled': true,
|
|
'nullable': null,
|
|
'metadata': { nested: true },
|
|
})).toEqual({
|
|
query: 'hello',
|
|
count: 3,
|
|
enabled: true,
|
|
nullable: '',
|
|
metadata: '{"nested":true}',
|
|
})
|
|
expect(coerceReplayUserInputs('invalid')).toBeNull()
|
|
expect(coerceReplayUserInputs(null)).toBeNull()
|
|
})
|
|
|
|
it('should normalize human-input multi-file types between frontend and backend payloads', () => {
|
|
const nodes: HumanInputTestNode[] = [
|
|
{
|
|
id: 'node-1',
|
|
type: 'custom',
|
|
position: { x: 0, y: 0 },
|
|
data: {
|
|
title: 'Human Input',
|
|
desc: '',
|
|
type: BlockEnum.HumanInput,
|
|
inputs: [
|
|
{ type: 'paragraph', output_variable_name: 'summary' },
|
|
{ type: 'file-list', output_variable_name: 'attachments' },
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
const backendNodes = normalizeWorkflowNodesForBackend(nodes) as HumanInputTestNode[]
|
|
expect(backendNodes[0]!.data.inputs).toEqual([
|
|
{ type: 'paragraph', output_variable_name: 'summary' },
|
|
{ type: 'file_list', output_variable_name: 'attachments' },
|
|
])
|
|
|
|
const frontendPayloadNodes: HumanInputTestNode[] = [
|
|
{
|
|
...nodes[0]!,
|
|
data: {
|
|
...nodes[0]!.data,
|
|
inputs: [
|
|
{ type: 'paragraph', output_variable_name: 'summary' },
|
|
{ type: 'file_list', output_variable_name: 'attachments' },
|
|
],
|
|
},
|
|
},
|
|
]
|
|
|
|
const frontendNodes = normalizeWorkflowNodesForFrontend(frontendPayloadNodes) as HumanInputTestNode[]
|
|
|
|
expect(frontendNodes[0]!.data.inputs).toEqual([
|
|
{ type: 'paragraph', output_variable_name: 'summary' },
|
|
{ type: 'file-list', output_variable_name: 'attachments' },
|
|
])
|
|
})
|
|
|
|
it('should build initial features with file-upload and feature fallbacks', () => {
|
|
const result = buildInitialFeatures({
|
|
file_upload: {
|
|
enabled: true,
|
|
allowed_file_types: [SupportUploadFileTypes.image],
|
|
allowed_file_extensions: ['.png'],
|
|
allowed_file_upload_methods: [TransferMethod.local_file],
|
|
number_limits: 2,
|
|
image: {
|
|
enabled: true,
|
|
number_limits: 5,
|
|
transfer_methods: [TransferMethod.remote_url],
|
|
},
|
|
},
|
|
opening_statement: 'hello',
|
|
suggested_questions: ['Q1'],
|
|
suggested_questions_after_answer: { enabled: true },
|
|
speech_to_text: { enabled: true },
|
|
text_to_speech: { enabled: true },
|
|
retriever_resource: { enabled: true },
|
|
sensitive_word_avoidance: { enabled: true },
|
|
}, { enabled: true } as never)
|
|
|
|
expect(result).toMatchObject({
|
|
file: {
|
|
enabled: true,
|
|
allowed_file_types: [SupportUploadFileTypes.image],
|
|
allowed_file_extensions: ['.png'],
|
|
allowed_file_upload_methods: [TransferMethod.local_file],
|
|
number_limits: 2,
|
|
fileUploadConfig: { enabled: true },
|
|
image: {
|
|
enabled: true,
|
|
number_limits: 5,
|
|
transfer_methods: [TransferMethod.remote_url],
|
|
},
|
|
},
|
|
opening: {
|
|
enabled: true,
|
|
opening_statement: 'hello',
|
|
suggested_questions: ['Q1'],
|
|
},
|
|
suggested: { enabled: true },
|
|
speech2text: { enabled: true },
|
|
text2speech: { enabled: true },
|
|
citation: { enabled: true },
|
|
moderation: { enabled: true },
|
|
})
|
|
})
|
|
})
|