Skip to content
This repository has been archived by the owner on Jul 9, 2024. It is now read-only.

SendPrimitiveAsync throws InvalidOperationException for enums #266

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [1.4.4] - 2024-06-21

### Changed

- Fixes handling enums by `SendPrimitiveAsync`

## [1.4.3] - 2024-05-24

### Changed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,5 +535,75 @@ public async Task ThrowsApiExceptionOnMissingMapping(HttpStatusCode statusCode)
Assert.Contains("The server returned an unexpected status code and no error factory is registered for this code", apiException.Message);
}
}

[Fact]
public async Task SendMethodHandleEnumIfValueIsString()
{
var mockHandler = new Mock<HttpMessageHandler>();
var client = new HttpClient(mockHandler.Object);
mockHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("Value1")
});

var mockParseNode = new Mock<IParseNode>();
mockParseNode.Setup(x => x.GetStringValue())
.Returns("Value1");

var mockParseNodeFactory = new Mock<IAsyncParseNodeFactory>();
mockParseNodeFactory.Setup(x => x.GetRootParseNodeAsync(It.IsAny<string>(), It.IsAny<Stream>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(mockParseNode.Object));
var adapter = new HttpClientRequestAdapter(_authenticationProvider, mockParseNodeFactory.Object, httpClient: client);
var requestInfo = new RequestInformation
{
HttpMethod = Method.GET,
URI = new Uri("https://example.com")
};

var response = await adapter.SendPrimitiveAsync<TestEnum?>(requestInfo);

Assert.Equal(TestEnum.Value1, response);
}

[Fact]
public async Task SendMethodHandleEnumIfValueIsInteger()
{
var mockHandler = new Mock<HttpMessageHandler>();
var client = new HttpClient(mockHandler.Object);
mockHandler.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content = new StringContent("1")
});

var mockParseNode = new Mock<IParseNode>();
mockParseNode.Setup(x => x.GetStringValue())
.Returns("1");

var mockParseNodeFactory = new Mock<IAsyncParseNodeFactory>();
mockParseNodeFactory.Setup(x => x.GetRootParseNodeAsync(It.IsAny<string>(), It.IsAny<Stream>(), It.IsAny<CancellationToken>()))
.Returns(Task.FromResult(mockParseNode.Object));
var adapter = new HttpClientRequestAdapter(_authenticationProvider, mockParseNodeFactory.Object, httpClient: client);
var requestInfo = new RequestInformation
{
HttpMethod = Method.GET,
URI = new Uri("https://example.com")
};

var response = await adapter.SendPrimitiveAsync<TestEnum?>(requestInfo);

Assert.Equal(TestEnum.Value2, response);
}
}

public enum TestEnum
{
Value1,
Value2
MartinM85 marked this conversation as resolved.
Show resolved Hide resolved
}
}
14 changes: 13 additions & 1 deletion src/HttpClientRequestAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,19 @@ public string? BaseUrl
{
result = rootNode.GetDateValue();
}
else throw new InvalidOperationException("error handling the response, unexpected type");
else
{
var underlyingType = Nullable.GetUnderlyingType(modelType);
if(underlyingType != null && underlyingType.IsEnum)
{
var rawValue = rootNode.GetStringValue();
result = Enum.Parse(underlyingType, rawValue!, true);
}
else
{
throw new InvalidOperationException("error handling the response, unexpected type");
}
}
MartinM85 marked this conversation as resolved.
Show resolved Hide resolved
SetResponseType(result, span);
return (ModelType)result!;
}
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.Kiota.Http.HttpClientLibrary.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageProjectUrl>https://aka.ms/kiota/docs</PackageProjectUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<Deterministic>true</Deterministic>
<VersionPrefix>1.4.3</VersionPrefix>
<VersionPrefix>1.4.4</VersionPrefix>
<VersionSuffix></VersionSuffix>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<!-- Enable this line once we go live to prevent breaking changes -->
Expand Down