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

StatusCode as string #385

Merged
merged 18 commits into from
Dec 26, 2019
3 changes: 2 additions & 1 deletion src/WireMock.Net.StandAlone/WireMock.Net.StandAlone.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net451;net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<!--<TargetFrameworks>net451;net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>-->
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net.StandAlone</AssemblyName>
<PackageId>WireMock.Net.StandAlone</PackageId>
Expand Down
2 changes: 1 addition & 1 deletion src/WireMock.Net/Admin/Mappings/ResponseModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ResponseModel
/// <summary>
/// Gets or sets the HTTP status.
/// </summary>
public int? StatusCode { get; set; }
public object StatusCode { get; set; }

/// <summary>
/// Gets or sets the body destination (SameAsSource, String or Bytes).
Expand Down
2 changes: 1 addition & 1 deletion src/WireMock.Net/Admin/Requests/LogResponseModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class LogResponseModel
/// <summary>
/// Gets or sets the status code.
/// </summary>
public int StatusCode { get; set; } = 200;
public object StatusCode { get; set; } = 200;

/// <summary>
/// Gets the headers.
Expand Down
12 changes: 11 additions & 1 deletion src/WireMock.Net/Owin/Mappers/OwinResponseMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,17 @@ public async Task MapAsync(ResponseMessage responseMessage, IResponse response)
break;
}

response.StatusCode = responseMessage.StatusCode;
switch (responseMessage.StatusCode)
{
case int statusCodeAsInteger:
response.StatusCode = statusCodeAsInteger;
break;

case string statusCodeAsString:
response.StatusCode = int.Parse(statusCodeAsString);
break;
}

SetResponseHeaders(responseMessage, response);

if (bytes != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,13 @@ public interface IStatusCodeResponseBuilder : IHeadersResponseBuilder
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithStatusCode(int code);

/// <summary>
/// The with status code.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithStatusCode(string code);

/// <summary>
/// The with status code.
/// </summary>
Expand Down
20 changes: 10 additions & 10 deletions src/WireMock.Net/ResponseBuilders/Response.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,23 +87,23 @@ private Response(ResponseMessage responseMessage)
ResponseMessage = responseMessage;
}

/// <summary>
/// The with status code.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>\
/// <inheritdoc cref="IStatusCodeResponseBuilder.WithStatusCode(int)"/>
[PublicAPI]
public IResponseBuilder WithStatusCode(int code)
{
ResponseMessage.StatusCode = code;
return this;
}

/// <summary>
/// The with status code.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
/// <inheritdoc cref="IStatusCodeResponseBuilder.WithStatusCode(string)"/>
[PublicAPI]
public IResponseBuilder WithStatusCode(string code)
{
ResponseMessage.StatusCode = code;
return this;
}

/// <inheritdoc cref="IStatusCodeResponseBuilder.WithStatusCode(HttpStatusCode)"/>
[PublicAPI]
public IResponseBuilder WithStatusCode(HttpStatusCode code)
{
Expand Down
2 changes: 1 addition & 1 deletion src/WireMock.Net/ResponseMessage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class ResponseMessage
/// <summary>
/// Gets or sets the status code.
/// </summary>
public int StatusCode { get; set; } = 200;
public object StatusCode { get; set; } = 200;

/// <summary>
/// Gets or sets the body.
Expand Down
10 changes: 8 additions & 2 deletions src/WireMock.Net/Server/FluentMockServer.Admin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -805,9 +805,15 @@ private IResponseBuilder InitResponseBuilder(ResponseModel responseModel)
return responseBuilder.WithProxy(proxyAndRecordSettings);
}

if (responseModel.StatusCode.HasValue)
switch (responseModel.StatusCode)
{
responseBuilder = responseBuilder.WithStatusCode(responseModel.StatusCode.Value);
case int statusCodeAsInteger:
responseBuilder = responseBuilder.WithStatusCode(statusCodeAsInteger);
break;

case string statusCodeAsString:
responseBuilder = responseBuilder.WithStatusCode(statusCodeAsString);
break;
}

if (responseModel.Headers != null)
Expand Down
58 changes: 47 additions & 11 deletions src/WireMock.Net/Transformers/ResponseMessageTransformer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using HandlebarsDotNet;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
Expand All @@ -24,14 +25,14 @@ public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage
{
var handlebarsContext = _factory.Create();

var responseMessage = new ResponseMessage { StatusCode = original.StatusCode };
var responseMessage = new ResponseMessage();

var template = new { request = requestMessage };

switch (original.BodyData.DetectedBodyType)
{
case BodyType.Json:
TransformBodyAsJson(handlebarsContext, template, original, responseMessage);
TransformBodyAsJson(handlebarsContext.Handlebars, template, original, responseMessage);
break;

case BodyType.File:
Expand All @@ -40,7 +41,7 @@ public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage

case BodyType.String:
responseMessage.BodyOriginal = original.BodyData.BodyAsString;
TransformBodyAsString(handlebarsContext, template, original, responseMessage);
TransformBodyAsString(handlebarsContext.Handlebars, template, original, responseMessage);
break;
}

Expand All @@ -62,29 +63,46 @@ public ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage

responseMessage.Headers = newHeaders;

switch (original.StatusCode)
{
case int statusCodeAsInteger:
responseMessage.StatusCode = statusCodeAsInteger;
break;

case string statusCodeAsString:
var templateForStatusCode = handlebarsContext.Handlebars.Compile(statusCodeAsString);
responseMessage.StatusCode = templateForStatusCode(template);
break;
}

return responseMessage;
}

private static void TransformBodyAsJson(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
private static void TransformBodyAsJson(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{
JToken jToken;
switch (original.BodyData.BodyAsJson)
{
case JObject bodyAsJObject:
jToken = bodyAsJObject.DeepClone();
WalkNode(handlebarsContext, jToken, template);
break;

case Array bodyAsArray:
jToken = JArray.FromObject(bodyAsArray);
WalkNode(handlebarsContext, jToken, template);
break;

case string bodyAsString:
jToken = ReplaceSingleNode(handlebarsContext, bodyAsString, template);
break;

default:
jToken = JObject.FromObject(original.BodyData.BodyAsJson);
WalkNode(handlebarsContext, jToken, template);
break;
}

WalkNode(handlebarsContext, jToken, template);

responseMessage.BodyData = new BodyData
{
DetectedBodyType = original.BodyData.DetectedBodyType,
Expand All @@ -93,7 +111,25 @@ private static void TransformBodyAsJson(IHandlebarsContext handlebarsContext, ob
};
}

private static void WalkNode(IHandlebarsContext handlebarsContext, JToken node, object context)
private static JToken ReplaceSingleNode(IHandlebars handlebarsContext, string stringValue, object context)
{
var templateForStringValue = handlebarsContext.Compile(stringValue);
string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString))
{
const string property = "_";
JObject dummy = JObject.Parse($"{{ \"{property}\": null }}");
JToken node = dummy[property];

ReplaceNodeValue(node, transformedString);

return dummy[property];
}

return stringValue;
}

private static void WalkNode(IHandlebars handlebarsContext, JToken node, object context)
{
if (node.Type == JTokenType.Object)
{
Expand All @@ -120,7 +156,7 @@ private static void WalkNode(IHandlebarsContext handlebarsContext, JToken node,
return;
}

var templateForStringValue = handlebarsContext.Handlebars.Compile(stringValue);
var templateForStringValue = handlebarsContext.Compile(stringValue);
string transformedString = templateForStringValue(context);
if (!string.Equals(stringValue, transformedString))
{
Expand Down Expand Up @@ -152,9 +188,9 @@ private static void ReplaceNodeValue(JToken node, string stringValue)
node.Replace(value);
}

private static void TransformBodyAsString(IHandlebarsContext handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
private static void TransformBodyAsString(IHandlebars handlebarsContext, object template, ResponseMessage original, ResponseMessage responseMessage)
{
var templateBodyAsString = handlebarsContext.Handlebars.Compile(original.BodyData.BodyAsString);
var templateBodyAsString = handlebarsContext.Compile(original.BodyData.BodyAsString);

responseMessage.BodyData = new BodyData
{
Expand Down
20 changes: 20 additions & 0 deletions src/WireMock.Net/Util/HttpStatusRangeParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,26 @@ namespace WireMock.Util
/// </summary>
internal static class HttpStatusRangeParser
{
/// <summary>
/// Determines whether the specified pattern is match.
/// </summary>
/// <param name="pattern">The pattern. (Can be null, in that case it's allowed.)</param>
/// <param name="httpStatusCode">The value.</param>
/// <exception cref="ArgumentException"><paramref name="pattern"/> is invalid.</exception>
public static bool IsMatch(string pattern, object httpStatusCode)
{
switch (httpStatusCode)
{
case int statusCodeAsInteger:
return IsMatch(pattern, statusCodeAsInteger);

case string statusCodeAsString:
return IsMatch(pattern, int.Parse(statusCodeAsString));
}

return false;
}

/// <summary>
/// Determines whether the specified pattern is match.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions src/WireMock.Net/WireMock.Net.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
<AssemblyTitle>WireMock.Net</AssemblyTitle>
<Authors>Stef Heyenrath</Authors>
<!--<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0;netcoreapp2.1</TargetFrameworks>-->
<!--<TargetFrameworks>net451;net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>-->
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<AssemblyName>WireMock.Net</AssemblyName>
Expand Down
6 changes: 3 additions & 3 deletions test/WireMock.Net.Tests/Owin/WireMockMiddlewareTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public async void WireMockMiddleware_Invoke_NoMatch()
// Assert and Verify
_optionsMock.Verify(o => o.Logger.Warn(It.IsAny<string>(), It.IsAny<object[]>()), Times.Once);

Expression<Func<ResponseMessage, bool>> match = r => r.StatusCode == 404 && ((StatusModel)r.BodyData.BodyAsJson).Status == "No matching mapping found";
Expression<Func<ResponseMessage, bool>> match = r => (int) r.StatusCode == 404 && ((StatusModel)r.BodyData.BodyAsJson).Status == "No matching mapping found";
_responseMapperMock.Verify(m => m.MapAsync(It.Is(match), It.IsAny<IResponse>()), Times.Once);
}

Expand All @@ -99,7 +99,7 @@ public async void WireMockMiddleware_Invoke_IsAdminInterface_EmptyHeaders_401()
// Assert and Verify
_optionsMock.Verify(o => o.Logger.Error(It.IsAny<string>(), It.IsAny<object[]>()), Times.Once);

Expression<Func<ResponseMessage, bool>> match = r => r.StatusCode == 401;
Expression<Func<ResponseMessage, bool>> match = r => (int) r.StatusCode == 401;
_responseMapperMock.Verify(m => m.MapAsync(It.Is(match), It.IsAny<IResponse>()), Times.Once);
}

Expand All @@ -120,7 +120,7 @@ public async void WireMockMiddleware_Invoke_IsAdminInterface_MissingHeader_401()
// Assert and Verify
_optionsMock.Verify(o => o.Logger.Error(It.IsAny<string>(), It.IsAny<object[]>()), Times.Once);

Expression<Func<ResponseMessage, bool>> match = r => r.StatusCode == 401;
Expression<Func<ResponseMessage, bool>> match = r => (int) r.StatusCode == 401;
_responseMapperMock.Verify(m => m.MapAsync(It.Is(match), It.IsAny<IResponse>()), Times.Once);
}

Expand Down
15 changes: 0 additions & 15 deletions test/WireMock.Net.Tests/RequestWithPathTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,6 @@ public class RequestWithPathTests
{
private const string ClientIp = "::1";

// [Fact] : TODO : this test fails???
public void Request_WithPath_EncodedSpaces()
{
// Assign
var spec = Request.Create().WithPath("/path/a%20b").UsingAnyMethod();

// when
var body = new BodyData();
var request = new RequestMessage(new UrlDetails("http://localhost/path/a%20b"), "GET", ClientIp, body);

// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}

[Fact]
public void Request_WithPath_Spaces()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

namespace WireMock.Net.Tests.ResponseBuilders
{
public class ResponseWithWithFaultTests
public class ResponseWithFaultTests
{
private readonly Mock<IFluentMockServerSettings> _settingsMock = new Mock<IFluentMockServerSettings>();
private const string ClientIp = "::1";
Expand Down
Loading