Skip to content

Commit 39a3f81

Browse files
committed
fix BaseElement FromDynamic, update tests, add roundtrip tests
1 parent 7c1a35b commit 39a3f81

File tree

3 files changed

+388
-17
lines changed

3 files changed

+388
-17
lines changed
Lines changed: 375 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,375 @@
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

Comments
 (0)