@@ -6,18 +6,22 @@ import type { ResolutionContext } from './reference'
66
77vi . mock ( '@sim/logger' , ( ) => loggerMock )
88
9- /**
10- * Creates a minimal workflow for testing.
11- */
12- function createTestWorkflow ( blocks : Array < { id : string ; name ?: string ; type ?: string } > = [ ] ) {
9+ function createTestWorkflow (
10+ blocks : Array < {
11+ id : string
12+ name ?: string
13+ type ?: string
14+ outputs ?: Record < string , any >
15+ } > = [ ]
16+ ) {
1317 return {
1418 version : '1.0' ,
1519 blocks : blocks . map ( ( b ) => ( {
1620 id : b . id ,
1721 position : { x : 0 , y : 0 } ,
1822 config : { tool : b . type ?? 'function' , params : { } } ,
1923 inputs : { } ,
20- outputs : { } ,
24+ outputs : b . outputs ?? { } ,
2125 metadata : { id : b . type ?? 'function' , name : b . name ?? b . id } ,
2226 enabled : true ,
2327 } ) ) ,
@@ -126,7 +130,7 @@ describe('BlockResolver', () => {
126130 expect ( resolver . resolve ( '<source.items.1.id>' , ctx ) ) . toBe ( 2 )
127131 } )
128132
129- it . concurrent ( 'should return undefined for non-existent path' , ( ) => {
133+ it . concurrent ( 'should return undefined for non-existent path when no schema defined ' , ( ) => {
130134 const workflow = createTestWorkflow ( [ { id : 'source' } ] )
131135 const resolver = new BlockResolver ( workflow )
132136 const ctx = createTestContext ( 'current' , {
@@ -136,6 +140,48 @@ describe('BlockResolver', () => {
136140 expect ( resolver . resolve ( '<source.nonexistent>' , ctx ) ) . toBeUndefined ( )
137141 } )
138142
143+ it . concurrent ( 'should throw error for path not in output schema' , ( ) => {
144+ const workflow = createTestWorkflow ( [
145+ {
146+ id : 'source' ,
147+ outputs : {
148+ validField : { type : 'string' , description : 'A valid field' } ,
149+ nested : {
150+ child : { type : 'number' , description : 'Nested child' } ,
151+ } ,
152+ } ,
153+ } ,
154+ ] )
155+ const resolver = new BlockResolver ( workflow )
156+ const ctx = createTestContext ( 'current' , {
157+ source : { validField : 'value' , nested : { child : 42 } } ,
158+ } )
159+
160+ expect ( ( ) => resolver . resolve ( '<source.invalidField>' , ctx ) ) . toThrow (
161+ / " i n v a l i d F i e l d " d o e s n ' t e x i s t o n b l o c k " s o u r c e " /
162+ )
163+ expect ( ( ) => resolver . resolve ( '<source.invalidField>' , ctx ) ) . toThrow ( / A v a i l a b l e f i e l d s : / )
164+ } )
165+
166+ it . concurrent ( 'should return undefined for path in schema but missing in data' , ( ) => {
167+ const workflow = createTestWorkflow ( [
168+ {
169+ id : 'source' ,
170+ outputs : {
171+ requiredField : { type : 'string' , description : 'Always present' } ,
172+ optionalField : { type : 'string' , description : 'Sometimes missing' } ,
173+ } ,
174+ } ,
175+ ] )
176+ const resolver = new BlockResolver ( workflow )
177+ const ctx = createTestContext ( 'current' , {
178+ source : { requiredField : 'value' } ,
179+ } )
180+
181+ expect ( resolver . resolve ( '<source.requiredField>' , ctx ) ) . toBe ( 'value' )
182+ expect ( resolver . resolve ( '<source.optionalField>' , ctx ) ) . toBeUndefined ( )
183+ } )
184+
139185 it . concurrent ( 'should return undefined for non-existent block' , ( ) => {
140186 const workflow = createTestWorkflow ( [ { id : 'existing' } ] )
141187 const resolver = new BlockResolver ( workflow )
0 commit comments