mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
test: add failing test for promoted indicator on nested subgraphs
Reproduces #10612 where the promoted widget ring indicator is missing on nested subgraphs due to a key mismatch in isPromotedByAny lookup.
This commit is contained in:
119
src/core/graph/subgraph/promotedWidgetIndicator.test.ts
Normal file
119
src/core/graph/subgraph/promotedWidgetIndicator.test.ts
Normal file
@@ -0,0 +1,119 @@
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
import { fromAny } from '@total-typescript/shoehorn'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { setActivePinia } from 'pinia'
|
||||
import { nextTick } from 'vue'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import type {
|
||||
SafeWidgetData,
|
||||
VueNodeData
|
||||
} from '@/composables/graph/useGraphNodeManager'
|
||||
import NodeWidgets from '@/renderer/extensions/vueNodes/components/NodeWidgets.vue'
|
||||
import { usePromotionStore } from '@/stores/promotionStore'
|
||||
|
||||
vi.mock('@/renderer/core/canvas/canvasStore', () => ({
|
||||
useCanvasStore: () => ({
|
||||
canvas: {
|
||||
graph: {
|
||||
rootGraph: {
|
||||
id: 'graph-test'
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}))
|
||||
|
||||
function createMockWidget(
|
||||
overrides: Partial<SafeWidgetData> = {}
|
||||
): SafeWidgetData {
|
||||
return {
|
||||
nodeId: 'test_node',
|
||||
name: 'test_widget',
|
||||
type: 'combo',
|
||||
options: undefined,
|
||||
callback: undefined,
|
||||
spec: undefined,
|
||||
isDOMWidget: false,
|
||||
slotMetadata: undefined,
|
||||
...overrides
|
||||
}
|
||||
}
|
||||
|
||||
function createMockNodeData(
|
||||
nodeType: string,
|
||||
widgets: SafeWidgetData[],
|
||||
id: string
|
||||
): VueNodeData {
|
||||
return {
|
||||
id,
|
||||
type: nodeType,
|
||||
widgets,
|
||||
title: 'Test Node',
|
||||
mode: 0,
|
||||
selected: false,
|
||||
executing: false,
|
||||
inputs: [],
|
||||
outputs: []
|
||||
}
|
||||
}
|
||||
|
||||
function mountComponent(nodeData: VueNodeData, setupStores?: () => void) {
|
||||
const pinia = createTestingPinia({ stubActions: false })
|
||||
setActivePinia(pinia)
|
||||
setupStores?.()
|
||||
|
||||
return mount(NodeWidgets, {
|
||||
props: { nodeData },
|
||||
global: {
|
||||
plugins: [pinia],
|
||||
stubs: { InputSlot: true },
|
||||
mocks: { $t: (key: string) => key }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function getBorderStyles(wrapper: ReturnType<typeof mount>) {
|
||||
return fromAny<{ processedWidgets: unknown[] }, unknown>(
|
||||
wrapper.vm
|
||||
).processedWidgets.map(
|
||||
(entry) =>
|
||||
(entry as { simplified: { borderStyle?: string } }).simplified.borderStyle
|
||||
)
|
||||
}
|
||||
|
||||
describe('promoted widget indicator on nested subgraphs', () => {
|
||||
test('shows promoted ring when promotion was stored without disambiguatingSourceNodeId', async () => {
|
||||
// Scenario: SubBNode (id=3) inside SubA promotes a widget from
|
||||
// ConcreteNode (id=1). The promotion at the SubA level is stored
|
||||
// WITHOUT disambiguatingSourceNodeId because ConcreteNode is not
|
||||
// itself a SubgraphNode.
|
||||
//
|
||||
// The widget rendered on SubBNode has storeName and storeNodeId set
|
||||
// (because it's a promoted widget), so NodeWidgets.vue would normally
|
||||
// compute a disambiguatingSourceNodeId from the storeNodeId.
|
||||
// This causes a key mismatch: lookup key "3:text:1" vs stored "3:text".
|
||||
const promotedWidget = createMockWidget({
|
||||
name: 'text',
|
||||
type: 'combo',
|
||||
nodeId: 'inner-subgraph:1',
|
||||
storeNodeId: 'inner-subgraph:1',
|
||||
storeName: 'text',
|
||||
slotName: 'text'
|
||||
})
|
||||
const nodeData = createMockNodeData('SubgraphNode', [promotedWidget], '3')
|
||||
const wrapper = mountComponent(nodeData, () => {
|
||||
// Store promotion WITHOUT disambiguatingSourceNodeId, as would
|
||||
// happen for a first-level nested promotion where the inner node
|
||||
// is not itself a SubgraphNode.
|
||||
usePromotionStore().promote('graph-test', '4', {
|
||||
sourceNodeId: '3',
|
||||
sourceWidgetName: 'text'
|
||||
})
|
||||
})
|
||||
await nextTick()
|
||||
const borderStyles = getBorderStyles(wrapper)
|
||||
|
||||
expect(borderStyles.some((style) => style?.includes('promoted'))).toBe(true)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user