diff --git a/test/RestSharp.Tests.Serializers.Xml/SampleClasses/NestedCategorySamples.cs b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/NestedCategorySamples.cs new file mode 100644 index 000000000..ccbbf8f9c --- /dev/null +++ b/test/RestSharp.Tests.Serializers.Xml/SampleClasses/NestedCategorySamples.cs @@ -0,0 +1,16 @@ +namespace RestSharp.Tests.Serializers.Xml.SampleClasses; + +public class Category { + public int Id { get; set; } + public string Name { get; set; } + public List Subcategories { get; set; } = new(); +} + +public class CategoryRoot { + public List Categories { get; set; } = new(); +} + +// This class derives from List and will trigger HandleListDerivative +public class CategoryList : List { + public int TotalCount { get; set; } +} diff --git a/test/RestSharp.Tests.Serializers.Xml/XmlDeserializerTests.cs b/test/RestSharp.Tests.Serializers.Xml/XmlDeserializerTests.cs index 5f26af53b..6df1cff18 100644 --- a/test/RestSharp.Tests.Serializers.Xml/XmlDeserializerTests.cs +++ b/test/RestSharp.Tests.Serializers.Xml/XmlDeserializerTests.cs @@ -1076,4 +1076,161 @@ public void Ignore_ReadOnly_Property_That_Exists_In_Data() { Assert.Null(p.ReadOnlyProxy); } + + [Fact] + public void Should_Not_Include_Nested_Elements_In_List_Deserialization() { + const string xml = @" + + + + 1 + Main Category + + + 2 + Sub Category 1 + + + 3 + Sub Category 2 + + + + +"; + + var deserializer = new XmlDeserializer(); + var result = deserializer.Deserialize(new() { Content = xml })!; + + // Should only have 1 category (the main one), not 3 (including nested ones) + Assert.NotNull(result.Categories); + Assert.Single(result.Categories); + Assert.Equal(1, result.Categories[0].Id); + Assert.Equal("Main Category", result.Categories[0].Name); + + // The nested subcategories should be deserialized correctly + Assert.NotNull(result.Categories[0].Subcategories); + Assert.Equal(2, result.Categories[0].Subcategories.Count); + Assert.Equal(2, result.Categories[0].Subcategories[0].Id); + Assert.Equal("Sub Category 1", result.Categories[0].Subcategories[0].Name); + Assert.Equal(3, result.Categories[0].Subcategories[1].Id); + Assert.Equal("Sub Category 2", result.Categories[0].Subcategories[1].Name); + } + + [Fact] + public void Should_Deserialize_List_With_Container_Element() { + const string xml = @" + + + + 1 + Category 1 + + + 2 + Category 2 + + +"; + + var deserializer = new XmlDeserializer(); + var result = deserializer.Deserialize(new() { Content = xml })!; + + Assert.NotNull(result.Categories); + Assert.Equal(2, result.Categories.Count); + Assert.Equal(1, result.Categories[0].Id); + Assert.Equal("Category 1", result.Categories[0].Name); + Assert.Equal(2, result.Categories[1].Id); + Assert.Equal("Category 2", result.Categories[1].Name); + } + + [Fact] + public void Should_Handle_Empty_List_With_Container() { + const string xml = @" + + + +"; + + var deserializer = new XmlDeserializer(); + var result = deserializer.Deserialize(new() { Content = xml })!; + + Assert.NotNull(result.Categories); + Assert.Empty(result.Categories); + } + + [Fact] + public void Should_Handle_Missing_Container_Element() { + const string xml = @" + +"; + + var deserializer = new XmlDeserializer(); + var result = deserializer.Deserialize(new() { Content = xml })!; + + Assert.NotNull(result.Categories); + Assert.Empty(result.Categories); + } + + [Fact] + public void Should_Not_Include_Nested_Elements_When_Deserializing_To_List_Directly() { + // This test demonstrates the actual bug in HandleListDerivative + const string xml = @" + + + 1 + Main Category + + + 2 + Sub Category 1 + + + 3 + Sub Category 2 + + + +"; + + var deserializer = new XmlDeserializer(); + var result = deserializer.Deserialize>(new() { Content = xml })!; + + // Should only have 1 category (the main one), not 3 (including nested ones) + Assert.NotNull(result); + Assert.Single(result); + Assert.Equal(1, result[0].Id); + Assert.Equal("Main Category", result[0].Name); + } + + [Fact] + public void Should_Not_Include_Nested_Elements_When_Using_List_Derivative() { + // This test uses a class that derives from List, which triggers HandleListDerivative + const string xml = @" + + + 1 + Main Category + + + 2 + Sub Category 1 + + + 3 + Sub Category 2 + + + +"; + + var deserializer = new XmlDeserializer(); + var result = deserializer.Deserialize(new() { Content = xml })!; + + // Should only have 1 category (the main one), not 3 (including nested ones) + Assert.NotNull(result); + Assert.Single(result); + Assert.Equal(1, result[0].Id); + Assert.Equal("Main Category", result[0].Name); + } } \ No newline at end of file