Skip to content

Commit

Permalink
Merge pull request #173 from hassanhabib/users/hassanhabib/clients-ex…
Browse files Browse the repository at this point in the history
…ecute-async

CLIENTS: Execute Any API Call w/ Validations
  • Loading branch information
hassanhabib authored Apr 28, 2024
2 parents 2dc5ae1 + bacadf1 commit dc9a0f6
Show file tree
Hide file tree
Showing 84 changed files with 449 additions and 197 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// ----------------------------------------------------------------------------------
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers
// ----------------------------------------------------------------------------------

using System;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using Newtonsoft.Json;
using RESTFulSense.Tests.Acceptance.Models;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using Xunit;

namespace RESTFulSense.Tests.Acceptance.Tests
{
public partial class RestfulApiClientTests
{

[Fact]
private async Task ShouldExecuteHttpCallAsync()
{
// given
TEntity randomTEntity = GetRandomTEntity();
TEntity expectedTEntity = randomTEntity;
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(this.wiremockServer.Urls[0]);

this.wiremockServer.Given(Request.Create()
.WithPath(relativeUrl)
.UsingGet())
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBodyAsJson(expectedTEntity));

// when
HttpResponseMessage httpResponseMessage =
await this.restfulApiClient.ExecuteHttpCallAsync(
httpClient.GetAsync("/tests"));

TEntity actualTEntityEntity =
JsonConvert.DeserializeObject<TEntity>(
await httpResponseMessage.Content.ReadAsStringAsync());

// then
actualTEntityEntity.Should().BeEquivalentTo(expectedTEntity);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public partial class RestfulApiClientTests
{

[Fact]
private async Task ShouldPostContentWithNoResponseAndDeserializeContentAsync()
private void ShouldPostContentWithNoResponseAndDeserializeContent()
{
// given
TEntity randomTEntity = GetRandomTEntity();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// ----------------------------------------------------------------------------------
// Copyright (c) The Standard Organization: A coalition of the Good-Hearted Engineers
// ----------------------------------------------------------------------------------

using System;
using System.Net.Http;
using System.Threading.Tasks;
using FluentAssertions;
using Newtonsoft.Json;
using RESTFulSense.Tests.Acceptance.Models;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
using Xunit;

namespace RESTFulSense.Tests.Acceptance.Tests
{
public partial class RestfulSenseApiFactoryTests
{
[Fact]
private async Task ShouldExecuteHttpCallAsync()
{
// given
TEntity randomTEntity = GetRandomTEntity();
TEntity expectedTEntity = randomTEntity;
var httpClient = new HttpClient();
httpClient.BaseAddress = new Uri(this.wiremockServer.Urls[0]);

this.wiremockServer.Given(Request.Create()
.WithPath(relativeUrl)
.UsingGet())
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithBodyAsJson(expectedTEntity));

// when
HttpResponseMessage httpResponseMessage =
await this.factoryClient.ExecuteHttpCallAsync(
httpClient.GetAsync("/tests"));

TEntity actualTEntityEntity =
JsonConvert.DeserializeObject<TEntity>(
await httpResponseMessage.Content.ReadAsStringAsync());

// then
actualTEntityEntity.Should().BeEquivalentTo(expectedTEntity);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ await this.factoryClient.PostContentWithNoResponseAsync<TEntity>(
}

[Fact]
private async Task ShouldPostContentWithNoResponseAndDeserializeContentAsync()
private void ShouldPostContentWithNoResponseAndDeserializeContent()
{
// given
TEntity randomTEntity = GetRandomTEntity();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using Newtonsoft.Json;
using RESTFulSense.Tests.Acceptance.Models;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private void ShouldThrowFormValidationExceptionOnAddByteContentWithNoFileNameIfA
// given
MultipartFormDataContent nullMultipartFormDataContent =
CreateNullMultipartFormDataContent();

byte[] nullContent = null;
string invalidName = invalidInput;

Expand Down Expand Up @@ -78,7 +78,7 @@ private void ShouldThrowFormValidationExceptionOnAddByteContentWithFileNameIfArg
// given
MultipartFormDataContent nullMultipartFormDataContent =
CreateNullMultipartFormDataContent();

byte[] nullContent = null;
string invalidName = invalidInput;
string invalidFileName = invalidInput;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ private void ShouldThrowFormValidationExceptionOnAddStreamContentWithNoFileNameI
// given
MultipartFormDataContent nullMultipartFormDataContent =
CreateNullMultipartFormDataContent();

Stream nullContent = null;
string invalidName = invalidInput;

Expand Down Expand Up @@ -79,7 +79,7 @@ private void ShouldThrowFormValidationExceptionOnAddStreamContentWithFileNameIfA
// given
MultipartFormDataContent nullMultipartFormDataContent =
CreateNullMultipartFormDataContent();

Stream nullContent = null;
string invalidName = invalidInput;
string invalidFileName = invalidInput;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ private void ShouldThrowFormValidationExceptionOnAddStringContentIfArgumentsIsIn
// given
MultipartFormDataContent nullMultipartFormDataContent =
CreateNullMultipartFormDataContent();

string invalidContent = invalidInput;
string invalidName = invalidInput;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ private void ShouldThrowPropertyServiceExceptionIfExceptionOccurs()
new FailedPropertyServiceException(
message: "Failed Property Service Exception occurred, please contact support for assistance.",
innerException: someException);

var expectedPropertyServiceException =
new PropertyServiceException(
message: "Property service error occurred, contact support.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ private void ShouldRetrieveProperties()
// given
PropertyInfo[] randomPropertyInfos =
CreateRandomProperties();

PropertyInfo[] returnedPropertyInfos =
randomPropertyInfos;

PropertyInfo[] expectedPropertyInfos =
returnedPropertyInfos;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ private void ShouldThrowTypeServiceExceptionIfExceptionOccurs()
new FailedTypeServiceException(
message: "Failed Type Service Exception occurred, please contact support for assistance.",
innerException: someException);

var expectedTypeServiceException =
new TypeServiceException(
message: "Type service error occurred, contact support.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private void ShouldRetrievePropertyValue()
object someObject = CreateSomeObject();
object someValue = CreateSomeObject();
object expectedValue = someValue;

PropertyInfo somePropertyInfo =
CreateSomePropertyInfo();

Expand Down
10 changes: 7 additions & 3 deletions RESTFulSense.WebAssembly/Clients/IRESTFulApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -16,7 +17,7 @@ public interface IRESTFulApiClient
ValueTask<T> GetContentAsync<T>(
string relativeUrl,
Func<string, ValueTask<T>> deserializationFunction = null);

ValueTask<T> GetContentAsync<T>(
string relativeUrl,
CancellationToken cancellationToken,
Expand Down Expand Up @@ -127,11 +128,11 @@ ValueTask<T> PutContentAsync<T>(
ValueTask<T>> deserializationFunction = null);

ValueTask DeleteContentAsync(string relativeUrl);

ValueTask DeleteContentAsync(
string relativeUrl,
CancellationToken cancellationToken);

ValueTask<T> DeleteContentAsync<T>(
string relativeUrl,
Func<string, ValueTask<T>> deserializationFunction = null);
Expand All @@ -140,5 +141,8 @@ ValueTask<T> DeleteContentAsync<T>(
string relativeUrl,
CancellationToken cancellationToken,
Func<string, ValueTask<T>> deserializationFunction = null);

ValueTask<HttpResponseMessage> ExecuteHttpCallAsync(
Task<HttpResponseMessage> function);
}
}
4 changes: 4 additions & 0 deletions RESTFulSense.WebAssembly/Clients/IRESTFulApiFactoryClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

using System;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

Expand Down Expand Up @@ -131,5 +132,8 @@ ValueTask<T> DeleteContentAsync<T>(
string relativeUrl,
CancellationToken cancellationToken,
Func<string, ValueTask<T>> deserializationFunction = null);

ValueTask<HttpResponseMessage> ExecuteHttpCallAsync(
Task<HttpResponseMessage> function);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Newtonsoft.Json;

namespace RESTFulSense.WebAssembly.Clients
{
{
public partial class RESTFulApiClient
{
private static JsonSerializerSettings CreateJsonSerializerSettings(bool ignoreDefaultValues)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private async static ValueTask<StringContent> ConvertToJsonStringContent<T>(
mediaType);

return contentString;
}
}

private static StreamContent ConvertToStreamContent<T>(T content, string mediaType)
where T : Stream
Expand Down
27 changes: 19 additions & 8 deletions RESTFulSense.WebAssembly/Clients/RESTFulApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public async ValueTask<T> GetContentAsync<T>(
{
HttpResponseMessage responseMessage =
await GetAsync(relativeUrl, cancellationToken);

await ValidationService.ValidateHttpResponseAsync(responseMessage);

return await DeserializeResponseContent<T>(responseMessage);
Expand Down Expand Up @@ -189,8 +189,8 @@ public async ValueTask<TResult> PostContentAsync<TContent, TResult>(
CancellationToken cancellationToken,
string mediaType = "text/json",
bool ignoreDefaultValues = false,
Func<TContent, ValueTask<string>> serializationFunction = null,
Func<string, ValueTask<TResult>> deserializationFunction = null)
Func<TContent, ValueTask<string>> serializationFunction = null,
Func<string, ValueTask<TResult>> deserializationFunction = null)
{
HttpContent contentString =
await ConvertToHttpContent(
Expand All @@ -217,7 +217,7 @@ public async ValueTask<T> PutContentAsync<T>(
Func<T, ValueTask<string>> serializationFunction = null,
Func<string, ValueTask<T>> deserializationFunction = null)
{
HttpContent contentString =
HttpContent contentString =
await ConvertToHttpContent(
content,
mediaType,
Expand All @@ -243,7 +243,7 @@ public async ValueTask<T> PutContentAsync<T>(
Func<T, ValueTask<string>> serializationFunction = null,
Func<string, ValueTask<T>> deserializationFunction = null)
{
HttpContent contentString =
HttpContent contentString =
await ConvertToHttpContent(
content,
mediaType,
Expand Down Expand Up @@ -297,7 +297,7 @@ public async ValueTask<TResult> PutContentAsync<TContent, TResult>(
Func<TContent, ValueTask<string>> serializationFunction = null,
Func<string, ValueTask<TResult>> deserializationFunction = null)
{
HttpContent contentString =
HttpContent contentString =
await ConvertToHttpContent(
content,
mediaType,
Expand Down Expand Up @@ -352,7 +352,7 @@ public async ValueTask DeleteContentAsync(string relativeUrl)
{
HttpResponseMessage responseMessage =
await DeleteAsync(relativeUrl);

await ValidationService.ValidateHttpResponseAsync(
responseMessage);
}
Expand All @@ -376,7 +376,7 @@ public async ValueTask<T> DeleteContentAsync<T>(
{
HttpResponseMessage responseMessage =
await DeleteAsync(relativeUrl);

await ValidationService.ValidateHttpResponseAsync(
responseMessage);

Expand Down Expand Up @@ -414,5 +414,16 @@ private static async ValueTask<T> DeserializeResponseContent<T>(
? JsonConvert.DeserializeObject<T>(responseString)
: await deserializationFunction(responseString);
}

public async ValueTask<HttpResponseMessage> ExecuteHttpCallAsync(
Task<HttpResponseMessage> function)
{
HttpResponseMessage httpResponseMessage =
await function;

await ValidationService.ValidateHttpResponseAsync(httpResponseMessage);

return httpResponseMessage;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Newtonsoft.Json;

namespace RESTFulSense.WebAssembly.Clients
{
{
public partial class RESTFulApiFactoryClient
{
private static JsonSerializerSettings CreateJsonSerializerSettings(bool ignoreDefaultValues)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ private async static ValueTask<StringContent> ConvertToJsonStringContent<T>(
mediaType);

return contentString;
}
}

private static StreamContent ConvertToStreamContent<T>(T content, string mediaType)
where T : Stream
Expand Down
Loading

0 comments on commit dc9a0f6

Please sign in to comment.