mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-02-15 23:07:41 +01:00
Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e701566a1f | ||
|
|
84ad5a927e | ||
|
|
3250604b5a | ||
|
|
9d2963632e |
@@ -1,3 +1,9 @@
|
||||
# 1.0.34.0 (22 October 2019)
|
||||
- [#354](https://github.com/WireMock-Net/WireMock.Net/pull/354) - AllowBodyForAllHttpMethods [bug, feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#365](https://github.com/WireMock-Net/WireMock.Net/pull/365) - Bump Microsoft.AspNetCore.All from 2.0.8 to 2.0.9 in /examples/WireMock.Net.WebApplication [dependencies] contributed by [dependabot[bot]](https://github.com/apps/dependabot)
|
||||
- [#366](https://github.com/WireMock-Net/WireMock.Net/pull/366) - Update ObsoleteAnnotations [feature] contributed by [StefH](https://github.com/StefH)
|
||||
- [#352](https://github.com/WireMock-Net/WireMock.Net/issues/352) - DELETE request drops the body [feature, question]
|
||||
|
||||
# 1.0.33.0 (12 October 2019)
|
||||
- [#311](https://github.com/WireMock-Net/WireMock.Net/pull/311) - fix jsonpath matcher [bug] contributed by [StefH](https://github.com/StefH)
|
||||
- [#324](https://github.com/WireMock-Net/WireMock.Net/pull/324) - Add CSharpCodeMatcher [feature] contributed by [StefH](https://github.com/StefH)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<VersionPrefix>1.0.33</VersionPrefix>
|
||||
<VersionPrefix>1.0.34</VersionPrefix>
|
||||
</PropertyGroup>
|
||||
|
||||
<Choose>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
https://github.com/StefH/GitHubReleaseNotes
|
||||
|
||||
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid --version 1.0.33.0
|
||||
GitHubReleaseNotes.exe --output CHANGELOG.md --skip-empty-releases --exclude-labels question invalid --version 1.0.34.0
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netcoreapp2.0'">
|
||||
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.2" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.8" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.9" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ namespace WireMock.Net.StandAlone
|
||||
/// <summary>
|
||||
/// The StandAloneApp
|
||||
/// </summary>
|
||||
[Obsolete("This class will be removed in version 1.1.0")]
|
||||
public static class StandAloneApp
|
||||
{
|
||||
/// <summary>
|
||||
@@ -19,7 +18,6 @@ namespace WireMock.Net.StandAlone
|
||||
/// </summary>
|
||||
/// <param name="settings">The FluentMockServerSettings</param>
|
||||
[PublicAPI]
|
||||
[Obsolete("Will be replaced by WireMockServer.Start(settings) in version 1.1.0")]
|
||||
public static FluentMockServer Start([NotNull] IFluentMockServerSettings settings)
|
||||
{
|
||||
Check.NotNull(settings, nameof(settings));
|
||||
@@ -37,7 +35,6 @@ namespace WireMock.Net.StandAlone
|
||||
/// <param name="args">The commandline arguments</param>
|
||||
/// <param name="logger">The logger</param>
|
||||
[PublicAPI]
|
||||
[Obsolete("Will be replaced by `var settings = WireMockServerSettingsParser.ParseArguments(args, logger); WireMockServer.Start(settings);` in version 1.1.0")]
|
||||
public static FluentMockServer Start([NotNull] string[] args, [CanBeNull] IWireMockLogger logger = null)
|
||||
{
|
||||
Check.NotNull(args, nameof(args));
|
||||
@@ -56,6 +53,7 @@ namespace WireMock.Net.StandAlone
|
||||
MaxRequestLogCount = parser.GetIntValue("MaxRequestLogCount"),
|
||||
RequestLogExpirationDuration = parser.GetIntValue("RequestLogExpirationDuration"),
|
||||
AllowCSharpCodeMatcher = parser.GetBoolValue("AllowCSharpCodeMatcher"),
|
||||
AllowBodyForAllHttpMethods = parser.GetBoolValue("AllowBodyForAllHttpMethods")
|
||||
};
|
||||
|
||||
if (logger != null)
|
||||
|
||||
@@ -24,5 +24,10 @@
|
||||
/// Gets or sets the MaxRequestLog count.
|
||||
/// </summary>
|
||||
public int? MaxRequestLogCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets wether to allow a body for all HTTP methods.
|
||||
/// </summary>
|
||||
public bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ namespace WireMock.Owin
|
||||
|
||||
IStringMatcher AuthorizationMatcher { get; set; }
|
||||
|
||||
bool AllowPartialMapping { get; set; }
|
||||
bool? AllowPartialMapping { get; set; }
|
||||
|
||||
ConcurrentDictionary<Guid, IMapping> Mappings { get; }
|
||||
|
||||
@@ -37,5 +37,7 @@ namespace WireMock.Owin
|
||||
Action<IAppBuilder> PostWireMockMiddlewareInit { get; set; }
|
||||
|
||||
IFileSystemHandler FileSystemHandler { get; set; }
|
||||
|
||||
bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,8 @@ namespace WireMock.Owin.Mappers
|
||||
/// MapAsync IRequest to RequestMessage
|
||||
/// </summary>
|
||||
/// <param name="request">The OwinRequest/HttpRequest</param>
|
||||
/// <param name="options">The WireMockMiddlewareOptions</param>
|
||||
/// <returns>RequestMessage</returns>
|
||||
Task<RequestMessage> MapAsync(IRequest request);
|
||||
Task<RequestMessage> MapAsync(IRequest request, IWireMockMiddlewareOptions options);
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,7 @@ namespace WireMock.Owin.Mappers
|
||||
internal class OwinRequestMapper : IOwinRequestMapper
|
||||
{
|
||||
/// <inheritdoc cref="IOwinRequestMapper.MapAsync"/>
|
||||
public async Task<RequestMessage> MapAsync(IRequest request)
|
||||
public async Task<RequestMessage> MapAsync(IRequest request, IWireMockMiddlewareOptions options)
|
||||
{
|
||||
(UrlDetails urldetails, string clientIP) = ParseRequest(request);
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace WireMock.Owin.Mappers
|
||||
}
|
||||
|
||||
BodyData body = null;
|
||||
if (request.Body != null && BodyParser.ShouldParseBody(method))
|
||||
if (request.Body != null && BodyParser.ShouldParseBody(method, options.AllowBodyForAllHttpMethods == true))
|
||||
{
|
||||
body = await BodyParser.Parse(request.Body, request.ContentType);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace WireMock.Owin
|
||||
}
|
||||
}
|
||||
|
||||
if (_options.AllowPartialMapping)
|
||||
if (_options.AllowPartialMapping == true)
|
||||
{
|
||||
var partialMappings = mappings
|
||||
.Where(pm => (pm.Mapping.IsAdminInterface && pm.RequestMatchResult.IsPerfectMatch) || !pm.Mapping.IsAdminInterface)
|
||||
|
||||
@@ -69,7 +69,7 @@ namespace WireMock.Owin
|
||||
|
||||
private async Task InvokeInternal(IContext ctx)
|
||||
{
|
||||
var request = await _requestMapper.MapAsync(ctx.Request);
|
||||
var request = await _requestMapper.MapAsync(ctx.Request, _options);
|
||||
|
||||
bool logRequest = false;
|
||||
ResponseMessage response = null;
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace WireMock.Owin
|
||||
|
||||
public IStringMatcher AuthorizationMatcher { get; set; }
|
||||
|
||||
public bool AllowPartialMapping { get; set; }
|
||||
public bool? AllowPartialMapping { get; set; }
|
||||
|
||||
public ConcurrentDictionary<Guid, IMapping> Mappings { get; } = new ConcurrentDictionary<Guid, IMapping>();
|
||||
|
||||
@@ -39,5 +39,8 @@ namespace WireMock.Owin
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.FileSystemHandler"/>
|
||||
public IFileSystemHandler FileSystemHandler { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IWireMockMiddlewareOptions.AllowBodyForAllHttpMethods"/>
|
||||
public bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -339,7 +339,8 @@ namespace WireMock.Server
|
||||
AllowPartialMapping = _options.AllowPartialMapping,
|
||||
MaxRequestLogCount = _options.MaxRequestLogCount,
|
||||
RequestLogExpirationDuration = _options.RequestLogExpirationDuration,
|
||||
GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds
|
||||
GlobalProcessingDelay = (int?)_options.RequestProcessingDelay?.TotalMilliseconds,
|
||||
AllowBodyForAllHttpMethods = _options.AllowBodyForAllHttpMethods
|
||||
};
|
||||
|
||||
return ToJson(model);
|
||||
@@ -361,6 +362,11 @@ namespace WireMock.Server
|
||||
_options.RequestProcessingDelay = TimeSpan.FromMilliseconds(settings.GlobalProcessingDelay.Value);
|
||||
}
|
||||
|
||||
if (settings.AllowBodyForAllHttpMethods != null)
|
||||
{
|
||||
_options.AllowBodyForAllHttpMethods = settings.AllowBodyForAllHttpMethods.Value;
|
||||
}
|
||||
|
||||
return ResponseMessageBuilder.Create("Settings updated");
|
||||
}
|
||||
#endregion Settings
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Exceptions;
|
||||
using WireMock.Handlers;
|
||||
@@ -25,7 +25,7 @@ namespace WireMock.Server
|
||||
/// <summary>
|
||||
/// The fluent mock server.
|
||||
/// </summary>
|
||||
[Obsolete("Will be replaced by WireMockServer in version 1.1.0")]
|
||||
[Obsolete("Will be replaced by WireMockServer in version 2.x.x")]
|
||||
public partial class FluentMockServer : IDisposable
|
||||
{
|
||||
private const int ServerStartDelayInMs = 100;
|
||||
@@ -257,6 +257,12 @@ namespace WireMock.Server
|
||||
}
|
||||
}
|
||||
|
||||
if (settings.AllowBodyForAllHttpMethods == true)
|
||||
{
|
||||
_options.AllowBodyForAllHttpMethods = _settings.AllowBodyForAllHttpMethods;
|
||||
_settings.Logger.Info("AllowBodyForAllHttpMethods is set to {0}", _settings.AllowBodyForAllHttpMethods == true);
|
||||
}
|
||||
|
||||
if (settings.AllowPartialMapping == true)
|
||||
{
|
||||
AllowPartialMapping();
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace WireMock.Settings
|
||||
/// <summary>
|
||||
/// FluentMockServerSettings
|
||||
/// </summary>
|
||||
[Obsolete("Will be replaced by WireMockServerSettings in version 1.1.0")]
|
||||
[Obsolete("Will be replaced by WireMockServerSettings in version 2.x.x")]
|
||||
public class FluentMockServerSettings : IFluentMockServerSettings
|
||||
{
|
||||
/// <inheritdoc cref="IFluentMockServerSettings.Port"/>
|
||||
@@ -94,5 +94,9 @@ namespace WireMock.Settings
|
||||
/// <inheritdoc cref="IFluentMockServerSettings.AllowCSharpCodeMatcher"/>
|
||||
[PublicAPI]
|
||||
public bool? AllowCSharpCodeMatcher { get; set; }
|
||||
|
||||
/// <inheritdoc cref="IFluentMockServerSettings.AllowBodyForAllHttpMethods"/>
|
||||
[PublicAPI]
|
||||
public bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace WireMock.Settings
|
||||
/// <summary>
|
||||
/// IFluentMockServerSettings
|
||||
/// </summary>
|
||||
[Obsolete("This interface will be removed and replaced by the class WireMockServerSettings in version 1.1.0")]
|
||||
[Obsolete("This interface will be removed and replaced by the class WireMockServerSettings in version 2.x.x")]
|
||||
public interface IFluentMockServerSettings
|
||||
{
|
||||
/// <summary>
|
||||
@@ -124,6 +124,13 @@ namespace WireMock.Settings
|
||||
/// <summary>
|
||||
/// Allow the usage of CSharpCodeMatcher (default is not allowed).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? AllowCSharpCodeMatcher { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Allow a Body for all HTTP Methods. (default set to false).
|
||||
/// </summary>
|
||||
[PublicAPI]
|
||||
bool? AllowBodyForAllHttpMethods { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ namespace WireMock.Settings
|
||||
/// <summary>
|
||||
/// IProxyAndRecordSettings
|
||||
/// </summary>
|
||||
[Obsolete("This interface will be removed and replaced by the class ProxyAndRecordSettings in version 1.1.0")]
|
||||
[Obsolete("This interface will be removed and replaced by the class ProxyAndRecordSettings in version 2.x.x")]
|
||||
public interface IProxyAndRecordSettings
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -59,14 +59,19 @@ namespace WireMock.Util
|
||||
|
||||
private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings { DateParseHandling = DateParseHandling.None };
|
||||
|
||||
public static bool ShouldParseBody([CanBeNull] string method)
|
||||
public static bool ShouldParseBody([CanBeNull] string httpMethod, bool allowBodyForAllHttpMethods)
|
||||
{
|
||||
if (string.IsNullOrEmpty(method))
|
||||
if (string.IsNullOrEmpty(httpMethod))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BodyAllowedForMethods.TryGetValue(method.ToUpper(), out bool allowed))
|
||||
if (allowBodyForAllHttpMethods)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (BodyAllowedForMethods.TryGetValue(httpMethod.ToUpper(), out bool allowed))
|
||||
{
|
||||
return allowed;
|
||||
}
|
||||
|
||||
@@ -116,7 +116,25 @@ namespace WireMock.Net.Tests
|
||||
|
||||
// Assert
|
||||
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
|
||||
Check.That(options.AllowPartialMapping).IsTrue();
|
||||
Check.That(options.AllowPartialMapping).Equals(true);
|
||||
|
||||
// Verify
|
||||
_loggerMock.Verify(l => l.Info(It.IsAny<string>(), It.IsAny<bool>()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FluentMockServer_FluentMockServerSettings_AllowBodyForAllHttpMethods()
|
||||
{
|
||||
// Assign and Act
|
||||
var server = FluentMockServer.Start(new FluentMockServerSettings
|
||||
{
|
||||
Logger = _loggerMock.Object,
|
||||
AllowBodyForAllHttpMethods = true
|
||||
});
|
||||
|
||||
// Assert
|
||||
var options = server.GetPrivateFieldValue<IWireMockMiddlewareOptions>("_options");
|
||||
Check.That(options.AllowBodyForAllHttpMethods).Equals(true);
|
||||
|
||||
// Verify
|
||||
_loggerMock.Verify(l => l.Info(It.IsAny<string>(), It.IsAny<bool>()));
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
_requestMapperMock = new Mock<IOwinRequestMapper>();
|
||||
_requestMapperMock.SetupAllProperties();
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1");
|
||||
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>())).ReturnsAsync(request);
|
||||
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request);
|
||||
|
||||
_responseMapperMock = new Mock<IOwinResponseMapper>();
|
||||
_responseMapperMock.SetupAllProperties();
|
||||
@@ -87,7 +87,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]>());
|
||||
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>())).ReturnsAsync(request);
|
||||
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request);
|
||||
|
||||
_optionsMock.SetupGet(o => o.AuthorizationMatcher).Returns(new ExactMatcher());
|
||||
_mappingMock.SetupGet(m => m.IsAdminInterface).Returns(true);
|
||||
@@ -108,7 +108,7 @@ namespace WireMock.Net.Tests.Owin
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/foo"), "GET", "::1", null, new Dictionary<string, string[]> { { "h", new[] { "x" } } });
|
||||
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>())).ReturnsAsync(request);
|
||||
_requestMapperMock.Setup(m => m.MapAsync(It.IsAny<IRequest>(), It.IsAny<IWireMockMiddlewareOptions>())).ReturnsAsync(request);
|
||||
|
||||
_optionsMock.SetupGet(o => o.AuthorizationMatcher).Returns(new ExactMatcher());
|
||||
_mappingMock.SetupGet(m => m.IsAdminInterface).Returns(true);
|
||||
|
||||
@@ -1,168 +1,185 @@
|
||||
using NFluent;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Util
|
||||
{
|
||||
public class BodyParserTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("application/json", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
[InlineData("application/json; charset=utf-8", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
[InlineData("application/json; odata.metadata=minimal", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
[InlineData("application/vnd.api+json", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
[InlineData("application/vnd.test+json", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
public async Task BodyParser_Parse_ContentTypeJson(string contentType, string bodyAsJson, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
Check.That(body.BodyAsJson).IsNotNull();
|
||||
Check.That(body.BodyAsString).Equals(bodyAsJson);
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("application/xml", "<xml>hello</xml>", BodyType.String, BodyType.String)]
|
||||
[InlineData("something", "hello", BodyType.String, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_ContentTypeString(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
Check.That(body.BodyAsJson).IsNull();
|
||||
Check.That(body.BodyAsString).Equals(bodyAsString);
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] {34, 97, 34}, BodyType.Json)]
|
||||
[InlineData(new byte[] {97}, BodyType.String)]
|
||||
[InlineData(new byte[] {0xFF, 0xD8, 0xFF, 0xE0}, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_DetectedBodyType(byte[] content, BodyType detectedBodyType)
|
||||
{
|
||||
// arrange
|
||||
var memoryStream = new MemoryStream(content);
|
||||
|
||||
// act
|
||||
var body = await BodyParser.Parse(memoryStream, null);
|
||||
|
||||
// assert
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BodyParser_Parse_WithUTF8EncodingAndContentTypeMultipart_DetectedBodyTypeEqualsString()
|
||||
{
|
||||
// Arrange
|
||||
string contentType = "multipart/form-data";
|
||||
string body = @"
|
||||
|
||||
-----------------------------9051914041544843365972754266
|
||||
Content-Disposition: form-data; name=""text""
|
||||
|
||||
text default
|
||||
-----------------------------9051914041544843365972754266
|
||||
Content-Disposition: form-data; name=""file1""; filename=""a.txt""
|
||||
Content-Type: text/plain
|
||||
|
||||
Content of a txt
|
||||
|
||||
-----------------------------9051914041544843365972754266
|
||||
Content-Disposition: form-data; name=""file2""; filename=""a.html""
|
||||
Content-Type: text/html
|
||||
|
||||
<!DOCTYPE html><title>Content of a.html.</title>
|
||||
|
||||
-----------------------------9051914041544843365972754266--";
|
||||
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.String);
|
||||
Check.That(result.DetectedBodyTypeFromContentType).IsEqualTo(BodyType.MultiPart);
|
||||
Check.That(result.BodyAsBytes).IsNotNull();
|
||||
Check.That(result.BodyAsJson).IsNull();
|
||||
Check.That(result.BodyAsString).IsNotNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BodyParser_Parse_WithUTF16EncodingAndContentTypeMultipart_DetectedBodyTypeEqualsString()
|
||||
{
|
||||
// Arrange
|
||||
string contentType = "multipart/form-data";
|
||||
string body = char.ConvertFromUtf32(0x1D161); //U+1D161 = MUSICAL SYMBOL SIXTEENTH NOTE
|
||||
|
||||
var memoryStream = new MemoryStream(Encoding.UTF32.GetBytes(body));
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes);
|
||||
Check.That(result.DetectedBodyTypeFromContentType).IsEqualTo(BodyType.MultiPart);
|
||||
Check.That(result.BodyAsBytes).IsNotNull();
|
||||
Check.That(result.BodyAsJson).IsNull();
|
||||
Check.That(result.BodyAsString).IsNull();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, "hello", BodyType.String, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_ContentTypeIsNull(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
Check.That(body.BodyAsJson).IsNull();
|
||||
Check.That(body.BodyAsString).Equals(bodyAsString);
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("HEAD", false)]
|
||||
[InlineData("GET", false)]
|
||||
[InlineData("PUT", true)]
|
||||
[InlineData("POST", true)]
|
||||
using NFluent;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Util
|
||||
{
|
||||
public class BodyParserTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("application/json", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
[InlineData("application/json; charset=utf-8", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
[InlineData("application/json; odata.metadata=minimal", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
[InlineData("application/vnd.api+json", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
[InlineData("application/vnd.test+json", "{ \"x\": 1 }", BodyType.Json, BodyType.Json)]
|
||||
public async Task BodyParser_Parse_ContentTypeJson(string contentType, string bodyAsJson, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsJson));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
Check.That(body.BodyAsJson).IsNotNull();
|
||||
Check.That(body.BodyAsString).Equals(bodyAsJson);
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("application/xml", "<xml>hello</xml>", BodyType.String, BodyType.String)]
|
||||
[InlineData("something", "hello", BodyType.String, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_ContentTypeString(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
Check.That(body.BodyAsJson).IsNull();
|
||||
Check.That(body.BodyAsString).Equals(bodyAsString);
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(new byte[] {34, 97, 34}, BodyType.Json)]
|
||||
[InlineData(new byte[] {97}, BodyType.String)]
|
||||
[InlineData(new byte[] {0xFF, 0xD8, 0xFF, 0xE0}, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_DetectedBodyType(byte[] content, BodyType detectedBodyType)
|
||||
{
|
||||
// arrange
|
||||
var memoryStream = new MemoryStream(content);
|
||||
|
||||
// act
|
||||
var body = await BodyParser.Parse(memoryStream, null);
|
||||
|
||||
// assert
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BodyParser_Parse_WithUTF8EncodingAndContentTypeMultipart_DetectedBodyTypeEqualsString()
|
||||
{
|
||||
// Arrange
|
||||
string contentType = "multipart/form-data";
|
||||
string body = @"
|
||||
|
||||
-----------------------------9051914041544843365972754266
|
||||
Content-Disposition: form-data; name=""text""
|
||||
|
||||
text default
|
||||
-----------------------------9051914041544843365972754266
|
||||
Content-Disposition: form-data; name=""file1""; filename=""a.txt""
|
||||
Content-Type: text/plain
|
||||
|
||||
Content of a txt
|
||||
|
||||
-----------------------------9051914041544843365972754266
|
||||
Content-Disposition: form-data; name=""file2""; filename=""a.html""
|
||||
Content-Type: text/html
|
||||
|
||||
<!DOCTYPE html><title>Content of a.html.</title>
|
||||
|
||||
-----------------------------9051914041544843365972754266--";
|
||||
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(body));
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.String);
|
||||
Check.That(result.DetectedBodyTypeFromContentType).IsEqualTo(BodyType.MultiPart);
|
||||
Check.That(result.BodyAsBytes).IsNotNull();
|
||||
Check.That(result.BodyAsJson).IsNull();
|
||||
Check.That(result.BodyAsString).IsNotNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task BodyParser_Parse_WithUTF16EncodingAndContentTypeMultipart_DetectedBodyTypeEqualsString()
|
||||
{
|
||||
// Arrange
|
||||
string contentType = "multipart/form-data";
|
||||
string body = char.ConvertFromUtf32(0x1D161); //U+1D161 = MUSICAL SYMBOL SIXTEENTH NOTE
|
||||
|
||||
var memoryStream = new MemoryStream(Encoding.UTF32.GetBytes(body));
|
||||
|
||||
// Act
|
||||
var result = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(result.DetectedBodyType).IsEqualTo(BodyType.Bytes);
|
||||
Check.That(result.DetectedBodyTypeFromContentType).IsEqualTo(BodyType.MultiPart);
|
||||
Check.That(result.BodyAsBytes).IsNotNull();
|
||||
Check.That(result.BodyAsJson).IsNull();
|
||||
Check.That(result.BodyAsString).IsNull();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null, "hello", BodyType.String, BodyType.Bytes)]
|
||||
public async Task BodyParser_Parse_ContentTypeIsNull(string contentType, string bodyAsString, BodyType detectedBodyType, BodyType detectedBodyTypeFromContentType)
|
||||
{
|
||||
// Arrange
|
||||
var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(bodyAsString));
|
||||
|
||||
// Act
|
||||
var body = await BodyParser.Parse(memoryStream, contentType);
|
||||
|
||||
// Assert
|
||||
Check.That(body.BodyAsBytes).IsNotNull();
|
||||
Check.That(body.BodyAsJson).IsNull();
|
||||
Check.That(body.BodyAsString).Equals(bodyAsString);
|
||||
Check.That(body.DetectedBodyType).IsEqualTo(detectedBodyType);
|
||||
Check.That(body.DetectedBodyTypeFromContentType).IsEqualTo(detectedBodyTypeFromContentType);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("HEAD", false)]
|
||||
[InlineData("GET", false)]
|
||||
[InlineData("PUT", true)]
|
||||
[InlineData("POST", true)]
|
||||
[InlineData("DELETE", false)]
|
||||
[InlineData("TRACE", false)]
|
||||
[InlineData("OPTIONS", true)]
|
||||
[InlineData("CONNECT", false)]
|
||||
[InlineData("PATCH", true)]
|
||||
public void BodyParser_ShouldParseBody_ExpectedResultForKnownMethods(string method, bool resultShouldBe)
|
||||
[InlineData("PATCH", true)]
|
||||
public void BodyParser_ShouldParseBodyForMethodAndAllowAllIsFalse_ExpectedResultForKnownMethods(string method, bool resultShouldBe)
|
||||
{
|
||||
Check.That(BodyParser.ShouldParseBody(method)).Equals(resultShouldBe);
|
||||
Check.That(BodyParser.ShouldParseBody(method, false)).Equals(resultShouldBe);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("REPORT")]
|
||||
[InlineData("SOME-UNKNOWN-METHOD")]
|
||||
[Theory]
|
||||
[InlineData("HEAD")]
|
||||
[InlineData("GET")]
|
||||
[InlineData("PUT")]
|
||||
[InlineData("POST")]
|
||||
[InlineData("DELETE")]
|
||||
[InlineData("TRACE")]
|
||||
[InlineData("OPTIONS")]
|
||||
[InlineData("CONNECT")]
|
||||
[InlineData("PATCH")]
|
||||
[InlineData("REPORT")]
|
||||
[InlineData("SOME-UNKNOWN-METHOD")]
|
||||
public void BodyParser_ShouldParseBodyForMethodAndAllowAllIsTrue_ExpectedResultShouldBeTrue(string method)
|
||||
{
|
||||
Check.That(BodyParser.ShouldParseBody(method, true)).IsTrue();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("REPORT")]
|
||||
[InlineData("SOME-UNKNOWN-METHOD")]
|
||||
public void BodyParser_ShouldParseBody_DefaultIsTrueForUnknownMethods(string method)
|
||||
{
|
||||
Check.That(BodyParser.ShouldParseBody(method)).IsTrue();
|
||||
}
|
||||
}
|
||||
Check.That(BodyParser.ShouldParseBody(method, false)).IsTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user