diff --git a/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs b/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs index d62898ac..1b700dce 100644 --- a/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs +++ b/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Text; using System.Threading.Tasks; +using JsonConverter.Abstractions; namespace WireMock.ResponseBuilders; @@ -69,4 +70,23 @@ public interface IBodyResponseBuilder : IFaultResponseBuilder /// Defines if this file is cached in memory or retrieved from disk every time the response is created. /// A . IResponseBuilder WithBodyFromFile(string filename, bool cache = true); + + /// + /// WithBody : Create a string response based on a object (which will be converted to a JSON string using the ). + /// + /// The body. + /// The JsonConverter. + /// The IJsonConverterOption [optional]. + /// A . + IResponseBuilder WithBody(object body, IJsonConverter converter, JsonConverterOptions? options = null); + + /// + /// WithBody : Create a string response based on a object (which will be converted to a JSON string using the ). + /// + /// The body. + /// The body encoding, can be null. + /// The JsonConverter. + /// The IJsonConverterOption [optional]. + /// A . + IResponseBuilder WithBody(object body, Encoding? encoding, IJsonConverter converter, JsonConverterOptions? options = null); } \ No newline at end of file diff --git a/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs b/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs new file mode 100644 index 00000000..a73f4a8c --- /dev/null +++ b/src/WireMock.Net/ResponseBuilders/Response.WithBody.cs @@ -0,0 +1,173 @@ +using System; +using System.Text; +using System.Threading.Tasks; +using JsonConverter.Abstractions; +using Stef.Validation; +using WireMock.Types; +using WireMock.Util; + +namespace WireMock.ResponseBuilders; + +public partial class Response +{ + /// + public IResponseBuilder WithBody(Func bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null) + { + Guard.NotNull(bodyFactory, nameof(bodyFactory)); + + return WithCallbackInternal(true, req => new ResponseMessage + { + BodyData = new BodyData + { + DetectedBodyType = BodyType.String, + BodyAsString = bodyFactory(req), + Encoding = encoding ?? Encoding.UTF8 + } + }); + } + + /// + public IResponseBuilder WithBody(Func> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null) + { + Guard.NotNull(bodyFactory, nameof(bodyFactory)); + + return WithCallbackInternal(true, async req => new ResponseMessage + { + BodyData = new BodyData + { + DetectedBodyType = BodyType.String, + BodyAsString = await bodyFactory(req).ConfigureAwait(false), + Encoding = encoding ?? Encoding.UTF8 + } + }); + } + + /// + public IResponseBuilder WithBody(byte[] body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null) + { + Guard.NotNull(body); + + ResponseMessage.BodyDestination = destination; + ResponseMessage.BodyData = new BodyData(); + + switch (destination) + { + case BodyDestinationFormat.String: + var enc = encoding ?? Encoding.UTF8; + ResponseMessage.BodyData.DetectedBodyType = BodyType.String; + ResponseMessage.BodyData.BodyAsString = enc.GetString(body); + ResponseMessage.BodyData.Encoding = enc; + break; + + default: + ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes; + ResponseMessage.BodyData.BodyAsBytes = body; + break; + } + + return this; + } + + /// + public IResponseBuilder WithBodyFromFile(string filename, bool cache = true) + { + Guard.NotNull(filename); + + ResponseMessage.BodyData = new BodyData + { + BodyAsFileIsCached = cache, + BodyAsFile = filename + }; + + if (cache && !UseTransformer) + { + ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes; + } + else + { + ResponseMessage.BodyData.DetectedBodyType = BodyType.File; + } + + return this; + } + + /// + public IResponseBuilder WithBody(string body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null) + { + Guard.NotNull(body); + + encoding ??= Encoding.UTF8; + + ResponseMessage.BodyDestination = destination; + ResponseMessage.BodyData = new BodyData + { + Encoding = encoding + }; + + switch (destination) + { + case BodyDestinationFormat.Bytes: + ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes; + ResponseMessage.BodyData.BodyAsBytes = encoding.GetBytes(body); + break; + + case BodyDestinationFormat.Json: + ResponseMessage.BodyData.DetectedBodyType = BodyType.Json; + ResponseMessage.BodyData.BodyAsJson = JsonUtils.DeserializeObject(body); + break; + + default: + ResponseMessage.BodyData.DetectedBodyType = BodyType.String; + ResponseMessage.BodyData.BodyAsString = body; + break; + } + + return this; + } + + /// + public IResponseBuilder WithBodyAsJson(object body, Encoding? encoding = null, bool? indented = null) + { + Guard.NotNull(body); + + ResponseMessage.BodyDestination = null; + ResponseMessage.BodyData = new BodyData + { + Encoding = encoding, + DetectedBodyType = BodyType.Json, + BodyAsJson = body, + BodyAsJsonIndented = indented + }; + + return this; + } + + /// + public IResponseBuilder WithBodyAsJson(object body, bool indented) + { + return WithBodyAsJson(body, null, indented); + } + + /// + public IResponseBuilder WithBody(object body, IJsonConverter converter, JsonConverterOptions? options = null) + { + return WithBody(body, null, converter, options); + } + + /// + public IResponseBuilder WithBody(object body, Encoding? encoding, IJsonConverter converter, JsonConverterOptions? options = null) + { + Guard.NotNull(body); + Guard.NotNull(converter); + + ResponseMessage.BodyDestination = null; + ResponseMessage.BodyData = new BodyData + { + Encoding = encoding, + DetectedBodyType = BodyType.String, + BodyAsString = converter.Serialize(body, options) + }; + + return this; + } +} \ No newline at end of file diff --git a/src/WireMock.Net/ResponseBuilders/Response.cs b/src/WireMock.Net/ResponseBuilders/Response.cs index 63ae3fb0..871e277e 100644 --- a/src/WireMock.Net/ResponseBuilders/Response.cs +++ b/src/WireMock.Net/ResponseBuilders/Response.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net; -using System.Text; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; @@ -15,7 +14,6 @@ using WireMock.Transformers; using WireMock.Transformers.Handlebars; using WireMock.Transformers.Scriban; using WireMock.Types; -using WireMock.Util; namespace WireMock.ResponseBuilders; @@ -196,144 +194,6 @@ public partial class Response : IResponseBuilder return this; } - /// - public IResponseBuilder WithBody(Func bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null) - { - Guard.NotNull(bodyFactory, nameof(bodyFactory)); - - return WithCallbackInternal(true, req => new ResponseMessage - { - BodyData = new BodyData - { - DetectedBodyType = BodyType.String, - BodyAsString = bodyFactory(req), - Encoding = encoding ?? Encoding.UTF8 - } - }); - } - - /// - public IResponseBuilder WithBody(Func> bodyFactory, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null) - { - Guard.NotNull(bodyFactory, nameof(bodyFactory)); - - return WithCallbackInternal(true, async req => new ResponseMessage - { - BodyData = new BodyData - { - DetectedBodyType = BodyType.String, - BodyAsString = await bodyFactory(req).ConfigureAwait(false), - Encoding = encoding ?? Encoding.UTF8 - } - }); - } - - /// - public IResponseBuilder WithBody(byte[] body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null) - { - Guard.NotNull(body); - - ResponseMessage.BodyDestination = destination; - ResponseMessage.BodyData = new BodyData(); - - switch (destination) - { - case BodyDestinationFormat.String: - var enc = encoding ?? Encoding.UTF8; - ResponseMessage.BodyData.DetectedBodyType = BodyType.String; - ResponseMessage.BodyData.BodyAsString = enc.GetString(body); - ResponseMessage.BodyData.Encoding = enc; - break; - - default: - ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes; - ResponseMessage.BodyData.BodyAsBytes = body; - break; - } - - return this; - } - - /// - public IResponseBuilder WithBodyFromFile(string filename, bool cache = true) - { - Guard.NotNull(filename); - - ResponseMessage.BodyData = new BodyData - { - BodyAsFileIsCached = cache, - BodyAsFile = filename - }; - - if (cache && !UseTransformer) - { - ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes; - } - else - { - ResponseMessage.BodyData.DetectedBodyType = BodyType.File; - } - - return this; - } - - /// - public IResponseBuilder WithBody(string body, string? destination = BodyDestinationFormat.SameAsSource, Encoding? encoding = null) - { - Guard.NotNull(body); - - encoding ??= Encoding.UTF8; - - ResponseMessage.BodyDestination = destination; - ResponseMessage.BodyData = new BodyData - { - Encoding = encoding - }; - - switch (destination) - { - case BodyDestinationFormat.Bytes: - ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes; - ResponseMessage.BodyData.BodyAsBytes = encoding.GetBytes(body); - break; - - case BodyDestinationFormat.Json: - ResponseMessage.BodyData.DetectedBodyType = BodyType.Json; - ResponseMessage.BodyData.BodyAsJson = JsonUtils.DeserializeObject(body); - break; - - default: - ResponseMessage.BodyData.DetectedBodyType = BodyType.String; - ResponseMessage.BodyData.BodyAsString = body; - break; - } - - return this; - } - - /// - public IResponseBuilder WithBodyAsJson(object body, Encoding? encoding = null, bool? indented = null) - { - Guard.NotNull(body); - - ResponseMessage.BodyDestination = null; - ResponseMessage.BodyData = new BodyData - { - Encoding = encoding, - DetectedBodyType = BodyType.Json, - BodyAsJson = body, - BodyAsJsonIndented = indented - }; - - return this; - } - - /// - public IResponseBuilder WithBodyAsJson(object body, bool indented) - { - return WithBodyAsJson(body, null, indented); - } - /// public IResponseBuilder WithTransformer(bool transformContentFromBodyAsFile) { diff --git a/src/WireMock.Net/WireMock.Net.csproj b/src/WireMock.Net/WireMock.Net.csproj index c4556590..5687c70f 100644 --- a/src/WireMock.Net/WireMock.Net.csproj +++ b/src/WireMock.Net/WireMock.Net.csproj @@ -57,6 +57,7 @@ + @@ -157,6 +158,12 @@ + + + Response.cs + + + diff --git a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs index 6c56302b..8bae514b 100644 --- a/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs +++ b/test/WireMock.Net.Tests/ResponseBuilders/ResponseWithBodyTests.cs @@ -1,6 +1,7 @@ using System; using System.Text; using System.Threading.Tasks; +using FluentAssertions; using Moq; using Newtonsoft.Json.Linq; using NFluent; @@ -12,317 +13,338 @@ using WireMock.Types; using WireMock.Util; using Xunit; -namespace WireMock.Net.Tests.ResponseBuilders +namespace WireMock.Net.Tests.ResponseBuilders; + +public class ResponseWithBodyTests { - public class ResponseWithBodyTests + private const string ClientIp = "::1"; + + private readonly Mock _filesystemHandlerMock; + private readonly WireMockServerSettings _settings = new WireMockServerSettings(); + + public ResponseWithBodyTests() { - private const string ClientIp = "::1"; + _filesystemHandlerMock = new Mock(MockBehavior.Strict); + _filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny())).Returns("abc"); - private readonly Mock _filesystemHandlerMock; - private readonly WireMockServerSettings _settings = new WireMockServerSettings(); - - public ResponseWithBodyTests() - { - _filesystemHandlerMock = new Mock(MockBehavior.Strict); - _filesystemHandlerMock.Setup(fs => fs.ReadResponseBodyAsString(It.IsAny())).Returns("abc"); - - _settings.FileSystemHandler = _filesystemHandlerMock.Object; - } - - [Fact] - public async Task Response_ProvideResponse_WithBody_Bytes_Encoding_Destination_String() - { - // given - var body = new BodyData - { - DetectedBodyType = BodyType.String, - BodyAsString = "abc" - }; - var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body); - - var responseBuilder = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.String, Encoding.ASCII); - - // act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // then - Check.That(response.Message.BodyData.BodyAsString).Equals("01"); - Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); - Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); - } - - [Fact] - public async Task Response_ProvideResponse_WithBody_Bytes_Encoding_Destination_Bytes() - { - // given - var body = new BodyData - { - DetectedBodyType = BodyType.String, - BodyAsString = "abc" - }; - var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body); - - var responseBuilder = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.SameAsSource, Encoding.ASCII); - - // act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // then - Check.That(response.Message.BodyData.BodyAsBytes).ContainsExactly(new byte[] { 48, 49 }); - Check.That(response.Message.BodyData.BodyAsString).IsNull(); - Check.That(response.Message.BodyData.Encoding).IsNull(); - } - - [Fact] - public async Task Response_ProvideResponse_WithBody_String_Encoding() - { - // given - var body = new BodyData - { - DetectedBodyType = BodyType.String, - BodyAsString = "abc" - }; - var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body); - - var responseBuilder = Response.Create().WithBody("test", null, Encoding.ASCII); - - // act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // then - Check.That(response.Message.BodyData.BodyAsString).Equals("test"); - Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); - } - - [Fact] - public async Task Response_ProvideResponse_WithBody_Object_Encoding() - { - // 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 { value = "test" }; - var responseBuilder = Response.Create().WithBodyAsJson(x, Encoding.ASCII); - - // act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // then - Check.That(response.Message.BodyData.BodyAsJson).Equals(x); - 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(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() - { - // Assign - var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp); - - var responseBuilder = Response.Create().WithBody("r", BodyDestinationFormat.SameAsSource, Encoding.ASCII); - - // Act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // Assert - Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); - Check.That(response.Message.BodyData.BodyAsJson).IsNull(); - Check.That(response.Message.BodyData.BodyAsString).Equals("r"); - Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); - } - - [Fact] - public async Task Response_ProvideResponse_WithBody_String_Bytes_Encoding() - { - // Assign - var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp); - - var responseBuilder = Response.Create().WithBody("r", BodyDestinationFormat.Bytes, Encoding.ASCII); - - // Act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // Assert - Check.That(response.Message.BodyData.BodyAsString).IsNull(); - Check.That(response.Message.BodyData.BodyAsJson).IsNull(); - Check.That(response.Message.BodyData.BodyAsBytes).IsNotNull(); - Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); - } - - [Fact] - public async Task Response_ProvideResponse_WithBody_String_Json_Encoding() - { - // Assign - var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp); - - var responseBuilder = Response.Create().WithBody("{ \"value\": 42 }", BodyDestinationFormat.Json, Encoding.ASCII); - - // Act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // Assert - Check.That(response.Message.BodyData.BodyAsString).IsNull(); - Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); - Check.That(((dynamic)response.Message.BodyData.BodyAsJson).value).Equals(42); - Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); - } - - [Fact] - public async Task Response_ProvideResponse_WithBody_Func() - { - // Assign - var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp); - - var responseBuilder = Response.Create() - .WithStatusCode(500) - .WithHeader("H1", "X1") - .WithHeader("H2", "X2") - .WithBody(req => $"path: {req.Path}"); - - // Act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // Assert - Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test"); - Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); - Check.That(response.Message.BodyData.BodyAsJson).IsNull(); - Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage); - Check.That(response.Message.StatusCode).IsEqualTo(500); - Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1"); - Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2"); - } - - [Fact] - public async Task Response_ProvideResponse_WithBody_FuncAsync() - { - // Assign - var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp); - - var responseBuilder = Response.Create() - .WithStatusCode(500) - .WithHeader("H1", "X1") - .WithHeader("H2", "X2") - .WithBody(async req => - { - await Task.Delay(1).ConfigureAwait(false); - return $"path: {req.Path}"; - }); - - // Act - var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); - - // Assert - Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test"); - Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); - Check.That(response.Message.BodyData.BodyAsJson).IsNull(); - Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage); - Check.That(response.Message.StatusCode).IsEqualTo(500); - Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1"); - Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2"); - } - - [Fact] - public async Task Response_ProvideResponse_WithJsonBodyAndTransform_Func() - { - // Assign - const int request1Id = 1; - const int request2Id = 2; - - var request1 = new RequestMessage(new UrlDetails($"http://localhost/test?id={request1Id}"), "GET", ClientIp); - var request2 = new RequestMessage(new UrlDetails($"http://localhost/test?id={request2Id}"), "GET", ClientIp); - - var responseBuilder = Response.Create() - .WithStatusCode(200) - .WithBodyAsJson(JObject.Parse("{ \"id\": \"{{request.query.id}}\" }")) - .WithTransformer(); - - // Act - var response1 = await responseBuilder.ProvideResponseAsync(request1, _settings).ConfigureAwait(false); - var response2 = await responseBuilder.ProvideResponseAsync(request2, _settings).ConfigureAwait(false); - - // Assert - Check.That(((JToken)response1.Message.BodyData.BodyAsJson).SelectToken("id")?.Value()).IsEqualTo(request1Id); - Check.That(response1.Message.BodyData.BodyAsBytes).IsNull(); - Check.That(response1.Message.BodyData.BodyAsString).IsNull(); - Check.That(response1.Message.StatusCode).IsEqualTo(200); - - Check.That(((JToken)response2.Message.BodyData.BodyAsJson).SelectToken("id")?.Value()).IsEqualTo(request2Id); - Check.That(response2.Message.BodyData.BodyAsBytes).IsNull(); - Check.That(response2.Message.BodyData.BodyAsString).IsNull(); - Check.That(response2.Message.StatusCode).IsEqualTo(200); - } - - [Fact] - public async Task Response_ProvideResponse_WithBodyAsFile() - { - var fileContents = "testFileContents" + Guid.NewGuid(); - var bodyDataAsFile = new BodyData { BodyAsFile = fileContents }; - - var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "PUT", ClientIp, bodyDataAsFile); - - var responseBuilder = Response.Create().WithStatusCode(200).WithBody(fileContents); - - var response = await responseBuilder.ProvideResponseAsync(request1, _settings).ConfigureAwait(false); - - Check.That(response.Message.StatusCode).IsEqualTo(200); - Check.That(response.Message.BodyData.BodyAsString).Contains(fileContents); - } - - [Fact] - public async Task Response_ProvideResponse_WithResponseAsFile() - { - var fileContents = "testFileContents" + Guid.NewGuid(); - var bodyDataAsFile = new BodyData { BodyAsFile = fileContents }; - - var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "GET", ClientIp, bodyDataAsFile); - - var responseBuilder = Response.Create().WithStatusCode(200).WithBody(fileContents); - - var response = await responseBuilder.ProvideResponseAsync(request1, _settings).ConfigureAwait(false); - - Check.That(response.Message.StatusCode).IsEqualTo(200); - Check.That(response.Message.BodyData.BodyAsString).Contains(fileContents); - } - - [Fact] - public async Task Response_ProvideResponse_WithResponseDeleted() - { - var fileContents = "testFileContents" + Guid.NewGuid(); - var bodyDataAsFile = new BodyData { BodyAsFile = fileContents }; - - var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "DELETE", ClientIp, bodyDataAsFile); - - var responseBuilder = Response.Create().WithStatusCode(200).WithBody("File deleted."); - - var response = await responseBuilder.ProvideResponseAsync(request1, _settings).ConfigureAwait(false); - - Check.That(response.Message.StatusCode).IsEqualTo(200); - Check.That(response.Message.BodyData.BodyAsString).Contains("File deleted."); - } + _settings.FileSystemHandler = _filesystemHandlerMock.Object; } -} + + [Fact] + public async Task Response_ProvideResponse_WithBody_Bytes_Encoding_Destination_String() + { + // given + var body = new BodyData + { + DetectedBodyType = BodyType.String, + BodyAsString = "abc" + }; + var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body); + + var responseBuilder = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.String, Encoding.ASCII); + + // act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // then + Check.That(response.Message.BodyData.BodyAsString).Equals("01"); + Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); + Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); + } + + [Fact] + public async Task Response_ProvideResponse_WithBody_Bytes_Encoding_Destination_Bytes() + { + // given + var body = new BodyData + { + DetectedBodyType = BodyType.String, + BodyAsString = "abc" + }; + var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body); + + var responseBuilder = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.SameAsSource, Encoding.ASCII); + + // act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // then + Check.That(response.Message.BodyData.BodyAsBytes).ContainsExactly(new byte[] { 48, 49 }); + Check.That(response.Message.BodyData.BodyAsString).IsNull(); + Check.That(response.Message.BodyData.Encoding).IsNull(); + } + + [Fact] + public async Task Response_ProvideResponse_WithBody_String_Encoding() + { + // given + var body = new BodyData + { + DetectedBodyType = BodyType.String, + BodyAsString = "abc" + }; + var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, body); + + var responseBuilder = Response.Create().WithBody("test", null, Encoding.ASCII); + + // act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // then + Check.That(response.Message.BodyData.BodyAsString).Equals("test"); + Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); + } + + [Fact] + public async Task Response_ProvideResponse_WithBody_Object_Encoding() + { + // 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 { value = "test" }; + var responseBuilder = Response.Create().WithBodyAsJson(x, Encoding.ASCII); + + // act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // then + Check.That(response.Message.BodyData.BodyAsJson).Equals(x); + 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(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() + { + // Assign + var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp); + + var responseBuilder = Response.Create().WithBody("r", BodyDestinationFormat.SameAsSource, Encoding.ASCII); + + // Act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // Assert + Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); + Check.That(response.Message.BodyData.BodyAsJson).IsNull(); + Check.That(response.Message.BodyData.BodyAsString).Equals("r"); + Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); + } + + [Fact] + public async Task Response_ProvideResponse_WithBody_String_Bytes_Encoding() + { + // Assign + var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp); + + var responseBuilder = Response.Create().WithBody("r", BodyDestinationFormat.Bytes, Encoding.ASCII); + + // Act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // Assert + Check.That(response.Message.BodyData.BodyAsString).IsNull(); + Check.That(response.Message.BodyData.BodyAsJson).IsNull(); + Check.That(response.Message.BodyData.BodyAsBytes).IsNotNull(); + Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); + } + + [Fact] + public async Task Response_ProvideResponse_WithBody_String_Json_Encoding() + { + // Assign + var request = new RequestMessage(new UrlDetails("http://localhost"), "GET", ClientIp); + + var responseBuilder = Response.Create().WithBody("{ \"value\": 42 }", BodyDestinationFormat.Json, Encoding.ASCII); + + // Act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // Assert + Check.That(response.Message.BodyData.BodyAsString).IsNull(); + Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); + Check.That(((dynamic)response.Message.BodyData.BodyAsJson).value).Equals(42); + Check.That(response.Message.BodyData.Encoding).Equals(Encoding.ASCII); + } + + [Fact] + public async Task Response_ProvideResponse_WithBody_Func() + { + // Assign + var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp); + + var responseBuilder = Response.Create() + .WithStatusCode(500) + .WithHeader("H1", "X1") + .WithHeader("H2", "X2") + .WithBody(req => $"path: {req.Path}"); + + // Act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // Assert + Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test"); + Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); + Check.That(response.Message.BodyData.BodyAsJson).IsNull(); + Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage); + Check.That(response.Message.StatusCode).IsEqualTo(500); + Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1"); + Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2"); + } + + [Fact] + public async Task Response_ProvideResponse_WithBody_FuncAsync() + { + // Assign + var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp); + + var responseBuilder = Response.Create() + .WithStatusCode(500) + .WithHeader("H1", "X1") + .WithHeader("H2", "X2") + .WithBody(async req => + { + await Task.Delay(1).ConfigureAwait(false); + return $"path: {req.Path}"; + }); + + // Act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // Assert + Check.That(response.Message.BodyData.BodyAsString).IsEqualTo("path: /test"); + Check.That(response.Message.BodyData.BodyAsBytes).IsNull(); + Check.That(response.Message.BodyData.BodyAsJson).IsNull(); + Check.That(response.Message.BodyData.Encoding.CodePage).Equals(Encoding.UTF8.CodePage); + Check.That(response.Message.StatusCode).IsEqualTo(500); + Check.That(response.Message.Headers["H1"].ToString()).IsEqualTo("X1"); + Check.That(response.Message.Headers["H2"].ToString()).IsEqualTo("X2"); + } + + [Fact] + public async Task Response_ProvideResponse_WithJsonBodyAndTransform_Func() + { + // Assign + const int request1Id = 1; + const int request2Id = 2; + + var request1 = new RequestMessage(new UrlDetails($"http://localhost/test?id={request1Id}"), "GET", ClientIp); + var request2 = new RequestMessage(new UrlDetails($"http://localhost/test?id={request2Id}"), "GET", ClientIp); + + var responseBuilder = Response.Create() + .WithStatusCode(200) + .WithBodyAsJson(JObject.Parse("{ \"id\": \"{{request.query.id}}\" }")) + .WithTransformer(); + + // Act + var response1 = await responseBuilder.ProvideResponseAsync(request1, _settings).ConfigureAwait(false); + var response2 = await responseBuilder.ProvideResponseAsync(request2, _settings).ConfigureAwait(false); + + // Assert + Check.That(((JToken)response1.Message.BodyData.BodyAsJson).SelectToken("id")?.Value()).IsEqualTo(request1Id); + Check.That(response1.Message.BodyData.BodyAsBytes).IsNull(); + Check.That(response1.Message.BodyData.BodyAsString).IsNull(); + Check.That(response1.Message.StatusCode).IsEqualTo(200); + + Check.That(((JToken)response2.Message.BodyData.BodyAsJson).SelectToken("id")?.Value()).IsEqualTo(request2Id); + Check.That(response2.Message.BodyData.BodyAsBytes).IsNull(); + Check.That(response2.Message.BodyData.BodyAsString).IsNull(); + Check.That(response2.Message.StatusCode).IsEqualTo(200); + } + + [Fact] + public async Task Response_ProvideResponse_WithBodyAsFile() + { + var fileContents = "testFileContents" + Guid.NewGuid(); + var bodyDataAsFile = new BodyData { BodyAsFile = fileContents }; + + var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "PUT", ClientIp, bodyDataAsFile); + + var responseBuilder = Response.Create().WithStatusCode(200).WithBody(fileContents); + + var response = await responseBuilder.ProvideResponseAsync(request1, _settings).ConfigureAwait(false); + + Check.That(response.Message.StatusCode).IsEqualTo(200); + Check.That(response.Message.BodyData.BodyAsString).Contains(fileContents); + } + + [Fact] + public async Task Response_ProvideResponse_WithResponseAsFile() + { + var fileContents = "testFileContents" + Guid.NewGuid(); + var bodyDataAsFile = new BodyData { BodyAsFile = fileContents }; + + var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "GET", ClientIp, bodyDataAsFile); + + var responseBuilder = Response.Create().WithStatusCode(200).WithBody(fileContents); + + var response = await responseBuilder.ProvideResponseAsync(request1, _settings).ConfigureAwait(false); + + Check.That(response.Message.StatusCode).IsEqualTo(200); + Check.That(response.Message.BodyData.BodyAsString).Contains(fileContents); + } + + [Fact] + public async Task Response_ProvideResponse_WithResponseDeleted() + { + var fileContents = "testFileContents" + Guid.NewGuid(); + var bodyDataAsFile = new BodyData { BodyAsFile = fileContents }; + + var request1 = new RequestMessage(new UrlDetails("http://localhost/__admin/files/filename.txt"), "DELETE", ClientIp, bodyDataAsFile); + + var responseBuilder = Response.Create().WithStatusCode(200).WithBody("File deleted."); + + var response = await responseBuilder.ProvideResponseAsync(request1, _settings).ConfigureAwait(false); + + Check.That(response.Message.StatusCode).IsEqualTo(200); + Check.That(response.Message.BodyData.BodyAsString).Contains("File deleted."); + } + +#if !(NET451 || NET452) + [Fact] + public async Task Response_ProvideResponse_WithBody_IJsonConverter_SystemTextJson() + { + // Arrange + var requestBody = new BodyData + { + DetectedBodyType = BodyType.String, + BodyAsString = "abc" + }; + var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "POST", ClientIp, requestBody); + + var responseBuilder = Response.Create().WithBody(new { foo = "bar", n = 42 }, new JsonConverter.System.Text.Json.SystemTextJsonConverter()); + + // Act + var response = await responseBuilder.ProvideResponseAsync(request, _settings).ConfigureAwait(false); + + // Assert + response.Message.BodyData!.BodyAsString.Should().Be(@"{""foo"":""bar"",""n"":42}"); + } +#endif +} \ No newline at end of file diff --git a/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj b/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj index a85488e0..89d851c4 100644 --- a/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj +++ b/test/WireMock.Net.Tests/WireMock.Net.Tests.csproj @@ -78,6 +78,7 @@ +