mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-04-01 23:23:29 +02:00
WireMockList
This commit is contained in:
@@ -33,7 +33,8 @@ namespace WireMock.Net.ConsoleApplication
|
|||||||
.WithStatusCode(200)
|
.WithStatusCode(200)
|
||||||
.WithHeader("Content-Type", "application/json")
|
.WithHeader("Content-Type", "application/json")
|
||||||
.WithHeader("Transformed-Postman-Token", "token is {{request.headers.Postman-Token}}")
|
.WithHeader("Transformed-Postman-Token", "token is {{request.headers.Postman-Token}}")
|
||||||
.WithBody(@"{""msg"": ""Hello world! : {{request.url}} : {{request.path}} : {{request.query.start}} : {{request.query.stop.[0]}}""")
|
.WithBody(@"{""msg"": ""Hello world! : {{request.url}} : {{request.path}} :
|
||||||
|
bykey={{request.query.start}} : bykey={{request.query.stop}} byidx0={{request.query.stop.[0]}} byidx1={{request.query.stop.[1]}}""")
|
||||||
.WithTransformer()
|
.WithTransformer()
|
||||||
.WithDelay(TimeSpan.FromMilliseconds(100))
|
.WithDelay(TimeSpan.FromMilliseconds(100))
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock.Matchers.Request
|
namespace WireMock.Matchers.Request
|
||||||
@@ -21,7 +22,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IEnumerable<string> _values;
|
private readonly IEnumerable<string> _values;
|
||||||
|
|
||||||
private readonly Func<IDictionary<string, List<string>>, bool> _func;
|
private readonly Func<IDictionary<string, WireMockList<string>>, bool> _func;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessageParamMatcher"/> class.
|
||||||
@@ -47,7 +48,7 @@ namespace WireMock.Matchers.Request
|
|||||||
/// <param name="func">
|
/// <param name="func">
|
||||||
/// The func.
|
/// The func.
|
||||||
/// </param>
|
/// </param>
|
||||||
public RequestMessageParamMatcher([NotNull] Func<IDictionary<string, List<string>>, bool> func)
|
public RequestMessageParamMatcher([NotNull] Func<IDictionary<string, WireMockList<string>>, bool> func)
|
||||||
{
|
{
|
||||||
Check.NotNull(func, nameof(func));
|
Check.NotNull(func, nameof(func));
|
||||||
_func = func;
|
_func = func;
|
||||||
@@ -64,7 +65,7 @@ namespace WireMock.Matchers.Request
|
|||||||
{
|
{
|
||||||
if (_func != null)
|
if (_func != null)
|
||||||
{
|
{
|
||||||
return _func(requestMessage.Parameters);
|
return _func(requestMessage.Query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return requestMessage.GetParameter(_key).Intersect(_values).Count() == _values.Count();
|
return requestMessage.GetParameter(_key).Intersect(_values).Count() == _values.Count();
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.RequestBuilders
|
namespace WireMock.RequestBuilders
|
||||||
{
|
{
|
||||||
@@ -33,6 +34,6 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>
|
/// <returns>
|
||||||
/// The <see cref="IRequestMatcher"/>.
|
/// The <see cref="IRequestMatcher"/>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
IRequestMatcher WithParam([NotNull] Func<IDictionary<string, List<string>>, bool> func);
|
IRequestMatcher WithParam([NotNull] Func<IDictionary<string, WireMockList<string>>, bool> func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using WireMock.Matchers;
|
using WireMock.Matchers;
|
||||||
using WireMock.Matchers.Request;
|
using WireMock.Matchers.Request;
|
||||||
|
using WireMock.Util;
|
||||||
|
|
||||||
namespace WireMock.RequestBuilders
|
namespace WireMock.RequestBuilders
|
||||||
{
|
{
|
||||||
@@ -299,7 +300,7 @@ namespace WireMock.RequestBuilders
|
|||||||
/// <returns>
|
/// <returns>
|
||||||
/// The <see cref="IRequestMatcher"/>.
|
/// The <see cref="IRequestMatcher"/>.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public IRequestMatcher WithParam(Func<IDictionary<string, List<string>>, bool> func)
|
public IRequestMatcher WithParam(Func<IDictionary<string, WireMockList<string>>, bool> func)
|
||||||
{
|
{
|
||||||
_requestMatchers.Add(new RequestMessageParamMatcher(func));
|
_requestMatchers.Add(new RequestMessageParamMatcher(func));
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using WireMock.Extensions;
|
using WireMock.Extensions;
|
||||||
|
using WireMock.Util;
|
||||||
using WireMock.Validation;
|
using WireMock.Validation;
|
||||||
|
|
||||||
namespace WireMock
|
namespace WireMock
|
||||||
@@ -12,6 +13,41 @@ namespace WireMock
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class RequestMessage
|
public class RequestMessage
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the url.
|
||||||
|
/// </summary>
|
||||||
|
public string Url { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the path.
|
||||||
|
/// </summary>
|
||||||
|
public string Path { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the verb.
|
||||||
|
/// </summary>
|
||||||
|
public string Verb { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the headers.
|
||||||
|
/// </summary>
|
||||||
|
public IDictionary<string, string> Headers { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the query.
|
||||||
|
/// </summary>
|
||||||
|
public IDictionary<string, WireMockList<string>> Query { get; } = new Dictionary<string, WireMockList<string>>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the bodyAsBytes.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] BodyAsBytes { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the body.
|
||||||
|
/// </summary>
|
||||||
|
public string Body { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -40,85 +76,30 @@ namespace WireMock
|
|||||||
query = query.Substring(1);
|
query = query.Substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Parameters = query.Split('&').Aggregate(
|
Query = query.Split('&').Aggregate(
|
||||||
new Dictionary<string, List<string>>(),
|
new Dictionary<string, WireMockList<string>>(),
|
||||||
(dict, term) =>
|
(dict, term) =>
|
||||||
{
|
{
|
||||||
var key = term.Split('=')[0];
|
var key = term.Split('=')[0];
|
||||||
if (!dict.ContainsKey(key))
|
if (!dict.ContainsKey(key))
|
||||||
{
|
{
|
||||||
dict.Add(key, new List<string>());
|
dict.Add(key, new WireMockList<string>());
|
||||||
}
|
}
|
||||||
|
|
||||||
dict[key].Add(term.Split('=')[1]);
|
dict[key].Add(term.Split('=')[1]);
|
||||||
return dict;
|
return dict;
|
||||||
});
|
});
|
||||||
|
|
||||||
var tmpDictionary = new Dictionary<string, object>();
|
|
||||||
foreach (var parameter in Parameters.Where(p => p.Value.Any()))
|
|
||||||
{
|
|
||||||
if (parameter.Value.Count == 1)
|
|
||||||
{
|
|
||||||
tmpDictionary.Add(parameter.Key, parameter.Value.First());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tmpDictionary.Add(parameter.Key, parameter.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Query = tmpDictionary.ToExpandoObject();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the url.
|
/// The get a query parameter.
|
||||||
/// </summary>
|
|
||||||
public string Url { get; private set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the path.
|
|
||||||
/// </summary>
|
|
||||||
public string Path { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the verb.
|
|
||||||
/// </summary>
|
|
||||||
public string Verb { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the headers.
|
|
||||||
/// </summary>
|
|
||||||
public IDictionary<string, string> Headers { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the query parameters.
|
|
||||||
/// </summary>
|
|
||||||
public IDictionary<string, List<string>> Parameters { get; } = new Dictionary<string, List<string>>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the query as object.
|
|
||||||
/// </summary>
|
|
||||||
[PublicAPI]
|
|
||||||
public dynamic Query { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the bodyAsBytes.
|
|
||||||
/// </summary>
|
|
||||||
public byte[] BodyAsBytes { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the body.
|
|
||||||
/// </summary>
|
|
||||||
public string Body { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The get parameter.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">The key.</param>
|
/// <param name="key">The key.</param>
|
||||||
/// <returns>The parameter.s</returns>
|
/// <returns>The query parameter.</returns>
|
||||||
public List<string> GetParameter(string key)
|
public List<string> GetParameter(string key)
|
||||||
{
|
{
|
||||||
return Parameters.ContainsKey(key) ? Parameters[key] : new List<string>();
|
return Query.ContainsKey(key) ? Query[key] : new WireMockList<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
42
src/WireMock/Util/WireMockList.cs
Normal file
42
src/WireMock/Util/WireMockList.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace WireMock.Util
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A special List which overrides the ToString() to return first value.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The generic type</typeparam>
|
||||||
|
/// <seealso cref="List{T}" />
|
||||||
|
public class WireMockList<T> : List<T>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="WireMockList{T}"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public WireMockList()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="WireMockList{T}"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collection">The collection whose elements are copied to the new list.</param>
|
||||||
|
public WireMockList(IEnumerable<T> collection) : base(collection)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a <see cref="string" /> that represents this instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// A <see cref="string" /> that represents this instance.
|
||||||
|
/// </returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
if (this != null && this.Any())
|
||||||
|
return this.First().ToString();
|
||||||
|
|
||||||
|
return base.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using NFluent;
|
using NFluent;
|
||||||
@@ -13,14 +12,16 @@ namespace WireMock.Net.Tests
|
|||||||
public class ResponseTests
|
public class ResponseTests
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Response_ProvideResponse_Handlebars_body()
|
public async Task Response_ProvideResponse_Handlebars_UrlPathVerb()
|
||||||
{
|
{
|
||||||
// given
|
// given
|
||||||
string bodyAsString = "abc";
|
string bodyAsString = "abc";
|
||||||
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
|
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
|
||||||
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", body, bodyAsString);
|
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", body, bodyAsString);
|
||||||
|
|
||||||
var response = Response.Create().WithBody("test {{request.url}} {{request.path}} {{request.verb}}").WithTransformer();
|
var response = Response.Create()
|
||||||
|
.WithBody("test {{request.url}} {{request.path}} {{request.verb}}")
|
||||||
|
.WithTransformer();
|
||||||
|
|
||||||
// act
|
// act
|
||||||
var responseMessage = await response.ProvideResponse(request);
|
var responseMessage = await response.ProvideResponse(request);
|
||||||
@@ -30,7 +31,26 @@ namespace WireMock.Net.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Response_ProvideResponse_Handlebars_headers()
|
public async Task Response_ProvideResponse_Handlebars_Query()
|
||||||
|
{
|
||||||
|
// given
|
||||||
|
string bodyAsString = "abc";
|
||||||
|
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
|
||||||
|
var request = new RequestMessage(new Uri("http://localhost/foo?a=1&a=2&b=5"), "POST", body, bodyAsString);
|
||||||
|
|
||||||
|
var response = Response.Create()
|
||||||
|
.WithBody("test keya={{request.query.a}} idx={{request.query.a.[0]}} idx={{request.query.a.[1]}} keyb={{request.query.b}}")
|
||||||
|
.WithTransformer();
|
||||||
|
|
||||||
|
// act
|
||||||
|
var responseMessage = await response.ProvideResponse(request);
|
||||||
|
|
||||||
|
// then
|
||||||
|
Check.That(responseMessage.Body).Equals("test keya=1 idx=1 idx=2 keyb=5");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Response_ProvideResponse_Handlebars_Headers()
|
||||||
{
|
{
|
||||||
// given
|
// given
|
||||||
string bodyAsString = "abc";
|
string bodyAsString = "abc";
|
||||||
|
|||||||
Reference in New Issue
Block a user