Rename to WireMock.Net

This commit is contained in:
Stef Heyenrath
2017-01-24 22:28:08 +01:00
parent 4809fed513
commit 3cb1a6d2e1
65 changed files with 5 additions and 5 deletions

View File

@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Newtonsoft.Json;
using WireMock.Admin;
using WireMock.Matchers;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
namespace WireMock.Server
{
/// <summary>
/// The fluent mock server.
/// </summary>
public partial class FluentMockServer
{
private void InitAdmin()
{
Given(Request.Create().WithUrl("/__admin/mappings").UsingGet()).RespondWith(new DynamicResponseProvider(MappingsGet));
}
private ResponseMessage MappingsGet()
{
var result = new List<MappingModel>();
foreach (var mapping in Mappings.Where(m => !(m.Provider is DynamicResponseProvider)))
{
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 verbMatcher = request.GetRequestMessageMatcher<RequestMessageVerbMatcher>();
var response = (Response) mapping.Provider;
var model = new MappingModel
{
Guid = Guid.NewGuid(),
Request = new RequestModel
{
Url = new UrlModel
{
Matchers = urlMatchers != null ? Map(urlMatchers.Where(m => m.Matchers != null).SelectMany(m => m.Matchers)) : null
},
Verbs = verbMatcher != null ? verbMatcher.Verbs : 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
}
},
Response = new ResponseModel
{
StatusCode = response.ResponseMessage.StatusCode,
Headers = response.ResponseMessage.Headers,
Body = response.ResponseMessage.Body
}
};
result.Add(model);
}
return ToJson(result);
}
private IList<MatcherModel> Map([CanBeNull] IEnumerable<IMatcher> matchers)
{
return matchers?.Select(Map).Where(x => x != null).ToList();
}
private MatcherModel Map([CanBeNull] IMatcher matcher)
{
if (matcher == null)
return null;
return new MatcherModel
{
Name = matcher.GetType().Name,
Pattern = matcher.GetPattern()
};
}
private ResponseMessage ToJson<T>(T result)
{
return new ResponseMessage
{
Body = JsonConvert.SerializeObject(result, Formatting.Indented),
StatusCode = 200,
Headers = new Dictionary<string, string> { { "Content-Type", "application/json" } }
};
}
}
}

View File

@@ -0,0 +1,272 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using JetBrains.Annotations;
using WireMock.Http;
using WireMock.Matchers.Request;
using WireMock.Validation;
namespace WireMock.Server
{
/// <summary>
/// The fluent mock server.
/// </summary>
public partial class FluentMockServer
{
/// <summary>
/// The _http server.
/// </summary>
private readonly TinyHttpServer _httpServer;
/// <summary>
/// The _mappings.
/// </summary>
private readonly IList<Mapping> _mappings = new List<Mapping>();
/// <summary>
/// The _request logs.
/// </summary>
private readonly IList<RequestMessage> _requestLogs = new List<RequestMessage>();
/// <summary>
/// The _request mapper.
/// </summary>
private readonly HttpListenerRequestMapper _requestMapper = new HttpListenerRequestMapper();
/// <summary>
/// The _response mapper.
/// </summary>
private readonly HttpListenerResponseMapper _responseMapper = new HttpListenerResponseMapper();
/// <summary>
/// The _sync root.
/// </summary>
private readonly object _syncRoot = new object();
/// <summary>
/// The _request processing delay.
/// </summary>
private TimeSpan _requestProcessingDelay = TimeSpan.Zero;
/// <summary>
/// Gets the port.
/// </summary>
public int Port { get; }
/// <summary>
/// Gets the request logs.
/// </summary>
public IEnumerable<RequestMessage> RequestLogs
{
get
{
lock (((ICollection)_requestLogs).SyncRoot)
{
return new ReadOnlyCollection<RequestMessage>(_requestLogs);
}
}
}
/// <summary>
/// Gets the routes.
/// </summary>
public IEnumerable<Mapping> Mappings
{
get
{
lock (((ICollection)_mappings).SyncRoot)
{
return new ReadOnlyCollection<Mapping>(_mappings);
}
}
}
/// <summary>
/// Start this FluentMockServer.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="ssl">The SSL support.</param>
/// <returns>The <see cref="FluentMockServer"/>.</returns>
[PublicAPI]
public static FluentMockServer Start(int port = 0, bool ssl = false)
{
Check.Condition(port, p => p >= 0, nameof(port));
if (port == 0)
port = Ports.FindFreeTcpPort();
return new FluentMockServer(false, port, ssl);
}
/// <summary>
/// Start this FluentMockServer with the admin interface.
/// </summary>
/// <param name="port">The port.</param>
/// <param name="ssl">The SSL support.</param>
/// <returns>The <see cref="FluentMockServer"/>.</returns>
[PublicAPI]
public static FluentMockServer StartWithAdminInterface(int port = 0, bool ssl = false)
{
Check.Condition(port, p => p >= 0, nameof(port));
if (port == 0)
port = Ports.FindFreeTcpPort();
return new FluentMockServer(true, port, ssl);
}
private FluentMockServer(bool startAdmin, int port, bool ssl)
{
string protocol = ssl ? "https" : "http";
_httpServer = new TinyHttpServer(protocol + "://localhost:" + port + "/", HandleRequestAsync);
Port = port;
_httpServer.Start();
if (startAdmin)
{
InitAdmin();
}
}
/// <summary>
/// Stop this server.
/// </summary>
public void Stop()
{
_httpServer.Stop();
}
/// <summary>
/// The reset.
/// </summary>
public void Reset()
{
lock (((ICollection)_requestLogs).SyncRoot)
{
_requestLogs.Clear();
}
lock (((ICollection)_mappings).SyncRoot)
{
_mappings.Clear();
}
}
/// <summary>
/// The search logs for.
/// </summary>
/// <param name="spec">
/// The matcher.
/// </param>
/// <returns>
/// The <see cref="IEnumerable"/>.
/// </returns>
public IEnumerable<RequestMessage> SearchLogsFor(IRequestMatcher spec)
{
lock (((ICollection)_requestLogs).SyncRoot)
{
return _requestLogs.Where(spec.IsMatch);
}
}
/// <summary>
/// The add request processing delay.
/// </summary>
/// <param name="delay">
/// The delay.
/// </param>
public void AddRequestProcessingDelay(TimeSpan delay)
{
lock (_syncRoot)
{
_requestProcessingDelay = delay;
}
}
/// <summary>
/// The given.
/// </summary>
/// <param name="requestMatcher">The request matcher.</param>
/// <returns>The <see cref="IRespondWithAProvider"/>.</returns>
public IRespondWithAProvider Given(IRequestMatcher requestMatcher)
{
return new RespondWithAProvider(RegisterMapping, requestMatcher);
}
/// <summary>
/// The register mapping.
/// </summary>
/// <param name="mapping">
/// The mapping.
/// </param>
private void RegisterMapping(Mapping mapping)
{
lock (((ICollection)_mappings).SyncRoot)
{
_mappings.Add(mapping);
}
}
/// <summary>
/// The log request.
/// </summary>
/// <param name="requestMessage">
/// The request.
/// </param>
private void LogRequest(RequestMessage requestMessage)
{
lock (((ICollection)_requestLogs).SyncRoot)
{
_requestLogs.Add(requestMessage);
}
}
/// <summary>
/// The handle request.
/// </summary>
/// <param name="ctx">The HttpListenerContext.</param>
private async void HandleRequestAsync(HttpListenerContext ctx)
{
lock (_syncRoot)
{
Task.Delay(_requestProcessingDelay).Wait();
}
var request = _requestMapper.Map(ctx.Request);
LogRequest(request);
try
{
var targetRoute = _mappings.FirstOrDefault(route => route.IsRequestHandled(request));
if (targetRoute == null)
{
ctx.Response.StatusCode = 404;
byte[] content = Encoding.UTF8.GetBytes("No mapping found");
ctx.Response.OutputStream.Write(content, 0, content.Length);
}
else
{
var response = await targetRoute.ResponseTo(request);
_responseMapper.Map(response, ctx.Response);
}
}
catch (Exception ex)
{
ctx.Response.StatusCode = 500;
byte[] content = Encoding.UTF8.GetBytes(ex.ToString());
ctx.Response.OutputStream.Write(content, 0, content.Length);
}
finally
{
ctx.Response.Close();
}
}
}
}

View File

@@ -0,0 +1,16 @@
namespace WireMock.Server
{
/// <summary>
/// IRespondWithAProvider
/// </summary>
public interface IRespondWithAProvider
{
/// <summary>
/// The respond with.
/// </summary>
/// <param name="provider">
/// The provider.
/// </param>
void RespondWith(IResponseProvider provider);
}
}

View File

@@ -0,0 +1,42 @@
using WireMock.Matchers.Request;
namespace WireMock.Server
{
/// <summary>
/// The respond with a provider.
/// </summary>
internal class RespondWithAProvider : IRespondWithAProvider
{
/// <summary>
/// The _registration callback.
/// </summary>
private readonly RegistrationCallback _registrationCallback;
/// <summary>
/// The _request matcher.
/// </summary>
private readonly IRequestMatcher _requestMatcher;
/// <summary>
/// Initializes a new instance of the <see cref="RespondWithAProvider"/> class.
/// </summary>
/// <param name="registrationCallback">The registration callback.</param>
/// <param name="requestMatcher">The request matcher.</param>
public RespondWithAProvider(RegistrationCallback registrationCallback, IRequestMatcher requestMatcher)
{
_registrationCallback = registrationCallback;
_requestMatcher = requestMatcher;
}
/// <summary>
/// The respond with.
/// </summary>
/// <param name="provider">
/// The provider.
/// </param>
public void RespondWith(IResponseProvider provider)
{
_registrationCallback(new Mapping(_requestMatcher, provider));
}
}
}