Skip to content

Commit

Permalink
SendPrimitiveAsync throws InvalidOperationException for enums
Browse files Browse the repository at this point in the history
  • Loading branch information
MartinM85 committed Jul 12, 2024
1 parent a84c42f commit 17afac7
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 53 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.9.9] - 2024-07-11
## [1.9.9] - 2024-07-12

- Fix enum deserialization for SendPrimitiveAsync and
- Fix enum deserialization for SendPrimitiveAsync and SendPrimitiveCollectionAsync

## [1.9.8] - 2024-07-08

Expand Down
43 changes: 0 additions & 43 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -10,47 +10,4 @@
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- Common project properties for PACKAGED projects TO BE RELEASED-->
<PropertyGroup Condition="('$(IsTestProject)' != 'true') and ('$(IsAnalyzerProject)' != 'true')">
<Authors>Microsoft</Authors>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<PackageIconUrl>http://go.microsoft.com/fwlink/?LinkID=288890</PackageIconUrl>
<RepositoryUrl>https://github.com/microsoft/kiota-dotnet</RepositoryUrl>
<PackageProjectUrl>https://aka.ms/kiota/docs</PackageProjectUrl>
<PackageReleaseNotes>
https://github.com/microsoft/kiota-dotnet/releases
</PackageReleaseNotes>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<Deterministic>true</Deterministic>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<SignAssembly>false</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);NU5048;NETSDK1138</NoWarn>
<IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)','net5.0'))">true</IsTrimmable>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)','net8.0'))">true</IsAotCompatible>
<ContinuousIntegrationBuild Condition="'$(TF_BUILD)' == 'true'">true</ContinuousIntegrationBuild>
</PropertyGroup>
<!-- Common project properties for TEST projects-->
<PropertyGroup Condition="'$(IsTestProject)' == 'true'">
<IsPackable>false</IsPackable>
<OutputType>Library</OutputType>
</PropertyGroup>
<!-- Include ReadMe.md for PACKAGED projects TO BE RELEASED-->
<ItemGroup Condition="('$(IsTestProject)' != 'true') and ('$(IsAnalyzerProject)' != 'true')">
<None Include="README.md">
<Pack>True</Pack>
<PackagePath>
</PackagePath>
</None>
</ItemGroup>
<!-- Include SourceLink Dependency for packages TO BE RELEASED-->
<ItemGroup Condition="('$(IsTestProject)' != 'true') and ('$(IsAnalyzerProject)' != 'true')">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
</ItemGroup>
</Project>
50 changes: 50 additions & 0 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<Project>
<PropertyGroup>
<VersionPrefix>1.9.9</VersionPrefix>
<VersionSuffix></VersionSuffix>
<!-- This is overidden in test projects by setting to true-->
<IsTestProject>false</IsTestProject>
<!-- This is overidden in test projects by setting to true-->
<IsAnalyzerProject>false</IsAnalyzerProject>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
<!-- Common project properties for PACKAGED projects TO BE RELEASED-->
<PropertyGroup Condition="('$(IsTestProject)' != 'true') and ('$(IsAnalyzerProject)' != 'true')">
<Authors>Microsoft</Authors>
<Copyright>© Microsoft Corporation. All rights reserved.</Copyright>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<PackageIconUrl>http://go.microsoft.com/fwlink/?LinkID=288890</PackageIconUrl>
<RepositoryUrl>https://github.com/microsoft/kiota-dotnet</RepositoryUrl>
<PackageProjectUrl>https://aka.ms/kiota/docs</PackageProjectUrl>
<PackageReleaseNotes>
https://github.com/microsoft/kiota-dotnet/releases
</PackageReleaseNotes>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageReadmeFile>README.md</PackageReadmeFile>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<Deterministic>true</Deterministic>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<SignAssembly>false</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>35MSSharedLib1024.snk</AssemblyOriginatorKeyFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>$(NoWarn);NU5048;NETSDK1138</NoWarn>
<IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)','net5.0'))">true</IsTrimmable>
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)','net8.0'))">true</IsAotCompatible>
<ContinuousIntegrationBuild Condition="'$(TF_BUILD)' == 'true'">true</ContinuousIntegrationBuild>
</PropertyGroup>
<!-- Include ReadMe.md for PACKAGED projects TO BE RELEASED-->
<ItemGroup Condition="('$(IsTestProject)' != 'true') and ('$(IsAnalyzerProject)' != 'true')">
<None Include="README.md">
<Pack>True</Pack>
<PackagePath>
</PackagePath>
</None>
</ItemGroup>
<!-- Include SourceLink Dependency for packages TO BE RELEASED-->
<ItemGroup Condition="('$(IsTestProject)' != 'true') and ('$(IsAnalyzerProject)' != 'true')">
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PrivateAssets="All" />
</ItemGroup>
</Project>
18 changes: 10 additions & 8 deletions src/abstractions/Helpers/EnumHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,46 +86,48 @@ private static ReadOnlySpan<char> ToEnumRawName<T>(ReadOnlySpan<char> span) wher
{
return null;
}
if(type.IsDefined(typeof(FlagsAttribute)))
Type enumType = (Nullable.GetUnderlyingType(type) is { IsEnum: true } underlyingType) ? underlyingType : type;
if(enumType.IsDefined(typeof(FlagsAttribute)))
{
int intValue = 0;
while(rawValue.Length > 0)
{
int commaIndex = rawValue.IndexOf(',');
var valueName = commaIndex < 0 ? rawValue : rawValue.Substring(0, commaIndex);
if(Nullable.GetUnderlyingType(type) is { IsEnum: true } underlyingType && TryGetFieldValueName(underlyingType, valueName, out var value))
if(TryGetFieldValueName(enumType, valueName, out var value))
{
valueName = value;
}
#if NET5_0_OR_GREATER
if(Enum.TryParse(type, valueName, true, out var enumPartResult))
if(Enum.TryParse(enumType, valueName, true, out var enumPartResult))
intValue |= (int)enumPartResult!;
#else
try
{
intValue |= (int)Enum.Parse(type, valueName, true);
intValue |= (int)Enum.Parse(enumType, valueName, true);
}
catch { }
#endif

rawValue = commaIndex < 0 ? string.Empty : rawValue.Substring(commaIndex + 1);
}
result = intValue > 0 ? Enum.Parse(type, intValue.ToString(), true) : null;
result = intValue > 0 ? Enum.Parse(enumType, intValue.ToString(), true) : null;
}
else
{
if(Nullable.GetUnderlyingType(type) is { IsEnum: true } underlyingType && TryGetFieldValueName(underlyingType, rawValue, out var value))

if(TryGetFieldValueName(enumType, rawValue, out var value))
{
rawValue = value;
}

#if NET5_0_OR_GREATER
Enum.TryParse(type, rawValue, true, out object? enumResult);
Enum.TryParse(enumType, rawValue, true, out object? enumResult);
result = enumResult;
#else
try
{
result = Enum.Parse(type, rawValue, true);
result = Enum.Parse(enumType, rawValue, true);
}
catch
{
Expand Down
56 changes: 56 additions & 0 deletions tests/abstractions/EnumHelperTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,14 @@ public void EnumIsParsedIfValueIsInteger()
Assert.Equal(TestEnum.First, result);
}

[Fact]
public void NullableEnumIsParsedIfValueIsInteger()
{
var result = EnumHelpers.GetEnumValue(typeof(TestEnum?), "0");

Assert.Equal(TestEnum.First, result);
}

[Fact]
public void EnumWithFlagsIsParsedIfValuesAreIntegers()
{
Expand All @@ -78,6 +86,14 @@ public void EnumWithFlagsIsParsedIfValuesAreIntegers()
Assert.Equal(TestEnumWithFlags.Value1 | TestEnumWithFlags.Value2, result);
}

[Fact]
public void NullableEnumWithFlagsIsParsedIfValuesAreIntegers()
{
var result = EnumHelpers.GetEnumValue(typeof(TestEnumWithFlags?), "1,2");

Assert.Equal(TestEnumWithFlags.Value1 | TestEnumWithFlags.Value2, result);
}

[Fact]
public void EnumIsParsedIfValueIsString()
{
Expand All @@ -86,6 +102,14 @@ public void EnumIsParsedIfValueIsString()
Assert.Equal(TestEnum.First, result);
}

[Fact]
public void NullableEnumIsParsedIfValueIsString()
{
var result = EnumHelpers.GetEnumValue(typeof(TestEnum?), "First");

Assert.Equal(TestEnum.First, result);
}

[Fact]
public void EnumWithFlagsIsParsedIfValuesAreStrings()
{
Expand All @@ -94,6 +118,14 @@ public void EnumWithFlagsIsParsedIfValuesAreStrings()
Assert.Equal(TestEnumWithFlags.Value1 | TestEnumWithFlags.Value3, result);
}

[Fact]
public void NullableEnumWithFlagsIsParsedIfValuesAreStrings()
{
var result = EnumHelpers.GetEnumValue(typeof(TestEnumWithFlags?), "Value1,Value3");

Assert.Equal(TestEnumWithFlags.Value1 | TestEnumWithFlags.Value3, result);
}

[Fact]
public void EnumIsParsedIfValueIsFromEnumMember()
{
Expand All @@ -102,6 +134,14 @@ public void EnumIsParsedIfValueIsFromEnumMember()
Assert.Equal(TestEnum.Second, result);
}

[Fact]
public void NullableEnumIsParsedIfValueIsFromEnumMember()
{
var result = EnumHelpers.GetEnumValue(typeof(TestEnum?), "Value_2");

Assert.Equal(TestEnum.Second, result);
}

[Fact]
public void EnumWithFlagsIsParsedIfValuesAreFromEnumMember()
{
Expand All @@ -110,12 +150,28 @@ public void EnumWithFlagsIsParsedIfValuesAreFromEnumMember()
Assert.Equal(TestEnumWithFlags.Value2 | TestEnumWithFlags.Value3, result);
}

[Fact]
public void NullableEnumWithFlagsIsParsedIfValuesAreFromEnumMember()
{
var result = EnumHelpers.GetEnumValue(typeof(TestEnumWithFlags?), "Value__2,Value__3");

Assert.Equal(TestEnumWithFlags.Value2 | TestEnumWithFlags.Value3, result);
}

[Fact]
public void IfEnumIsNotParsedThenNullIsReturned()
{
var result = EnumHelpers.GetEnumValue(typeof(TestEnum), "Value_5");

Assert.Null(result);
}

[Fact]
public void IfNullableEnumIsNotParsedThenNullIsReturned()
{
var result = EnumHelpers.GetEnumValue(typeof(TestEnum?), "Value_5");

Assert.Null(result);
}
}
}
Loading

0 comments on commit 17afac7

Please sign in to comment.