From 2f2e250ab2d75129fc9f4e21b4225d7fb1acca85 Mon Sep 17 00:00:00 2001 From: Luca Mazzanti Date: Fri, 7 May 2021 01:23:53 +0200 Subject: [PATCH] [csharp-netcore][httpclient] Issues managing error statuses (#9389) * [csharp-netcore] correct rawContent read * [csharp-netcore] avoid deserialize result when in error * [csharp-netcore] avoid aggregate exceptions * Updated samples * Updated samples * Refactored PetApiTest * Updated samples * Fixed test issues * reverted previous commit --- .../libraries/httpclient/ApiClient.mustache | 25 +- .../Org.OpenAPITools.Test/Api/PetApiTests.cs | 40 +- .../Api/PetApiTestsV2.cs | 579 ++++++++++++++++++ .../Org.OpenAPITools.Test.csproj | 11 +- .../src/Org.OpenAPITools/Client/ApiClient.cs | 25 +- 5 files changed, 652 insertions(+), 28 deletions(-) create mode 100644 samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTestsV2.cs diff --git a/modules/openapi-generator/src/main/resources/csharp-netcore/libraries/httpclient/ApiClient.mustache b/modules/openapi-generator/src/main/resources/csharp-netcore/libraries/httpclient/ApiClient.mustache index 640e0335c119..5477cb0cc73d 100644 --- a/modules/openapi-generator/src/main/resources/csharp-netcore/libraries/httpclient/ApiClient.mustache +++ b/modules/openapi-generator/src/main/resources/csharp-netcore/libraries/httpclient/ApiClient.mustache @@ -98,13 +98,13 @@ namespace {{packageName}}.Client if (type == typeof(byte[])) // return byte array { - return response.Content.ReadAsByteArrayAsync().Result; + return response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult(); } // TODO: ? if (type.IsAssignableFrom(typeof(Stream))) if (type == typeof(Stream)) { - var bytes = response.Content.ReadAsByteArrayAsync().Result; + var bytes = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult(); if (headers != null) { var filePath = String.IsNullOrEmpty(_configuration.TempFolderPath) @@ -128,18 +128,18 @@ namespace {{packageName}}.Client if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content.ReadAsStringAsync().Result, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), null, System.Globalization.DateTimeStyles.RoundtripKind); } if (type == typeof(String) || type.Name.StartsWith("System.Nullable")) // return primitive type { - return Convert.ChangeType(response.Content.ReadAsStringAsync().Result, type); + return Convert.ChangeType(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), type); } // at this point, it must be a model (json) try { - return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result, type, _serializerSettings); + return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), type, _serializerSettings); } catch (Exception e) { @@ -401,10 +401,10 @@ namespace {{packageName}}.Client partial void InterceptRequest(HttpRequestMessage req); partial void InterceptResponse(HttpRequestMessage req, HttpResponseMessage response); - private ApiResponse ToApiResponse(HttpResponseMessage response, object responseData, Uri uri) + private async Task> ToApiResponse(HttpResponseMessage response, object responseData, Uri uri) { T result = (T) responseData; - string rawContent = response.Content.ToString(); + string rawContent = await response.Content.ReadAsStringAsync(); var transformed = new ApiResponse(response.StatusCode, new Multimap({{#caseInsensitiveResponseHeaders}}StringComparer.OrdinalIgnoreCase{{/caseInsensitiveResponseHeaders}}), result, rawContent) { @@ -446,7 +446,7 @@ namespace {{packageName}}.Client private ApiResponse Exec(HttpRequestMessage req, IReadableConfiguration configuration) { - return ExecAsync(req, configuration).Result; + return ExecAsync(req, configuration).GetAwaiter().GetResult(); } private async Task> ExecAsync(HttpRequestMessage req, @@ -511,6 +511,11 @@ namespace {{packageName}}.Client } {{/supportsRetry}} + if (!response.IsSuccessStatusCode) + { + return await ToApiResponse(response, default(T), req.RequestUri); + } + object responseData = deserializer.Deserialize(response); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data @@ -525,9 +530,7 @@ namespace {{packageName}}.Client InterceptResponse(req, response); - var result = ToApiResponse(response, responseData, req.RequestUri); - - return result; + return await ToApiResponse(response, responseData, req.RequestUri); } {{#supportsAsync}} diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTests.cs b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTests.cs index 04ef8503f955..1af712abb4d0 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTests.cs +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTests.cs @@ -36,6 +36,7 @@ public class PetApiTests : IDisposable private PetApi instance; private long petId = 11088; + private long notExsistentPetId = 99999; /// /// Create a Pet object @@ -204,6 +205,25 @@ public void TestGetPetByIdAsync() Assert.Equal("sample category name2", response.Category.Name); } + /// + /// Test GetPetById on an not existent Id + /// + [Fact] + public void TestGetPetById_TestException() + { + PetApi petApi = new PetApi(); + + var exception = Assert.Throws(() => + { + petApi.GetPetById(notExsistentPetId); + }); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.ErrorContent); + Assert.Equal("Error calling GetPetById: {\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.Message); + } + /* a simple test for binary response. no longer in use. [Fact] public void TestGetByIdBinaryResponse() @@ -247,7 +267,25 @@ public void TestGetPetByIdWithHttpInfoAsync() Assert.Equal(56, response.Category.Id); Assert.Equal("sample category name2", response.Category.Name); } - + + [Fact] + public void TestGetPetByIdWithHttpInfoAsync_Test404Response() + { + PetApi petApi = new PetApi(); + petApi.ExceptionFactory = null; + var response = petApi.GetPetByIdWithHttpInfoAsync(notExsistentPetId).Result; + Pet result = response.Data; + + Assert.IsType>(response); + Assert.Equal(404, (int)response.StatusCode); + Assert.True(response.Headers.ContainsKey("Content-Type")); + Assert.Equal("application/json", response.Headers["Content-Type"][0]); + + Assert.Null(result); + Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", response.RawContent); + Assert.Equal("Not Found", response.ErrorText); + } + /// /// Test UpdatePet /// diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTestsV2.cs b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTestsV2.cs new file mode 100644 index 000000000000..e00f3d614671 --- /dev/null +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Api/PetApiTestsV2.cs @@ -0,0 +1,579 @@ +/* + * OpenAPI Petstore + * + * This spec is mainly for testing Petstore server and contains fake endpoints, models. Please do not use this for any other purpose. Special characters: \" \\ + * + * OpenAPI spec version: 1.0.0 + * + * Generated by: https://github.com/openapitools/openapi-generator.git + */ +using Org.OpenAPITools.Api; +using Org.OpenAPITools.Client; +using Org.OpenAPITools.Model; +using System; +using System.Collections.Generic; +using System.IO; +using System.Net.Http; +using System.Reflection; +using System.Threading.Tasks; +using Xunit; + +namespace Org.OpenAPITools.Test.Api +{ + /// + /// Class for testing PetApi + /// + /// + /// This file is automatically generated by OpenAPI Generator (https://openapi-generator.tech). + /// Please update the test case below to test the API endpoint. + /// + public class PetApiTestsV2 : IDisposable + { + // CONFIGURE TESTING PARAMETERS HERE + // see the Integration Test Wiki for details: https://github.com/OpenAPITools/openapi-generator/wiki/Integration-Tests + private const string BasePath = "http://petstore.swagger.io/v2"; + private const long PetId = 100000; + private const long NotExistentId = 100001; + + private readonly HttpClient _httpClient = new HttpClient(); + private readonly PetApi _petApi; + + public PetApiTestsV2() + { + // prepare the client + _petApi = new PetApi(_httpClient, new Configuration + { + BasePath = BasePath, + Timeout = 10000, + UserAgent = "TEST_USER_AGENT" + }); + + // add a sample pet for the expected PetId + _petApi.AddPet(BuildSamplePet()); + + // ensure there is not a pet for that ID + try + { + _petApi.DeletePet(NotExistentId); + } + catch (ApiException ex) when (ex.ErrorCode == 404) { } + } + + #region Get + + /// + /// Test GetPetById with an existent Id + /// + [Fact] + public void GetPetById_GivenExistentId_ReturnsPet() + { + Pet expected = BuildSamplePet(); + + Pet response = _petApi.GetPetById(PetId); + + Assert.IsType(response); + Assert.Equal(expected.Name, response.Name); + Assert.Equal(expected.Status, response.Status); + Assert.IsType>(response.Tags); + Assert.Equal(expected.Tags[0].Id, response.Tags[0].Id); + Assert.Equal(expected.Tags[0].Name, response.Tags[0].Name); + Assert.IsType>(response.PhotoUrls); + Assert.Equal(expected.PhotoUrls[0], response.PhotoUrls[0]); + Assert.IsType(response.Category); + Assert.Equal(expected.Category.Id, response.Category.Id); + Assert.Equal(expected.Category.Name, response.Category.Name); + } + + /// + /// Test GetPetById with a not existent Id + /// + [Fact] + public void GetPetById_GivenNotExistentId_ThrowsApiException() + { + var exception = Assert.Throws(() => + { + _petApi.GetPetById(NotExistentId); + }); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.ErrorContent); + Assert.Equal("Error calling GetPetById: {\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.Message); + } + + /// + /// Test GetPetByIdWithHttpInfo with an existent Id + /// + [Fact] + public void GetPetByIdWithHttpInfo_GivenExistentId_Returns200Response() + { + Pet expected = BuildSamplePet(); + + ApiResponse response = _petApi.GetPetByIdWithHttpInfo(PetId); + Pet result = response.Data; + + Assert.IsType>(response); + Assert.Equal(200, (int)response.StatusCode); + Assert.True(response.Headers.ContainsKey("Content-Type")); + Assert.Equal("application/json", response.Headers["Content-Type"][0]); + + Assert.Equal(expected.Name, result.Name); + Assert.Equal(expected.Status, result.Status); + Assert.IsType>(result.Tags); + Assert.Equal(expected.Tags[0].Id, result.Tags[0].Id); + Assert.Equal(expected.Tags[0].Name, result.Tags[0].Name); + Assert.IsType>(result.PhotoUrls); + Assert.Equal(expected.PhotoUrls[0], result.PhotoUrls[0]); + Assert.IsType(result.Category); + Assert.Equal(expected.Category.Id, result.Category.Id); + Assert.Equal(expected.Category.Name, result.Category.Name); + } + + /// + /// Test GetPetByIdWithHttpInfo with a not existent Id and the ExceptionFactory disabled + /// + [Fact] + public void GetPetByIdWithHttpInfo_GivenNotExistentId_ThrowsApiException() + { + var exception = Assert.Throws(() => + { + _petApi.GetPetByIdWithHttpInfo(NotExistentId); + }); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.ErrorContent); + Assert.Equal("Error calling GetPetById: {\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.Message); + } + + /// + /// Test GetPetByIdWithHttpInfo with a not existent Id and the ExceptionFactory disabled + /// + [Fact] + public void GetPetByIdWithHttpInfo_WithoutExceptionFactory_GivenNotExistentId_Returns404Response() + { + _petApi.ExceptionFactory = null; + ApiResponse response = _petApi.GetPetByIdWithHttpInfo(NotExistentId); + Pet result = response.Data; + + Assert.IsType>(response); + Assert.Equal(404, (int)response.StatusCode); + Assert.True(response.Headers.ContainsKey("Content-Type")); + Assert.Equal("application/json", response.Headers["Content-Type"][0]); + + Assert.Null(result); + Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", response.RawContent); + Assert.Equal("Not Found", response.ErrorText); + } + + #endregion + + #region Get Async + + /// + /// Test GetPetByIdAsync with an existent Id. + /// + [Fact] + public async Task GetPetByIdAsync_GivenExistentId_ReturnsPet() + { + Pet expected = BuildSamplePet(); + + Pet response = await _petApi.GetPetByIdAsync(PetId); + + Assert.IsType(response); + Assert.Equal(expected.Name, response.Name); + Assert.Equal(expected.Status, response.Status); + Assert.IsType>(response.Tags); + Assert.Equal(expected.Tags[0].Id, response.Tags[0].Id); + Assert.Equal(expected.Tags[0].Name, response.Tags[0].Name); + Assert.IsType>(response.PhotoUrls); + Assert.Equal(expected.PhotoUrls[0], response.PhotoUrls[0]); + Assert.IsType(response.Category); + Assert.Equal(expected.Category.Id, response.Category.Id); + Assert.Equal(expected.Category.Name, response.Category.Name); + } + + /// + /// Test GetPetByIdAsync with a not existent Id. + /// + [Fact] + public async Task GetPetByIdAsync_GivenNotExistentId_ThrowsApiException() + { + var exception = await Assert.ThrowsAsync(() => _petApi.GetPetByIdAsync(NotExistentId)); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.ErrorContent); + Assert.Equal("Error calling GetPetById: {\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.Message); + } + + /// + /// Test GetPetByIdWithHttpInfoAsync with an existent Id. + /// + [Fact] + public async Task GetPetByIdWithHttpInfoAsync_GivenExistentId_Returns200Response() + { + Pet expected = BuildSamplePet(); + + ApiResponse response = await _petApi.GetPetByIdWithHttpInfoAsync(PetId); + Pet result = response.Data; + + Assert.IsType>(response); + Assert.Equal(200, (int)response.StatusCode); + Assert.True(response.Headers.ContainsKey("Content-Type")); + Assert.Equal("application/json", response.Headers["Content-Type"][0]); + + Assert.Equal(expected.Name, result.Name); + Assert.Equal(expected.Status, result.Status); + Assert.IsType>(result.Tags); + Assert.Equal(expected.Tags[0].Id, result.Tags[0].Id); + Assert.Equal(expected.Tags[0].Name, result.Tags[0].Name); + Assert.IsType>(result.PhotoUrls); + Assert.Equal(expected.PhotoUrls[0], result.PhotoUrls[0]); + Assert.IsType(result.Category); + Assert.Equal(expected.Category.Id, result.Category.Id); + Assert.Equal(expected.Category.Name, result.Category.Name); + } + + /// + /// Test GetPetByIdWithHttpInfoAsync with a not existent Id and the ExceptionFactory disabled. + /// + [Fact] + public async Task GetPetByIdWithHttpInfoAsync_GivenNotExistentId_ThrowsApiException() + { + var exception = await Assert.ThrowsAsync(() => _petApi.GetPetByIdWithHttpInfoAsync(NotExistentId)); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.ErrorContent); + Assert.Equal("Error calling GetPetById: {\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", exception.Message); + } + + /// + /// Test GetPetByIdWithHttpInfoAsync with a not existent Id and the ExceptionFactory disabled. + /// + [Fact] + public async Task GetPetByIdWithHttpInfoAsync_WithoutExceptionFactory_GivenNotExistentId_Returns404Response() + { + _petApi.ExceptionFactory = null; + ApiResponse response = await _petApi.GetPetByIdWithHttpInfoAsync(NotExistentId); + Pet result = response.Data; + + Assert.IsType>(response); + Assert.Equal(404, (int)response.StatusCode); + Assert.True(response.Headers.ContainsKey("Content-Type")); + Assert.Equal("application/json", response.Headers["Content-Type"][0]); + + Assert.Null(result); + Assert.Equal("{\"code\":1,\"type\":\"error\",\"message\":\"Pet not found\"}", response.RawContent); + Assert.Equal("Not Found", response.ErrorText); + } + + #endregion + + #region Find + + /// + /// Test FindPetsByStatus filtering available pets. + /// + [Fact(Skip = "too much elements to fetch, the server cut the json content")] + public void FindPetsByStatus_ReturnsListOfPetsFiltered() + { + List pets = _petApi.FindPetsByStatus(new List(new[] { "available" })); + + foreach (Pet pet in pets) + { + Assert.IsType(pet); + Assert.Equal(Pet.StatusEnum.Available, pet.Status); + } + } + + #endregion + + #region Add + + /// + /// Test AddPet with an existent Id. The current server beavior is to update the Pet. + /// + [Fact] + public void AddPet_GivenExistentId_UpdateThePet() + { + Pet pet = BuildSamplePet(); + + _petApi.AddPet(pet); + } + + #endregion + + #region AddAsync + + /// + /// Test AddPetAsync with an existent Id. The current server beavior is to update the Pet. + /// + [Fact] + public async Task AddPetAsync_GivenExistentId_UpdateThePet() + { + Pet pet = BuildSamplePet(); + + await _petApi.AddPetAsync(pet); + } + + #endregion + + #region Update + + /// + /// Test UpdatePet with an existent Id. + /// + [Fact] + public void UpdatePet_GivenExistentId_UpdateThePet() + { + Pet pet = BuildSamplePet(); + + _petApi.UpdatePet(pet); + } + + /// + /// Test UpdatePet with a not existent Id. The current server beavior is to create the Pet. + /// + [Fact] + public void UpdatePet_GivenNotExistentId_UpdateThePet() + { + Pet pet = BuildSamplePet(i => i.Id = NotExistentId); + + _petApi.UpdatePet(pet); + } + + /// + /// Test UpdatePetWithForm with an existent Id. + /// + [Fact] + public void UpdatePetWithForm_GivenExistentId_UpdatesTheFields() + { + Pet expected = BuildSamplePet(pet => + { + pet.Name = "name updated"; + pet.Status = Pet.StatusEnum.Pending; + }); + + _petApi.UpdatePetWithForm(PetId, "name updated", "pending"); + + Pet response = _petApi.GetPetById(PetId); + + Assert.IsType(response); + Assert.Equal(expected.Name, response.Name); + Assert.Equal(expected.Status, response.Status); + Assert.IsType>(response.Tags); + Assert.Equal(expected.Tags[0].Id, response.Tags[0].Id); + Assert.Equal(expected.Tags[0].Name, response.Tags[0].Name); + Assert.IsType>(response.PhotoUrls); + Assert.Equal(expected.PhotoUrls[0], response.PhotoUrls[0]); + Assert.IsType(response.Category); + Assert.Equal(expected.Category.Id, response.Category.Id); + Assert.Equal(expected.Category.Name, response.Category.Name); + + _petApi.UpdatePetWithForm(PetId, "name updated twice"); + + response = _petApi.GetPetById(PetId); + + Assert.Equal("name updated twice", response.Name); + } + + /// + /// Test UploadFile with an existent Id. + /// + [Fact(Skip = "generates 500 code at the time of test")] + public void UploadFile_UploadFileUsingFormParameters_UpdatesTheFields() + { + var assembly = Assembly.GetExecutingAssembly(); + using Stream imageStream = assembly.GetManifestResourceStream("Org.OpenAPITools.Test.linux-logo.png"); + _petApi.UploadFile(PetId, "metadata sample", imageStream); + } + + /// + /// Test UploadFile with an existent Id. + /// + [Fact(Skip = "generates 500 code at the time of test")] + public void UploadFile_UploadFileAlone_UpdatesTheField() + { + var assembly = Assembly.GetExecutingAssembly(); + using Stream imageStream = assembly.GetManifestResourceStream("Org.OpenAPITools.Test.linux-logo.png"); + _petApi.UploadFile(petId: PetId, file: imageStream); + } + + #endregion + + #region UpdateAsync + + /// + /// Test UpdatePetAsync with an existent Id. + /// + [Fact] + public async Task UpdatePetAsync_GivenExistentId_UpdateThePet() + { + Pet pet = BuildSamplePet(); + + await _petApi.UpdatePetAsync(pet); + } + + /// + /// Test UpdatePetAsync with a not existent Id. The current server beavior is to create the Pet. + /// + [Fact] + public async Task UpdatePetAsync_GivenNotExistentId_UpdateThePet() + { + Pet pet = BuildSamplePet(i => i.Id = NotExistentId); + + await _petApi.UpdatePetAsync(pet); + } + + /// + /// Test UpdatePetWithFormAsync with an existent Id. + /// + [Fact] + public async Task UpdatePetWithFormAsync_GivenExistentId_UpdatesTheFields() + { + Pet expected = BuildSamplePet(pet => + { + pet.Name = "name updated"; + pet.Status = Pet.StatusEnum.Pending; + }); + + await _petApi.UpdatePetWithFormAsync(PetId, "name updated", "pending"); + + Pet response = await _petApi.GetPetByIdAsync(PetId); + + Assert.IsType(response); + Assert.Equal(expected.Name, response.Name); + Assert.Equal(expected.Status, response.Status); + Assert.IsType>(response.Tags); + Assert.Equal(expected.Tags[0].Id, response.Tags[0].Id); + Assert.Equal(expected.Tags[0].Name, response.Tags[0].Name); + Assert.IsType>(response.PhotoUrls); + Assert.Equal(expected.PhotoUrls[0], response.PhotoUrls[0]); + Assert.IsType(response.Category); + Assert.Equal(expected.Category.Id, response.Category.Id); + Assert.Equal(expected.Category.Name, response.Category.Name); + + await _petApi.UpdatePetWithFormAsync(PetId, "name updated twice"); + + response = await _petApi.GetPetByIdAsync(PetId); + + Assert.Equal("name updated twice", response.Name); + } + + /// + /// Test UploadFileAsync with an existent Id. + /// + [Fact(Skip = "generates 500 code at the time of test")] + public async Task UploadFileAsync_UploadFileUsingFormParameters_UpdatesTheFields() + { + var assembly = Assembly.GetExecutingAssembly(); + await using Stream imageStream = assembly.GetManifestResourceStream("Org.OpenAPITools.Test.linux-logo.png"); + await _petApi.UploadFileAsync(PetId, "metadata sample", imageStream); + } + + /// + /// Test UploadFileAsync with an existent Id. + /// + [Fact(Skip = "generates 500 code at the time of test")] + public async Task UploadFileAsync_UploadFileAlone_UpdatesTheField() + { + var assembly = Assembly.GetExecutingAssembly(); + await using Stream imageStream = assembly.GetManifestResourceStream("Org.OpenAPITools.Test.linux-logo.png"); + await _petApi.UploadFileAsync(petId: PetId, file: imageStream); + } + + #endregion + + #region Delete + + /// + /// Test DeletePet with an existent Id. + /// + [Fact] + public void DeletePet_GivenExistentId_DeleteThePet() + { + _petApi.DeletePet(PetId); + + var exception = Assert.Throws(() => _petApi.GetPetById(PetId)); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + } + + /// + /// Test DeletePet with a not existent Id. The current server beavior is to return 404. + /// + [Fact] + public void DeletePet_GivenNotExistentId_ThrowsApiException() + { + var exception = Assert.Throws(() => _petApi.DeletePet(NotExistentId)); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + } + + #endregion + + #region DeleteAsync + + /// + /// Test DeletePet with an existent Id. + /// + [Fact] + public async Task DeletePetAsync_GivenExistentId_DeleteThePet() + { + await _petApi.DeletePetAsync(PetId); + + var exception = Assert.Throws(() => _petApi.GetPetById(PetId)); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + } + + /// + /// Test DeletePet with a not existent Id. The current server beavior is to return 404. + /// + [Fact] + public async Task DeletePetAsync_GivenNotExistentId_ThrowsApiException() + { + var exception = await Assert.ThrowsAsync(() => _petApi.DeletePetAsync(NotExistentId)); + + Assert.IsType(exception); + Assert.Equal(404, exception.ErrorCode); + } + + #endregion + + private static Pet BuildSamplePet(Action callback = null) + { + var pet = new Pet( + name: "csharp test", + photoUrls: new List { "http://petstore.com/csharp_test" }) + { + Id = PetId, + Status = Pet.StatusEnum.Available, + Category = new Category { Id = 10, Name = "sample category" }, + Tags = new List { new Tag { Id = 100, Name = "sample tag" } } + }; + + callback?.Invoke(pet); + + return pet; + } + + public void Dispose() + { + // remove the pet after testing + try + { + _petApi.DeletePet(PetId); + } + catch (ApiException ex) when (ex.ErrorCode == 404) { } + + _petApi.Dispose(); + _httpClient.Dispose(); + } + } +} diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj index dcc1208d75cf..20f33144c2a7 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools.Test/Org.OpenAPITools.Test.csproj @@ -8,7 +8,10 @@ - + + + + @@ -18,9 +21,7 @@ - - - - + + diff --git a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools/Client/ApiClient.cs index 9bdab1cf4c87..526a43111178 100644 --- a/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp-netcore/OpenAPIClient-httpclient/src/Org.OpenAPITools/Client/ApiClient.cs @@ -98,13 +98,13 @@ internal object Deserialize(HttpResponseMessage response, Type type) if (type == typeof(byte[])) // return byte array { - return response.Content.ReadAsByteArrayAsync().Result; + return response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult(); } // TODO: ? if (type.IsAssignableFrom(typeof(Stream))) if (type == typeof(Stream)) { - var bytes = response.Content.ReadAsByteArrayAsync().Result; + var bytes = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult(); if (headers != null) { var filePath = String.IsNullOrEmpty(_configuration.TempFolderPath) @@ -128,18 +128,18 @@ internal object Deserialize(HttpResponseMessage response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content.ReadAsStringAsync().Result, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), null, System.Globalization.DateTimeStyles.RoundtripKind); } if (type == typeof(String) || type.Name.StartsWith("System.Nullable")) // return primitive type { - return Convert.ChangeType(response.Content.ReadAsStringAsync().Result, type); + return Convert.ChangeType(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), type); } // at this point, it must be a model (json) try { - return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().Result, type, _serializerSettings); + return JsonConvert.DeserializeObject(response.Content.ReadAsStringAsync().GetAwaiter().GetResult(), type, _serializerSettings); } catch (Exception e) { @@ -399,10 +399,10 @@ private HttpRequestMessage NewRequest( partial void InterceptRequest(HttpRequestMessage req); partial void InterceptResponse(HttpRequestMessage req, HttpResponseMessage response); - private ApiResponse ToApiResponse(HttpResponseMessage response, object responseData, Uri uri) + private async Task> ToApiResponse(HttpResponseMessage response, object responseData, Uri uri) { T result = (T) responseData; - string rawContent = response.Content.ToString(); + string rawContent = await response.Content.ReadAsStringAsync(); var transformed = new ApiResponse(response.StatusCode, new Multimap(), result, rawContent) { @@ -444,7 +444,7 @@ private ApiResponse ToApiResponse(HttpResponseMessage response, object res private ApiResponse Exec(HttpRequestMessage req, IReadableConfiguration configuration) { - return ExecAsync(req, configuration).Result; + return ExecAsync(req, configuration).GetAwaiter().GetResult(); } private async Task> ExecAsync(HttpRequestMessage req, @@ -505,6 +505,11 @@ private async Task> ExecAsync(HttpRequestMessage req, response = await _httpClient.SendAsync(req, cancellationToken).ConfigureAwait(false); } + if (!response.IsSuccessStatusCode) + { + return await ToApiResponse(response, default(T), req.RequestUri); + } + object responseData = deserializer.Deserialize(response); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data @@ -519,9 +524,7 @@ private async Task> ExecAsync(HttpRequestMessage req, InterceptResponse(req, response); - var result = ToApiResponse(response, responseData, req.RequestUri); - - return result; + return await ToApiResponse(response, responseData, req.RequestUri); } #region IAsynchronousClient