fix(workflow): correct loop boolean break condition values (#41186)

This commit is contained in:
HelloSrauker
2026-08-27 08:02:52 +00:00
committed by GitHub
parent 15021ad350
commit 1db542c706
4 changed files with 93 additions and 4 deletions
@@ -0,0 +1,86 @@
import type { Condition } from '../types'
import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { VarType } from '@/app/components/workflow/types'
import ConditionItem from '../components/condition-list/condition-item'
import { ComparisonOperator } from '../types'
vi.mock('@/app/components/workflow/panel/chat-variable-panel/components/bool-value', () => ({
default: ({ value }: { value: boolean }) => <div data-testid="bool-value">{String(value)}</div>,
}))
vi.mock('../components/condition-list/condition-input', () => ({
default: () => <div />,
}))
vi.mock('../components/condition-list/condition-operator', () => ({
default: () => <div />,
}))
vi.mock('../components/condition-list/condition-var-selector', () => ({
default: ({
onChange,
}: {
onChange: (selector: string[], variable: { type: string }) => void
}) => (
<button type="button" onClick={() => onChange(['source', 'flag'], { type: 'boolean' })}>
Select boolean variable
</button>
),
}))
const renderConditionItem = (condition: Condition, onUpdateCondition = vi.fn()) => {
const result = render(
<ConditionItem
conditionId={condition.id}
condition={condition}
onUpdateCondition={onUpdateCondition}
nodeId="loop-node"
availableNodes={[]}
numberVariables={[]}
availableVars={[]}
/>,
)
return { ...result, onUpdateCondition }
}
describe('ConditionItem', () => {
it.each([
{ value: 'false', expected: 'false' },
{ value: 'true', expected: 'true' },
] as const)('should render legacy boolean string $value as $expected', ({ value, expected }) => {
renderConditionItem({
id: 'condition-1',
varType: VarType.boolean,
variable_selector: ['source', 'flag'],
comparison_operator: ComparisonOperator.is,
value,
})
expect(screen.getByTestId('bool-value')).toHaveTextContent(expected)
})
it('should reset the value to boolean false when selecting a boolean variable', async () => {
const user = userEvent.setup()
const { onUpdateCondition } = renderConditionItem({
id: 'condition-1',
varType: VarType.string,
variable_selector: ['source', 'text'],
comparison_operator: ComparisonOperator.contains,
value: '',
})
await user.click(screen.getByRole('button', { name: 'Select boolean variable' }))
expect(onUpdateCondition).toHaveBeenCalledWith(
'condition-1',
expect.objectContaining({
varType: VarType.boolean,
variable_selector: ['source', 'flag'],
comparison_operator: ComparisonOperator.is,
value: false,
}),
)
})
})
@@ -103,7 +103,7 @@ describe('loop use-config helpers', () => {
id: 'condition-1',
varType: VarType.boolean,
comparison_operator: ComparisonOperator.is,
value: 'false',
value: false,
}),
])
expect(withFileCondition.break_conditions?.[1]).toEqual(
@@ -212,7 +212,7 @@ const ConditionItem = ({
const newCondition = produce(condition, (draft) => {
draft.variable_selector = valueSelector
draft.varType = varItem.type
draft.value = ''
draft.value = varItem.type === VarType.boolean ? false : ''
draft.comparison_operator = getOperators(varItem.type)[0]
delete draft.key
delete draft.sub_variable_condition
@@ -326,7 +326,10 @@ const ConditionItem = ({
{!comparisonOperatorNotRequireValue(condition.comparison_operator) &&
condition.varType === VarType.boolean && (
<div className="p-1">
<BoolValue value={condition.value as boolean} onChange={handleUpdateConditionValue} />
<BoolValue
value={condition.value === true || condition.value === 'true'}
onChange={handleUpdateConditionValue}
/>
</div>
)}
{!comparisonOperatorNotRequireValue(condition.comparison_operator) &&
@@ -43,7 +43,7 @@ export const addBreakCondition = ({
variable.type,
isVarFileAttribute ? { key: valueSelector.slice(-1)[0]! } : undefined,
)[0],
value: variable.type === VarType.boolean ? 'false' : '',
value: variable.type === VarType.boolean ? false : '',
})
})