@@ -7,6 +7,7 @@ mod unit_tests {
77 use crate :: models:: workflow:: * ;
88 use crate :: models:: task:: * ;
99 use crate :: models:: map:: * ;
10+ use serde_json:: json;
1011
1112 #[ test]
1213 fn create_workflow ( ) {
@@ -37,4 +38,203 @@ mod unit_tests {
3738 assert_eq ! ( workflow. document. summary, summary) ;
3839 }
3940
41+ #[ test]
42+ fn test_for_loop_definition_each_field_deserialization ( ) {
43+ // This test verifies that ForLoopDefinition correctly deserializes "each"
44+ let for_loop_json = serde_json:: json!( {
45+ "each" : "item" ,
46+ "in" : ".items"
47+ } ) ;
48+
49+ let result: Result < ForLoopDefinition , _ > = serde_json:: from_value ( for_loop_json) ;
50+
51+ match result {
52+ Ok ( for_loop) => {
53+ assert_eq ! ( for_loop. each, "item" , "The 'each' field should be 'item'" ) ;
54+ assert_eq ! ( for_loop. in_, ".items" , "The 'in' field should be '.items'" ) ;
55+ }
56+ Err ( e) => {
57+ panic ! (
58+ "Failed to deserialize ForLoopDefinition with 'each' field: {}" ,
59+ e
60+ ) ;
61+ }
62+ }
63+ }
64+
65+ #[ test]
66+ fn test_for_task_deserialization ( ) {
67+ // This is a valid For task - it has a "for" field and a "do" field
68+ let for_task_json = json ! ( {
69+ "for" : {
70+ "each" : "item" ,
71+ "in" : ".items"
72+ } ,
73+ "do" : [
74+ {
75+ "processItem" : {
76+ "call" : "processFunction" ,
77+ "with" : {
78+ "item" : "${ .item }"
79+ }
80+ }
81+ }
82+ ]
83+ } ) ;
84+
85+ let result: Result < TaskDefinition , _ > = serde_json:: from_value ( for_task_json. clone ( ) ) ;
86+
87+ match result {
88+ Ok ( TaskDefinition :: For ( for_def) ) => {
89+ assert_eq ! ( for_def. for_. each, "item" ) ;
90+ assert_eq ! ( for_def. for_. in_, ".items" ) ;
91+ assert_eq ! ( for_def. do_. entries. len( ) , 1 ) ;
92+ let has_process_item = for_def
93+ . do_
94+ . entries
95+ . iter ( )
96+ . any ( |entry| entry. contains_key ( "processItem" ) ) ;
97+ assert ! (
98+ has_process_item,
99+ "For task should contain processItem subtask"
100+ ) ;
101+ }
102+ Ok ( TaskDefinition :: Do ( _) ) => {
103+ panic ! ( "For task incorrectly deserialized as DoTaskDefinition" ) ;
104+ }
105+ Ok ( other) => {
106+ panic ! ( "For task deserialized as unexpected variant: {:?}" , other) ;
107+ }
108+ Err ( e) => {
109+ panic ! ( "Failed to deserialize For task: {}" , e) ;
110+ }
111+ }
112+ }
113+
114+ #[ test]
115+ fn test_do_task_deserialization ( ) {
116+ // This is a valid Do task
117+ let do_task_json = json ! ( {
118+ "do" : [
119+ {
120+ "step1" : {
121+ "call" : "function1"
122+ }
123+ } ,
124+ {
125+ "step2" : {
126+ "call" : "function2"
127+ }
128+ }
129+ ]
130+ } ) ;
131+
132+ let result: Result < TaskDefinition , _ > = serde_json:: from_value ( do_task_json) ;
133+
134+ match result {
135+ Ok ( TaskDefinition :: Do ( do_def) ) => {
136+ assert_eq ! ( do_def. do_. entries. len( ) , 2 ) ;
137+ let has_step1 = do_def
138+ . do_
139+ . entries
140+ . iter ( )
141+ . any ( |entry| entry. contains_key ( "step1" ) ) ;
142+ let has_step2 = do_def
143+ . do_
144+ . entries
145+ . iter ( )
146+ . any ( |entry| entry. contains_key ( "step2" ) ) ;
147+ assert ! ( has_step1, "Do task should contain step1" ) ;
148+ assert ! ( has_step2, "Do task should contain step2" ) ;
149+ }
150+ Ok ( other) => {
151+ panic ! ( "Do task deserialized as unexpected variant: {:?}" , other) ;
152+ }
153+ Err ( e) => {
154+ panic ! ( "Failed to deserialize Do task: {}" , e) ;
155+ }
156+ }
157+ }
158+
159+ #[ test]
160+ fn test_for_task_with_while_condition ( ) {
161+ // TestFor task with a while condition
162+ let for_task_json = json ! ( {
163+ "for" : {
164+ "each" : "user" ,
165+ "in" : ".users" ,
166+ "at" : "index"
167+ } ,
168+ "while" : "${ .index < 10 }" ,
169+ "do" : [
170+ {
171+ "notifyUser" : {
172+ "call" : "notifyUser" ,
173+ "with" : {
174+ "user" : "${ .user }" ,
175+ "index" : "${ .index }"
176+ }
177+ }
178+ }
179+ ]
180+ } ) ;
181+
182+ let result: Result < TaskDefinition , _ > = serde_json:: from_value ( for_task_json. clone ( ) ) ;
183+
184+ match result {
185+ Ok ( TaskDefinition :: For ( for_def) ) => {
186+ assert_eq ! ( for_def. for_. each, "user" ) ;
187+ assert_eq ! ( for_def. for_. in_, ".users" ) ;
188+ assert_eq ! ( for_def. for_. at, Some ( "index" . to_string( ) ) ) ;
189+ assert_eq ! ( for_def. while_, Some ( "${ .index < 10 }" . to_string( ) ) ) ;
190+ assert_eq ! ( for_def. do_. entries. len( ) , 1 ) ;
191+ }
192+ Ok ( TaskDefinition :: Do ( _) ) => {
193+ panic ! ( "For task incorrectly deserialized as DoTaskDefinition" ) ;
194+ }
195+ Ok ( other) => {
196+ panic ! ( "For task deserialized as unexpected variant: {:?}" , other) ;
197+ }
198+ Err ( e) => {
199+ panic ! ( "Failed to deserialize For task with while: {}" , e) ;
200+ }
201+ }
202+ }
203+
204+ #[ test]
205+ fn test_roundtrip_serialization ( ) {
206+ // Create a ForTaskDefinition programmatically
207+
208+ let for_loop = ForLoopDefinition :: new ( "item" , ".collection" , None , None ) ;
209+ let mut do_tasks = Map :: new ( ) ;
210+ do_tasks. add (
211+ "task1" . to_string ( ) ,
212+ TaskDefinition :: Call ( CallTaskDefinition :: new ( "someFunction" , None , None ) ) ,
213+ ) ;
214+
215+ let for_task = ForTaskDefinition :: new ( for_loop, do_tasks, None ) ;
216+ let task_def = TaskDefinition :: For ( for_task) ;
217+
218+ // Serialize to JSON
219+ let json_str = serde_json:: to_string ( & task_def) . expect ( "Failed to serialize" ) ;
220+ println ! ( "Serialized: {}" , json_str) ;
221+
222+ // Deserialize back
223+ let deserialized: TaskDefinition =
224+ serde_json:: from_str ( & json_str) . expect ( "Failed to deserialize" ) ;
225+
226+ // Should still be a For task
227+ match deserialized {
228+ TaskDefinition :: For ( for_def) => {
229+ assert_eq ! ( for_def. for_. each, "item" ) ;
230+ assert_eq ! ( for_def. for_. in_, ".collection" ) ;
231+ }
232+ TaskDefinition :: Do ( _) => {
233+ panic ! ( "After roundtrip serialization, For task became a Do task" ) ;
234+ }
235+ other => {
236+ panic ! ( "Unexpected variant after roundtrip: {:?}" , other) ;
237+ }
238+ }
239+ }
40240}
0 commit comments