Compare commits

..

1 Commits

Author SHA1 Message Date
CodeRabbit Fixer
69bc33eef5 fix: Add unit tests for resolveSubgraphInputLink (#9293)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 17:04:25 +01:00
2 changed files with 65 additions and 22 deletions

View File

@@ -278,7 +278,7 @@ describe('Nested promoted widget mapping', () => {
setActivePinia(createTestingPinia({ stubActions: false }))
})
function createTwoLayerPromotionSetup() {
it('maps store identity to deepest concrete widget for two-layer promotions', () => {
const subgraphA = createTestSubgraph({
inputs: [{ name: 'a_input', type: '*' }]
})
@@ -308,30 +308,11 @@ describe('Nested promoted widget mapping', () => {
const nodeData = vueNodeData.get(String(subgraphNodeB.id))
const mappedWidget = nodeData?.widgets?.[0]
return { innerNode, subgraphNodeB, mappedWidget }
}
it('resolves storeNodeId to the deepest concrete node for two-layer promotions', () => {
const { innerNode, subgraphNodeB, mappedWidget } =
createTwoLayerPromotionSetup()
expect(mappedWidget).toBeDefined()
expect(mappedWidget?.type).toBe('combo')
expect(mappedWidget?.storeName).toBe('picker')
expect(mappedWidget?.storeNodeId).toBe(
`${subgraphNodeB.subgraph.id}:${innerNode.id}`
)
})
it('resolves storeName to the deepest concrete widget name for two-layer promotions', () => {
const { mappedWidget } = createTwoLayerPromotionSetup()
expect(mappedWidget).toBeDefined()
expect(mappedWidget?.storeName).toBe('picker')
})
it('resolves effectiveWidget type to the deepest concrete widget type for two-layer promotions', () => {
const { mappedWidget } = createTwoLayerPromotionSetup()
expect(mappedWidget).toBeDefined()
expect(mappedWidget?.type).toBe('combo')
})
})

View File

@@ -121,6 +121,68 @@ describe('resolveSubgraphInputLink', () => {
expect(result).toBe('seed_input')
})
test('skips broken links where getLink returns undefined', () => {
const { subgraph, subgraphNode } = createSubgraphSetup('prompt')
addLinkedInteriorInput(subgraph, 'prompt', 'valid_input', 'valid')
const broken = addLinkedInteriorInput(
subgraph,
'prompt',
'broken_input',
'broken'
)
const originalGetLink = subgraph.getLink.bind(subgraph)
vi.spyOn(subgraph, 'getLink').mockImplementation((linkId) => {
if (typeof linkId !== 'number') return originalGetLink(linkId)
if (linkId === broken.linkId) return undefined
return originalGetLink(linkId)
})
const result = resolveSubgraphInputLink(
subgraphNode,
'prompt',
({ targetInput }) => targetInput.name
)
expect(result).toBe('valid_input')
})
test('returns result from latest connection when multiple links resolve', () => {
const { subgraph, subgraphNode } = createSubgraphSetup('prompt')
addLinkedInteriorInput(subgraph, 'prompt', 'older_input', 'older')
addLinkedInteriorInput(subgraph, 'prompt', 'newer_input', 'newer')
const result = resolveSubgraphInputLink(
subgraphNode,
'prompt',
({ targetInput }) => targetInput.name
)
expect(result).toBe('newer_input')
})
test('falls back to earlier link when latest resolve callback returns undefined', () => {
const { subgraph, subgraphNode } = createSubgraphSetup('prompt')
addLinkedInteriorInput(subgraph, 'prompt', 'fallback_input', 'fallback')
const newer = addLinkedInteriorInput(
subgraph,
'prompt',
'skipped_input',
'skipped'
)
const result = resolveSubgraphInputLink(
subgraphNode,
'prompt',
({ targetInput }) => {
if (targetInput.link === newer.linkId) return undefined
return targetInput.name
}
)
expect(result).toBe('fallback_input')
})
test('caches getTargetWidget result within the same callback evaluation', () => {
const { subgraph, subgraphNode } = createSubgraphSetup('model')
const linked = addLinkedInteriorInput(