1+ using  FluentAssertions ; 
2+ using  Kontent . Ai . Management . Models . LanguageVariants . Elements ; 
3+ using  Kontent . Ai . Management . Models . Shared ; 
4+ using  Kontent . Ai . Management . Models . Types . Elements ; 
5+ using  System ; 
6+ using  System . Linq ; 
7+ using  Xunit ; 
8+ 
9+ namespace  Kontent . Ai . Management . Tests . Modules . ModelBuilders ; 
10+ 
11+ /// <summary> 
12+ /// Tests for BaseElement round-trip conversion (element -> dynamic -> element). 
13+ /// </summary> 
14+ public  class  BaseElementRoundTripTests 
15+ { 
16+     [ Fact ] 
17+     public  void  TaxonomyElement_RoundTripConversion_WithByCodename_PreservesValues ( ) 
18+     { 
19+         // Arrange 
20+         var  original  =  new  TaxonomyElement 
21+         { 
22+             Element  =  Reference . ByCodename ( "taxonomy_element" ) , 
23+             Value  =  [ Reference . ByCodename ( "tag1" ) ,  Reference . ByCodename ( "tag2" ) ] 
24+         } ; 
25+ 
26+         // Act - Round trip conversion 
27+         var  dynamic  =  original . ToDynamic ( ) ; 
28+         var  converted  =  ( TaxonomyElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Taxonomy ) ; 
29+ 
30+         // Assert 
31+         converted . Element . Codename . Should ( ) . Be ( "taxonomy_element" ) ; 
32+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
33+         converted . Value . First ( ) . Codename . Should ( ) . Be ( "tag1" ) ; 
34+         converted . Value . Last ( ) . Codename . Should ( ) . Be ( "tag2" ) ; 
35+     } 
36+ 
37+     [ Fact ] 
38+     public  void  TaxonomyElement_RoundTripConversion_WithById_PreservesValues ( ) 
39+     { 
40+         // Arrange 
41+         var  guid1  =  Guid . NewGuid ( ) ; 
42+         var  guid2  =  Guid . NewGuid ( ) ; 
43+         var  elementGuid  =  Guid . NewGuid ( ) ; 
44+         var  original  =  new  TaxonomyElement 
45+         { 
46+             Element  =  Reference . ById ( elementGuid ) , 
47+             Value  =  [ Reference . ById ( guid1 ) ,  Reference . ById ( guid2 ) ] 
48+         } ; 
49+ 
50+         // Act 
51+         var  dynamic  =  original . ToDynamic ( ) ; 
52+         var  converted  =  ( TaxonomyElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Taxonomy ) ; 
53+ 
54+         // Assert 
55+         converted . Element . Id . Should ( ) . Be ( elementGuid ) ; 
56+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
57+         converted . Value . First ( ) . Id . Should ( ) . Be ( guid1 ) ; 
58+         converted . Value . Last ( ) . Id . Should ( ) . Be ( guid2 ) ; 
59+     } 
60+ 
61+     [ Fact ] 
62+     public  void  TaxonomyElement_RoundTripConversion_WithByExternalId_PreservesValues ( ) 
63+     { 
64+         // Arrange 
65+         var  original  =  new  TaxonomyElement 
66+         { 
67+             Element  =  Reference . ByExternalId ( "ext_taxonomy" ) , 
68+             Value  =  [ Reference . ByExternalId ( "ext_tag1" ) ,  Reference . ByExternalId ( "ext_tag2" ) ] 
69+         } ; 
70+ 
71+         // Act 
72+         var  dynamic  =  original . ToDynamic ( ) ; 
73+         var  converted  =  ( TaxonomyElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Taxonomy ) ; 
74+ 
75+         // Assert 
76+         converted . Element . ExternalId . Should ( ) . Be ( "ext_taxonomy" ) ; 
77+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
78+         converted . Value . First ( ) . ExternalId . Should ( ) . Be ( "ext_tag1" ) ; 
79+         converted . Value . Last ( ) . ExternalId . Should ( ) . Be ( "ext_tag2" ) ; 
80+     } 
81+ 
82+     [ Fact ] 
83+     public  void  TaxonomyElement_RoundTripConversion_MixedReferenceTypes_PreservesCorrectTypes ( ) 
84+     { 
85+         // Arrange 
86+         var  guid  =  Guid . NewGuid ( ) ; 
87+         var  original  =  new  TaxonomyElement 
88+         { 
89+             Element  =  Reference . ByCodename ( "taxonomy_element" ) , 
90+             Value  =  [  
91+                 Reference . ById ( guid ) ,  
92+                 Reference . ByCodename ( "codename_tag" ) , 
93+                 Reference . ByExternalId ( "external_tag" ) 
94+             ] 
95+         } ; 
96+ 
97+         // Act 
98+         var  dynamic  =  original . ToDynamic ( ) ; 
99+         var  converted  =  ( TaxonomyElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Taxonomy ) ; 
100+ 
101+         // Assert 
102+         var  values  =  converted . Value . ToArray ( ) ; 
103+         values [ 0 ] . Id . Should ( ) . Be ( guid ) ; 
104+         values [ 0 ] . Codename . Should ( ) . BeNull ( ) ; 
105+         values [ 0 ] . ExternalId . Should ( ) . BeNull ( ) ; 
106+         
107+         values [ 1 ] . Codename . Should ( ) . Be ( "codename_tag" ) ; 
108+         values [ 1 ] . Id . Should ( ) . BeNull ( ) ; 
109+         values [ 1 ] . ExternalId . Should ( ) . BeNull ( ) ; 
110+         
111+         values [ 2 ] . ExternalId . Should ( ) . Be ( "external_tag" ) ; 
112+         values [ 2 ] . Id . Should ( ) . BeNull ( ) ; 
113+         values [ 2 ] . Codename . Should ( ) . BeNull ( ) ; 
114+     } 
115+ 
116+     [ Fact ] 
117+     public  void  TaxonomyElement_RoundTripConversion_WithNullValue_HandlesGracefully ( ) 
118+     { 
119+         // Arrange 
120+         var  original  =  new  TaxonomyElement 
121+         { 
122+             Element  =  Reference . ByCodename ( "taxonomy_element" ) , 
123+             Value  =  null 
124+         } ; 
125+ 
126+         // Act 
127+         var  dynamic  =  original . ToDynamic ( ) ; 
128+         var  converted  =  ( TaxonomyElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Taxonomy ) ; 
129+ 
130+         // Assert 
131+         converted . Element . Codename . Should ( ) . Be ( "taxonomy_element" ) ; 
132+         converted . Value . Should ( ) . BeNull ( ) ; 
133+     } 
134+ 
135+     [ Fact ] 
136+     public  void  TaxonomyElement_RoundTripConversion_WithEmptyValue_HandlesGracefully ( ) 
137+     { 
138+         // Arrange 
139+         var  original  =  new  TaxonomyElement 
140+         { 
141+             Element  =  Reference . ByCodename ( "taxonomy_element" ) , 
142+             Value  =  [ ] 
143+         } ; 
144+ 
145+         // Act 
146+         var  dynamic  =  original . ToDynamic ( ) ; 
147+         var  converted  =  ( TaxonomyElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Taxonomy ) ; 
148+ 
149+         // Assert 
150+         converted . Element . Codename . Should ( ) . Be ( "taxonomy_element" ) ; 
151+         converted . Value . Should ( ) . BeEmpty ( ) ; 
152+     } 
153+ 
154+     [ Fact ] 
155+     public  void  LinkedItemsElement_RoundTripConversion_PreservesValues ( ) 
156+     { 
157+         // Arrange 
158+         var  original  =  new  LinkedItemsElement 
159+         { 
160+             Element  =  Reference . ByCodename ( "linked_items" ) , 
161+             Value  =  [ Reference . ByCodename ( "item1" ) ,  Reference . ByExternalId ( "ext_item2" ) ] 
162+         } ; 
163+ 
164+         // Act 
165+         var  dynamic  =  original . ToDynamic ( ) ; 
166+         var  converted  =  ( LinkedItemsElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . LinkedItems ) ; 
167+ 
168+         // Assert 
169+         converted . Element . Codename . Should ( ) . Be ( "linked_items" ) ; 
170+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
171+         converted . Value . First ( ) . Codename . Should ( ) . Be ( "item1" ) ; 
172+         converted . Value . Last ( ) . ExternalId . Should ( ) . Be ( "ext_item2" ) ; 
173+     } 
174+ 
175+     [ Fact ] 
176+     public  void  MultipleChoiceElement_RoundTripConversion_PreservesValues ( ) 
177+     { 
178+         // Arrange 
179+         var  original  =  new  MultipleChoiceElement 
180+         { 
181+             Element  =  Reference . ByCodename ( "multiple_choice" ) , 
182+             Value  =  [ Reference . ByCodename ( "option1" ) ,  Reference . ByCodename ( "option2" ) ] 
183+         } ; 
184+ 
185+         // Act 
186+         var  dynamic  =  original . ToDynamic ( ) ; 
187+         var  converted  =  ( MultipleChoiceElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . MultipleChoice ) ; 
188+ 
189+         // Assert 
190+         converted . Element . Codename . Should ( ) . Be ( "multiple_choice" ) ; 
191+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
192+         converted . Value . First ( ) . Codename . Should ( ) . Be ( "option1" ) ; 
193+         converted . Value . Last ( ) . Codename . Should ( ) . Be ( "option2" ) ; 
194+     } 
195+ 
196+     [ Fact ] 
197+     public  void  SubpagesElement_RoundTripConversion_PreservesValues ( ) 
198+     { 
199+         // Arrange 
200+         var  original  =  new  SubpagesElement 
201+         { 
202+             Element  =  Reference . ByCodename ( "subpages" ) , 
203+             Value  =  [ Reference . ByCodename ( "page1" ) ,  Reference . ByCodename ( "page2" ) ] 
204+         } ; 
205+ 
206+         // Act 
207+         var  dynamic  =  original . ToDynamic ( ) ; 
208+         var  converted  =  ( SubpagesElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Subpages ) ; 
209+ 
210+         // Assert 
211+         converted . Element . Codename . Should ( ) . Be ( "subpages" ) ; 
212+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
213+         converted . Value . First ( ) . Codename . Should ( ) . Be ( "page1" ) ; 
214+         converted . Value . Last ( ) . Codename . Should ( ) . Be ( "page2" ) ; 
215+     } 
216+ 
217+     [ Fact ] 
218+     public  void  AssetElement_RoundTripConversion_WithByCodename_PreservesValues ( ) 
219+     { 
220+         // Arrange 
221+         var  original  =  new  AssetElement 
222+         { 
223+             Element  =  Reference . ByCodename ( "asset_element" ) , 
224+             Value  =  [  
225+                 new  AssetWithRenditionsReference ( Reference . ByCodename ( "asset1" ) ,  [ Reference . ByCodename ( "rendition1" ) ] ) , 
226+                 new  AssetWithRenditionsReference ( Reference . ByCodename ( "asset2" ) ) 
227+             ] 
228+         } ; 
229+ 
230+         // Act 
231+         var  dynamic  =  original . ToDynamic ( ) ; 
232+         var  converted  =  ( AssetElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Asset ) ; 
233+ 
234+         // Assert 
235+         converted . Element . Codename . Should ( ) . Be ( "asset_element" ) ; 
236+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
237+         
238+         var  assets  =  converted . Value . ToArray ( ) ; 
239+         assets [ 0 ] . Codename . Should ( ) . Be ( "asset1" ) ; 
240+         assets [ 0 ] . Renditions . Should ( ) . HaveCount ( 1 ) ; 
241+         assets [ 0 ] . Renditions . First ( ) . Codename . Should ( ) . Be ( "rendition1" ) ; 
242+         
243+         assets [ 1 ] . Codename . Should ( ) . Be ( "asset2" ) ; 
244+         assets [ 1 ] . Renditions . Should ( ) . BeEmpty ( ) ; 
245+     } 
246+ 
247+     [ Fact ] 
248+     public  void  AssetElement_RoundTripConversion_WithById_PreservesValues ( ) 
249+     { 
250+         // Arrange 
251+         var  elementGuid  =  Guid . NewGuid ( ) ; 
252+         var  asset1Guid  =  Guid . NewGuid ( ) ; 
253+         var  asset2Guid  =  Guid . NewGuid ( ) ; 
254+         var  rendition1Guid  =  Guid . NewGuid ( ) ; 
255+         var  rendition2Guid  =  Guid . NewGuid ( ) ; 
256+         
257+         var  original  =  new  AssetElement 
258+         { 
259+             Element  =  Reference . ById ( elementGuid ) , 
260+             Value  =  [  
261+                 new  AssetWithRenditionsReference ( Reference . ById ( asset1Guid ) ,  [ Reference . ById ( rendition1Guid ) ,  Reference . ById ( rendition2Guid ) ] ) , 
262+                 new  AssetWithRenditionsReference ( Reference . ById ( asset2Guid ) ) 
263+             ] 
264+         } ; 
265+ 
266+         // Act 
267+         var  dynamic  =  original . ToDynamic ( ) ; 
268+         var  converted  =  ( AssetElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Asset ) ; 
269+ 
270+         // Assert 
271+         converted . Element . Id . Should ( ) . Be ( elementGuid ) ; 
272+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
273+         
274+         var  assets  =  converted . Value . ToArray ( ) ; 
275+         assets [ 0 ] . Id . Should ( ) . Be ( asset1Guid ) ; 
276+         assets [ 0 ] . Renditions . Should ( ) . HaveCount ( 2 ) ; 
277+         assets [ 0 ] . Renditions . First ( ) . Id . Should ( ) . Be ( rendition1Guid ) ; 
278+         assets [ 0 ] . Renditions . Last ( ) . Id . Should ( ) . Be ( rendition2Guid ) ; 
279+         
280+         assets [ 1 ] . Id . Should ( ) . Be ( asset2Guid ) ; 
281+         assets [ 1 ] . Renditions . Should ( ) . BeEmpty ( ) ; 
282+     } 
283+ 
284+     [ Fact ] 
285+     public  void  AssetElement_RoundTripConversion_WithByExternalId_PreservesValues ( ) 
286+     { 
287+         // Arrange 
288+         var  original  =  new  AssetElement 
289+         { 
290+             Element  =  Reference . ByExternalId ( "ext_asset_element" ) , 
291+             Value  =  [  
292+                 new  AssetWithRenditionsReference ( Reference . ByExternalId ( "ext_asset1" ) ,  [ Reference . ByExternalId ( "ext_rendition1" ) ] ) , 
293+                 new  AssetWithRenditionsReference ( Reference . ByExternalId ( "ext_asset2" ) ) 
294+             ] 
295+         } ; 
296+ 
297+         // Act 
298+         var  dynamic  =  original . ToDynamic ( ) ; 
299+         var  converted  =  ( AssetElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Asset ) ; 
300+ 
301+         // Assert 
302+         converted . Element . ExternalId . Should ( ) . Be ( "ext_asset_element" ) ; 
303+         converted . Value . Should ( ) . HaveCount ( 2 ) ; 
304+         
305+         var  assets  =  converted . Value . ToArray ( ) ; 
306+         assets [ 0 ] . ExternalId . Should ( ) . Be ( "ext_asset1" ) ; 
307+         assets [ 0 ] . Renditions . Should ( ) . HaveCount ( 1 ) ; 
308+         assets [ 0 ] . Renditions . First ( ) . ExternalId . Should ( ) . Be ( "ext_rendition1" ) ; 
309+         
310+         assets [ 1 ] . ExternalId . Should ( ) . Be ( "ext_asset2" ) ; 
311+         assets [ 1 ] . Renditions . Should ( ) . BeEmpty ( ) ; 
312+     } 
313+ 
314+     [ Fact ] 
315+     public  void  AssetElement_RoundTripConversion_MixedReferenceTypes_PreservesCorrectTypes ( ) 
316+     { 
317+         // Arrange 
318+         var  assetGuid  =  Guid . NewGuid ( ) ; 
319+         var  renditionGuid  =  Guid . NewGuid ( ) ; 
320+         
321+         var  original  =  new  AssetElement 
322+         { 
323+             Element  =  Reference . ByCodename ( "asset_element" ) , 
324+             Value  =  [  
325+                 new  AssetWithRenditionsReference ( Reference . ById ( assetGuid ) ,  [ Reference . ByCodename ( "rendition_codename" ) ] ) , 
326+                 new  AssetWithRenditionsReference ( Reference . ByCodename ( "asset_codename" ) ,  [ Reference . ById ( renditionGuid ) ] ) , 
327+                 new  AssetWithRenditionsReference ( Reference . ByExternalId ( "ext_asset" ) ,  [ Reference . ByExternalId ( "ext_rendition" ) ] ) 
328+             ] 
329+         } ; 
330+ 
331+         // Act 
332+         var  dynamic  =  original . ToDynamic ( ) ; 
333+         var  converted  =  ( AssetElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Asset ) ; 
334+ 
335+         // Assert 
336+         var  assets  =  converted . Value . ToArray ( ) ; 
337+         
338+         // First asset: ById with ByCodename rendition 
339+         assets [ 0 ] . Id . Should ( ) . Be ( assetGuid ) ; 
340+         assets [ 0 ] . Codename . Should ( ) . BeNull ( ) ; 
341+         assets [ 0 ] . ExternalId . Should ( ) . BeNull ( ) ; 
342+         assets [ 0 ] . Renditions . First ( ) . Codename . Should ( ) . Be ( "rendition_codename" ) ; 
343+         
344+         // Second asset: ByCodename with ById rendition 
345+         assets [ 1 ] . Codename . Should ( ) . Be ( "asset_codename" ) ; 
346+         assets [ 1 ] . Id . Should ( ) . BeNull ( ) ; 
347+         assets [ 1 ] . ExternalId . Should ( ) . BeNull ( ) ; 
348+         assets [ 1 ] . Renditions . First ( ) . Id . Should ( ) . Be ( renditionGuid ) ; 
349+         
350+         // Third asset: ByExternalId with ByExternalId rendition 
351+         assets [ 2 ] . ExternalId . Should ( ) . Be ( "ext_asset" ) ; 
352+         assets [ 2 ] . Id . Should ( ) . BeNull ( ) ; 
353+         assets [ 2 ] . Codename . Should ( ) . BeNull ( ) ; 
354+         assets [ 2 ] . Renditions . First ( ) . ExternalId . Should ( ) . Be ( "ext_rendition" ) ; 
355+     } 
356+ 
357+     [ Fact ] 
358+     public  void  AssetElement_RoundTripConversion_WithNullValue_HandlesGracefully ( ) 
359+     { 
360+         // Arrange 
361+         var  original  =  new  AssetElement 
362+         { 
363+             Element  =  Reference . ByCodename ( "asset_element" ) , 
364+             Value  =  null 
365+         } ; 
366+ 
367+         // Act 
368+         var  dynamic  =  original . ToDynamic ( ) ; 
369+         var  converted  =  ( AssetElement ) BaseElement . FromDynamic ( dynamic ,  ElementMetadataType . Asset ) ; 
370+ 
371+         // Assert 
372+         converted . Element . Codename . Should ( ) . Be ( "asset_element" ) ; 
373+         converted . Value . Should ( ) . BeNull ( ) ; 
374+     } 
375+ }  
0 commit comments