Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add WithBodyAsJson builder method with accepts a Func #881

Merged
merged 2 commits into from
Feb 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
35 changes: 34 additions & 1 deletion examples/WireMock.Net.Console.Net452.Classic/MainApp.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using Newtonsoft.Json;
Expand Down Expand Up @@ -33,6 +35,11 @@ public void Render(TextWriter writer, dynamic context, object[] parameters)
}
}

public class Todo
{
public int Id { get; set; }
}

public static class MainApp
{
public static void Run()
Expand All @@ -54,6 +61,32 @@ public static void Run()
var s = WireMockServer.Start();
s.Stop();

var todos = new Dictionary<int, Todo>();

var server = WireMockServer.Start();

server
.Given(Request.Create()
.WithPath("todos")
.UsingGet()
)
.RespondWith(Response.Create()
.WithBodyAsJson(todos.Values)
);

server
.Given(Request.Create()
.UsingGet()
.WithPath("todos")
.WithParam("id")
)
.RespondWith(Response.Create()
.WithBodyAsJson(rm => todos[int.Parse(rm.Query!["id"].ToString())])
);

var httpClient = server.CreateClient();
//server.Stop();

var httpAndHttpsWithPort = WireMockServer.Start(new WireMockServerSettings
{
HostingScheme = HostingScheme.HttpAndHttps,
Expand All @@ -71,7 +104,7 @@ public static void Run()
string url2 = "http://localhost:9092/";
string url3 = "https://localhost:9443/";

var server = WireMockServer.Start(new WireMockServerSettings
server = WireMockServer.Start(new WireMockServerSettings
{
AllowCSharpCodeMatcher = true,
Urls = new[] { url1, url2, url3 },
Expand Down
18 changes: 17 additions & 1 deletion src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public interface IBodyResponseBuilder : IFaultResponseBuilder
IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null);

/// <summary>
/// WithBody : Create a ... response based on a callback function.
/// WithBody : Create a ... response based on a async callback function.
/// </summary>
/// <param name="bodyFactory">The async delegate to build the body.</param>
/// <param name="destination">The Body Destination format (SameAsSource, String or Bytes).</param>
Expand Down Expand Up @@ -63,6 +63,22 @@ public interface IBodyResponseBuilder : IFaultResponseBuilder
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBodyAsJson(object body, bool indented);

/// <summary>
/// WithBodyAsJson : Create a ... response based on a callback function.
/// </summary>
/// <param name="bodyFactory">The delegate to build the body.</param>
/// <param name="encoding">The body encoding.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBodyAsJson(Func<IRequestMessage, object> bodyFactory, Encoding? encoding = null);

/// <summary>
/// WithBodyAsJson : Create a ... response based on a async callback function.
/// </summary>
/// <param name="bodyFactory">The async delegate to build the body.</param>
/// <param name="encoding">The body encoding.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBodyAsJson(Func<IRequestMessage, Task<object>> bodyFactory, Encoding? encoding = null);

/// <summary>
/// WithBodyFromFile : Create a ... response based on a File.
/// </summary>
Expand Down
44 changes: 39 additions & 5 deletions src/WireMock.Net/ResponseBuilders/Response.WithBody.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public partial class Response
/// <inheritdoc />
public IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
{
Guard.NotNull(bodyFactory, nameof(bodyFactory));
Guard.NotNull(bodyFactory);

return WithCallbackInternal(true, req => new ResponseMessage
{
Expand All @@ -30,7 +30,7 @@ public IResponseBuilder WithBody(Func<IRequestMessage, string> bodyFactory, stri
/// <inheritdoc />
public IResponseBuilder WithBody(Func<IRequestMessage, Task<string>> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null)
{
Guard.NotNull(bodyFactory, nameof(bodyFactory));
Guard.NotNull(bodyFactory);

return WithCallbackInternal(true, async req => new ResponseMessage
{
Expand Down Expand Up @@ -70,7 +70,7 @@ public IResponseBuilder WithBody(byte[] body, string? destination = BodyDestinat
return this;
}

/// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromFile"/>
/// <inheritdoc />
public IResponseBuilder WithBodyFromFile(string filename, bool cache = true)
{
Guard.NotNull(filename);
Expand Down Expand Up @@ -127,7 +127,7 @@ public IResponseBuilder WithBody(string body, string? destination = BodyDestinat
return this;
}

/// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson(object, Encoding, bool?)"/>
/// <inheritdoc />
public IResponseBuilder WithBodyAsJson(object body, Encoding? encoding = null, bool? indented = null)
{
Guard.NotNull(body);
Expand All @@ -144,12 +144,46 @@ public IResponseBuilder WithBodyAsJson(object body, Encoding? encoding = null, b
return this;
}

/// <inheritdoc cref="IBodyResponseBuilder.WithBodyAsJson(object, bool)"/>
/// <inheritdoc />
public IResponseBuilder WithBodyAsJson(object body, bool indented)
{
return WithBodyAsJson(body, null, indented);
}

/// <inheritdoc />
public IResponseBuilder WithBodyAsJson(Func<IRequestMessage, object> bodyFactory, Encoding? encoding = null)
{
Guard.NotNull(bodyFactory);

return WithCallbackInternal(true, req => new ResponseMessage
{
BodyData = new BodyData
{
Encoding = encoding ?? Encoding.UTF8,
DetectedBodyType = BodyType.Json,
BodyAsJson = bodyFactory(req),
IsFuncUsed = "Func<IRequestMessage, object>"
}
});
}

/// <inheritdoc />
public IResponseBuilder WithBodyAsJson(Func<IRequestMessage, Task<object>> bodyFactory, Encoding? encoding = null)
{
Guard.NotNull(bodyFactory);

return WithCallbackInternal(true, async req => new ResponseMessage
{
BodyData = new BodyData
{
Encoding = encoding ?? Encoding.UTF8,
DetectedBodyType = BodyType.Json,
BodyAsJson = await bodyFactory(req).ConfigureAwait(false),
IsFuncUsed = "Func<IRequestMessage, Task<object>>"
}
});
}

/// <inheritdoc />
public IResponseBuilder WithBody(object body, IJsonConverter converter, JsonConverterOptions? options = null)
{
Expand Down
86 changes: 64 additions & 22 deletions test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,28 +120,6 @@ public async Task Response_ProvideResponse_WithBody_Object_Encoding()
Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII);
}

[Fact]
public async Task Response_ProvideResponse_WithBody_Object_Indented()
{
// given
var body = new BodyData
{
DetectedBodyType = BodyType.String,
BodyAsString = "abc"
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);

object x = new { message = "Hello" };
var responseBuilder = Response.Create().WithBodyAsJson(x, true);

// act
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);

// then
Check.That(response.Message.BodyData.BodyAsJson).Equals(x);
Check.That(response.Message.BodyData.BodyAsJsonIndented).IsEqualTo(true);
}

[Fact]
public async Task Response_ProvideResponse_WithBody_String_SameAsSource_Encoding()
{
Expand Down Expand Up @@ -196,6 +174,70 @@ public async Task Response_ProvideResponse_WithBody_String_Json_Encoding()
Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII);
}

[Fact]
public async Task Response_ProvideResponse_WithBodyAsJson_Object_Indented()
{
// given
var body = new BodyData
{
DetectedBodyType = BodyType.String,
BodyAsString = "abc"
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body);

object x = new { message = "Hello" };
var responseBuilder = Response.Create().WithBodyAsJson(x, true);

// act
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);

// then
Check.That(response.Message.BodyData.BodyAsJson).Equals(x);
Check.That(response.Message.BodyData.BodyAsJsonIndented).IsEqualTo(true);
}

[Fact]
public async Task Response_ProvideResponse_WithBodyAsJson_FuncObject()
{
// Arrange
var requestBody = new BodyData
{
DetectedBodyType = BodyType.String,
BodyAsString = "abc"
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, requestBody);

object responseBody = new { message = "Hello" };
var responseBuilder = Response.Create().WithBodyAsJson(requestMessage => responseBody);

// Act
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);

// Assert
response.Message.BodyData!.BodyAsJson.Should().BeEquivalentTo(responseBody);
}

[Fact]
public async Task Response_ProvideResponse_WithBodyAsJson_AsyncFuncObject()
{
// Arrange
var requestBody = new BodyData
{
DetectedBodyType = BodyType.String,
BodyAsString = "abc"
};
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, requestBody);

object responseBody = new { message = "Hello" };
var responseBuilder = Response.Create().WithBodyAsJson(requestMessage => Task.FromResult(responseBody));

// Act
var response = await responseBuilder.ProvideResponseAsync(_mappingMock.Object, request, _settings).ConfigureAwait(false);

// Assert
response.Message.BodyData!.BodyAsJson.Should().BeEquivalentTo(responseBody);
}

[Fact]
public async Task Response_ProvideResponse_WithJsonBodyAndTransform()
{
Expand Down