Add a new stub mapping

This commit is contained in:
Stef Heyenrath
2017-01-27 21:19:30 +01:00
parent a334974bef
commit 1f33e6a671
28 changed files with 576 additions and 264 deletions

View File

@@ -5,7 +5,29 @@ A C# .NET version based on https://github.com/alexvictoor/WireMock which tries t
[![Version](https://img.shields.io/nuget/v/WireMock.Net.svg)](https://www.nuget.org/packages/WireMock.Net)
Based on class HttpListener from the .net framework, it is very lightweight and have no external dependencies.
Based on class HttpListener from the .net framework, it is very lightweight and have no external dependencies.
## Admin API Reference
The WireMock admin API provides functionality to define the mappings via a http interface. The following interfaces are supported:
### /__admin/mappings
The mappings defined in the mock service.
* `GET /__admin/mappings` --> Gets all defined mappings
* `DELETE /__admin/mappings` --> Create a new stub mapping
* `POST /__admin/mappings` --> TODO
* `DELETE /__admin/mappings` --> TODO
### /__admin/requests
Logged requests and responses received by the mock service.
* `GET /__admin/requests` --> Get received requests
* `GET /__admin/requests/{requestId}` --> TODO
* `POST /__admin/requests/reset` --> TODO
* `POST /__admin/requests/count` --> TODO
* `POST /__admin/requests/find` --> TODO
* `GET /__admin/requests/unmatched` --> TODO
* `GET /__admin/requests/unmatched/near-misses` --> TODO
## Stubbing
A core feature of WireMock is the ability to return canned HTTP responses for requests matching criteria.
@@ -303,25 +325,5 @@ var server = FluentMockServer.Start(port: 8443, ssl: true);
```
Obviously you need a certificate registered on your box, properly associated with your application and the port number that will be used. This is not really specific to WireMock, not very straightforward and hence the following stackoverflow thread might come handy: [Httplistener with https support](http://stackoverflow.com/questions/11403333/httplistener-with-https-support)
## Admin API Reference
The WireMock admin API provides functionality to define the mappings via a http interface. The following interfaces are supported:
### /__admin/mappings
The mappings defined in the mock service.
* `GET /__admin/mappings` --> Gets all defined mappings.
* `DELETE /__admin/mappings` --> TODO
* `POST /__admin/mappings` --> TODO
* `DELETE /__admin/mappings` --> TODO
### /__admin/requests
Logged requests and responses received by the mock service.
* `GET /__admin/requests` --> Get received requests
* `GET /__admin/requests/{requestId}` --> TODO
* `POST /__admin/requests/reset` --> TODO
* `POST /__admin/requests/count` --> TODO
* `POST /__admin/requests/find` --> TODO
* `GET /__admin/requests/unmatched` --> TODO
* `GET /__admin/requests/unmatched/near-misses` --> TODO
## Simulating faults
Currently not done - need to get rid of HttpListener and use lower level TcpListener in order to be able to implement this properly

View File

@@ -28,6 +28,7 @@ namespace WireMock.Net.ConsoleApplication
// http://localhost:8080/gffgfgf/sddsds?start=1000&stop=1&stop=2
server
.Given(Request.Create().WithUrl("/*").UsingGet().WithParam("start"))
.WithGuid(Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05"))
.RespondWith(Response.Create()
.WithStatusCode(200)
.WithHeader("Content-Type", "application/json")

View File

@@ -13,7 +13,7 @@ namespace WireMock.Admin.Mappings
/// <value>
/// The unique identifier.
/// </value>
public Guid Guid { get; set; }
public Guid? Guid { get; set; }
/// <summary>
/// Gets or sets the request.

View File

@@ -20,5 +20,13 @@
/// The pattern.
/// </value>
public string Pattern { get; set; }
/// <summary>
/// Gets or sets the ignore case.
/// </summary>
/// <value>
/// The ignore case.
/// </value>
public bool? IgnoreCase { get; set; }
}
}

View File

@@ -8,12 +8,12 @@ namespace WireMock.Admin.Mappings
public class RequestModel
{
/// <summary>
/// Gets or sets the URL.
/// Gets or sets the URL. (Can be a string or a UrlModel)
/// </summary>
/// <value>
/// The URL.
/// </value>
public UrlModel Url { get; set; }
public object Url { get; set; }
/// <summary>
/// The methods

View File

@@ -13,7 +13,7 @@ namespace WireMock.Admin.Mappings
/// <value>
/// The HTTP status.
/// </value>
public int StatusCode { get; set; }
public int? StatusCode { get; set; }
/// <summary>
/// Gets or sets the body.
@@ -23,6 +23,30 @@ namespace WireMock.Admin.Mappings
/// </value>
public string Body { get; set; }
/// <summary>
/// Gets or sets the body.
/// </summary>
/// <value>
/// The body.
/// </value>
public string BodyAsBase64 { get; set; }
/// <summary>
/// Gets or sets the body (as JSON object).
/// </summary>
/// <value>
/// The body.
/// </value>
public object BodyAsJson { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [use transformer].
/// </summary>
/// <value>
/// <c>true</c> if [use transformer]; otherwise, <c>false</c>.
/// </value>
public bool UseTransformer { get; set; }
/// <summary>
/// Gets or sets the headers.
/// </summary>

View File

@@ -13,6 +13,6 @@ namespace WireMock.Admin.Mappings
/// <value>
/// The matchers.
/// </value>
public IList<MatcherModel> Matchers { get; set; }
public MatcherModel[] Matchers { get; set; }
}
}

View File

@@ -7,9 +7,9 @@ namespace WireMock
{
internal class DynamicResponseProvider : IResponseProvider
{
private readonly Func<ResponseMessage> _responseMessageFunc;
private readonly Func<RequestMessage, ResponseMessage> _responseMessageFunc;
public DynamicResponseProvider([NotNull] Func<ResponseMessage> responseMessageFunc)
public DynamicResponseProvider([NotNull] Func<RequestMessage, ResponseMessage> responseMessageFunc)
{
Check.NotNull(responseMessageFunc, nameof(responseMessageFunc));
@@ -18,7 +18,7 @@ namespace WireMock
public Task<ResponseMessage> ProvideResponse(RequestMessage requestMessage)
{
return Task.FromResult(_responseMessageFunc());
return Task.FromResult(_responseMessageFunc(requestMessage));
}
}
}

View File

@@ -9,25 +9,28 @@ namespace WireMock
/// </summary>
public class HttpListenerResponseMapper
{
private readonly Encoding _utf8NoBom = new UTF8Encoding(false);
/// <summary>
/// The map.
/// </summary>
/// <param name="responseMessage">
/// The response.
/// </param>
/// <param name="result">
/// The result.
/// </param>
public void Map(ResponseMessage responseMessage, HttpListenerResponse result)
/// <param name="listenerResponse">The listenerResponse.</param>
public void Map(ResponseMessage responseMessage, HttpListenerResponse listenerResponse)
{
result.StatusCode = responseMessage.StatusCode;
listenerResponse.StatusCode = responseMessage.StatusCode;
responseMessage.Headers.ToList().ForEach(pair => result.AddHeader(pair.Key, pair.Value));
responseMessage.Headers.ToList().ForEach(pair => listenerResponse.AddHeader(pair.Key, pair.Value));
if (responseMessage.Body != null)
{
var content = Encoding.UTF8.GetBytes(responseMessage.Body);
result.OutputStream.Write(content, 0, content.Length);
byte[] buffer = _utf8NoBom.GetBytes(responseMessage.Body);
listenerResponse.ContentEncoding = _utf8NoBom;
listenerResponse.ContentLength64 = buffer.Length;
listenerResponse.OutputStream.Write(buffer, 0, buffer.Length);
listenerResponse.OutputStream.Flush();
}
}
}

View File

@@ -1,13 +1,22 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using WireMock.Matchers.Request;
namespace WireMock
{
/// <summary>
/// The route.
/// The Mapping.
/// </summary>
public class Mapping
{
/// <summary>
/// Gets the unique identifier.
/// </summary>
/// <value>
/// The unique identifier.
/// </value>
public Guid Guid { get; }
/// <summary>
/// The Request matcher.
/// </summary>
@@ -21,10 +30,12 @@ namespace WireMock
/// <summary>
/// Initializes a new instance of the <see cref="Mapping"/> class.
/// </summary>
/// <param name="guid">The the unique identifier.</param>
/// <param name="requestMatcher">The request matcher.</param>
/// <param name="provider">The provider.</param>
public Mapping(IRequestMatcher requestMatcher, IResponseProvider provider)
public Mapping(Guid guid, IRequestMatcher requestMatcher, IResponseProvider provider)
{
Guid = guid;
RequestMatcher = requestMatcher;
Provider = provider;
}

View File

@@ -41,6 +41,20 @@ namespace WireMock.Matchers.Request
Matchers = new IMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] params IMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNull(matchers, nameof(matchers));
Name = name;
Matchers = matchers;
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
/// </summary>
@@ -48,6 +62,7 @@ namespace WireMock.Matchers.Request
public RequestMessageCookieMatcher([NotNull] params Func<IDictionary<string, string>, bool>[] funcs)
{
Check.NotNull(funcs, nameof(funcs));
_cookieFuncs = funcs;
}

View File

@@ -41,6 +41,20 @@ namespace WireMock.Matchers.Request
Matchers = new IMatcher[] { new WildcardMatcher(pattern, ignoreCase) };
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] params IMatcher[] matchers)
{
Check.NotNull(name, nameof(name));
Check.NotNull(matchers, nameof(matchers));
Name = name;
Matchers = matchers;
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
/// </summary>
@@ -48,6 +62,7 @@ namespace WireMock.Matchers.Request
public RequestMessageHeaderMatcher([NotNull] params Func<IDictionary<string, string>, bool>[] funcs)
{
Check.NotNull(funcs, nameof(funcs));
_headerFuncs = funcs;
}

View File

@@ -16,10 +16,8 @@ namespace WireMock.RequestBuilders
/// <param name="matcher">
/// The matcher.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
IRequestMatcher WithBody([NotNull] IMatcher matcher);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody([NotNull] IMatcher matcher);
/// <summary>
/// The with body.
@@ -27,10 +25,8 @@ namespace WireMock.RequestBuilders
/// <param name="body">
/// The body.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
IRequestMatcher WithBody(string body);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(string body);
/// <summary>
/// The with body byte[].
@@ -38,10 +34,8 @@ namespace WireMock.RequestBuilders
/// <param name="body">
/// The body as byte[].
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
IRequestMatcher WithBody(byte[] body);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(byte[] body);
/// <summary>
/// The with body string func.
@@ -49,10 +43,8 @@ namespace WireMock.RequestBuilders
/// <param name="body">
/// The body string function.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
IRequestMatcher WithBody(Func<string, bool> body);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(Func<string, bool> body);
/// <summary>
/// The with body byte[] func.
@@ -60,9 +52,7 @@ namespace WireMock.RequestBuilders
/// <param name="body">
/// The body byte[] function.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
IRequestMatcher WithBody(Func<byte[], bool> body);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithBody(Func<byte[], bool> body);
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using WireMock.Matchers;
using WireMock.Matchers.Request;
namespace WireMock.RequestBuilders
@@ -16,30 +17,46 @@ namespace WireMock.RequestBuilders
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">ignore Case</param>
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
IHeadersAndCookiesRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true);
/// <summary>
/// The with header.
/// </summary>
/// <param name="funcs">The headers funcs.</param>
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
IHeadersAndCookiesRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string>, bool>[] funcs);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, string pattern, bool ignoreCase = true);
/// <summary>
/// The with header.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">ignore Case</param>
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
IHeadersAndCookiesRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true);
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, [NotNull] params IMatcher[] matchers);
/// <summary>
/// The with header.
/// </summary>
/// <param name="funcs">The headers funcs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string>, bool>[] funcs);
/// <summary>
/// The with cookie.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">ignore Case</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, string pattern, bool ignoreCase = true);
/// <summary>
/// The with cookie.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] string name, [NotNull] params IMatcher[] matchers);
/// <summary>
/// The with cookie.
/// </summary>
/// <param name="cookieFuncs">The funcs.</param>
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
IHeadersAndCookiesRequestBuilder WithCookie([NotNull] params Func<IDictionary<string, string>, bool>[] cookieFuncs);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithCookie([NotNull] params Func<IDictionary<string, string>, bool>[] cookieFuncs);
}
}

View File

@@ -11,55 +11,55 @@ namespace WireMock.RequestBuilders
/// The using get.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IHeadersAndCookiesRequestBuilder UsingGet();
IRequestBuilder UsingGet();
/// <summary>
/// The using post.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IHeadersAndCookiesRequestBuilder UsingPost();
IRequestBuilder UsingPost();
/// <summary>
/// The using delete.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IHeadersAndCookiesRequestBuilder UsingDelete();
IRequestBuilder UsingDelete();
/// <summary>
/// The using put.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IHeadersAndCookiesRequestBuilder UsingPut();
IRequestBuilder UsingPut();
/// <summary>
/// The using head.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IHeadersAndCookiesRequestBuilder UsingHead();
IRequestBuilder UsingHead();
/// <summary>
/// The using any verb.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IHeadersAndCookiesRequestBuilder UsingAnyVerb();
IRequestBuilder UsingAnyVerb();
/// <summary>
/// The using verb.
/// </summary>
/// <param name="verbs">The verb.</param>
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
IHeadersAndCookiesRequestBuilder UsingVerb([NotNull] params string[] verbs);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder UsingVerb([NotNull] params string[] verbs);
}
}

View File

@@ -20,16 +20,14 @@ namespace WireMock.RequestBuilders
/// <param name="values">
/// The values.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
IRequestMatcher WithParam([NotNull] string key, params string[] values);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithParam([NotNull] string key, params string[] values);
/// <summary>
/// The with parameters.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns>The <see cref="IRequestMatcher"/>.</returns>
IRequestMatcher WithParam([NotNull] params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithParam([NotNull] params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs);
}
}

View File

@@ -13,42 +13,42 @@ namespace WireMock.RequestBuilders
/// The with url.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithUrl([NotNull] params IMatcher[] matchers);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl([NotNull] params IMatcher[] matchers);
/// <summary>
/// The with url.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithUrl([NotNull] params string[] urls);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl([NotNull] params string[] urls);
/// <summary>
/// The with url.
/// </summary>
/// <param name="funcs">The url funcs.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithUrl([NotNull] params Func<string, bool>[] funcs);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithUrl([NotNull] params Func<string, bool>[] funcs);
/// <summary>
/// The with path.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithPath([NotNull] params IMatcher[] matchers);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params IMatcher[] matchers);
/// <summary>
/// The with path.
/// </summary>
/// <param name="paths">The paths.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithPath([NotNull] params string[] paths);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params string[] paths);
/// <summary>
/// The with path.
/// </summary>
/// <param name="func">The path func.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
IUrlAndPathRequestBuilder WithPath([NotNull] params Func<string, bool>[] func);
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithPath([NotNull] params Func<string, bool>[] func);
}
}

View File

@@ -57,8 +57,8 @@ namespace WireMock.RequestBuilders
/// The with url.
/// </summary>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithUrl(params IMatcher[] matchers)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithUrl(params IMatcher[] matchers)
{
_requestMatchers.Add(new RequestMessageUrlMatcher(matchers));
return this;
@@ -68,8 +68,8 @@ namespace WireMock.RequestBuilders
/// The with url.
/// </summary>
/// <param name="urls">The urls.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithUrl(params string[] urls)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithUrl(params string[] urls)
{
_requestMatchers.Add(new RequestMessageUrlMatcher(urls));
return this;
@@ -79,8 +79,8 @@ namespace WireMock.RequestBuilders
/// The with url.
/// </summary>
/// <param name="funcs">The url func.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithUrl(params Func<string, bool>[] funcs)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithUrl(params Func<string, bool>[] funcs)
{
_requestMatchers.Add(new RequestMessageUrlMatcher(funcs));
return this;
@@ -90,8 +90,8 @@ namespace WireMock.RequestBuilders
/// The with url.
/// </summary>
/// <param name="matcher">The matcher.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithPath(params IMatcher[] matcher)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithPath(params IMatcher[] matcher)
{
_requestMatchers.Add(new RequestMessagePathMatcher(matcher));
return this;
@@ -101,8 +101,8 @@ namespace WireMock.RequestBuilders
/// The with path.
/// </summary>
/// <param name="paths">The path.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithPath(params string[] paths)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithPath(params string[] paths)
{
_requestMatchers.Add(new RequestMessagePathMatcher(paths));
return this;
@@ -112,8 +112,8 @@ namespace WireMock.RequestBuilders
/// The with path.
/// </summary>
/// <param name="funcs">The path func.</param>
/// <returns>The <see cref="IUrlAndPathRequestBuilder"/>.</returns>
public IUrlAndPathRequestBuilder WithPath(params Func<string, bool>[] funcs)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithPath(params Func<string, bool>[] funcs)
{
_requestMatchers.Add(new RequestMessagePathMatcher(funcs));
return this;
@@ -123,9 +123,9 @@ namespace WireMock.RequestBuilders
/// The using get.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
public IHeadersAndCookiesRequestBuilder UsingGet()
public IRequestBuilder UsingGet()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("get"));
return this;
@@ -135,9 +135,9 @@ namespace WireMock.RequestBuilders
/// The using post.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
public IHeadersAndCookiesRequestBuilder UsingPost()
public IRequestBuilder UsingPost()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("post"));
return this;
@@ -147,9 +147,9 @@ namespace WireMock.RequestBuilders
/// The using put.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
public IHeadersAndCookiesRequestBuilder UsingPut()
public IRequestBuilder UsingPut()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("put"));
return this;
@@ -159,9 +159,9 @@ namespace WireMock.RequestBuilders
/// The using delete.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
public IHeadersAndCookiesRequestBuilder UsingDelete()
public IRequestBuilder UsingDelete()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("delete"));
return this;
@@ -170,10 +170,8 @@ namespace WireMock.RequestBuilders
/// <summary>
/// The using head.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// </returns>
public IHeadersAndCookiesRequestBuilder UsingHead()
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder UsingHead()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("head"));
return this;
@@ -183,9 +181,9 @@ namespace WireMock.RequestBuilders
/// The using any verb.
/// </summary>
/// <returns>
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
/// The <see cref="IRequestBuilder"/>.
/// </returns>
public IHeadersAndCookiesRequestBuilder UsingAnyVerb()
public IRequestBuilder UsingAnyVerb()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
foreach (var matcher in matchers)
@@ -200,8 +198,8 @@ namespace WireMock.RequestBuilders
/// The using verb.
/// </summary>
/// <param name="verbs">The verbs.</param>
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
public IHeadersAndCookiesRequestBuilder UsingVerb(params string[] verbs)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder UsingVerb(params string[] verbs)
{
_requestMatchers.Add(new RequestMessageMethodMatcher(verbs));
return this;
@@ -213,10 +211,8 @@ namespace WireMock.RequestBuilders
/// <param name="body">
/// The body.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
public IRequestMatcher WithBody(string body)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithBody(string body)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
return this;
@@ -228,10 +224,8 @@ namespace WireMock.RequestBuilders
/// <param name="body">
/// The body as byte[].
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
public IRequestMatcher WithBody(byte[] body)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithBody(byte[] body)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(body));
return this;
@@ -243,10 +237,8 @@ namespace WireMock.RequestBuilders
/// <param name="func">
/// The body function.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
public IRequestMatcher WithBody(Func<string, bool> func)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithBody(Func<string, bool> func)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
@@ -258,10 +250,8 @@ namespace WireMock.RequestBuilders
/// <param name="func">
/// The body function.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
public IRequestMatcher WithBody(Func<byte[], bool> func)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithBody(Func<byte[], bool> func)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(func));
return this;
@@ -271,10 +261,8 @@ namespace WireMock.RequestBuilders
/// The with body.
/// </summary>
/// <param name="matcher">The matcher.</param>
/// <returns>
/// The <see cref="IRequestMatcher" />.
/// </returns>
public IRequestMatcher WithBody(IMatcher matcher)
/// <returns>The <see cref="IRequestBuilder" />.</returns>
public IRequestBuilder WithBody(IMatcher matcher)
{
_requestMatchers.Add(new RequestMessageBodyMatcher(matcher));
return this;
@@ -289,12 +277,10 @@ namespace WireMock.RequestBuilders
/// <param name="values">
/// The values.
/// </param>
/// <returns>
/// The <see cref="IRequestMatcher"/>.
/// </returns>
public IRequestMatcher WithParam(string key, params string[] values)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithParam(string key, params string[] values)
{
_requestMatchers.Add(new RequestMessageParamMatcher(key, values.ToList()));
_requestMatchers.Add(new RequestMessageParamMatcher(key, values));
return this;
}
@@ -302,8 +288,8 @@ namespace WireMock.RequestBuilders
/// The with parameters.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns>The <see cref="IRequestMatcher"/>.</returns>
public IRequestMatcher WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithParam(params Func<IDictionary<string, WireMockList<string>>, bool>[] funcs)
{
_requestMatchers.Add(new RequestMessageParamMatcher(funcs));
return this;
@@ -315,19 +301,31 @@ namespace WireMock.RequestBuilders
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
/// <returns></returns>
public IHeadersAndCookiesRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true)
{
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, pattern, ignoreCase));
return this;
}
/// <summary>
/// With header.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithHeader(string name, params IMatcher[] matchers)
{
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, matchers));
return this;
}
/// <summary>
/// With header.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns></returns>
public IHeadersAndCookiesRequestBuilder WithHeader(params Func<IDictionary<string, string>, bool>[] funcs)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithHeader(params Func<IDictionary<string, string>, bool>[] funcs)
{
_requestMatchers.Add(new RequestMessageHeaderMatcher(funcs));
return this;
@@ -339,19 +337,31 @@ namespace WireMock.RequestBuilders
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
/// <returns></returns>
public IHeadersAndCookiesRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true)
{
_requestMatchers.Add(new RequestMessageCookieMatcher(name, pattern, ignoreCase));
return this;
}
/// <summary>
/// With cookie.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="matchers">The matchers.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithCookie(string name, params IMatcher[] matchers)
{
_requestMatchers.Add(new RequestMessageCookieMatcher(name, matchers));
return this;
}
/// <summary>
/// With header.
/// </summary>
/// <param name="funcs">The funcs.</param>
/// <returns></returns>
public IHeadersAndCookiesRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
public IRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
{
_requestMatchers.Add(new RequestMessageCookieMatcher(funcs));
return this;

View File

@@ -12,15 +12,22 @@ namespace WireMock.ResponseBuilders
/// The with body.
/// </summary>
/// <param name="body">The body.</param>
/// <returns>A <see cref="ITransformResponseBuilder"/>.</returns>
ITransformResponseBuilder WithBody([NotNull] string body);
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBody([NotNull] string body);
/// <summary>
/// The with body.
/// </summary>
/// <param name="body">The body.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBodyAsJson([NotNull] object body);
/// <summary>
/// The with body as base64.
/// </summary>
/// <param name="bodyAsbase64">The body asbase64.</param>
/// <param name="encoding">The Encoding.</param>
/// <returns>A <see cref="ITransformResponseBuilder"/>.</returns>
ITransformResponseBuilder WithBodyAsBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithBodyAsBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
}
}

View File

@@ -1,4 +1,6 @@
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using JetBrains.Annotations;
namespace WireMock.ResponseBuilders
{
@@ -12,7 +14,14 @@ namespace WireMock.ResponseBuilders
/// </summary>
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
/// <returns>The <see cref="IHeadersResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithHeader([NotNull] string name, string value);
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithHeader([NotNull] string name, string value);
/// <summary>
/// The with headers.
/// </summary>
/// <param name="headers">The headers.</param>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithHeaders([NotNull] IDictionary<string,string> headers);
}
}

View File

@@ -13,8 +13,8 @@ namespace WireMock.ResponseBuilders
/// <param name="code">
/// The code.
/// </param>
/// <returns>The <see cref="IHeadersResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithStatusCode(int code);
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithStatusCode(int code);
/// <summary>
/// The with status code.
@@ -22,19 +22,19 @@ namespace WireMock.ResponseBuilders
/// <param name="code">
/// The code.
/// </param>
/// <returns>The <see cref="IHeadersResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithStatusCode(HttpStatusCode code);
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IResponseBuilder WithStatusCode(HttpStatusCode code);
/// <summary>
/// The with Success status code (200).
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithSuccess();
IResponseBuilder WithSuccess();
/// <summary>
/// The with NotFound status code (404).
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
IHeadersResponseBuilder WithNotFound();
IResponseBuilder WithNotFound();
}
}

View File

@@ -9,8 +9,8 @@
/// The with transformer.
/// </summary>
/// <returns>
/// The <see cref="IDelayResponseBuilder"/>.
/// The <see cref="IResponseBuilder"/>.
/// </returns>
IDelayResponseBuilder WithTransformer();
IResponseBuilder WithTransformer();
}
}

View File

@@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using HandlebarsDotNet;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.Validation;
namespace WireMock.ResponseBuilders
@@ -15,7 +18,14 @@ namespace WireMock.ResponseBuilders
public class Response : IResponseBuilder
{
private TimeSpan _delay = TimeSpan.Zero;
private bool _useTransformer;
/// <summary>
/// Gets a value indicating whether [use transformer].
/// </summary>
/// <value>
/// <c>true</c> if [use transformer]; otherwise, <c>false</c>.
/// </value>
public bool UseTransformer { get; private set; }
/// <summary>
/// Gets the response message.
@@ -64,9 +74,9 @@ namespace WireMock.ResponseBuilders
/// The with status code.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>A <see cref="IHeadersResponseBuilder"/>.</returns>\
/// <returns>A <see cref="IResponseBuilder"/>.</returns>\
[PublicAPI]
public IHeadersResponseBuilder WithStatusCode(int code)
public IResponseBuilder WithStatusCode(int code)
{
ResponseMessage.StatusCode = code;
return this;
@@ -76,9 +86,9 @@ namespace WireMock.ResponseBuilders
/// The with status code.
/// </summary>
/// <param name="code">The code.</param>
/// <returns>A <see cref="IHeadersResponseBuilder"/>.</returns>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
[PublicAPI]
public IHeadersResponseBuilder WithStatusCode(HttpStatusCode code)
public IResponseBuilder WithStatusCode(HttpStatusCode code)
{
return WithStatusCode((int)code);
}
@@ -86,9 +96,9 @@ namespace WireMock.ResponseBuilders
/// <summary>
/// The with Success status code (200).
/// </summary>
/// <returns></returns>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
[PublicAPI]
public IHeadersResponseBuilder WithSuccess()
public IResponseBuilder WithSuccess()
{
return WithStatusCode((int)HttpStatusCode.OK);
}
@@ -98,7 +108,7 @@ namespace WireMock.ResponseBuilders
/// </summary>
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
[PublicAPI]
public IHeadersResponseBuilder WithNotFound()
public IResponseBuilder WithNotFound()
{
return WithStatusCode((int)HttpStatusCode.NotFound);
}
@@ -108,8 +118,8 @@ namespace WireMock.ResponseBuilders
/// </summary>
/// <param name="name">The name.</param>
/// <param name="value">The value.</param>
/// <returns>The <see cref="IHeadersResponseBuilder"/>.</returns>
public IHeadersResponseBuilder WithHeader(string name, string value)
/// <returns>The <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithHeader(string name, string value)
{
Check.NotNull(name, nameof(name));
@@ -117,12 +127,23 @@ namespace WireMock.ResponseBuilders
return this;
}
/// <summary>
/// The with headers.
/// </summary>
/// <param name="headers">The headers.</param>
/// <returns></returns>
public IResponseBuilder WithHeaders(IDictionary<string, string> headers)
{
ResponseMessage.Headers = headers;
return this;
}
/// <summary>
/// The with body.
/// </summary>
/// <param name="body">The body.</param>
/// <returns>A <see cref="ITransformResponseBuilder"/>.</returns>
public ITransformResponseBuilder WithBody(string body)
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithBody(string body)
{
Check.NotNull(body, nameof(body));
@@ -130,13 +151,26 @@ namespace WireMock.ResponseBuilders
return this;
}
/// <summary>
/// The with body (AsJson object).
/// </summary>
/// <param name="body">The body.</param>
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithBodyAsJson(object body)
{
Check.NotNull(body, nameof(body));
ResponseMessage.Body = JsonConvert.SerializeObject(body, new JsonSerializerSettings { Formatting = Formatting.None, NullValueHandling = NullValueHandling.Ignore } );
return this;
}
/// <summary>
/// The with body as base64.
/// </summary>
/// <param name="bodyAsbase64">The body asbase64.</param>
/// <param name="encoding">The Encoding.</param>
/// <returns>A <see cref="ITransformResponseBuilder"/>.</returns>
public ITransformResponseBuilder WithBodyAsBase64(string bodyAsbase64, Encoding encoding = null)
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
public IResponseBuilder WithBodyAsBase64(string bodyAsbase64, Encoding encoding = null)
{
Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));
@@ -150,9 +184,9 @@ namespace WireMock.ResponseBuilders
/// <returns>
/// The <see cref="IResponseBuilder"/>.
/// </returns>
public IDelayResponseBuilder WithTransformer()
public IResponseBuilder WithTransformer()
{
_useTransformer = true;
UseTransformer = true;
return this;
}
@@ -183,7 +217,7 @@ namespace WireMock.ResponseBuilders
public async Task<ResponseMessage> ProvideResponse(RequestMessage requestMessage)
{
ResponseMessage responseMessage;
if (_useTransformer)
if (UseTransformer)
{
responseMessage = new ResponseMessage { StatusCode = ResponseMessage.StatusCode, BodyOriginal = ResponseMessage.Body };

View File

@@ -17,14 +17,128 @@ namespace WireMock.Server
/// </summary>
public partial class FluentMockServer
{
private readonly JsonSerializerSettings _settings = new JsonSerializerSettings
{
Formatting = Formatting.None,
NullValueHandling = NullValueHandling.Ignore
};
private void InitAdmin()
{
Given(Request.Create().WithUrl("/__admin/mappings").UsingGet()).RespondWith(new DynamicResponseProvider(MappingsGet));
Given(Request.Create().WithUrl("/__admin/mappings").UsingPost()).RespondWith(new DynamicResponseProvider(MappingsPost));
Given(Request.Create().WithUrl("/__admin/requests").UsingGet()).RespondWith(new DynamicResponseProvider(RequestsGet));
}
private ResponseMessage RequestsGet()
private ResponseMessage MappingsGet(RequestMessage requestMessage)
{
var result = new List<MappingModel>();
foreach (var mapping in Mappings.Where(m => !(m.Provider is DynamicResponseProvider)))
{
var model = ToMappingModel(mapping);
result.Add(model);
}
return ToJson(result);
}
private ResponseMessage MappingsPost(RequestMessage requestMessage)
{
var mappingModel = JsonConvert.DeserializeObject<MappingModel>(requestMessage.Body);
if (mappingModel.Request == null)
return new ResponseMessage { StatusCode = 400, Body = "Request missing" };
if (mappingModel.Response == null)
return new ResponseMessage { StatusCode = 400, Body = "Response missing" };
var requestBuilder = InitRequestBuilder(mappingModel);
var responseBuilder = InitResponseBuilder(mappingModel);
IRespondWithAProviderGuid respondProvider = Given(requestBuilder);
if (mappingModel.Guid != null && mappingModel.Guid != Guid.Empty)
respondProvider = respondProvider.WithGuid(mappingModel.Guid.Value);
respondProvider.RespondWith(responseBuilder);
return new ResponseMessage { Body = "Mapping added" };
}
private IRequestBuilder InitRequestBuilder(MappingModel mappingModel)
{
IRequestBuilder requestBuilder = Request.Create();
string url = mappingModel.Request.Url as string;
if (url != null)
requestBuilder = requestBuilder.WithUrl(url);
else
requestBuilder = requestBuilder.WithUrl("/*");
//UrlModel urlModel = mappingModel.Request.Url as UrlModel;
//if (urlModel?.Matchers != null)
// builder = builder.WithUrl(urlModel.Matchers.Select(Map).ToArray());
if (mappingModel.Request.Methods != null)
requestBuilder = requestBuilder.UsingVerb(mappingModel.Request.Methods);
else
requestBuilder = requestBuilder.UsingAnyVerb();
if (mappingModel.Request.Headers != null)
{
foreach (var headerModel in mappingModel.Request.Headers.Where(h => h.Matchers != null))
{
requestBuilder = requestBuilder.WithHeader(headerModel.Name, headerModel.Matchers.Select(Map).ToArray());
}
}
if (mappingModel.Request.Cookies != null)
{
foreach (var cookieModel in mappingModel.Request.Cookies.Where(c => c.Matchers != null))
{
requestBuilder = requestBuilder.WithCookie(cookieModel.Name, cookieModel.Matchers.Select(Map).ToArray());
}
}
if (mappingModel.Request.Params != null)
{
foreach (var paramModel in mappingModel.Request.Params.Where(p => p.Values != null))
{
requestBuilder = requestBuilder.WithParam(paramModel.Name, paramModel.Values.ToArray());
}
}
if (mappingModel.Request.Body?.Matcher != null)
{
var bodyMatcher = Map(mappingModel.Request.Body.Matcher);
requestBuilder = requestBuilder.WithBody(bodyMatcher);
}
return requestBuilder;
}
private IResponseBuilder InitResponseBuilder(MappingModel mappingModel)
{
IResponseBuilder responseBuilder = Response.Create();
if (mappingModel.Response.StatusCode.HasValue)
responseBuilder = responseBuilder.WithStatusCode(mappingModel.Response.StatusCode.Value);
if (mappingModel.Response.Headers != null)
responseBuilder = responseBuilder.WithHeaders(mappingModel.Response.Headers);
if (mappingModel.Response.Body != null)
responseBuilder = responseBuilder.WithBody(mappingModel.Response.Body);
else if (mappingModel.Response.BodyAsJson != null)
responseBuilder = responseBuilder.WithBodyAsJson(mappingModel.Response.BodyAsJson);
else if (mappingModel.Response.BodyAsBase64 != null)
responseBuilder = responseBuilder.WithBodyAsBase64(mappingModel.Response.BodyAsBase64);
if (mappingModel.Response.UseTransformer)
responseBuilder = responseBuilder.WithTransformer();
return responseBuilder;
}
private ResponseMessage RequestsGet(RequestMessage requestMessage)
{
var result = new List<LogEntryModel>();
foreach (var logEntry in LogEntries.Where(r => !r.RequestMessage.Path.StartsWith("/__admin/")))
@@ -58,68 +172,61 @@ namespace WireMock.Server
return ToJson(result);
}
private ResponseMessage MappingsGet()
private MappingModel ToMappingModel(Mapping mapping)
{
var result = new List<MappingModel>();
foreach (var mapping in Mappings.Where(m => !(m.Provider is DynamicResponseProvider)))
var request = (Request)mapping.RequestMatcher;
var response = (Response)mapping.Provider;
var urlMatchers = request.GetRequestMessageMatchers<RequestMessageUrlMatcher>();
var headerMatchers = request.GetRequestMessageMatchers<RequestMessageHeaderMatcher>();
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
return new MappingModel
{
var request = (Request) mapping.RequestMatcher;
var urlMatchers = request.GetRequestMessageMatchers<RequestMessageUrlMatcher>();
var headerMatchers = request.GetRequestMessageMatchers<RequestMessageHeaderMatcher>();
var cookieMatchers = request.GetRequestMessageMatchers<RequestMessageCookieMatcher>();
var paramsMatchers = request.GetRequestMessageMatchers<RequestMessageParamMatcher>();
var bodyMatcher = request.GetRequestMessageMatcher<RequestMessageBodyMatcher>();
var methodMatcher = request.GetRequestMessageMatcher<RequestMessageMethodMatcher>();
var response = (Response) mapping.Provider;
var model = new MappingModel
Guid = mapping.Guid,
Request = new RequestModel
{
Guid = Guid.NewGuid(),
Request = new RequestModel
Url = new UrlModel
{
Url = new UrlModel
{
Matchers = urlMatchers != null ? Map(urlMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers)) : null
},
Methods = methodMatcher != null ? methodMatcher.Methods : new [] { "any" },
Headers = headerMatchers?.Select(hm => new HeaderModel
{
Name = hm.Name,
Matchers = Map(hm.Matchers)
}).ToList(),
Cookies = cookieMatchers?.Select(hm => new CookieModel
{
Name = hm.Name,
Matchers = Map(hm.Matchers)
}).ToList(),
Params = paramsMatchers?.Select(hm => new ParamModel
{
Name = hm.Key,
Values = hm.Values?.ToList()
}).ToList(),
Body = new BodyModel
{
Matcher = bodyMatcher != null ? Map(bodyMatcher.Matcher) : null
}
Matchers = urlMatchers != null ? Map(urlMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers)) : null
},
Response = new ResponseModel
Methods = methodMatcher != null ? methodMatcher.Methods : new[] { "any" },
Headers = headerMatchers?.Select(hm => new HeaderModel
{
StatusCode = response.ResponseMessage.StatusCode,
Headers = response.ResponseMessage.Headers,
Body = response.ResponseMessage.Body
Name = hm.Name,
Matchers = Map(hm.Matchers)
}).ToList(),
Cookies = cookieMatchers?.Select(hm => new CookieModel
{
Name = hm.Name,
Matchers = Map(hm.Matchers)
}).ToList(),
Params = paramsMatchers?.Select(hm => new ParamModel
{
Name = hm.Key,
Values = hm.Values?.ToList()
}).ToList(),
Body = new BodyModel
{
Matcher = bodyMatcher != null ? Map(bodyMatcher.Matcher) : null
}
};
result.Add(model);
}
return ToJson(result);
},
Response = new ResponseModel
{
StatusCode = response.ResponseMessage.StatusCode,
Headers = response.ResponseMessage.Headers,
Body = response.ResponseMessage.Body,
UseTransformer = response.UseTransformer
}
};
}
private IList<MatcherModel> Map([CanBeNull] IEnumerable<IMatcher> matchers)
private MatcherModel[] Map([CanBeNull] IEnumerable<IMatcher> matchers)
{
return matchers?.Select(Map).Where(x => x != null).ToList();
return matchers?.Select(Map).Where(x => x != null).ToArray();
}
private MatcherModel Map([CanBeNull] IMatcher matcher)
@@ -134,11 +241,32 @@ namespace WireMock.Server
};
}
private IMatcher Map([CanBeNull] MatcherModel matcher)
{
if (matcher == null)
return null;
switch (matcher.Name)
{
case "RegExMatcher":
return new RegexMatcher(matcher.Pattern);
case "JsonPathMatcher":
return new JsonPathMatcher(matcher.Pattern);
case "XPathMatcher":
return new XPathMatcher(matcher.Pattern);
default:
return new WildcardMatcher(matcher.Pattern, matcher.IgnoreCase == true);
}
}
private ResponseMessage ToJson<T>(T result)
{
return new ResponseMessage
{
Body = JsonConvert.SerializeObject(result, Formatting.Indented),
Body = JsonConvert.SerializeObject(result, _settings),
StatusCode = 200,
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
};

View File

@@ -167,8 +167,8 @@ namespace WireMock.Server
/// The given.
/// </summary>
/// <param name="requestMatcher">The request matcher.</param>
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
public IRespondWithAProvider Given(IRequestMatcher requestMatcher)
/// <returns>The <see cref="IRespondWithAProviderGuid"/>.</returns>
public IRespondWithAProviderGuid Given(IRequestMatcher requestMatcher)
{
return new RespondWithAProvider(RegisterMapping, requestMatcher);
}

View File

@@ -0,0 +1,17 @@
using System;
namespace WireMock.Server
{
/// <summary>
/// IRespondWithAProviderGuid
/// </summary>
public interface IRespondWithAProviderGuid : IRespondWithAProvider
{
/// <summary>
/// Define a unique identifier for this mapping.
/// </summary>
/// <param name="guid">The unique identifier.</param>
/// <returns>The <see cref="IRespondWithAProviderGuid"/>.</returns>
IRespondWithAProviderGuid WithGuid(Guid guid);
}
}

View File

@@ -1,12 +1,15 @@
using WireMock.Matchers.Request;
using System;
using WireMock.Matchers.Request;
namespace WireMock.Server
{
/// <summary>
/// The respond with a provider.
/// </summary>
internal class RespondWithAProvider : IRespondWithAProvider
internal class RespondWithAProvider : IRespondWithAProviderGuid
{
private Guid? _guid;
/// <summary>
/// The _registration callback.
/// </summary>
@@ -36,7 +39,20 @@ namespace WireMock.Server
/// </param>
public void RespondWith(IResponseProvider provider)
{
_registrationCallback(new Mapping(_requestMatcher, provider));
var mappingGuid = _guid ?? Guid.NewGuid();
_registrationCallback(new Mapping(mappingGuid, _requestMatcher, provider));
}
/// <summary>
/// Define a unique identifier for this mapping.
/// </summary>
/// <param name="guid">The unique identifier.</param>
/// <returns>The <see cref="IRespondWithAProviderGuid"/>.</returns>
public IRespondWithAProviderGuid WithGuid(Guid guid)
{
_guid = guid;
return this;
}
}
}

View File

@@ -22,9 +22,11 @@ namespace WireMock.Net.Tests
[Test]
public void FluentMockServer_get_routes()
{
var guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
_server = FluentMockServer.Start();
_server.Given(Request.Create().WithUrl("/foo1").UsingGet())
.WithGuid(guid)
.RespondWith(Response.Create().WithStatusCode(201).WithBody("1"));
_server.Given(Request.Create().WithUrl("/foo2").UsingGet())
@@ -32,9 +34,14 @@ namespace WireMock.Net.Tests
var routes = _server.Mappings;
Check.That(routes).HasSize(2);
Check.That(routes.First().RequestMatcher).IsNotNull();
Check.That(routes.First().Provider).IsNotNull();
var enumerable = routes.ToArray();
Check.That(enumerable).HasSize(2);
Check.That(enumerable.First().RequestMatcher).IsNotNull();
Check.That(enumerable.First().Provider).IsNotNull();
Check.That(enumerable.First().Guid).Equals(guid);
Check.That(enumerable[1].Guid).Not.Equals(guid);
}
[Test]