mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-02-20 15:58:11 +01:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f9aaeda1a | ||
|
|
da64934c13 | ||
|
|
ec39d12cfe | ||
|
|
cf75b67307 | ||
|
|
913f605993 | ||
|
|
33b96c6af9 | ||
|
|
39b1eb8f43 | ||
|
|
f3c395833a | ||
|
|
9e44f7eb0e | ||
|
|
41fd1ef99d |
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,3 +1,19 @@
|
||||
# 1.0.4.16 (11 September 2018)
|
||||
|
||||
- [#202](https://github.com/WireMock-Net/WireMock.Net/pull/202) - Update handlebars code to support Regex.Match (#201) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||
- [#201](https://github.com/WireMock-Net/WireMock.Net/issues/201) - Question : Extracting text from a request.body that is not json
|
||||
|
||||
Commits: f3c395833a...da64934c13
|
||||
|
||||
|
||||
# 1.0.4.15 (04 September 2018)
|
||||
|
||||
- [#199](https://github.com/WireMock-Net/WireMock.Net/pull/199) - Fix for .WithBody(Func<RequestMessage, string>...) contributed by Stef Heyenrath ([StefH](https://github.com/StefH))
|
||||
- [#198](https://github.com/WireMock-Net/WireMock.Net/issues/198) - Issue : creating response using .WithBody(Func<RequestMessage, string>...) and .WithStatusCode +fix
|
||||
|
||||
Commits: 41fd1ef99d...41fd1ef99d
|
||||
|
||||
|
||||
# 1.0.4.14 (02 September 2018)
|
||||
|
||||
- [#197](https://github.com/WireMock-Net/WireMock.Net/pull/197) - Set IsStarted = true in a IApplicationLifetime.ApplicationStarted listener contributed by ([davide-romanini](https://github.com/davide-romanini)) +fix
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
https://github.com/GitTools/GitReleaseNotes
|
||||
|
||||
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.4.14
|
||||
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /Version 1.0.4.16
|
||||
|
||||
GitReleaseNotes.exe . /OutputFile CHANGELOG.md /allTags
|
||||
|
||||
@@ -358,6 +358,20 @@ namespace WireMock.Net.ConsoleApplication
|
||||
.WithBody("linq match !!!")
|
||||
);
|
||||
|
||||
server
|
||||
.Given(Request.Create().WithPath("/myendpoint").UsingAnyMethod())
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(500)
|
||||
.WithBody(requestMessage =>
|
||||
{
|
||||
string returnStr = JsonConvert.SerializeObject(new
|
||||
{
|
||||
Message = "Test error"
|
||||
});
|
||||
return returnStr;
|
||||
})
|
||||
);
|
||||
|
||||
System.Console.WriteLine("Press any key to stop the server");
|
||||
System.Console.ReadKey();
|
||||
server.Stop();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
|
||||
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
|
||||
<Version>1.0.4.14</Version>
|
||||
<Version>1.0.4.16</Version>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net451;net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Linq;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
{
|
||||
@@ -63,29 +65,35 @@ namespace WireMock.Matchers
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
///// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
//public double IsMatch(object input)
|
||||
//{
|
||||
// object value;
|
||||
// switch (input)
|
||||
// {
|
||||
// case JObject valueAsJObject:
|
||||
// value = valueAsJObject.ToObject<object>();
|
||||
// break;
|
||||
/// <inheritdoc cref="IObjectMatcher.IsMatch"/>
|
||||
public double IsMatch(object input)
|
||||
{
|
||||
JObject value;
|
||||
switch (input)
|
||||
{
|
||||
case JObject valueAsJObject:
|
||||
value = valueAsJObject;
|
||||
break;
|
||||
|
||||
// default:
|
||||
// value = input;
|
||||
// break;
|
||||
// }
|
||||
default:
|
||||
value = JObject.FromObject(input);
|
||||
break;
|
||||
}
|
||||
|
||||
// // Convert a single object to a Queryable object-list with 1 entry.
|
||||
// IQueryable queryable = new[] { value }.AsQueryable().Select("new (it as x)");
|
||||
// Convert a single object to a Queryable JObject-list with 1 entry.
|
||||
var queryable1 = new[] { value }.AsQueryable();
|
||||
|
||||
// // Use the Any(...) method to check if the result matches
|
||||
// double match = MatchScores.ToScore(_patterns.Select(pattern => queryable.Any(pattern)));
|
||||
// Generate the DynamicLinq select statement.
|
||||
string dynamicSelect = JsonUtils.GenerateDynamicLinqStatement(value);
|
||||
|
||||
// return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
//}
|
||||
// Execute DynamicLinq Select statement.
|
||||
var queryable2 = queryable1.Select(dynamicSelect);
|
||||
|
||||
// Use the Any(...) method to check if the result matches.
|
||||
double match = MatchScores.ToScore(_patterns.Select(pattern => queryable2.Any(pattern)));
|
||||
|
||||
return MatchBehaviourHelper.Convert(MatchBehaviour, match);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IStringMatcher.GetPatterns"/>
|
||||
public string[] GetPatterns()
|
||||
|
||||
@@ -7,9 +7,9 @@ using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using WireMock.Http;
|
||||
using WireMock.HttpsCertificate;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Owin
|
||||
@@ -43,7 +43,7 @@ namespace WireMock.Owin
|
||||
{
|
||||
Urls.Add(uriPrefix);
|
||||
|
||||
PortUtil.TryExtractProtocolAndPort(uriPrefix, out string host, out int port);
|
||||
PortUtils.TryExtractProtocolAndPort(uriPrefix, out string host, out int port);
|
||||
Ports.Add(port);
|
||||
}
|
||||
|
||||
@@ -75,13 +75,13 @@ namespace WireMock.Owin
|
||||
// https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore2x
|
||||
foreach (string url in _urls.Where(u => u.StartsWith("http://", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
PortUtil.TryExtractProtocolAndPort(url, out string host, out int port);
|
||||
PortUtils.TryExtractProtocolAndPort(url, out string host, out int port);
|
||||
options.Listen(System.Net.IPAddress.Any, port);
|
||||
}
|
||||
|
||||
foreach (string url in _urls.Where(u => u.StartsWith("https://", StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
PortUtil.TryExtractProtocolAndPort(url, out string host, out int port);
|
||||
PortUtils.TryExtractProtocolAndPort(url, out string host, out int port);
|
||||
options.Listen(System.Net.IPAddress.Any, port, listenOptions =>
|
||||
{
|
||||
listenOptions.UseHttps(PublicCertificateHelper.GetX509Certificate2());
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using WireMock.Http;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Owin
|
||||
@@ -30,7 +31,7 @@ namespace WireMock.Owin
|
||||
{
|
||||
Urls.Add(uriPrefix);
|
||||
|
||||
PortUtil.TryExtractProtocolAndPort(uriPrefix, out string host, out int port);
|
||||
PortUtils.TryExtractProtocolAndPort(uriPrefix, out string host, out int port);
|
||||
Ports.Add(port);
|
||||
}
|
||||
|
||||
|
||||
@@ -169,7 +169,14 @@ namespace WireMock.ResponseBuilders
|
||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(Func{RequestMessage, string}, string, Encoding)"/>
|
||||
public IResponseBuilder WithBody(Func<RequestMessage, string> bodyFactory, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
|
||||
{
|
||||
return WithCallback(req => new ResponseMessage { Body = bodyFactory(req) });
|
||||
Check.NotNull(bodyFactory, nameof(bodyFactory));
|
||||
|
||||
return WithCallback(req => new ResponseMessage
|
||||
{
|
||||
Body = bodyFactory(req),
|
||||
BodyDestination = destination,
|
||||
BodyEncoding = encoding ?? Encoding.UTF8
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBody(byte[], string, Encoding)"/>
|
||||
@@ -353,6 +360,22 @@ namespace WireMock.ResponseBuilders
|
||||
await Task.Delay(Delay.Value);
|
||||
}
|
||||
|
||||
if (Callback != null)
|
||||
{
|
||||
var callbackResponseMessage = Callback(requestMessage);
|
||||
|
||||
// Copy StatusCode from ResponseMessage
|
||||
callbackResponseMessage.StatusCode = ResponseMessage.StatusCode;
|
||||
|
||||
// Copy Headers from ResponseMessage (if defined)
|
||||
if (ResponseMessage.Headers != null)
|
||||
{
|
||||
callbackResponseMessage.Headers = ResponseMessage.Headers;
|
||||
}
|
||||
|
||||
return callbackResponseMessage;
|
||||
}
|
||||
|
||||
if (ProxyUrl != null && _httpClientForProxy != null)
|
||||
{
|
||||
var requestUri = new Uri(requestMessage.Url);
|
||||
@@ -367,11 +390,7 @@ namespace WireMock.ResponseBuilders
|
||||
return ResponseMessageTransformer.Transform(requestMessage, ResponseMessage);
|
||||
}
|
||||
|
||||
if (Callback != null)
|
||||
{
|
||||
return Callback(requestMessage);
|
||||
}
|
||||
|
||||
// Just return normal defined ResponseMessage
|
||||
return ResponseMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ using WireMock.Owin;
|
||||
using WireMock.RequestBuilders;
|
||||
using WireMock.ResponseProviders;
|
||||
using WireMock.Settings;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Server
|
||||
@@ -199,7 +200,7 @@ namespace WireMock.Server
|
||||
}
|
||||
else
|
||||
{
|
||||
int port = settings.Port > 0 ? settings.Port.Value : PortUtil.FindFreeTcpPort();
|
||||
int port = settings.Port > 0 ? settings.Port.Value : PortUtils.FindFreeTcpPort();
|
||||
Urls = new[] { $"{(settings.UseSSL == true ? "https" : "http")}://localhost:{port}" };
|
||||
}
|
||||
|
||||
|
||||
@@ -1,89 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using HandlebarsDotNet;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandlebarsHelpers
|
||||
{
|
||||
public static void Register()
|
||||
{
|
||||
Handlebars.RegisterHelper("JsonPath.SelectToken", (writer, context, arguments) =>
|
||||
{
|
||||
(JObject valueToProcess, string jsonpath) = Parse(arguments);
|
||||
HandleBarsRegex.Register();
|
||||
|
||||
JToken result = null;
|
||||
try
|
||||
{
|
||||
result = valueToProcess.SelectToken(jsonpath);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and return
|
||||
return;
|
||||
}
|
||||
HandleBarsJsonPath.Register();
|
||||
|
||||
if (result != null)
|
||||
{
|
||||
writer.WriteSafeString(result);
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.RegisterHelper("JsonPath.SelectTokens", (writer, options, context, arguments) =>
|
||||
{
|
||||
(JObject valueToProcess, string jsonpath) = Parse(arguments);
|
||||
|
||||
IEnumerable<JToken> values = null;
|
||||
try
|
||||
{
|
||||
values = valueToProcess.SelectTokens(jsonpath);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and return
|
||||
return;
|
||||
}
|
||||
|
||||
if (values == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int id = 0;
|
||||
foreach (JToken value in values)
|
||||
{
|
||||
options.Template(writer, new { id, value });
|
||||
id++;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static (JObject valueToProcess, string jsonpath) Parse(object[] arguments)
|
||||
{
|
||||
Check.Condition(arguments, args => args.Length == 2, nameof(arguments));
|
||||
Check.NotNull(arguments[0], "arguments[0]");
|
||||
Check.NotNullOrEmpty(arguments[1] as string, "arguments[1]");
|
||||
|
||||
JObject valueToProcess;
|
||||
|
||||
switch (arguments[0])
|
||||
{
|
||||
case string jsonAsString:
|
||||
valueToProcess = JObject.Parse(jsonAsString);
|
||||
break;
|
||||
|
||||
case JObject jsonAsJObject:
|
||||
valueToProcess = jsonAsJObject;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"The value '{arguments[0]}' with type {arguments[0].GetType()} cannot be used in Handlebars JsonPath.");
|
||||
}
|
||||
|
||||
return (valueToProcess, arguments[1] as string);
|
||||
HandleBarsLinq.Register();
|
||||
}
|
||||
}
|
||||
}
|
||||
75
src/WireMock.Net/Transformers/HandleBarsJsonPath.cs
Normal file
75
src/WireMock.Net/Transformers/HandleBarsJsonPath.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using HandlebarsDotNet;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsJsonPath
|
||||
{
|
||||
public static void Register()
|
||||
{
|
||||
Handlebars.RegisterHelper("JsonPath.SelectToken", (writer, context, arguments) =>
|
||||
{
|
||||
(JObject valueToProcess, string jsonpath) = ParseArguments(arguments);
|
||||
|
||||
try
|
||||
{
|
||||
var result = valueToProcess.SelectToken(jsonpath);
|
||||
writer.WriteSafeString(result);
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and return
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.RegisterHelper("JsonPath.SelectTokens", (writer, options, context, arguments) =>
|
||||
{
|
||||
(JObject valueToProcess, string jsonpath) = ParseArguments(arguments);
|
||||
|
||||
try
|
||||
{
|
||||
var values = valueToProcess.SelectTokens(jsonpath);
|
||||
if (values != null)
|
||||
{
|
||||
options.Template(writer, values.ToDictionary(value => value.Path, value => value));
|
||||
}
|
||||
}
|
||||
catch (JsonException)
|
||||
{
|
||||
// Ignore JsonException and return
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static (JObject valueToProcess, string jsonpath) ParseArguments(object[] arguments)
|
||||
{
|
||||
Check.Condition(arguments, args => args.Length == 2, nameof(arguments));
|
||||
Check.NotNull(arguments[0], "arguments[0]");
|
||||
Check.NotNullOrEmpty(arguments[1] as string, "arguments[1]");
|
||||
|
||||
JObject valueToProcess;
|
||||
|
||||
switch (arguments[0])
|
||||
{
|
||||
case string jsonAsString:
|
||||
valueToProcess = JObject.Parse(jsonAsString);
|
||||
break;
|
||||
|
||||
case JObject jsonAsJObject:
|
||||
valueToProcess = jsonAsJObject;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"The value '{arguments[0]}' with type '{arguments[0]?.GetType()}' cannot be used in Handlebars JsonPath.");
|
||||
}
|
||||
|
||||
return (valueToProcess, arguments[1] as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
88
src/WireMock.Net/Transformers/HandleBarsLinq.cs
Normal file
88
src/WireMock.Net/Transformers/HandleBarsLinq.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using System.Linq.Dynamic.Core.Exceptions;
|
||||
using HandlebarsDotNet;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsLinq
|
||||
{
|
||||
public static void Register()
|
||||
{
|
||||
Handlebars.RegisterHelper("Linq", (writer, context, arguments) =>
|
||||
{
|
||||
(JToken valueToProcess, string linqStatement) = ParseArguments(arguments);
|
||||
|
||||
try
|
||||
{
|
||||
object result = ExecuteDynamicLinq(valueToProcess, linqStatement);
|
||||
writer.WriteSafeString(result);
|
||||
}
|
||||
catch (ParseException)
|
||||
{
|
||||
// Ignore ParseException and return
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.RegisterHelper("Linq", (writer, options, context, arguments) =>
|
||||
{
|
||||
(JToken valueToProcess, string linqStatement) = ParseArguments(arguments);
|
||||
|
||||
try
|
||||
{
|
||||
var result = ExecuteDynamicLinq(valueToProcess, linqStatement);
|
||||
options.Template(writer, result);
|
||||
}
|
||||
catch (ParseException)
|
||||
{
|
||||
// Ignore ParseException and return
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static dynamic ExecuteDynamicLinq(JToken value, string linqStatement)
|
||||
{
|
||||
// Convert a single object to a Queryable JObject-list with 1 entry.
|
||||
var queryable1 = new[] { value }.AsQueryable();
|
||||
|
||||
// Generate the DynamicLinq select statement.
|
||||
string dynamicSelect = JsonUtils.GenerateDynamicLinqStatement(value);
|
||||
|
||||
// Execute DynamicLinq Select statement.
|
||||
var queryable2 = queryable1.Select(dynamicSelect);
|
||||
|
||||
// Execute the Select(...) method and get first result with FirstOrDefault().
|
||||
return queryable2.Select(linqStatement).FirstOrDefault();
|
||||
}
|
||||
|
||||
private static (JToken valueToProcess, string linqStatement) ParseArguments(object[] arguments)
|
||||
{
|
||||
Check.Condition(arguments, args => args.Length == 2, nameof(arguments));
|
||||
Check.NotNull(arguments[0], "arguments[0]");
|
||||
Check.NotNullOrEmpty(arguments[1] as string, "arguments[1]");
|
||||
|
||||
JToken valueToProcess;
|
||||
switch (arguments[0])
|
||||
{
|
||||
case string jsonAsString:
|
||||
valueToProcess = new JValue(jsonAsString);
|
||||
break;
|
||||
|
||||
case JToken jsonAsJObject:
|
||||
valueToProcess = jsonAsJObject;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException($"The value '{arguments[0]}' with type '{arguments[0]?.GetType()}' cannot be used in Handlebars Linq.");
|
||||
}
|
||||
|
||||
return (valueToProcess, arguments[1] as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/WireMock.Net/Transformers/HandleBarsRegex.cs
Normal file
66
src/WireMock.Net/Transformers/HandleBarsRegex.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using HandlebarsDotNet;
|
||||
using WireMock.Utils;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Transformers
|
||||
{
|
||||
internal static class HandleBarsRegex
|
||||
{
|
||||
public static void Register()
|
||||
{
|
||||
Handlebars.RegisterHelper("Regex.Match", (writer, context, arguments) =>
|
||||
{
|
||||
(string stringToProcess, string regexPattern, object defaultValue) = ParseArguments(arguments);
|
||||
|
||||
Match match = Regex.Match(stringToProcess, regexPattern);
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
writer.WriteSafeString(match.Value);
|
||||
}
|
||||
else if (defaultValue != null)
|
||||
{
|
||||
writer.WriteSafeString(defaultValue);
|
||||
}
|
||||
});
|
||||
|
||||
Handlebars.RegisterHelper("Regex.Match", (writer, options, context, arguments) =>
|
||||
{
|
||||
(string stringToProcess, string regexPattern, object defaultValue) = ParseArguments(arguments);
|
||||
|
||||
var regex = new Regex(regexPattern);
|
||||
var namedGroups = RegexUtils.GetNamedGroups(regex, stringToProcess);
|
||||
if (namedGroups.Any())
|
||||
{
|
||||
options.Template(writer, namedGroups);
|
||||
}
|
||||
else if (defaultValue != null)
|
||||
{
|
||||
options.Template(writer, defaultValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static (string stringToProcess, string regexPattern, object defaultValue) ParseArguments(object[] arguments)
|
||||
{
|
||||
Check.Condition(arguments, args => args.Length == 2 || args.Length == 3, nameof(arguments));
|
||||
|
||||
string ParseAsString(object arg)
|
||||
{
|
||||
if (arg is string)
|
||||
{
|
||||
return arg as string;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"The value '{arg}' with type '{arg?.GetType()}' cannot be used in Handlebars Regex.");
|
||||
}
|
||||
}
|
||||
|
||||
return (ParseAsString(arguments[0]), ParseAsString(arguments[1]), arguments.Length == 3 ? arguments[2] : null);
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/WireMock.Net/Util/IndexableDictionary.cs
Normal file
26
src/WireMock.Net/Util/IndexableDictionary.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
public class IndexableDictionary<TKey, TValue> : Dictionary<TKey, TValue>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the value associated with the specified index.
|
||||
/// </summary>
|
||||
/// <param name="index"> The index of the value to get.</param>
|
||||
/// <returns>The value associated with the specified index.</returns>
|
||||
public TValue this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
// get the item for that index.
|
||||
if (index < 0 || index > Count)
|
||||
{
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
return Values.Cast<TValue>().ToArray()[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,8 @@
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
@@ -6,12 +10,138 @@ namespace WireMock.Util
|
||||
{
|
||||
public static T ParseJTokenToObject<T>(object value)
|
||||
{
|
||||
if (value == null)
|
||||
switch (value)
|
||||
{
|
||||
return default(T);
|
||||
case JToken tokenValue:
|
||||
return tokenValue.ToObject<T>();
|
||||
|
||||
default:
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
|
||||
public static string GenerateDynamicLinqStatement(JToken jsonObject)
|
||||
{
|
||||
var lines = new List<string>();
|
||||
WalkNode(jsonObject, null, null, lines);
|
||||
|
||||
return lines.First();
|
||||
}
|
||||
|
||||
private static void WalkNode(JToken node, string path, string propertyName, List<string> lines)
|
||||
{
|
||||
if (node.Type == JTokenType.Object)
|
||||
{
|
||||
ProcessObject(node, propertyName, lines);
|
||||
}
|
||||
else if (node.Type == JTokenType.Array)
|
||||
{
|
||||
ProcessArray(node, propertyName, lines);
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessItem(node, path ?? "it", propertyName, lines);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ProcessObject(JToken node, string propertyName, List<string> lines)
|
||||
{
|
||||
var items = new List<string>();
|
||||
var text = new StringBuilder("new (");
|
||||
|
||||
// In case of Object, loop all children. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
foreach (JProperty child in node.Children<JProperty>().ToArray())
|
||||
{
|
||||
WalkNode(child.Value, child.Path, child.Name, items);
|
||||
}
|
||||
|
||||
return !(value is JToken token) ? default(T) : token.ToObject<T>();
|
||||
text.Append(string.Join(", ", items));
|
||||
text.Append(")");
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
text.AppendFormat(" as {0}", propertyName);
|
||||
}
|
||||
|
||||
lines.Add(text.ToString());
|
||||
}
|
||||
|
||||
private static void ProcessArray(JToken node, string propertyName, List<string> lines)
|
||||
{
|
||||
var items = new List<string>();
|
||||
var text = new StringBuilder("(new [] { ");
|
||||
|
||||
// In case of Array, loop all items. Do a ToArray() to avoid `Collection was modified` exceptions.
|
||||
int idx = 0;
|
||||
foreach (JToken child in node.Children().ToArray())
|
||||
{
|
||||
WalkNode(child, $"{node.Path}[{idx}]", null, items);
|
||||
idx++;
|
||||
}
|
||||
|
||||
text.Append(string.Join(", ", items));
|
||||
text.Append("})");
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
text.AppendFormat(" as {0}", propertyName);
|
||||
}
|
||||
|
||||
lines.Add(text.ToString());
|
||||
}
|
||||
|
||||
private static void ProcessItem(JToken node, string path, string propertyName, List<string> lines)
|
||||
{
|
||||
string castText = string.Empty;
|
||||
switch (node.Type)
|
||||
{
|
||||
case JTokenType.Boolean:
|
||||
castText = $"bool({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Date:
|
||||
castText = $"DateTime({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Float:
|
||||
castText = $"double({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Guid:
|
||||
castText = $"Guid({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Integer:
|
||||
castText = $"int({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Null:
|
||||
castText = "null";
|
||||
break;
|
||||
|
||||
case JTokenType.String:
|
||||
castText = $"string({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.TimeSpan:
|
||||
castText = $"TimeSpan({path})";
|
||||
break;
|
||||
|
||||
case JTokenType.Uri:
|
||||
castText = $"Uri({path})";
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(
|
||||
$"JTokenType '{node.Type}' cannot be converted to a Dynamic Linq cast operator.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
{
|
||||
castText += $" as {propertyName}";
|
||||
}
|
||||
|
||||
lines.Add(castText);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,12 +2,12 @@
|
||||
using System.Net.Sockets;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace WireMock.Http
|
||||
namespace WireMock.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// Port Utility class
|
||||
/// </summary>
|
||||
public static class PortUtil
|
||||
public static class PortUtils
|
||||
{
|
||||
private static readonly Regex UrlDetailsRegex = new Regex(@"^(?<proto>\w+)://[^/]+?(?<port>\d+)/?", RegexOptions.Compiled);
|
||||
|
||||
24
src/WireMock.Net/Util/RegexUtils.cs
Normal file
24
src/WireMock.Net/Util/RegexUtils.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace WireMock.Utils
|
||||
{
|
||||
internal static class RegexUtils
|
||||
{
|
||||
public static Dictionary<string, string> GetNamedGroups(Regex regex, string input)
|
||||
{
|
||||
var namedGroupsDictionary = new Dictionary<string, string>();
|
||||
|
||||
GroupCollection groups = regex.Match(input).Groups;
|
||||
foreach (string groupName in regex.GetGroupNames())
|
||||
{
|
||||
if (groups[groupName].Captures.Count > 0)
|
||||
{
|
||||
namedGroupsDictionary.Add(groupName, groups[groupName].Value);
|
||||
}
|
||||
}
|
||||
|
||||
return namedGroupsDictionary;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
|
||||
<AssemblyTitle>WireMock.Net</AssemblyTitle>
|
||||
<Version>1.0.4.14</Version>
|
||||
<Version>1.0.4.16</Version>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
@@ -37,6 +37,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Util\IndexableDictionary.cs" />
|
||||
<Compile Remove="Util\NamedReaderWriterLocker.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -49,7 +50,7 @@
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
||||
<PackageReference Include="RestEase" Version="1.4.4" />
|
||||
<PackageReference Include="MimeKitLite" Version="2.0.1" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.8.17" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.8.18" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
|
||||
|
||||
@@ -48,15 +48,15 @@ namespace WireMock.Net.Tests
|
||||
[Fact]
|
||||
public void FluentMockServer_Admin_StartStop()
|
||||
{
|
||||
var server1 = FluentMockServer.Start("http://localhost:9091");
|
||||
var server1 = FluentMockServer.Start("http://localhost:19091");
|
||||
|
||||
Check.That(server1.Urls[0]).Equals("http://localhost:9091");
|
||||
Check.That(server1.Urls[0]).Equals("http://localhost:19091");
|
||||
|
||||
server1.Stop();
|
||||
|
||||
var server2 = FluentMockServer.Start("http://localhost:9091/");
|
||||
var server2 = FluentMockServer.Start("http://localhost:19091/");
|
||||
|
||||
Check.That(server2.Urls[0]).Equals("http://localhost:9091/");
|
||||
Check.That(server2.Urls[0]).Equals("http://localhost:19091/");
|
||||
|
||||
server2.Stop();
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace WireMock.Net.Tests
|
||||
[Fact]
|
||||
public async Task FluentMockServer_Should_respond_to_request_bodyAsCallback()
|
||||
{
|
||||
// given
|
||||
// Assign
|
||||
var _server = FluentMockServer.Start();
|
||||
|
||||
_server
|
||||
@@ -114,14 +114,18 @@ namespace WireMock.Net.Tests
|
||||
.WithPath("/foo")
|
||||
.UsingGet())
|
||||
.RespondWith(Response.Create()
|
||||
.WithStatusCode(200)
|
||||
.WithBody(req => $"{{ path: '{req.Path}' }}"));
|
||||
.WithStatusCode(500)
|
||||
.WithHeader("H1", "X1")
|
||||
.WithBody(req => $"path: {req.Path}"));
|
||||
|
||||
// when
|
||||
var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
|
||||
// Act
|
||||
var response = await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
|
||||
|
||||
// then
|
||||
Check.That(response).IsEqualTo("{ path: '/foo' }");
|
||||
// Assert
|
||||
string content = await response.Content.ReadAsStringAsync();
|
||||
Check.That(content).IsEqualTo("path: /foo");
|
||||
Check.That((int) response.StatusCode).IsEqualTo(500);
|
||||
Check.That(response.Headers.GetValues("H1")).ContainsExactly("X1");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using NFluent;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Matchers;
|
||||
using Xunit;
|
||||
|
||||
@@ -45,43 +46,41 @@ namespace WireMock.Net.Tests.Matchers
|
||||
Check.That(matcher.IsMatch(input)).IsEqualTo(0.0d);
|
||||
}
|
||||
|
||||
//[Fact]
|
||||
//public void LinqMatcher_For_Object_IsMatch()
|
||||
//{
|
||||
// // Assign
|
||||
// var input = new
|
||||
// {
|
||||
// Id = 9,
|
||||
// Name = "Test"
|
||||
// };
|
||||
[Fact]
|
||||
public void LinqMatcher_For_Object_IsMatch()
|
||||
{
|
||||
// Assign
|
||||
var input = new
|
||||
{
|
||||
Id = 9,
|
||||
Name = "Test"
|
||||
};
|
||||
|
||||
// // Act
|
||||
// var matcher = new LinqMatcher("Id > 1 AND Name == \"Test\"");
|
||||
// Act
|
||||
var matcher = new LinqMatcher("Id > 1 AND Name == \"Test\"");
|
||||
double match = matcher.IsMatch(input);
|
||||
|
||||
// double match = matcher.IsMatch(input);
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
}
|
||||
|
||||
// // Assert
|
||||
// Assert.Equal(1.0, match);
|
||||
//}
|
||||
[Fact]
|
||||
public void LinqMatcher_For_JObject_IsMatch()
|
||||
{
|
||||
// Assign
|
||||
var input = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
};
|
||||
|
||||
//[Fact]
|
||||
//public void LinqMatcher_For_JObject_IsMatch()
|
||||
//{
|
||||
// // Assign
|
||||
// var input = new JObject
|
||||
// {
|
||||
// { "Id", new JValue(9) },
|
||||
// { "Name", new JValue("Test") }
|
||||
// };
|
||||
// Act
|
||||
var matcher = new LinqMatcher("Id > 1 AND Name == \"Test\"");
|
||||
double match = matcher.IsMatch(input);
|
||||
|
||||
// // Act
|
||||
// var matcher = new LinqMatcher("it.Id > 1 AND it.Name == \"Test\"");
|
||||
|
||||
// double match = matcher.IsMatch(input);
|
||||
|
||||
// // Assert
|
||||
// Assert.Equal(1.0, match);
|
||||
//}
|
||||
// Assert
|
||||
Assert.Equal(1.0, match);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void LinqMatcher_GetName()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using NFluent;
|
||||
using WireMock.Models;
|
||||
@@ -150,5 +149,30 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
|
||||
Check.That(((dynamic)responseMessage.BodyAsJson).value).Equals(42);
|
||||
Check.That(responseMessage.BodyEncoding).Equals(Encoding.ASCII);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_WithBody_Func()
|
||||
{
|
||||
// Assign
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost/test"), "GET", ClientIp);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithStatusCode(500)
|
||||
.WithHeader("H1", "X1")
|
||||
.WithHeader("H2", "X2")
|
||||
.WithBody(req => $"path: {req.Path}");
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).IsEqualTo("path: /test");
|
||||
Check.That(responseMessage.BodyAsBytes).IsNull();
|
||||
Check.That(responseMessage.BodyAsJson).IsNull();
|
||||
Check.That(responseMessage.BodyEncoding.CodePage).Equals(Encoding.UTF8.CodePage);
|
||||
Check.That(responseMessage.StatusCode).IsEqualTo(500);
|
||||
Check.That(responseMessage.Headers["H1"].ToString()).IsEqualTo("X1");
|
||||
Check.That(responseMessage.Headers["H2"].ToString()).IsEqualTo("X2");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,324 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilderTests
|
||||
{
|
||||
public class ResponseWithHandlebarsJsonPathTests
|
||||
{
|
||||
private const string ClientIp = "::1";
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Object_ResponseBodyAsJson()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = @"{
|
||||
""Stores"": [
|
||||
""Lambton Quay"",
|
||||
""Willis Street""
|
||||
],
|
||||
""Manufacturers"": [
|
||||
{
|
||||
""Name"": ""Acme Co"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Anvil"",
|
||||
""Price"": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
""Name"": ""Contoso"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Elbow Grease"",
|
||||
""Price"": 99.95
|
||||
},
|
||||
{
|
||||
""Name"": ""Headlight Fluid"",
|
||||
""Price"": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}"
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"]["Name"].ToString()).Equals("Acme Co");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Number_ResponseBodyAsJson()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "{ \"Price\": 99 }" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{JsonPath.SelectToken request.body \"..Price\"}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"].Value<long>()).Equals(99);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Request_BodyAsString()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = @"{
|
||||
""Stores"": [
|
||||
""Lambton Quay"",
|
||||
""Willis Street""
|
||||
],
|
||||
""Manufacturers"": [
|
||||
{
|
||||
""Name"": ""Acme Co"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Anvil"",
|
||||
""Price"": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
""Name"": ""Contoso"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Elbow Grease"",
|
||||
""Price"": 99.95
|
||||
},
|
||||
{
|
||||
""Name"": ""Headlight Fluid"",
|
||||
""Price"": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}"
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).Equals("{\r\n \"Name\": \"Acme Co\",\r\n \"Products\": [\r\n {\r\n \"Name\": \"Anvil\",\r\n \"Price\": 50\r\n }\r\n ]\r\n}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Request_BodyAsJObject()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = JObject.Parse(@"{
|
||||
'Stores': [
|
||||
'Lambton Quay',
|
||||
'Willis Street'
|
||||
],
|
||||
'Manufacturers': [
|
||||
{
|
||||
'Name': 'Acme Co',
|
||||
'Products': [
|
||||
{
|
||||
'Name': 'Anvil',
|
||||
'Price': 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'Name': 'Contoso',
|
||||
'Products': [
|
||||
{
|
||||
'Name': 'Elbow Grease',
|
||||
'Price': 99.95
|
||||
},
|
||||
{
|
||||
'Name': 'Headlight Fluid',
|
||||
'Price': 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}")
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{JsonPath.SelectToken request.bodyAsJson \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).Equals("{\r\n \"Name\": \"Acme Co\",\r\n \"Products\": [\r\n {\r\n \"Name\": \"Anvil\",\r\n \"Price\": 50\r\n }\r\n ]\r\n}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectTokens_Request_BodyAsString()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = @"{
|
||||
""Stores"": [
|
||||
""Lambton Quay"",
|
||||
""Willis Street""
|
||||
],
|
||||
""Manufacturers"": [
|
||||
{
|
||||
""Name"": ""Acme Co"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Anvil"",
|
||||
""Price"": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
""Name"": ""Contoso"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Elbow Grease"",
|
||||
""Price"": 99.95
|
||||
},
|
||||
{
|
||||
""Name"": ""Headlight Fluid"",
|
||||
""Price"": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}"
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.body \"$..Products[?(@.Price >= 50)].Name\"}}{{#each this}}%{{@index}}:{{this}}%{{/each}}{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).Equals("%0:Anvil%%1:Elbow Grease%");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectTokens_Request_BodyAsJObject()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = JObject.Parse(@"{
|
||||
'Stores': [
|
||||
'Lambton Quay',
|
||||
'Willis Street'
|
||||
],
|
||||
'Manufacturers': [
|
||||
{
|
||||
'Name': 'Acme Co',
|
||||
'Products': [
|
||||
{
|
||||
'Name': 'Anvil',
|
||||
'Price': 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'Name': 'Contoso',
|
||||
'Products': [
|
||||
{
|
||||
'Name': 'Elbow Grease',
|
||||
'Price': 99.95
|
||||
},
|
||||
{
|
||||
'Name': 'Headlight Fluid',
|
||||
'Price': 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}")
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.bodyAsJson \"$..Products[?(@.Price >= 50)].Name\"}}{{#each this}}%{{@index}}:{{this}}%{{/each}}{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).Equals("%0:Anvil%%1:Elbow Grease%");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_JsonPath_SelectTokens_Throws()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = JObject.Parse(@"{
|
||||
'Stores': [
|
||||
'Lambton Quay',
|
||||
'Willis Street'
|
||||
]
|
||||
}")
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.body \"$..Products[?(@.Price >= 50)].Name\"}}{{id}} {{value}},{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request)).Throws<ArgumentNullException>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilderTests
|
||||
{
|
||||
public class ResponseWithHandlebarsLinqTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String0()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234/pathtest"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.Path 'it'}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("/pathtest");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String1()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
}
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 'it.Name + \"_123\"' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("Test_123");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq1_String2()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
}
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 'new(it.Name + \"_123\" as N, it.Id as I)' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("{ N = Test_123, I = 9 }");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_Linq2_Object()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
}
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{#Linq request.bodyAsJson 'new(it.Name + \"_123\" as N, it.Id as I)' }}{{this}}{{/Linq}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"].ToString()).Equals("{ N = Test_123, I = 9 }");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq_Throws_NotSupportedException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsJson = new { x = "x" }};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson 1}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request)).Throws<NotSupportedException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq1_Throws_ArgumentNullException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.body 'Name'}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request)).Throws<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_Linq1_Throws_ArgumentException()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson}} ''" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request)).Throws<ArgumentException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Response_ProvideResponse_Handlebars_Linq1_ParseError_Returns_Empty()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
}
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{Linq request.bodyAsJson '---' }}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"].ToString()).IsEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Response_ProvideResponse_Handlebars_Linq2_ParseError_Returns_Empty()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = new JObject
|
||||
{
|
||||
{ "Id", new JValue(9) },
|
||||
{ "Name", new JValue("Test") }
|
||||
}
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", "::1", body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBodyAsJson(new { x = "{{#Linq request.bodyAsJson '---' }}{{this}}{{/Linq}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"].ToString()).IsEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
using System;
|
||||
using NFluent;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.ResponseBuilderTests
|
||||
{
|
||||
public class ResponseWithHandlebarsRegexTests
|
||||
{
|
||||
private const string ClientIp = "::1";
|
||||
|
||||
[Fact]
|
||||
public async void Response_ProvideResponse_Handlebars_RegexMatch()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "abc" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{Regex.Match request.body \"^(?<x>\\w+)$\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.Body).Equals("abc");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Response_ProvideResponse_Handlebars_RegexMatch_NoMatch()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "abc" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{Regex.Match request.body \"^?0$\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.Body).Equals("");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Response_ProvideResponse_Handlebars_RegexMatch_NoMatch_WithDefaultValue()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "abc" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{Regex.Match request.body \"^?0$\" \"d\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.Body).Equals("d");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Response_ProvideResponse_Handlebars_RegexMatch2()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "https://localhost:5000/" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{#Regex.Match request.body \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\"}}{{this.port}}-{{this.proto}}{{/Regex.Match}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.Body).Equals("5000-https");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Response_ProvideResponse_Handlebars_RegexMatch2_NoMatch()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "{{\\test" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{#Regex.Match request.body \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\"}}{{this}}{{/Regex.Match}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.Body).Equals("");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async void Response_ProvideResponse_Handlebars_RegexMatch2_NoMatch_WithDefaultValue()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "{{\\test" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{#Regex.Match request.body \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\" \"x\"}}{{this}}{{/Regex.Match}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// assert
|
||||
Check.That(responseMessage.Body).Equals("x");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_RegexMatch2_Throws()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "{{\\test" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithBody("{{#Regex.Match request.bodyAsJson \"^(?<proto>\\w+)://[^/]+?(?<port>\\d+)/?\"}}{{/Regex.Match}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act and Assert
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request)).Throws<NotSupportedException>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ using Microsoft.Owin;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
#endif
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using WireMock.Models;
|
||||
using WireMock.ResponseBuilders;
|
||||
@@ -186,314 +185,6 @@ namespace WireMock.Net.Tests.ResponseBuilderTests
|
||||
Check.That(responseMessage.Body).Equals("test http://localhost:1234 1234 http localhost");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Object_ResponseBodyAsJson()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = @"{
|
||||
""Stores"": [
|
||||
""Lambton Quay"",
|
||||
""Willis Street""
|
||||
],
|
||||
""Manufacturers"": [
|
||||
{
|
||||
""Name"": ""Acme Co"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Anvil"",
|
||||
""Price"": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
""Name"": ""Contoso"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Elbow Grease"",
|
||||
""Price"": 99.95
|
||||
},
|
||||
{
|
||||
""Name"": ""Headlight Fluid"",
|
||||
""Price"": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}"
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"]).IsNotNull();
|
||||
Check.That(j["x"]["Name"].ToString()).Equals("Acme Co");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Number_ResponseBodyAsJson()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData { BodyAsString = "{ \"Price\": 99 }" };
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBodyAsJson(new { x = "{{JsonPath.SelectToken request.body \"..Price\"}}" })
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
JObject j = JObject.FromObject(responseMessage.BodyAsJson);
|
||||
Check.That(j["x"].Value<long>()).Equals(99);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Request_BodyAsString()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = @"{
|
||||
""Stores"": [
|
||||
""Lambton Quay"",
|
||||
""Willis Street""
|
||||
],
|
||||
""Manufacturers"": [
|
||||
{
|
||||
""Name"": ""Acme Co"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Anvil"",
|
||||
""Price"": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
""Name"": ""Contoso"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Elbow Grease"",
|
||||
""Price"": 99.95
|
||||
},
|
||||
{
|
||||
""Name"": ""Headlight Fluid"",
|
||||
""Price"": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}"
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{JsonPath.SelectToken request.body \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).Equals("{\r\n \"Name\": \"Acme Co\",\r\n \"Products\": [\r\n {\r\n \"Name\": \"Anvil\",\r\n \"Price\": 50\r\n }\r\n ]\r\n}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectToken_Request_BodyAsJObject()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = JObject.Parse(@"{
|
||||
'Stores': [
|
||||
'Lambton Quay',
|
||||
'Willis Street'
|
||||
],
|
||||
'Manufacturers': [
|
||||
{
|
||||
'Name': 'Acme Co',
|
||||
'Products': [
|
||||
{
|
||||
'Name': 'Anvil',
|
||||
'Price': 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'Name': 'Contoso',
|
||||
'Products': [
|
||||
{
|
||||
'Name': 'Elbow Grease',
|
||||
'Price': 99.95
|
||||
},
|
||||
{
|
||||
'Name': 'Headlight Fluid',
|
||||
'Price': 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}")
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{JsonPath.SelectToken request.bodyAsJson \"$.Manufacturers[?(@.Name == 'Acme Co')]\"}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).Equals("{\r\n \"Name\": \"Acme Co\",\r\n \"Products\": [\r\n {\r\n \"Name\": \"Anvil\",\r\n \"Price\": 50\r\n }\r\n ]\r\n}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectTokens_Request_BodyAsString()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsString = @"{
|
||||
""Stores"": [
|
||||
""Lambton Quay"",
|
||||
""Willis Street""
|
||||
],
|
||||
""Manufacturers"": [
|
||||
{
|
||||
""Name"": ""Acme Co"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Anvil"",
|
||||
""Price"": 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
""Name"": ""Contoso"",
|
||||
""Products"": [
|
||||
{
|
||||
""Name"": ""Elbow Grease"",
|
||||
""Price"": 99.95
|
||||
},
|
||||
{
|
||||
""Name"": ""Headlight Fluid"",
|
||||
""Price"": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}"
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.body \"$..Products[?(@.Price >= 50)].Name\"}}{{id}} {{value}},{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).Equals("0 Anvil,1 Elbow Grease,");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_JsonPath_SelectTokens_Request_BodyAsJObject()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = JObject.Parse(@"{
|
||||
'Stores': [
|
||||
'Lambton Quay',
|
||||
'Willis Street'
|
||||
],
|
||||
'Manufacturers': [
|
||||
{
|
||||
'Name': 'Acme Co',
|
||||
'Products': [
|
||||
{
|
||||
'Name': 'Anvil',
|
||||
'Price': 50
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
'Name': 'Contoso',
|
||||
'Products': [
|
||||
{
|
||||
'Name': 'Elbow Grease',
|
||||
'Price': 99.95
|
||||
},
|
||||
{
|
||||
'Name': 'Headlight Fluid',
|
||||
'Price': 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}")
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.bodyAsJson \"$..Products[?(@.Price >= 50)].Name\"}}{{id}} {{value}},{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
var responseMessage = await response.ProvideResponseAsync(request);
|
||||
|
||||
// Assert
|
||||
Check.That(responseMessage.Body).Equals("0 Anvil,1 Elbow Grease,");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Response_ProvideResponse_Handlebars_JsonPath_SelectTokens_Throws()
|
||||
{
|
||||
// Assign
|
||||
var body = new BodyData
|
||||
{
|
||||
BodyAsJson = JObject.Parse(@"{
|
||||
'Stores': [
|
||||
'Lambton Quay',
|
||||
'Willis Street'
|
||||
]
|
||||
}")
|
||||
};
|
||||
|
||||
var request = new RequestMessage(new UrlDetails("http://localhost:1234"), "POST", ClientIp, body);
|
||||
|
||||
var response = Response.Create()
|
||||
.WithHeader("Content-Type", "application/json")
|
||||
.WithBody("{{#JsonPath.SelectTokens request.body \"$..Products[?(@.Price >= 50)].Name\"}}{{id}} {{value}},{{/JsonPath.SelectTokens}}")
|
||||
.WithTransformer();
|
||||
|
||||
// Act
|
||||
Check.ThatAsyncCode(() => response.ProvideResponseAsync(request)).Throws<ArgumentNullException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Response_ProvideResponse_Handlebars_WithBodyAsJson_ResultAsArray()
|
||||
{
|
||||
|
||||
92
test/WireMock.Net.Tests/Util/JsonUtilsTests.cs
Normal file
92
test/WireMock.Net.Tests/Util/JsonUtilsTests.cs
Normal file
@@ -0,0 +1,92 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NFluent;
|
||||
using System.Linq.Dynamic.Core;
|
||||
using WireMock.Util;
|
||||
using Xunit;
|
||||
|
||||
namespace WireMock.Net.Tests.Util
|
||||
{
|
||||
public class JsonUtilsTests
|
||||
{
|
||||
[Fact]
|
||||
public void JsonUtils_ParseJTokenToObject()
|
||||
{
|
||||
// Assign
|
||||
object value = "test";
|
||||
|
||||
// Act
|
||||
string result = JsonUtils.ParseJTokenToObject<string>(value);
|
||||
|
||||
// Assert
|
||||
Check.That(result).IsEqualTo(default(string));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonUtils_GenerateDynamicLinqStatement_JToken()
|
||||
{
|
||||
// Assign
|
||||
JToken j = "Test";
|
||||
|
||||
// Act
|
||||
string line = JsonUtils.GenerateDynamicLinqStatement(j);
|
||||
|
||||
// Assert
|
||||
var queryable = new[] { j }.AsQueryable().Select(line);
|
||||
bool result = queryable.Any("it == \"Test\"");
|
||||
Check.That(result).IsTrue();
|
||||
|
||||
Check.That(line).IsEqualTo("string(it)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonUtils_GenerateDynamicLinqStatement_JObject()
|
||||
{
|
||||
// Assign
|
||||
var j = new JObject
|
||||
{
|
||||
{"U", new JValue(new Uri("http://localhost:80/abc?a=5"))},
|
||||
{"N", new JValue((object) null)},
|
||||
{"G", new JValue(Guid.NewGuid())},
|
||||
{"Flt", new JValue(10.0f)},
|
||||
{"Dbl", new JValue(Math.PI)},
|
||||
{"Check", new JValue(true)},
|
||||
{"Items", new JArray(new[] {new JValue(4), new JValue(8)})},
|
||||
{
|
||||
"Child", new JObject
|
||||
{
|
||||
{"ChildId", new JValue(4)},
|
||||
{"ChildDateTime", new JValue(new DateTime(2018, 2, 17))},
|
||||
{"TS", new JValue(TimeSpan.FromMilliseconds(999))}
|
||||
}
|
||||
},
|
||||
{"Id", new JValue(9)},
|
||||
{"Name", new JValue("Test")}
|
||||
};
|
||||
|
||||
// Act
|
||||
string line = JsonUtils.GenerateDynamicLinqStatement(j);
|
||||
|
||||
// Assert
|
||||
var queryable = new[] { j }.AsQueryable().Select(line);
|
||||
bool result = queryable.Any("Id > 4");
|
||||
Check.That(result).IsTrue();
|
||||
|
||||
Check.That(line).IsEqualTo("new (Uri(U) as U, null as N, Guid(G) as G, double(Flt) as Flt, double(Dbl) as Dbl, bool(Check) as Check, (new [] { int(Items[0]), int(Items[1])}) as Items, new (int(Child.ChildId) as ChildId, DateTime(Child.ChildDateTime) as ChildDateTime, TimeSpan(Child.TS) as TS) as Child, int(Id) as Id, string(Name) as Name)");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void JsonUtils_GenerateDynamicLinqStatement_Throws()
|
||||
{
|
||||
// Assign
|
||||
var j = new JObject
|
||||
{
|
||||
{"B", new JValue(new byte[] {48, 49})}
|
||||
};
|
||||
|
||||
// Act and Assert
|
||||
Check.ThatCode(() => JsonUtils.GenerateDynamicLinqStatement(j)).Throws<NotSupportedException>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,8 @@
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.4" />
|
||||
<PackageReference Include="System.Threading" Version="4.3.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.8.18" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)' == 'net452'">
|
||||
|
||||
Reference in New Issue
Block a user