fix: propertyIcons mock, key stability, isValidConnection memoized
- Add resolvePropertyIcon mock to BaseNode tests - Reset mockZoom in top-level beforeEach to prevent test bleed - Use prop.key instead of index as list key in BaseNode properties - Extract isValidConnection into useCallback in CanvasContainer
This commit is contained in:
@@ -78,6 +78,11 @@ export function CanvasContainer({ onConnect: onConnectProp, onEdgeDoubleClick, o
|
|||||||
return true
|
return true
|
||||||
}, [snapshotHistory])
|
}, [snapshotHistory])
|
||||||
|
|
||||||
|
const isValidConnection = useCallback(
|
||||||
|
(connection: { source: string | null; target: string | null }) => connection.source !== connection.target,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full" style={{ background: theme.colors.canvasBackground }}>
|
<div className="w-full h-full" style={{ background: theme.colors.canvasBackground }}>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
@@ -107,7 +112,7 @@ export function CanvasContainer({ onConnect: onConnectProp, onEdgeDoubleClick, o
|
|||||||
colorMode={theme.colors.reactFlowColorMode}
|
colorMode={theme.colors.reactFlowColorMode}
|
||||||
elevateNodesOnSelect={false}
|
elevateNodesOnSelect={false}
|
||||||
connectionMode={ConnectionMode.Loose}
|
connectionMode={ConnectionMode.Loose}
|
||||||
isValidConnection={(connection) => connection.source !== connection.target}
|
isValidConnection={isValidConnection}
|
||||||
>
|
>
|
||||||
<Background
|
<Background
|
||||||
variant={BackgroundVariant.Dots}
|
variant={BackgroundVariant.Dots}
|
||||||
|
|||||||
@@ -50,11 +50,17 @@ vi.mock('@/utils/maskIp', () => ({
|
|||||||
maskIp: (ip: string) => ip,
|
maskIp: (ip: string) => ip,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
vi.mock('@/utils/propertyIcons', () => ({
|
||||||
|
resolvePropertyIcon: (icon: string | null) => icon ? Server : null,
|
||||||
|
}))
|
||||||
|
|
||||||
vi.mock('@/utils/handleUtils', () => ({
|
vi.mock('@/utils/handleUtils', () => ({
|
||||||
BOTTOM_HANDLE_IDS: ['bottom'],
|
BOTTOM_HANDLE_IDS: ['bottom'],
|
||||||
BOTTOM_HANDLE_POSITIONS: { 1: [50] },
|
BOTTOM_HANDLE_POSITIONS: { 1: [50] },
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
beforeEach(() => { mockZoom = 1 })
|
||||||
|
|
||||||
function makeNode(data: Partial<NodeData>): Node<NodeData> {
|
function makeNode(data: Partial<NodeData>): Node<NodeData> {
|
||||||
return {
|
return {
|
||||||
id: 'n1',
|
id: 'n1',
|
||||||
|
|||||||
@@ -115,10 +115,10 @@ export function BaseNode({ id, data, selected, icon: typeIcon, width, height }:
|
|||||||
<>
|
<>
|
||||||
<div style={{ height: 1, background: `${colors.border}44`, margin: '0 8px' }} />
|
<div style={{ height: 1, background: `${colors.border}44`, margin: '0 8px' }} />
|
||||||
<div className="flex flex-col gap-1 px-2.5 py-1.5">
|
<div className="flex flex-col gap-1 px-2.5 py-1.5">
|
||||||
{visibleProperties.map((prop, i) => {
|
{visibleProperties.map((prop) => {
|
||||||
const Icon = resolvePropertyIcon(prop.icon)
|
const Icon = resolvePropertyIcon(prop.icon)
|
||||||
return (
|
return (
|
||||||
<div key={i} className="flex items-center gap-1 font-mono text-[10px]" style={{ color: theme.colors.nodeSubtextColor }}>
|
<div key={prop.key} className="flex items-center gap-1 font-mono text-[10px]" style={{ color: theme.colors.nodeSubtextColor }}>
|
||||||
{Icon && <Icon size={9} className="shrink-0" />}
|
{Icon && <Icon size={9} className="shrink-0" />}
|
||||||
<span className="truncate max-w-[60px] shrink-0" title={prop.key}>{prop.key}</span>
|
<span className="truncate max-w-[60px] shrink-0" title={prop.key}>{prop.key}</span>
|
||||||
<span className="truncate" title={prop.value}>· {prop.value}</span>
|
<span className="truncate" title={prop.value}>· {prop.value}</span>
|
||||||
|
|||||||
Reference in New Issue
Block a user