Compare commits

...

14 Commits

Author SHA1 Message Date
Stef Heyenrath
ea16ee866b 1.0.2.8 2017-11-23 20:54:30 +01:00
Stef Heyenrath
ee0cb6e670 Added unit-test for #68
Added unit-test for #68
2017-11-22 21:33:40 +01:00
Alastair Crabtree
798603118c bug: fix supporting the Patch method and logging the body (#67)
* bug: fix supporting the Patch method and logging the body

- Patch not configured to support Body
- Add a unit test

* chore: typo fixed

* Added / reordered tests for PATCH method
2017-11-20 19:32:36 +01:00
Alastair Crabtree
208303729e bug: Fix admin api client definition returning the wrong types (#65)
* bug: Fix admin api client definition returning the wrong types

- IFluentMockServerAdmin get, find and get all requests should return a log entry model
- Add tests for get and find using the rest ease api client

* Fix Build status and rename tests
2017-11-19 20:44:05 +01:00
Stef Heyenrath
d39e9ef7fa Fixed readme 2017-11-19 11:47:42 +01:00
Stef Heyenrath
431e5656ca <DebugType>full</DebugType> 2017-11-19 11:37:50 +01:00
Stef Heyenrath
fa919343ac <DebugType>portable</DebugType> 2017-11-19 11:32:39 +01:00
Stef Heyenrath
d0b48e2967 DebugType, IncludeSource and IncludeSymbols set to 'true' 2017-11-19 10:39:11 +01:00
Stef Heyenrath
018d2a904d 1.0.2.7 2017-11-18 13:49:22 +01:00
Stef Heyenrath
939a5a61ab 1.0.2.7 2017-11-18 13:48:12 +01:00
vladimir-fed
a15e6747b0 Fix issue with concurrent logging (#63)
* Fix issue with concurrent logging

* Fix namespace + code format/cleanup
2017-11-18 12:22:19 +01:00
Alastair Crabtree
6c38400827 Add the Host, Protocol, Port and Origin to the Request message so they can be used in templating (#62)
* feat: Add the Host, Protocol Port and Origin to the Request message

- Add new fields during request message creation, derived from the Uri object
- Allow the new fields to be accessed in the templating engine
- Add tests for the new fields

* source code file reformat

* appveyor
2017-11-18 12:03:13 +01:00
Stef Heyenrath
cb1117fdaa IHeadersAndCookiesRequestBuilder 2017-11-11 10:09:41 +01:00
Stef Heyenrath
e25c873765 Update ProxyAndRecord
ProxyAndRecord does not save query-parameters, headers and body (#57)
2017-11-07 21:52:30 +01:00
35 changed files with 795 additions and 402 deletions

View File

@@ -3,9 +3,9 @@ A C# .NET version based on [mock4net](https://github.com/alexvictoor/mock4net) w
[![Build status](https://ci.appveyor.com/api/projects/status/b3n6q3ygbww4lyls?svg=true)](https://ci.appveyor.com/project/StefH/wiremock-net)
[![codecov](https://codecov.io/gh/WireMock-Net/WireMock.Net/branch/master/graph/badge.svg)](https://codecov.io/gh/WireMock-Net/WireMock.Net)
[![Coverage Status](https://coveralls.io/repos/github/StefH/WireMock.Net/badge.svg?branch=master)](https://coveralls.io/github/StefH/WireMock.Net?branch=master)
[![GitHub issues](https://img.shields.io/github/issues/StefH/WireMock.Net.svg)](https://github.com/StefH/WireMock.Net/issues)
[![GitHub stars](https://img.shields.io/github/stars/StefH/WireMock.Net.svg)](https://github.com/StefH/WireMock.Net/stargazers)
[![Coverage Status](https://coveralls.io/repos/github/WireMock-Net/WireMock.Net/badge.svg?branch=master)](https://coveralls.io/github/WireMock-Net/WireMock.Net?branch=master)
[![GitHub issues](https://img.shields.io/github/issues/WireMock-Net/WireMock.Net.svg)](https://github.com/WireMock-Net/WireMock.Net/issues)
[![GitHub stars](https://img.shields.io/github/stars/WireMock-Net/WireMock.Net.svg)](https://github.com/WireMock-Net/WireMock.Net/stargazers)
| Name | NuGet |
| ---- | ----- |

View File

@@ -39,6 +39,6 @@ test_script:
- nuget.exe install coveralls.net -ExcludeVersion
- pip install codecov
- cmd: '"OpenCover\tools\OpenCover.Console.exe" -register:user -target:dotnet.exe -targetargs:"test test\WireMock.Net.Tests\WireMock.Net.Tests.csproj --no-build" -returntargetcode -filter:"+[WireMock.Net]* -[WireMock.Net.Tests*]*" -output:coverage.xml -oldstyle -searchdirs:".\test\WireMock.Net.Tests\bin\%CONFIGURATION%\net452"'
- cmd: '"OpenCover\tools\OpenCover.Console.exe" -target:dotnet.exe -targetargs:"test test\WireMock.Net.Tests\WireMock.Net.Tests.csproj --no-build" -output:coverage.xml -returntargetcode -register:user -filter:"+[WireMock.Net]* -[WireMock.Net.Tests*]*" -nodefaultfilters -returntargetcode -oldstyle -searchdirs:".\test\WireMock.Net.Tests\bin\%CONFIGURATION%\net452"'
- codecov -f "coverage.xml"
- coveralls.net\tools\csmacnz.Coveralls.exe --opencover -i .\coverage.xml

View File

@@ -12,12 +12,13 @@ namespace WireMock.Net.Console.Record.NETCoreApp
{
Urls = new[] { "http://localhost:9091/", "https://localhost:9443/" },
StartAdminInterface = true,
ReadStaticMappings = true,
ReadStaticMappings = false,
ProxyAndRecordSettings = new ProxyAndRecordSettings
{
Url = "https://www.google.com",
//X509Certificate2ThumbprintOrSubjectName = "www.yourclientcertname.com OR yourcertificatethumbprint (only if the service you're proxying to requires it)",
SaveMapping = true
SaveMapping = true,
SaveMappingToFile = false
}
});

View File

@@ -66,6 +66,7 @@ namespace WireMock.Net.StandAlone
{
Url = proxyURL,
SaveMapping = parser.GetBoolValue("SaveMapping"),
SaveMappingToFile = parser.GetBoolValue("SaveMappingToFile"),
X509Certificate2ThumbprintOrSubjectName = parser.GetStringValue("X509Certificate2ThumbprintOrSubjectName")
};
}

View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
<Version>1.0.2.6</Version>
<Version>1.0.2.8</Version>
<Authors>Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>

View File

@@ -103,7 +103,7 @@ namespace WireMock.Client
/// </summary>
/// <returns>LogRequestModels</returns>
[Get("__admin/requests")]
Task<IList<LogRequestModel>> GetRequestsAsync();
Task<IList<LogEntryModel>> GetRequestsAsync();
/// <summary>
/// Delete all requests.
@@ -123,7 +123,7 @@ namespace WireMock.Client
/// <param name="guid">The Guid</param>
/// <returns>MappingModel</returns>
[Get("__admin/requests/{guid}")]
Task<LogRequestModel> GetRequestAsync([Path] Guid guid);
Task<LogEntryModel> GetRequestAsync([Path] Guid guid);
/// <summary>
/// Delete a request based on the guid
@@ -137,7 +137,7 @@ namespace WireMock.Client
/// </summary>
/// <param name="model">The RequestModel</param>
[Post("__admin/requests/find")]
Task<IList<LogRequestModel>> FindRequestsAsync([Body] RequestModel model);
Task<IList<LogEntryModel>> FindRequestsAsync([Body] RequestModel model);
/// <summary>
/// Get all scenarios

View File

@@ -13,25 +13,16 @@ namespace WireMock
/// <summary>
/// Gets the unique identifier.
/// </summary>
/// <value>
/// The unique identifier.
/// </value>
public Guid Guid { get; }
/// <summary>
/// Gets the unique title.
/// </summary>
/// <value>
/// The unique title.
/// </value>
public string Title { get; }
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>
/// The priority.
/// </value>
public int Priority { get; }
/// <summary>

View File

@@ -25,7 +25,7 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessageClientIPMatcher"/> class.
/// </summary>
/// <param name="clientIPs">The clientIPs.</param>
public RequestMessageClientIPMatcher([NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new WildcardMatcher(ip)).ToArray())
public RequestMessageClientIPMatcher([NotNull] params string[] clientIPs) : this(clientIPs.Select(ip => new WildcardMatcher(ip)).Cast<IMatcher>().ToArray())
{
}
@@ -49,14 +49,7 @@ namespace WireMock.Matchers.Request
Funcs = funcs;
}
/// <summary>
/// Determines whether the specified RequestMessage is match.
/// </summary>
/// <param name="requestMessage">The RequestMessage.</param>
/// <param name="requestMatchResult">The RequestMatchResult.</param>
/// <returns>
/// A value between 0.0 - 1.0 of the similarity.
/// </returns>
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);

View File

@@ -10,6 +10,7 @@ namespace WireMock.Matchers.Request
/// <summary>
/// The request header matcher.
/// </summary>
/// <inheritdoc cref="IRequestMatcher"/>
public class RequestMessageHeaderMatcher : IRequestMatcher
{
/// <summary>
@@ -32,7 +33,7 @@ namespace WireMock.Matchers.Request
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
/// <param name="ignoreCase">The ignoreCase.</param>
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
{
Check.NotNull(name, nameof(name));
@@ -42,6 +43,21 @@ 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="patterns">The patterns.</param>
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
public RequestMessageHeaderMatcher([NotNull] string name, [NotNull] string[] patterns, bool ignoreCase = true)
{
Check.NotNull(name, nameof(name));
Check.NotNull(patterns, nameof(patterns));
Name = name;
Matchers = patterns.Select(pattern => new WildcardMatcher(pattern, ignoreCase)).Cast<IMatcher>().ToArray();
}
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessageHeaderMatcher"/> class.
/// </summary>
@@ -67,14 +83,7 @@ namespace WireMock.Matchers.Request
Funcs = funcs;
}
/// <summary>
/// Determines whether the specified RequestMessage is match.
/// </summary>
/// <param name="requestMessage">The RequestMessage.</param>
/// <param name="requestMatchResult">The RequestMatchResult.</param>
/// <returns>
/// A value between 0.0 - 1.0 of the similarity.
/// </returns>
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);

View File

@@ -25,7 +25,7 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessagePathMatcher"/> class.
/// </summary>
/// <param name="paths">The paths.</param>
public RequestMessagePathMatcher([NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(path)).ToArray())
public RequestMessagePathMatcher([NotNull] params string[] paths) : this(paths.Select(path => new WildcardMatcher(path)).Cast<IMatcher>().ToArray())
{
}
@@ -49,14 +49,7 @@ namespace WireMock.Matchers.Request
Funcs = funcs;
}
/// <summary>
/// Determines whether the specified RequestMessage is match.
/// </summary>
/// <param name="requestMessage">The RequestMessage.</param>
/// <param name="requestMatchResult">The RequestMatchResult.</param>
/// <returns>
/// A value between 0.0 - 1.0 of the similarity.
/// </returns>
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);

View File

@@ -25,7 +25,7 @@ namespace WireMock.Matchers.Request
/// Initializes a new instance of the <see cref="RequestMessageUrlMatcher"/> class.
/// </summary>
/// <param name="urls">The urls.</param>
public RequestMessageUrlMatcher([NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(url)).ToArray())
public RequestMessageUrlMatcher([NotNull] params string[] urls) : this(urls.Select(url => new WildcardMatcher(url)).Cast<IMatcher>().ToArray())
{
}
@@ -49,14 +49,7 @@ namespace WireMock.Matchers.Request
Funcs = funcs;
}
/// <summary>
/// Determines whether the specified RequestMessage is match.
/// </summary>
/// <param name="requestMessage">The RequestMessage.</param>
/// <param name="requestMatchResult">The RequestMatchResult.</param>
/// <returns>
/// A value between 0.0 - 1.0 of the similarity.
/// </returns>
/// <inheritdoc cref="IRequestMatcher.GetMatchingScore"/>
public double GetMatchingScore(RequestMessage requestMessage, RequestMatchResult requestMatchResult)
{
double score = IsMatch(requestMessage);

View File

@@ -46,6 +46,7 @@ namespace WireMock.Owin
_host = new WebHostBuilder()
.Configure(appBuilder =>
{
appBuilder.UseMiddleware<GlobalExceptionMiddleware>();
_options.PreWireMockMiddlewareInit?.Invoke(appBuilder);
appBuilder.UseMiddleware<WireMockMiddleware>(_options);
_options.PostWireMockMiddlewareInit?.Invoke(appBuilder);

View File

@@ -0,0 +1,49 @@
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
#if !NETSTANDARD
using Microsoft.Owin;
#else
using Microsoft.AspNetCore.Http;
#endif
namespace WireMock.Owin
{
#if !NETSTANDARD
internal class GlobalExceptionMiddleware : OwinMiddleware
#else
internal class GlobalExceptionMiddleware
#endif
{
#if !NETSTANDARD
public GlobalExceptionMiddleware(OwinMiddleware next) : base(next) { }
#else
public GlobalExceptionMiddleware(RequestDelegate next)
{
Next = next;
}
#endif
#if NETSTANDARD
public RequestDelegate Next { get; private set; }
#endif
private readonly OwinResponseMapper _responseMapper = new OwinResponseMapper();
#if !NETSTANDARD
public override async Task Invoke(IOwinContext ctx)
#else
public async Task Invoke(HttpContext ctx)
#endif
{
try
{
await Next?.Invoke(ctx);
}
catch (Exception ex)
{
await _responseMapper.MapAsync(new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) }, ctx.Response);
}
}
}
}

View File

@@ -91,8 +91,9 @@ namespace WireMock.Owin
TRACE - Body not supported.
OPTIONS - Body supported but no semantics on usage (maybe in the future).
CONNECT - No defined body semantics
PATCH - Body supported.
*/
return new[] { "PUT", "POST", "OPTIONS" }.Contains(method.ToUpper());
return new[] { "PUT", "POST", "OPTIONS", "PATCH" }.Contains(method.ToUpper());
}
}
}

View File

@@ -57,10 +57,11 @@ namespace WireMock.Owin
private void StartServers()
{
Console.WriteLine("WireMock.Net server using .net 4.5.x or .net 4.6.x");
Console.WriteLine("WireMock.Net server using .net 4.5.x or higher");
Action<IAppBuilder> startup = app =>
{
app.Use<GlobalExceptionMiddleware>();
_options.PreWireMockMiddlewareInit?.Invoke(app);
app.Use<WireMockMiddleware>(_options);
_options.PostWireMockMiddlewareInit?.Invoke(app);

View File

@@ -5,6 +5,7 @@ using WireMock.Matchers.Request;
using System.Linq;
using WireMock.Matchers;
using WireMock.Util;
using Newtonsoft.Json;
#if !NETSTANDARD
using Microsoft.Owin;
#else
@@ -124,7 +125,7 @@ namespace WireMock.Owin
}
catch (Exception ex)
{
response = new ResponseMessage { StatusCode = 500, Body = ex.ToString() };
response = new ResponseMessage { StatusCode = 500, Body = JsonConvert.SerializeObject(ex) };
}
finally
{

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using WireMock.Logging;
using WireMock.Matchers;
using WireMock.Util;
#if !NETSTANDARD
using Owin;
#else
@@ -22,7 +23,7 @@ namespace WireMock.Owin
public IList<Mapping> Mappings { get; set; } = new List<Mapping>();
public ObservableCollection<LogEntry> LogEntries { get; } = new ObservableCollection<LogEntry>();
public ObservableCollection<LogEntry> LogEntries { get; } = new ConcurentObservableCollection<LogEntry>();
public int? RequestLogExpirationDuration { get; set; }

View File

@@ -12,7 +12,7 @@ namespace WireMock.RequestBuilders
public interface IHeadersAndCookiesRequestBuilder : IBodyRequestBuilder, IRequestMatcher, IParamsRequestBuilder
{
/// <summary>
/// The with header.
/// Add Header matching based on name, pattern and ignoreCase.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="pattern">The pattern.</param>
@@ -20,6 +20,15 @@ namespace WireMock.RequestBuilders
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, string pattern, bool ignoreCase = true);
/// <summary>
/// Add Header matching based on name, patterns and ignoreCase.
/// </summary>
/// <param name="name">The name.</param>
/// <param name="patterns">The patterns.</param>
/// <param name="ignoreCase">ignore Case</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
IRequestBuilder WithHeader([NotNull] string name, string[] patterns, bool ignoreCase = true);
/// <summary>
/// The with header.
/// </summary>

View File

@@ -7,6 +7,14 @@ namespace WireMock.RequestBuilders
/// </summary>
public interface IMethodRequestBuilder : IHeadersAndCookiesRequestBuilder
{
/// <summary>
/// The using delete.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingDelete();
/// <summary>
/// The using get.
/// </summary>
@@ -15,6 +23,14 @@ namespace WireMock.RequestBuilders
/// </returns>
IRequestBuilder UsingGet();
/// <summary>
/// The using head.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingHead();
/// <summary>
/// The using post.
/// </summary>
@@ -24,12 +40,12 @@ namespace WireMock.RequestBuilders
IRequestBuilder UsingPost();
/// <summary>
/// The using delete.
/// The using patch.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingDelete();
IRequestBuilder UsingPatch();
/// <summary>
/// The using put.
@@ -39,14 +55,6 @@ namespace WireMock.RequestBuilders
/// </returns>
IRequestBuilder UsingPut();
/// <summary>
/// The using head.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
IRequestBuilder UsingHead();
/// <summary>
/// The using any verb.
/// </summary>

View File

@@ -171,70 +171,49 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The using get.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
public IRequestBuilder UsingGet()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("get"));
return this;
}
/// <summary>
/// The using post.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
public IRequestBuilder UsingPost()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("post"));
return this;
}
/// <summary>
/// The using put.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
public IRequestBuilder UsingPut()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("put"));
return this;
}
/// <summary>
/// The using delete.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
/// <inheritdoc cref="IMethodRequestBuilder.UsingDelete"/>
public IRequestBuilder UsingDelete()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("delete"));
return this;
}
/// <summary>
/// The using head.
/// </summary>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IMethodRequestBuilder.UsingGet"/>
public IRequestBuilder UsingGet()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("get"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingHead"/>
public IRequestBuilder UsingHead()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("head"));
return this;
}
/// <summary>
/// The using any verb.
/// </summary>
/// <returns>
/// The <see cref="IRequestBuilder"/>.
/// </returns>
/// <inheritdoc cref="IMethodRequestBuilder.UsingPost"/>
public IRequestBuilder UsingPost()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("post"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPatch"/>
public IRequestBuilder UsingPatch()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("patch"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingPut"/>
public IRequestBuilder UsingPut()
{
_requestMatchers.Add(new RequestMessageMethodMatcher("put"));
return this;
}
/// <inheritdoc cref="IMethodRequestBuilder.UsingAnyVerb"/>
public IRequestBuilder UsingAnyVerb()
{
var matchers = _requestMatchers.Where(m => m is RequestMessageMethodMatcher).ToList();
@@ -246,11 +225,7 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// The using verb.
/// </summary>
/// <param name="verbs">The verbs.</param>
/// <returns>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IMethodRequestBuilder.UsingVerb"/>
public IRequestBuilder UsingVerb(params string[] verbs)
{
Check.NotEmpty(verbs, nameof(verbs));
@@ -359,13 +334,7 @@ namespace WireMock.RequestBuilders
return this;
}
/// <summary>
/// With header.
/// </summary>
/// <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>The <see cref="IRequestBuilder"/>.</returns>
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string,string,bool)"/>
public IRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true)
{
Check.NotNull(name, nameof(name));
@@ -375,6 +344,16 @@ namespace WireMock.RequestBuilders
return this;
}
/// <inheritdoc cref="IHeadersAndCookiesRequestBuilder.WithHeader(string,string[],bool)"/>
public IRequestBuilder WithHeader(string name, string[] patterns, bool ignoreCase = true)
{
Check.NotNull(name, nameof(name));
Check.NotNull(patterns, nameof(patterns));
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, patterns, ignoreCase));
return this;
}
/// <summary>
/// With header.
/// </summary>

View File

@@ -1,146 +1,170 @@
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using WireMock.Util;
using WireMock.Validation;
using System.Text;
namespace WireMock
{
/// <summary>
/// The request.
/// </summary>
public class RequestMessage
{
/// <summary>
/// Gets the Client IP Address.
/// </summary>
public string ClientIP { get; }
/// <summary>
/// Gets the url.
/// </summary>
public string Url { get; }
/// <summary>
/// Gets the DateTime.
/// </summary>
public DateTime DateTime { get; set; }
/// <summary>
/// Gets the path.
/// </summary>
public string Path { get; }
/// <summary>
/// Gets the method.
/// </summary>
public string Method { get; }
/// <summary>
/// Gets the headers.
/// </summary>
public IDictionary<string, WireMockList<string>> Headers { get; }
/// <summary>
/// Gets the cookies.
/// </summary>
public IDictionary<string, string> Cookies { get; }
/// <summary>
/// Gets the query.
/// </summary>
public IDictionary<string, WireMockList<string>> Query { get; }
/// <summary>
/// Gets the bodyAsBytes.
/// </summary>
public byte[] BodyAsBytes { get; }
/// <summary>
/// Gets the body.
/// </summary>
public string Body { get; }
/// <summary>
/// Gets the body encoding.
/// </summary>
public Encoding BodyEncoding { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
/// </summary>
/// <param name="url">The original url.</param>
/// <param name="method">The HTTP method.</param>
/// <param name="clientIP">The client IP Address.</param>
/// <param name="bodyAsBytes">The bodyAsBytes byte[].</param>
/// <param name="body">The body string.</param>
/// <param name="bodyEncoding">The body encoding</param>
/// <param name="headers">The headers.</param>
/// <param name="cookies">The cookies.</param>
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] byte[] bodyAsBytes = null, [CanBeNull] string body = null, [CanBeNull] Encoding bodyEncoding = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
{
Check.NotNull(url, nameof(url));
Check.NotNull(method, nameof(method));
Check.NotNull(clientIP, nameof(clientIP));
Url = url.ToString();
Path = url.AbsolutePath;
Method = method.ToLower();
ClientIP = clientIP;
BodyAsBytes = bodyAsBytes;
Body = body;
BodyEncoding = bodyEncoding;
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
Cookies = cookies;
Query = ParseQuery(url.Query);
}
private IDictionary<string, WireMockList<string>> ParseQuery(string queryString)
{
if (string.IsNullOrEmpty(queryString))
{
return null;
}
if (queryString.StartsWith("?"))
{
queryString = queryString.Substring(1);
}
return queryString.Split('&').Aggregate(new Dictionary<string, WireMockList<string>>(),
(dict, term) =>
{
var parts = term.Split('=');
string key = parts[0];
if (!dict.ContainsKey(key))
{
dict.Add(key, new WireMockList<string>());
}
if (parts.Length == 2)
{
dict[key].Add(parts[1]);
}
return dict;
});
}
/// <summary>
/// The get a query parameter.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>The query parameter.</returns>
public List<string> GetParameter(string key)
{
if (Query == null)
{
return null;
}
return Query.ContainsKey(key) ? Query[key] : null;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using WireMock.Util;
using WireMock.Validation;
using System.Text;
namespace WireMock
{
/// <summary>
/// The request.
/// </summary>
public class RequestMessage
{
/// <summary>
/// Gets the Client IP Address.
/// </summary>
public string ClientIP { get; }
/// <summary>
/// Gets the url.
/// </summary>
public string Url { get; }
/// <summary>
/// Gets the DateTime.
/// </summary>
public DateTime DateTime { get; set; }
/// <summary>
/// Gets the path.
/// </summary>
public string Path { get; }
/// <summary>
/// Gets the method.
/// </summary>
public string Method { get; }
/// <summary>
/// Gets the headers.
/// </summary>
public IDictionary<string, WireMockList<string>> Headers { get; }
/// <summary>
/// Gets the cookies.
/// </summary>
public IDictionary<string, string> Cookies { get; }
/// <summary>
/// Gets the query.
/// </summary>
public IDictionary<string, WireMockList<string>> Query { get; }
/// <summary>
/// Gets the bodyAsBytes.
/// </summary>
public byte[] BodyAsBytes { get; }
/// <summary>
/// Gets the body.
/// </summary>
public string Body { get; }
/// <summary>
/// Gets the Host
/// </summary>
public string Host { get; }
/// <summary>
/// Gets the protocol
/// </summary>
public string Protocol { get; }
/// <summary>
/// Gets the port
/// </summary>
public int Port { get; }
/// <summary>
/// Gets the origin
/// </summary>
public string Origin { get; }
/// <summary>
/// Gets the body encoding.
/// </summary>
public Encoding BodyEncoding { get; }
/// <summary>
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
/// </summary>
/// <param name="url">The original url.</param>
/// <param name="method">The HTTP method.</param>
/// <param name="clientIP">The client IP Address.</param>
/// <param name="bodyAsBytes">The bodyAsBytes byte[].</param>
/// <param name="body">The body string.</param>
/// <param name="bodyEncoding">The body encoding</param>
/// <param name="headers">The headers.</param>
/// <param name="cookies">The cookies.</param>
public RequestMessage([NotNull] Uri url, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] byte[] bodyAsBytes = null, [CanBeNull] string body = null, [CanBeNull] Encoding bodyEncoding = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
{
Check.NotNull(url, nameof(url));
Check.NotNull(method, nameof(method));
Check.NotNull(clientIP, nameof(clientIP));
Url = url.ToString();
Protocol = url.Scheme;
Host = url.Host;
Port = url.Port;
Origin = $"{url.Scheme}://{url.Host}:{url.Port}";
Path = url.AbsolutePath;
Method = method.ToLower();
ClientIP = clientIP;
BodyAsBytes = bodyAsBytes;
Body = body;
BodyEncoding = bodyEncoding;
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
Cookies = cookies;
Query = ParseQuery(url.Query);
}
private IDictionary<string, WireMockList<string>> ParseQuery(string queryString)
{
if (string.IsNullOrEmpty(queryString))
{
return null;
}
if (queryString.StartsWith("?"))
{
queryString = queryString.Substring(1);
}
return queryString.Split('&').Aggregate(new Dictionary<string, WireMockList<string>>(),
(dict, term) =>
{
var parts = term.Split('=');
string key = parts[0];
if (!dict.ContainsKey(key))
{
dict.Add(key, new WireMockList<string>());
}
if (parts.Length == 2)
{
dict[key].Add(parts[1]);
}
return dict;
});
}
/// <summary>
/// The get a query parameter.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>The query parameter.</returns>
public List<string> GetParameter(string key)
{
if (Query == null)
{
return null;
}
return Query.ContainsKey(key) ? Query[key] : null;
}
}
}

View File

@@ -79,7 +79,7 @@ namespace WireMock.Serialization
Funcs = Map(pm.Funcs)
}).ToList() : null,
Body = methodMatcher?.Methods != null && methodMatcher.Methods.Count(m => m == "get") == 1 ? null : new BodyModel
Body = methodMatcher?.Methods != null && methodMatcher.Methods.Any(m => m == "get") ? null : new BodyModel
{
Matcher = bodyMatcher != null ? Map(bodyMatcher.Matcher) : null,
Func = bodyMatcher != null ? Map(bodyMatcher.Func) : null,
@@ -115,14 +115,16 @@ namespace WireMock.Serialization
mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyAsFile;
mappingModel.Response.BodyAsFileIsCached = response.ResponseMessage.BodyAsFileIsCached;
mappingModel.Response.UseTransformer = response.UseTransformer;
mappingModel.Response.BodyEncoding = response.ResponseMessage.BodyEncoding != null
? new EncodingModel
if (response.ResponseMessage.BodyEncoding != null)
{
mappingModel.Response.BodyEncoding = new EncodingModel
{
EncodingName = response.ResponseMessage.BodyEncoding.EncodingName,
CodePage = response.ResponseMessage.BodyEncoding.CodePage,
WebName = response.ResponseMessage.BodyEncoding.WebName
}
: null;
};
}
}
return mappingModel;

View File

@@ -130,11 +130,11 @@ namespace WireMock.Server
}
#region Proxy and Record
private HttpClient httpClientForProxy;
private HttpClient _httpClientForProxy;
private void InitProxyAndRecord(ProxyAndRecordSettings settings)
{
httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.X509Certificate2ThumbprintOrSubjectName);
_httpClientForProxy = HttpClientHelper.CreateHttpClient(settings.X509Certificate2ThumbprintOrSubjectName);
Given(Request.Create().WithPath("/*").UsingAnyVerb()).RespondWith(new ProxyAsyncResponseProvider(ProxyAndRecordAsync, settings));
}
@@ -144,12 +144,17 @@ namespace WireMock.Server
var proxyUri = new Uri(settings.Url);
var proxyUriWithRequestPathAndQuery = new Uri(proxyUri, requestUri.PathAndQuery);
var responseMessage = await HttpClientHelper.SendAsync(httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
var responseMessage = await HttpClientHelper.SendAsync(_httpClientForProxy, requestMessage, proxyUriWithRequestPathAndQuery.AbsoluteUri);
if (settings.SaveMapping)
{
var mapping = ToMapping(requestMessage, responseMessage);
SaveMappingToFile(mapping);
_options.Mappings.Add(mapping);
if (settings.SaveMappingToFile)
{
SaveMappingToFile(mapping);
}
}
return responseMessage;
@@ -157,11 +162,20 @@ namespace WireMock.Server
private Mapping ToMapping(RequestMessage requestMessage, ResponseMessage responseMessage)
{
var request = (Request)Request.Create();
var request = Request.Create();
request.WithPath(requestMessage.Path);
request.UsingVerb(requestMessage.Method);
var response = (Response)Response.Create(responseMessage);
requestMessage.Query.Loop((key, value) => request.WithParam(key, value.ToArray()));
requestMessage.Headers.Loop((key, value) => request.WithHeader(key, value.ToArray()));
requestMessage.Cookies.Loop((key, value) => request.WithCookie(key, value));
if (requestMessage.Body != null)
{
request.WithBody(new ExactMatcher(requestMessage.Body));
}
var response = Response.Create(responseMessage);
return new Mapping(Guid.NewGuid(), string.Empty, request, response, 0, null, null, null);
}
@@ -472,7 +486,7 @@ namespace WireMock.Server
}
}
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key);
var result = dict.OrderBy(x => x.Value.AverageTotalScore).Select(x => x.Key).Select(ToLogEntryModel);
return ToJson(result);
}
@@ -530,8 +544,9 @@ namespace WireMock.Server
{
var pathModel = JsonUtils.ParseJTokenToObject<PathModel>(requestModel.Path);
if (pathModel?.Matchers != null)
requestBuilder =
requestBuilder.WithPath(pathModel.Matchers.Select(MappingConverter.Map).ToArray());
{
requestBuilder = requestBuilder.WithPath(pathModel.Matchers.Select(MappingConverter.Map).ToArray());
}
}
}
@@ -546,8 +561,9 @@ namespace WireMock.Server
{
var urlModel = JsonUtils.ParseJTokenToObject<UrlModel>(requestModel.Url);
if (urlModel?.Matchers != null)
requestBuilder =
requestBuilder.WithUrl(urlModel.Matchers.Select(MappingConverter.Map).ToArray());
{
requestBuilder = requestBuilder.WithUrl(urlModel.Matchers.Select(MappingConverter.Map).ToArray());
}
}
}

View File

@@ -11,10 +11,15 @@
public string Url { get; set; }
/// <summary>
/// Save the mapping for each request/response.
/// Save the mapping for each request/response to the internal Mappings.
/// </summary>
public bool SaveMapping { get; set; } = true;
/// <summary>
/// Save the mapping for each request/response to also file. (Note that SaveMapping must also be set to true.)
/// </summary>
public bool SaveMappingToFile { get; set; } = true;
/// <summary>
/// The clientCertificate thumbprint or subject name fragment to use. Example thumbprint : "D2DBF135A8D06ACCD0E1FAD9BFB28678DF7A9818". Example subject name: "www.google.com""
/// </summary>

View File

@@ -0,0 +1,77 @@
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace WireMock.Util
{
/// <summary>
/// A special Collection that overrides methods of <see cref="ObservableCollection{T}"/> to make them thread safe
/// </summary>
/// <typeparam name="T">The type of elements in the collection.</typeparam>
/// <inheritdoc cref="ObservableCollection{T}" />
public class ConcurentObservableCollection<T> : ObservableCollection<T>
{
private readonly object _lockObject = new object();
/// <summary>
/// Initializes a new instance of the <see cref="T:WireMock.Util.ConcurentObservableCollection`1" /> class.
/// </summary>
public ConcurentObservableCollection() { }
/// <summary>
/// Initializes a new instance of the <see cref="ConcurentObservableCollection{T}"/> class that contains elements copied from the specified list.
/// </summary>
/// <param name="list">The list from which the elements are copied.</param>
public ConcurentObservableCollection(List<T> list) : base(list) { }
/// <summary>
/// Initializes a new instance of the <see cref="ConcurentObservableCollection{T}"/> class that contains elements copied from the specified collection.
/// </summary>
/// <param name="collection">The collection from which the elements are copied.</param>
public ConcurentObservableCollection(IEnumerable<T> collection) : base(collection) { }
/// <inheritdoc cref="ObservableCollection{T}.ClearItems"/>
protected override void ClearItems()
{
lock (_lockObject)
{
base.ClearItems();
}
}
/// <inheritdoc cref="ObservableCollection{T}.RemoveItem"/>
protected override void RemoveItem(int index)
{
lock (_lockObject)
{
base.RemoveItem(index);
}
}
/// <inheritdoc cref="ObservableCollection{T}.InsertItem"/>
protected override void InsertItem(int index, T item)
{
lock (_lockObject)
{
base.InsertItem(index, item);
}
}
/// <inheritdoc cref="ObservableCollection{T}.SetItem"/>
protected override void SetItem(int index, T item)
{
lock (_lockObject)
{
base.SetItem(index, item);
}
}
/// <inheritdoc cref="ObservableCollection{T}.MoveItem"/>
protected override void MoveItem(int oldIndex, int newIndex)
{
lock (_lockObject)
{
base.MoveItem(oldIndex, newIndex);
}
}
}
}

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using WireMock.Validation;
namespace WireMock.Util
{
/// <summary>
/// Some IDictionary Extensions
/// </summary>
public static class DictionaryExtensions
{
/// <summary>
/// Loops the dictionary and executes the specified action.
/// </summary>
/// <typeparam name="TKey">The type of the key.</typeparam>
/// <typeparam name="TValue">The type of the value.</typeparam>
/// <param name="dictionary">The dictionary to loop (can be null).</param>
/// <param name="action">The action.</param>
public static void Loop<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, [NotNull] Action<TKey, TValue> action)
{
Check.NotNull(action, nameof(action));
if (dictionary != null)
{
foreach (var entry in dictionary)
{
action(entry.Key, entry.Value);
}
}
}
}
}

View File

@@ -74,8 +74,7 @@ namespace WireMock.Util
public void RemoveLock(string name)
{
ReaderWriterLockSlim o;
_lockDict.TryRemove(name, out o);
_lockDict.TryRemove(name, out _);
}
}
}

View File

@@ -3,7 +3,7 @@
<PropertyGroup>
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
<AssemblyTitle>WireMock.Net</AssemblyTitle>
<Version>1.0.2.6</Version>
<Version>1.0.2.8</Version>
<Authors>Alexandre Victoor;Stef Heyenrath</Authors>
<TargetFrameworks>net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
@@ -17,9 +17,11 @@
<RepositoryType>git</RepositoryType>
<RepositoryUrl>https://github.com/WireMock-Net/WireMock.Net</RepositoryUrl>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<DebugType>portable</DebugType>
<ApplicationIcon>../../WireMock.Net-Logo.ico</ApplicationIcon>
<RootNamespace>WireMock</RootNamespace>
<DebugType>full</DebugType>
<IncludeSource>True</IncludeSource>
<IncludeSymbols>True</IncludeSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' or '$(TargetFramework)' == 'netstandard2.0'">

View File

@@ -0,0 +1,64 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using NFluent;
using RestEase;
using WireMock.Admin.Mappings;
using WireMock.Client;
using WireMock.Server;
using WireMock.Settings;
using Xunit;
namespace WireMock.Net.Tests
{
public class FluentMockServerAdminRestClientTests : IDisposable
{
public void Dispose()
{
_server?.Stop();
}
private FluentMockServer _server;
[Fact]
public async Task IFluentMockServerAdmin_FindRequestsAsync()
{
// given
_server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true });
var serverUrl = "http://localhost:" + _server.Ports[0];
await new HttpClient().GetAsync(serverUrl + "/foo");
var api = RestClient.For<IFluentMockServerAdmin>(serverUrl);
// when
var requests = await api.FindRequestsAsync(new RequestModel { Methods = new[] { "get" } });
// then
Check.That(requests).HasSize(1);
var requestLogged = requests.First();
Check.That(requestLogged.Request.Method).IsEqualTo("get");
Check.That(requestLogged.Request.Body).IsNull();
Check.That(requestLogged.Request.Path).IsEqualTo("/foo");
}
[Fact]
public async Task IFluentMockServerAdmin_GetRequestsAsync()
{
// given
_server = FluentMockServer.Start(new FluentMockServerSettings { StartAdminInterface = true });
var serverUrl = "http://localhost:" + _server.Ports[0];
await new HttpClient().GetAsync(serverUrl + "/foo");
var api = RestClient.For<IFluentMockServerAdmin>(serverUrl);
// when
var requests = await api.GetRequestsAsync();
// then
Check.That(requests).HasSize(1);
var requestLogged = requests.First();
Check.That(requestLogged.Request.Method).IsEqualTo("get");
Check.That(requestLogged.Request.Body).IsNull();
Check.That(requestLogged.Request.Path).IsEqualTo("/foo");
}
}
}

View File

@@ -175,6 +175,34 @@ namespace WireMock.Net.Tests
Check.That(requestLogged.RequestMessage.BodyAsBytes).IsNull();
}
[Fact]
public async Task FluentMockServer_Should_respond_to_request_methodPatch()
{
// given
_server = FluentMockServer.Start();
_server.Given(Request.Create().WithPath("/foo").UsingVerb("patch"))
.RespondWith(Response.Create().WithBody("hello patch"));
// when
var msg = new HttpRequestMessage(new HttpMethod("patch"), new Uri("http://localhost:" + _server.Ports[0] + "/foo"))
{
Content = new StringContent("{\"data\": {\"attr\":\"value\"}}")
};
var response = await new HttpClient().SendAsync(msg);
// then
Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.OK);
var responseBody = await response.Content.ReadAsStringAsync();
Check.That(responseBody).IsEqualTo("hello patch");
Check.That(_server.LogEntries).HasSize(1);
var requestLogged = _server.LogEntries.First();
Check.That(requestLogged.RequestMessage.Method).IsEqualTo("patch");
Check.That(requestLogged.RequestMessage.Body).IsNotNull();
Check.That(requestLogged.RequestMessage.Body).IsEqualTo("{\"data\": {\"attr\":\"value\"}}");
}
[Fact]
public async Task FluentMockServer_Should_respond_to_request_bodyAsString()
{

View File

@@ -1,5 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using NFluent;
using WireMock.RequestBuilders;
using WireMock.ResponseBuilders;
@@ -8,7 +13,7 @@ using Xunit;
namespace WireMock.Net.Tests
{
public class ObservableLogEntriesTest: IDisposable
public class ObservableLogEntriesTest : IDisposable
{
private FluentMockServer _server;
@@ -35,6 +40,42 @@ namespace WireMock.Net.Tests
Check.That(count).Equals(1);
}
[Fact]
public async Task ParallelTest()
{
var expectedCount = 100;
// Assign
_server = FluentMockServer.Start();
_server
.Given(Request.Create()
.WithPath("/foo")
.UsingGet())
.RespondWith(Response.Create()
.WithDelay(6)
.WithSuccess());
int count = 0;
_server.LogEntriesChanged += (sender, args) => count++;
var http = new HttpClient();
// Act
var listOfTasks = new List<Task<HttpResponseMessage>>();
for (var i = 0; i < expectedCount; i++)
{
Thread.Sleep(3);
listOfTasks.Add(http.GetAsync(_server.Urls[0] + $"/foo"));
}
var responses = await Task.WhenAll(listOfTasks);
var countResponsesWithStatusNotOk = responses.Where(r => r.StatusCode != HttpStatusCode.OK).Count();
// Assert
Check.That(countResponsesWithStatusNotOk).Equals(0);
Check.That(count).Equals(expectedCount);
}
public void Dispose()
{
_server?.Dispose();

View File

@@ -0,0 +1,113 @@
using System;
using System.Text;
using NFluent;
using Xunit;
using WireMock.RequestBuilders;
using WireMock.Matchers.Request;
namespace WireMock.Net.Tests
{
//[TestFixture]
public partial class RequestTests
{
[Fact]
public void Should_specify_requests_matching_given_path_and_method_delete()
{
// given
var spec = Request.Create().WithPath("/foo").UsingDelete();
// when
string bodyAsString = "whatever";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "Delete", ClientIp, body, bodyAsString, Encoding.UTF8);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_get()
{
// given
var spec = Request.Create().WithPath("/foo").UsingGet();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "GET", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_head()
{
// given
var spec = Request.Create().WithPath("/foo").UsingHead();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "HEAD", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_post()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPost();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_put()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPut();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_patch()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPatch();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "PATCH", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_exclude_requests_matching_given_path_but_not_http_method()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPut();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "HEAD", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
}
}

View File

@@ -0,0 +1,39 @@
using System;
using NFluent;
using WireMock.Matchers.Request;
using WireMock.RequestBuilders;
using Xunit;
namespace WireMock.Net.Tests
{
public partial class RequestTests
{
[Fact]
public void Should_specify_requests_matching_given_url_wildcard()
{
// given
var spec = Request.Create().WithUrl("*/foo");
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_url_exact()
{
// given
var spec = Request.Create().WithUrl("http://localhost/foo");
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
}
}

View File

@@ -83,106 +83,6 @@ namespace WireMock.Net.Tests
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_url()
{
// given
var spec = Request.Create().WithUrl("*/foo");
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "blabla", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_put()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPut();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_post()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPost();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_get()
{
// given
var spec = Request.Create().WithPath("/foo").UsingGet();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "GET", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_delete()
{
// given
var spec = Request.Create().WithPath("/foo").UsingDelete();
// when
string bodyAsString = "whatever";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "Delete", ClientIp, body, bodyAsString, Encoding.UTF8);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_specify_requests_matching_given_path_and_method_head()
{
// given
var spec = Request.Create().WithPath("/foo").UsingHead();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "HEAD", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsEqualTo(1.0);
}
[Fact]
public void Should_exclude_requests_matching_given_path_but_not_http_method()
{
// given
var spec = Request.Create().WithPath("/foo").UsingPut();
// when
var request = new RequestMessage(new Uri("http://localhost/foo"), "HEAD", ClientIp);
// then
var requestMatchResult = new RequestMatchResult();
Check.That(spec.GetMatchingScore(request, requestMatchResult)).IsNotEqualTo(1.0);
}
[Fact]
public void Should_exclude_requests_matching_given_http_method_but_not_url()
{
@@ -206,7 +106,7 @@ namespace WireMock.Net.Tests
// when
string bodyAsString = "whatever";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "X-toto", new [] { "tata" } } });
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", ClientIp, body, bodyAsString, Encoding.UTF8, new Dictionary<string, string[]> { { "X-toto", new[] { "tata" } } });
// then
var requestMatchResult = new RequestMatchResult();

View File

@@ -86,5 +86,24 @@ namespace WireMock.Net.Tests
Check.That(responseMessage.Headers["x"]).Contains("text/plain");
Check.That(responseMessage.Headers["x"]).Contains("http://localhost/foo");
}
[Fact]
public async Task Response_ProvideResponse_Handlebars_Origin_Port_Protocol_Host()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost:1234"), "POST", ClientIp, body, bodyAsString, Encoding.UTF8);
var response = Response.Create()
.WithBody("test {{request.origin}} {{request.port}} {{request.protocol}} {{request.host}}")
.WithTransformer();
// act
var responseMessage = await response.ProvideResponseAsync(request);
// then
Check.That(responseMessage.Body).Equals("test http://localhost:1234 1234 http localhost");
}
}
}