diff --git a/examples/WireMock.Net.ConsoleApplication/MainApp.cs b/examples/WireMock.Net.ConsoleApplication/MainApp.cs
index 6e889a6a..5583162c 100644
--- a/examples/WireMock.Net.ConsoleApplication/MainApp.cs
+++ b/examples/WireMock.Net.ConsoleApplication/MainApp.cs
@@ -1,5 +1,4 @@
using System;
-using System.Linq;
using Newtonsoft.Json;
using WireMock.Matchers;
using WireMock.RequestBuilders;
@@ -21,7 +20,7 @@ namespace WireMock.Net.ConsoleApplication
{
Urls = new[] { url1, url2, url3 },
StartAdminInterface = true,
- ReadStaticMappings = true
+ ReadStaticMappings = false
});
System.Console.WriteLine("FluentMockServer listening at {0}", string.Join(" and ", server.Urls));
@@ -29,6 +28,14 @@ namespace WireMock.Net.ConsoleApplication
// server.AllowPartialMapping();
+ server
+ .Given(Request.Create().WithPath("/bodyasbytes.png")
+ .UsingGet())
+ .RespondWith(Response.Create()
+ .WithHeader("Content-Type", "image/png")
+ .WithBody(Convert.FromBase64String("iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMTczbp9jAAAAJ0lEQVQoU2NgUPuPD6Hz0RCEAtJoiAxpCCBXGgmRIo0TofORkdp/AMiMdRVnV6O0AAAAAElFTkSuQmCC"))
+ );
+
server
.Given(Request.Create().WithPath("/oauth2/access").UsingPost().WithBody("grant_type=password;username=u;password=p"))
.RespondWith(Response.Create()
diff --git a/src/WireMock.Net/Admin/Mappings/ResponseModel.cs b/src/WireMock.Net/Admin/Mappings/ResponseModel.cs
index 21b95542..cd12d37a 100644
--- a/src/WireMock.Net/Admin/Mappings/ResponseModel.cs
+++ b/src/WireMock.Net/Admin/Mappings/ResponseModel.cs
@@ -15,6 +15,11 @@ namespace WireMock.Admin.Mappings
///
public int? StatusCode { get; set; }
+ ///
+ /// Gets or sets the body destination (SameAsSource, String or Bytes).
+ ///
+ public string BodyDestination { get; set; }
+
///
/// Gets or sets the body.
///
@@ -29,7 +34,7 @@ namespace WireMock.Admin.Mappings
///
/// The body.
///
- public string BodyAsBase64 { get; set; }
+ public string BodyFromBase64 { get; set; }
///
/// Gets or sets the body (as JSON object).
@@ -39,6 +44,14 @@ namespace WireMock.Admin.Mappings
///
public object BodyAsJson { get; set; }
+ ///
+ /// Gets or sets the body (as bytearray).
+ ///
+ ///
+ /// The body.
+ ///
+ public byte[] BodyAsBytes { get; set; }
+
///
/// Gets or sets the body encoding.
///
diff --git a/src/WireMock.Net/Admin/Requests/LogResponseModel.cs b/src/WireMock.Net/Admin/Requests/LogResponseModel.cs
index 5ce9a8c4..4d39fc1d 100644
--- a/src/WireMock.Net/Admin/Requests/LogResponseModel.cs
+++ b/src/WireMock.Net/Admin/Requests/LogResponseModel.cs
@@ -18,11 +18,21 @@ namespace WireMock.Admin.Requests
///
public IDictionary Headers { get; set; }
+ ///
+ /// Gets or sets the body destination (SameAsSource, String or Bytes).
+ ///
+ public string BodyDestination { get; set; }
+
///
/// Gets or sets the body.
///
public string Body { get; set; }
+ ///
+ /// Gets or sets the body.
+ ///
+ public byte[] BodyAsBytes { get; set; }
+
///
/// Gets or sets the original body.
///
diff --git a/src/WireMock.Net/Http/HttpClientHelper.cs b/src/WireMock.Net/Http/HttpClientHelper.cs
index 2f4eac1a..71ac8447 100644
--- a/src/WireMock.Net/Http/HttpClientHelper.cs
+++ b/src/WireMock.Net/Http/HttpClientHelper.cs
@@ -71,11 +71,12 @@ namespace WireMock.Http
// Call the URL
var httpResponseMessage = await client.SendAsync(httpRequestMessage, HttpCompletionOption.ResponseContentRead);
-
// Transform response
var responseMessage = new ResponseMessage
{
StatusCode = (int)httpResponseMessage.StatusCode,
+
+ // TODO : what about BodyAsBytes ???
Body = await httpResponseMessage.Content.ReadAsStringAsync()
};
diff --git a/src/WireMock.Net/Http/HttpKnownHeaderNames.cs b/src/WireMock.Net/Http/HttpKnownHeaderNames.cs
new file mode 100644
index 00000000..c17bc0ab
--- /dev/null
+++ b/src/WireMock.Net/Http/HttpKnownHeaderNames.cs
@@ -0,0 +1,96 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace WireMock.Http
+{
+ ///
+ /// Copied from https://raw.githubusercontent.com/dotnet/corefx/master/src/Common/src/System/Net/HttpKnownHeaderNames.cs
+ ///
+ internal static class HttpKnownHeaderNames
+ {
+ public const string Accept = "Accept";
+ public const string AcceptCharset = "Accept-Charset";
+ public const string AcceptEncoding = "Accept-Encoding";
+ public const string AcceptLanguage = "Accept-Language";
+ public const string AcceptPatch = "Accept-Patch";
+ public const string AcceptRanges = "Accept-Ranges";
+ public const string AccessControlAllowCredentials = "Access-Control-Allow-Credentials";
+ public const string AccessControlAllowHeaders = "Access-Control-Allow-Headers";
+ public const string AccessControlAllowMethods = "Access-Control-Allow-Methods";
+ public const string AccessControlAllowOrigin = "Access-Control-Allow-Origin";
+ public const string AccessControlExposeHeaders = "Access-Control-Expose-Headers";
+ public const string AccessControlMaxAge = "Access-Control-Max-Age";
+ public const string Age = "Age";
+ public const string Allow = "Allow";
+ public const string AltSvc = "Alt-Svc";
+ public const string Authorization = "Authorization";
+ public const string CacheControl = "Cache-Control";
+ public const string Connection = "Connection";
+ public const string ContentDisposition = "Content-Disposition";
+ public const string ContentEncoding = "Content-Encoding";
+ public const string ContentLanguage = "Content-Language";
+ public const string ContentLength = "Content-Length";
+ public const string ContentLocation = "Content-Location";
+ public const string ContentMD5 = "Content-MD5";
+ public const string ContentRange = "Content-Range";
+ public const string ContentSecurityPolicy = "Content-Security-Policy";
+ public const string ContentType = "Content-Type";
+ public const string Cookie = "Cookie";
+ public const string Cookie2 = "Cookie2";
+ public const string Date = "Date";
+ public const string ETag = "ETag";
+ public const string Expect = "Expect";
+ public const string Expires = "Expires";
+ public const string From = "From";
+ public const string Host = "Host";
+ public const string IfMatch = "If-Match";
+ public const string IfModifiedSince = "If-Modified-Since";
+ public const string IfNoneMatch = "If-None-Match";
+ public const string IfRange = "If-Range";
+ public const string IfUnmodifiedSince = "If-Unmodified-Since";
+ public const string KeepAlive = "Keep-Alive";
+ public const string LastModified = "Last-Modified";
+ public const string Link = "Link";
+ public const string Location = "Location";
+ public const string MaxForwards = "Max-Forwards";
+ public const string Origin = "Origin";
+ public const string P3P = "P3P";
+ public const string Pragma = "Pragma";
+ public const string ProxyAuthenticate = "Proxy-Authenticate";
+ public const string ProxyAuthorization = "Proxy-Authorization";
+ public const string ProxyConnection = "Proxy-Connection";
+ public const string PublicKeyPins = "Public-Key-Pins";
+ public const string Range = "Range";
+ public const string Referer = "Referer"; // NB: The spelling-mistake "Referer" for "Referrer" must be matched.
+ public const string RetryAfter = "Retry-After";
+ public const string SecWebSocketAccept = "Sec-WebSocket-Accept";
+ public const string SecWebSocketExtensions = "Sec-WebSocket-Extensions";
+ public const string SecWebSocketKey = "Sec-WebSocket-Key";
+ public const string SecWebSocketProtocol = "Sec-WebSocket-Protocol";
+ public const string SecWebSocketVersion = "Sec-WebSocket-Version";
+ public const string Server = "Server";
+ public const string SetCookie = "Set-Cookie";
+ public const string SetCookie2 = "Set-Cookie2";
+ public const string StrictTransportSecurity = "Strict-Transport-Security";
+ public const string TE = "TE";
+ public const string TSV = "TSV";
+ public const string Trailer = "Trailer";
+ public const string TransferEncoding = "Transfer-Encoding";
+ public const string Upgrade = "Upgrade";
+ public const string UpgradeInsecureRequests = "Upgrade-Insecure-Requests";
+ public const string UserAgent = "User-Agent";
+ public const string Vary = "Vary";
+ public const string Via = "Via";
+ public const string WWWAuthenticate = "WWW-Authenticate";
+ public const string Warning = "Warning";
+ public const string XAspNetVersion = "X-AspNet-Version";
+ public const string XContentDuration = "X-Content-Duration";
+ public const string XContentTypeOptions = "X-Content-Type-Options";
+ public const string XFrameOptions = "X-Frame-Options";
+ public const string XMSEdgeRef = "X-MSEdge-Ref";
+ public const string XPoweredBy = "X-Powered-By";
+ public const string XRequestID = "X-Request-ID";
+ public const string XUACompatible = "X-UA-Compatible";
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net/Owin/OwinRequestMapper.cs b/src/WireMock.Net/Owin/OwinRequestMapper.cs
index 4ccc3b9a..51c4d891 100644
--- a/src/WireMock.Net/Owin/OwinRequestMapper.cs
+++ b/src/WireMock.Net/Owin/OwinRequestMapper.cs
@@ -46,7 +46,7 @@ namespace WireMock.Owin
string bodyAsString = null;
byte[] body = null;
Encoding bodyEncoding = null;
- if (request.Body != null)
+ if (ParseBody(method) && request.Body != null)
{
using (var streamReader = new StreamReader(request.Body))
{
@@ -57,18 +57,42 @@ namespace WireMock.Owin
body = bodyEncoding.GetBytes(bodyAsString);
}
- var listenerHeaders = request.Headers;
+ Dictionary headers = null;
+ if (request.Headers.Any())
+ {
+ headers = new Dictionary();
+ foreach (var header in request.Headers)
+ {
+ headers.Add(header.Key, header.Value.FirstOrDefault());
+ }
+ }
- var headers = new Dictionary();
- foreach (var header in listenerHeaders)
- headers.Add(header.Key, header.Value.FirstOrDefault());
-
- var cookies = new Dictionary();
-
- foreach (var cookie in request.Cookies)
- cookies.Add(cookie.Key, cookie.Value);
+ IDictionary cookies = null;
+ if (request.Cookies.Any())
+ {
+ cookies = new Dictionary();
+ foreach (var cookie in request.Cookies)
+ {
+ cookies.Add(cookie.Key, cookie.Value);
+ }
+ }
return new RequestMessage(url, method, clientIP, body, bodyAsString, bodyEncoding, headers, cookies) { DateTime = DateTime.Now };
}
+
+ private bool ParseBody(string method)
+ {
+ /*
+ HEAD - No defined body semantics.
+ GET - No defined body semantics.
+ PUT - Body supported.
+ POST - Body supported.
+ DELETE - No defined body semantics.
+ TRACE - Body not supported.
+ OPTIONS - Body supported but no semantics on usage (maybe in the future).
+ CONNECT - No defined body semantics
+ */
+ return new[] { "PUT", "POST", "OPTIONS" }.Contains(method.ToUpper());
+ }
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/Owin/OwinResponseMapper.cs b/src/WireMock.Net/Owin/OwinResponseMapper.cs
index d66c9fa4..9abbfaed 100644
--- a/src/WireMock.Net/Owin/OwinResponseMapper.cs
+++ b/src/WireMock.Net/Owin/OwinResponseMapper.cs
@@ -2,6 +2,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using WireMock.Http;
#if !NETSTANDARD
using Microsoft.Owin;
#else
@@ -32,15 +33,28 @@ namespace WireMock.Owin
{
response.StatusCode = responseMessage.StatusCode;
- responseMessage.Headers.ToList().ForEach(pair => response.Headers.Append(pair.Key, pair.Value));
+ if (responseMessage.Headers.ContainsKey(HttpKnownHeaderNames.ContentType))
+ {
+ response.ContentType = responseMessage.Headers[HttpKnownHeaderNames.ContentType];
+ }
+ responseMessage.Headers.Where(h => h.Key != HttpKnownHeaderNames.ContentType).ToList().ForEach(pair => response.Headers.Append(pair.Key, pair.Value));
- if (responseMessage.Body == null)
+ if (responseMessage.Body == null && responseMessage.BodyAsBytes == null)
+ {
return;
+ }
+
+ if (responseMessage.BodyAsBytes != null)
+ {
+ await response.Body.WriteAsync(responseMessage.BodyAsBytes, 0, responseMessage.BodyAsBytes.Length);
+ return;
+ }
Encoding encoding = responseMessage.BodyEncoding ?? _utf8NoBom;
using (var writer = new StreamWriter(response.Body, encoding))
{
await writer.WriteAsync(responseMessage.Body);
+ // TODO : response.ContentLength = responseMessage.Body.Length;
}
}
}
diff --git a/src/WireMock.Net/RequestMessage.cs b/src/WireMock.Net/RequestMessage.cs
index 7ac655d4..8424ce54 100644
--- a/src/WireMock.Net/RequestMessage.cs
+++ b/src/WireMock.Net/RequestMessage.cs
@@ -51,7 +51,7 @@ namespace WireMock
///
/// Gets the query.
///
- public IDictionary> Query { get; } = new Dictionary>();
+ public IDictionary> Query { get; }
///
/// Gets the bodyAsBytes.
@@ -94,34 +94,38 @@ namespace WireMock
BodyEncoding = bodyEncoding;
Headers = headers;
Cookies = cookies;
+ Query = ParseQuery(url.Query);
+ }
- string query = url.Query;
- if (!string.IsNullOrEmpty(query))
+ private IDictionary> ParseQuery(string queryString)
+ {
+ if (string.IsNullOrEmpty(queryString))
{
- if (query.StartsWith("?"))
- {
- query = query.Substring(1);
- }
-
- Query = query.Split('&').Aggregate(
- new Dictionary>(),
- (dict, term) =>
- {
- var parts = term.Split('=');
- string key = parts[0];
- if (!dict.ContainsKey(key))
- {
- dict.Add(key, new WireMockList());
- }
-
- if (parts.Length == 2)
- {
- dict[key].Add(parts[1]);
- }
-
- return dict;
- });
+ return null;
}
+
+ if (queryString.StartsWith("?"))
+ {
+ queryString = queryString.Substring(1);
+ }
+
+ return queryString.Split('&').Aggregate(new Dictionary>(),
+ (dict, term) =>
+ {
+ var parts = term.Split('=');
+ string key = parts[0];
+ if (!dict.ContainsKey(key))
+ {
+ dict.Add(key, new WireMockList());
+ }
+
+ if (parts.Length == 2)
+ {
+ dict[key].Add(parts[1]);
+ }
+
+ return dict;
+ });
}
///
@@ -131,6 +135,11 @@ namespace WireMock
/// The query parameter.
public List GetParameter(string key)
{
+ if (Query == null)
+ {
+ return null;
+ }
+
return Query.ContainsKey(key) ? Query[key] : null;
}
}
diff --git a/src/WireMock.Net/ResponseBuilders/BodyDestinationFormat.cs b/src/WireMock.Net/ResponseBuilders/BodyDestinationFormat.cs
new file mode 100644
index 00000000..303f3bc1
--- /dev/null
+++ b/src/WireMock.Net/ResponseBuilders/BodyDestinationFormat.cs
@@ -0,0 +1,20 @@
+namespace WireMock.ResponseBuilders
+{
+ public static class BodyDestinationFormat
+ {
+ ///
+ /// Same as source (no conversion)
+ ///
+ public const string SameAsSource = "SameAsSource";
+
+ ///
+ /// Convert to string
+ ///
+ public const string String = "String";
+
+ ///
+ /// Convert to bytes
+ ///
+ public const string Bytes = "Bytes";
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs b/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs
index f8f8d3a0..edd84b86 100644
--- a/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs
+++ b/src/WireMock.Net/ResponseBuilders/IBodyResponseBuilder.cs
@@ -1,4 +1,5 @@
-using System.Text;
+using System;
+using System.Text;
using JetBrains.Annotations;
namespace WireMock.ResponseBuilders
@@ -8,16 +9,34 @@ namespace WireMock.ResponseBuilders
///
public interface IBodyResponseBuilder : ITransformResponseBuilder
{
- ///
- /// The with body.
- ///
- /// The body.
- /// The body encoding.
- /// A .
- IResponseBuilder WithBody([NotNull] string body, [CanBeNull] Encoding encoding = null);
+ /////
+ ///// WithBody : Create a string response based on a string.
+ /////
+ ///// The body.
+ ///// The body encoding.
+ ///// A .
+ //// IResponseBuilder WithBody([NotNull] string body, [CanBeNull] Encoding encoding = null);
///
- /// The with body as Json.
+ /// WithBody : Create a ... response based on a string.
+ ///
+ /// The body.
+ /// The Body Destination format (SameAsSource, String or Bytes).
+ /// The body encoding.
+ /// A .
+ IResponseBuilder WithBody([NotNull] string body, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
+
+ ///
+ /// WithBody : Create a ... response based on a bytearray.
+ ///
+ /// The body.
+ /// The Body Destination format (SameAsSource, String or Bytes).
+ /// The body encoding.
+ /// A .
+ IResponseBuilder WithBody([NotNull] byte[] body, [CanBeNull] string destination = BodyDestinationFormat.SameAsSource, [CanBeNull] Encoding encoding = null);
+
+ ///
+ /// WithBody : Create a string response based on a object (which will be converted to a JSON string).
///
/// The body.
/// The body encoding.
@@ -25,11 +44,12 @@ namespace WireMock.ResponseBuilders
IResponseBuilder WithBodyAsJson([NotNull] object body, [CanBeNull] Encoding encoding = null);
///
- /// The with body as base64.
+ /// WithBody : Create a string response based on a Base64 string (which will be decoded to a normal string).
///
- /// The body asbase64.
+ /// The body.
/// The Encoding.
/// A .
- IResponseBuilder WithBodyAsBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
+ [Obsolete]
+ IResponseBuilder WithBodyFromBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
}
}
\ No newline at end of file
diff --git a/src/WireMock.Net/ResponseBuilders/Response.cs b/src/WireMock.Net/ResponseBuilders/Response.cs
index eab40e34..41604c78 100644
--- a/src/WireMock.Net/ResponseBuilders/Response.cs
+++ b/src/WireMock.Net/ResponseBuilders/Response.cs
@@ -150,28 +150,59 @@ namespace WireMock.ResponseBuilders
return this;
}
- ///
- /// The with body.
- ///
- /// The body.
- /// The body encoding.
- /// A .
- public IResponseBuilder WithBody(string body, Encoding encoding = null)
+ ///
+ public IResponseBuilder WithBody(byte[] body, string destination, Encoding encoding = null)
{
Check.NotNull(body, nameof(body));
- ResponseMessage.Body = body;
- ResponseMessage.BodyEncoding = encoding ?? Encoding.UTF8;
+ ResponseMessage.BodyDestination = destination;
+
+ switch (destination)
+ {
+ case BodyDestinationFormat.String:
+ var enc = encoding ?? Encoding.UTF8;
+ ResponseMessage.BodyAsBytes = null;
+ ResponseMessage.Body = enc.GetString(body);
+ ResponseMessage.BodyEncoding = enc;
+ break;
+
+ default:
+ ResponseMessage.BodyAsBytes = body;
+ ResponseMessage.BodyEncoding = null;
+ break;
+ }
return this;
}
- ///
- /// The with body (AsJson object).
- ///
- /// The body.
- /// The body encoding.
- /// A .
+ ///
+ public IResponseBuilder WithBody(string body, string destination = BodyDestinationFormat.SameAsSource, Encoding encoding = null)
+ {
+ Check.NotNull(body, nameof(body));
+
+ encoding = encoding ?? Encoding.UTF8;
+
+ ResponseMessage.BodyDestination = destination;
+
+ switch (destination)
+ {
+ case BodyDestinationFormat.Bytes:
+ ResponseMessage.Body = null;
+ ResponseMessage.BodyAsBytes = encoding.GetBytes(body);
+ ResponseMessage.BodyEncoding = encoding;
+ break;
+
+ default:
+ ResponseMessage.Body = body;
+ ResponseMessage.BodyAsBytes = null;
+ ResponseMessage.BodyEncoding = encoding;
+ break;
+ }
+
+ return this;
+ }
+
+ ///
public IResponseBuilder WithBodyAsJson(object body, Encoding encoding = null)
{
Check.NotNull(body, nameof(body));
@@ -184,23 +215,20 @@ namespace WireMock.ResponseBuilders
ResponseMessage.BodyEncoding = encoding;
}
+ ResponseMessage.BodyDestination = null;
ResponseMessage.Body = jsonBody;
return this;
}
- ///
- /// The with body as base64.
- ///
- /// The body asbase64.
- /// The Encoding.
- /// A .
- public IResponseBuilder WithBodyAsBase64(string bodyAsbase64, Encoding encoding = null)
+ ///
+ public IResponseBuilder WithBodyFromBase64(string bodyAsbase64, Encoding encoding = null)
{
Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));
encoding = encoding ?? Encoding.UTF8;
+ ResponseMessage.BodyDestination = null;
ResponseMessage.Body = encoding.GetString(Convert.FromBase64String(bodyAsbase64));
ResponseMessage.BodyEncoding = encoding;
diff --git a/src/WireMock.Net/ResponseMessage.cs b/src/WireMock.Net/ResponseMessage.cs
index b60ed2ce..9c2bdc15 100644
--- a/src/WireMock.Net/ResponseMessage.cs
+++ b/src/WireMock.Net/ResponseMessage.cs
@@ -24,11 +24,21 @@ namespace WireMock
///
public string BodyOriginal { get; set; }
+ ///
+ /// Gets or sets the body destination (SameAsSource, String or Bytes).
+ ///
+ public string BodyDestination { get; set; }
+
///
/// Gets or sets the body.
///
public string Body { get; set; }
+ ///
+ /// Gets or sets the body.
+ ///
+ public byte[] BodyAsBytes { get; set; }
+
///
/// Gets or sets the body encoding.
///
diff --git a/src/WireMock.Net/Serialization/MappingConverter.cs b/src/WireMock.Net/Serialization/MappingConverter.cs
index 48c3e567..47661662 100644
--- a/src/WireMock.Net/Serialization/MappingConverter.cs
+++ b/src/WireMock.Net/Serialization/MappingConverter.cs
@@ -95,16 +95,20 @@ namespace WireMock.Serialization
{
mappingModel.Response.StatusCode = null;
mappingModel.Response.Headers = null;
+ mappingModel.Response.BodyDestination = null;
mappingModel.Response.Body = null;
+ mappingModel.Response.BodyAsBytes = null;
mappingModel.Response.UseTransformer = false;
mappingModel.Response.BodyEncoding = null;
mappingModel.Response.ProxyUrl = response.ProxyUrl;
}
else
{
+ mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
mappingModel.Response.Headers = response.ResponseMessage.Headers;
mappingModel.Response.Body = response.ResponseMessage.Body;
+ mappingModel.Response.BodyAsBytes = response.ResponseMessage.BodyAsBytes;
mappingModel.Response.UseTransformer = response.UseTransformer;
mappingModel.Response.BodyEncoding = response.ResponseMessage.BodyEncoding != null
? new EncodingModel
diff --git a/src/WireMock.Net/Server/FluentMockServer.Admin.cs b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
index e311d12a..482b16e3 100644
--- a/src/WireMock.Net/Server/FluentMockServer.Admin.cs
+++ b/src/WireMock.Net/Server/FluentMockServer.Admin.cs
@@ -412,7 +412,9 @@ namespace WireMock.Server
Response = new LogResponseModel
{
StatusCode = logEntry.ResponseMessage.StatusCode,
+ BodyDestination = logEntry.ResponseMessage.BodyDestination,
Body = logEntry.ResponseMessage.Body,
+ BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
Headers = logEntry.ResponseMessage.Headers,
BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
@@ -612,17 +614,21 @@ namespace WireMock.Server
}
}
- if (responseModel.Body != null)
+ if (responseModel.BodyAsBytes != null)
{
- responseBuilder = responseBuilder.WithBody(responseModel.Body, ToEncoding(responseModel.BodyEncoding));
+ responseBuilder = responseBuilder.WithBody(responseModel.BodyAsBytes, responseModel.BodyDestination, ToEncoding(responseModel.BodyEncoding));
+ }
+ else if (responseModel.Body != null)
+ {
+ responseBuilder = responseBuilder.WithBody(responseModel.Body, responseModel.BodyDestination, ToEncoding(responseModel.BodyEncoding));
}
else if (responseModel.BodyAsJson != null)
{
responseBuilder = responseBuilder.WithBodyAsJson(responseModel.BodyAsJson, ToEncoding(responseModel.BodyEncoding));
}
- else if (responseModel.BodyAsBase64 != null)
+ else if (responseModel.BodyFromBase64 != null)
{
- responseBuilder = responseBuilder.WithBodyAsBase64(responseModel.BodyAsBase64, ToEncoding(responseModel.BodyEncoding));
+ responseBuilder = responseBuilder.WithBodyFromBase64(responseModel.BodyFromBase64, ToEncoding(responseModel.BodyEncoding));
}
if (responseModel.UseTransformer)
diff --git a/test/WireMock.Net.Tests/FluentMockServerTests.cs b/test/WireMock.Net.Tests/FluentMockServerTests.cs
index a220f8ab..cb8b31ae 100644
--- a/test/WireMock.Net.Tests/FluentMockServerTests.cs
+++ b/test/WireMock.Net.Tests/FluentMockServerTests.cs
@@ -1,417 +1,434 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Threading.Tasks;
-using NFluent;
-using Xunit;
-using WireMock.Matchers;
-using WireMock.RequestBuilders;
-using WireMock.ResponseBuilders;
-using WireMock.Server;
-
-namespace WireMock.Net.Tests
-{
- //[TestFixture]
- //[Timeout(5000)]
- public class FluentMockServerTests : IDisposable
- {
- private FluentMockServer _server;
-
- // For for AppVeyor + OpenCover
- private string GetCurrentFolder()
- {
- string current = Directory.GetCurrentDirectory();
- //if (!current.EndsWith("WireMock.Net.Tests"))
- // return Path.Combine(current, "test", "WireMock.Net.Tests");
-
- return current;
- }
-
- [Fact]
- public void FluentMockServer_StartStop()
- {
- var server1 = FluentMockServer.Start("http://localhost:9091/");
- server1.Stop();
-
- var server2 = FluentMockServer.Start("http://localhost:9091/");
- server2.Stop();
- }
-
- [Fact]
- public void FluentMockServer_ReadStaticMapping_WithNonGuidFilename()
- {
- var guid = Guid.Parse("04ee4872-9efd-4770-90d3-88d445265d0d");
- string title = "documentdb_root_title";
-
- _server = FluentMockServer.Start();
-
- string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", "documentdb_root.json");
- _server.ReadStaticMapping(folder);
-
- var mappings = _server.Mappings.ToArray();
- Check.That(mappings).HasSize(1);
-
- Check.That(mappings.First().RequestMatcher).IsNotNull();
- Check.That(mappings.First().Provider).IsNotNull();
- Check.That(mappings.First().Guid).Equals(guid);
- Check.That(mappings.First().Title).Equals(title);
- }
-
- [Fact]
- public void FluentMockServer_ReadStaticMapping_WithGuidFilename()
- {
- string guid = "00000002-ee28-4f29-ae63-1ac9b0802d86";
-
- _server = FluentMockServer.Start();
- string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", guid + ".json");
- _server.ReadStaticMapping(folder);
-
- var mappings = _server.Mappings.ToArray();
- Check.That(mappings).HasSize(1);
-
- Check.That(mappings.First().RequestMatcher).IsNotNull();
- Check.That(mappings.First().Provider).IsNotNull();
- Check.That(mappings.First().Guid).Equals(Guid.Parse(guid));
- Check.That(mappings.First().Title).IsNullOrEmpty();
- }
-
- [Fact]
- public void FluentMockServer_ReadStaticMappings()
- {
- _server = FluentMockServer.Start();
-
- string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings");
- _server.ReadStaticMappings(folder);
-
- var mappings = _server.Mappings.ToArray();
- Check.That(mappings).HasSize(2);
- }
-
- [Fact]
- public void FluentMockServer_Admin_Mappings_Get()
- {
- var guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
- _server = FluentMockServer.Start();
-
- _server.Given(Request.Create().WithPath("/foo1").UsingGet())
- .WithGuid(guid)
- .RespondWith(Response.Create().WithStatusCode(201).WithBody("1"));
-
- _server.Given(Request.Create().WithPath("/foo2").UsingGet())
- .RespondWith(Response.Create().WithStatusCode(202).WithBody("2"));
-
- var mappings = _server.Mappings.ToArray();
- Check.That(mappings).HasSize(2);
-
- Check.That(mappings.First().RequestMatcher).IsNotNull();
- Check.That(mappings.First().Provider).IsNotNull();
- Check.That(mappings.First().Guid).Equals(guid);
-
- Check.That(mappings[1].Guid).Not.Equals(guid);
- }
-
- [Fact]
- public void FluentMockServer_Admin_Mappings_Add_SameGuid()
- {
- var guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
- _server = FluentMockServer.Start();
-
- _server.Given(Request.Create().WithPath("/1").UsingGet())
- .WithGuid(guid)
- .RespondWith(Response.Create().WithStatusCode(500));
-
- var mappings = _server.Mappings.ToArray();
- Check.That(mappings).HasSize(1);
- Check.That(mappings.First().Guid).Equals(guid);
-
- _server.Given(Request.Create().WithPath("/2").UsingGet())
- .WithGuid(guid)
- .RespondWith(Response.Create().WithStatusCode(500));
-
- Check.That(mappings).HasSize(1);
- Check.That(mappings.First().Guid).Equals(guid);
- }
-
- [Fact]
- public async Task FluentMockServer_Admin_Mappings_AtPriority()
- {
- _server = FluentMockServer.Start();
-
- // given
- _server.Given(Request.Create().WithPath("/1").UsingGet())
- .AtPriority(2)
- .RespondWith(Response.Create().WithStatusCode(200));
-
- _server.Given(Request.Create().WithPath("/1").UsingGet())
- .AtPriority(1)
- .RespondWith(Response.Create().WithStatusCode(400));
-
- var mappings = _server.Mappings.ToArray();
- Check.That(mappings).HasSize(2);
- Check.That(mappings[0].Priority).Equals(2);
- Check.That(mappings[1].Priority).Equals(1);
-
- // when
- var response = await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/1");
-
- // then
- Check.That((int)response.StatusCode).IsEqualTo(400);
- }
-
- [Fact]
- public async Task FluentMockServer_Admin_Requests_Get()
- {
- // given
- _server = FluentMockServer.Start();
-
- // when
- await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
-
- // then
- Check.That(_server.LogEntries).HasSize(1);
- var requestLogged = _server.LogEntries.First();
- Check.That(requestLogged.RequestMessage.Method).IsEqualTo("get");
- Check.That(requestLogged.RequestMessage.BodyAsBytes).IsEmpty();
- }
-
- [Fact]
- public async Task Should_respond_to_request()
- {
- // given
- _server = FluentMockServer.Start();
-
- _server
- .Given(Request.Create()
- .WithPath("/foo")
- .UsingGet())
- .RespondWith(Response.Create()
- .WithStatusCode(200)
- .WithBody(@"{ msg: ""Hello world!""}"));
-
- // when
- var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
-
- // then
- Check.That(response).IsEqualTo(@"{ msg: ""Hello world!""}");
- }
-
- [Fact]
- public async Task Should_respond_to_request_bodyAsBase64()
- {
- // given
- _server = FluentMockServer.Start();
-
- _server.Given(Request.Create().WithPath("/foo").UsingGet()).RespondWith(Response.Create().WithBodyAsBase64("SGVsbG8gV29ybGQ/"));
-
- // when
- var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
-
- // then
- Check.That(response).IsEqualTo("Hello World?");
- }
-
- [Fact]
- public async Task Should_respond_404_for_unexpected_request()
- {
- // given
- _server = FluentMockServer.Start();
-
- // when
- var response = await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
-
- // then
- Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound);
- Check.That((int)response.StatusCode).IsEqualTo(404);
- }
-
- [Fact]
- public async Task Should_find_a_request_satisfying_a_request_spec()
- {
- // given
- _server = FluentMockServer.Start();
-
- // when
- await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
- await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/bar");
-
- // then
- var result = _server.FindLogEntries(Request.Create().WithPath(new RegexMatcher("^/b.*"))).ToList();
- Check.That(result).HasSize(1);
-
- var requestLogged = result.First();
- Check.That(requestLogged.RequestMessage.Path).IsEqualTo("/bar");
- Check.That(requestLogged.RequestMessage.Url).IsEqualTo("http://localhost:" + _server.Ports[0] + "/bar");
- }
-
- [Fact]
- public async Task Should_reset_requestlogs()
- {
- // given
- _server = FluentMockServer.Start();
-
- // when
- await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
- _server.ResetLogEntries();
-
- // then
- Check.That(_server.LogEntries).IsEmpty();
- }
-
- [Fact]
- public void Should_reset_mappings()
- {
- // given
- _server = FluentMockServer.Start();
-
- _server
- .Given(Request.Create()
- .WithPath("/foo")
- .UsingGet())
- .RespondWith(Response.Create()
- .WithBody(@"{ msg: ""Hello world!""}"));
-
- // when
- _server.ResetMappings();
-
- // then
- Check.That(_server.Mappings).IsEmpty();
- Check.ThatAsyncCode(() => new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo"))
- .ThrowsAny();
- }
-
- [Fact]
- public async Task Should_respond_a_redirect_without_body()
- {
- // given
- _server = FluentMockServer.Start();
-
- _server
- .Given(Request.Create()
- .WithPath("/foo")
- .UsingGet())
- .RespondWith(Response.Create()
- .WithStatusCode(307)
- .WithHeader("Location", "/bar"));
- _server
- .Given(Request.Create()
- .WithPath("/bar")
- .UsingGet())
- .RespondWith(Response.Create()
- .WithStatusCode(200)
- .WithBody("REDIRECT SUCCESSFUL"));
-
- // when
- var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
-
- // then
- Check.That(response).IsEqualTo("REDIRECT SUCCESSFUL");
- }
-
- [Fact]
- public async Task Should_delay_responses_for_a_given_route()
- {
- // given
- _server = FluentMockServer.Start();
-
- _server
- .Given(Request.Create()
- .WithPath("/*"))
- .RespondWith(Response.Create()
- .WithBody(@"{ msg: ""Hello world!""}")
- .WithDelay(TimeSpan.FromMilliseconds(200)));
-
- // when
- var watch = new Stopwatch();
- watch.Start();
- await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
- watch.Stop();
-
- // then
- Check.That(watch.ElapsedMilliseconds).IsStrictlyGreaterThan(200);
- }
-
- [Fact]
- public async Task Should_delay_responses()
- {
- // given
- _server = FluentMockServer.Start();
- _server.AddGlobalProcessingDelay(TimeSpan.FromMilliseconds(200));
- _server
- .Given(Request.Create().WithPath("/*"))
- .RespondWith(Response.Create().WithBody(@"{ msg: ""Hello world!""}"));
-
- // when
- var watch = new Stopwatch();
- watch.Start();
- await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
- watch.Stop();
-
- // then
- Check.That(watch.ElapsedMilliseconds).IsStrictlyGreaterThan(200);
- }
-
- [Fact]
- public async Task Should_proxy_responses()
- {
- // given
- _server = FluentMockServer.Start();
- _server
- .Given(Request.Create().WithPath("/*"))
- .RespondWith(Response.Create().WithProxy("http://www.google.com"));
-
- // when
- var result = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/search?q=test");
-
- // then
- Check.That(result).Contains("google");
- }
-
- //Leaving commented as this requires an actual certificate with password, along with a service that expects a client certificate
- //[Fact]
- //public async Task Should_proxy_responses_with_client_certificate()
- //{
- // // given
- // _server = FluentMockServer.Start();
- // _server
- // .Given(Request.Create().WithPath("/*"))
- // .RespondWith(Response.Create().WithProxy("https://server-that-expects-a-client-certificate", @"\\yourclientcertificatecontainingprivatekey.pfx", "yourclientcertificatepassword"));
-
- // // when
- // var result = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/someurl?someQuery=someValue");
-
- // // then
- // Check.That(result).Contains("google");
- //}
-
- [Fact]
- public async Task FluentMockServer_Logging_SetMaxRequestLogCount()
- {
- // Assign
- var client = new HttpClient();
- // Act
- _server = FluentMockServer.Start();
- _server.SetMaxRequestLogCount(2);
-
- await client.GetAsync("http://localhost:" + _server.Ports[0] + "/foo1");
- await client.GetAsync("http://localhost:" + _server.Ports[0] + "/foo2");
- await client.GetAsync("http://localhost:" + _server.Ports[0] + "/foo3");
-
- // Assert
- Check.That(_server.LogEntries).HasSize(2);
-
- var requestLoggedA = _server.LogEntries.First();
- Check.That(requestLoggedA.RequestMessage.Path).EndsWith("/foo2");
-
- var requestLoggedB = _server.LogEntries.Last();
- Check.That(requestLoggedB.RequestMessage.Path).EndsWith("/foo3");
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Threading.Tasks;
+using NFluent;
+using Xunit;
+using WireMock.Matchers;
+using WireMock.RequestBuilders;
+using WireMock.ResponseBuilders;
+using WireMock.Server;
+
+namespace WireMock.Net.Tests
+{
+ //[TestFixture]
+ //[Timeout(5000)]
+ public class FluentMockServerTests : IDisposable
+ {
+ private FluentMockServer _server;
+
+ // For for AppVeyor + OpenCover
+ private string GetCurrentFolder()
+ {
+ string current = Directory.GetCurrentDirectory();
+ //if (!current.EndsWith("WireMock.Net.Tests"))
+ // return Path.Combine(current, "test", "WireMock.Net.Tests");
+
+ return current;
}
-
- public void Dispose()
- {
- _server?.Stop();
- }
- }
+
+ [Fact]
+ public void FluentMockServer_StartStop()
+ {
+ var server1 = FluentMockServer.Start("http://localhost:9091/");
+ server1.Stop();
+
+ var server2 = FluentMockServer.Start("http://localhost:9091/");
+ server2.Stop();
+ }
+
+ [Fact]
+ public void FluentMockServer_ReadStaticMapping_WithNonGuidFilename()
+ {
+ var guid = Guid.Parse("04ee4872-9efd-4770-90d3-88d445265d0d");
+ string title = "documentdb_root_title";
+
+ _server = FluentMockServer.Start();
+
+ string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", "documentdb_root.json");
+ _server.ReadStaticMapping(folder);
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(1);
+
+ Check.That(mappings.First().RequestMatcher).IsNotNull();
+ Check.That(mappings.First().Provider).IsNotNull();
+ Check.That(mappings.First().Guid).Equals(guid);
+ Check.That(mappings.First().Title).Equals(title);
+ }
+
+ [Fact]
+ public void FluentMockServer_ReadStaticMapping_WithGuidFilename()
+ {
+ string guid = "00000002-ee28-4f29-ae63-1ac9b0802d86";
+
+ _server = FluentMockServer.Start();
+ string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings", guid + ".json");
+ _server.ReadStaticMapping(folder);
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(1);
+
+ Check.That(mappings.First().RequestMatcher).IsNotNull();
+ Check.That(mappings.First().Provider).IsNotNull();
+ Check.That(mappings.First().Guid).Equals(Guid.Parse(guid));
+ Check.That(mappings.First().Title).IsNullOrEmpty();
+ }
+
+ [Fact]
+ public void FluentMockServer_ReadStaticMappings()
+ {
+ _server = FluentMockServer.Start();
+
+ string folder = Path.Combine(GetCurrentFolder(), "__admin", "mappings");
+ _server.ReadStaticMappings(folder);
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(2);
+ }
+
+ [Fact]
+ public void FluentMockServer_Admin_Mappings_Get()
+ {
+ var guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
+ _server = FluentMockServer.Start();
+
+ _server.Given(Request.Create().WithPath("/foo1").UsingGet())
+ .WithGuid(guid)
+ .RespondWith(Response.Create().WithStatusCode(201).WithBody("1"));
+
+ _server.Given(Request.Create().WithPath("/foo2").UsingGet())
+ .RespondWith(Response.Create().WithStatusCode(202).WithBody("2"));
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(2);
+
+ Check.That(mappings.First().RequestMatcher).IsNotNull();
+ Check.That(mappings.First().Provider).IsNotNull();
+ Check.That(mappings.First().Guid).Equals(guid);
+
+ Check.That(mappings[1].Guid).Not.Equals(guid);
+ }
+
+ [Fact]
+ public void FluentMockServer_Admin_Mappings_Add_SameGuid()
+ {
+ var guid = Guid.Parse("90356dba-b36c-469a-a17e-669cd84f1f05");
+ _server = FluentMockServer.Start();
+
+ _server.Given(Request.Create().WithPath("/1").UsingGet())
+ .WithGuid(guid)
+ .RespondWith(Response.Create().WithStatusCode(500));
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(1);
+ Check.That(mappings.First().Guid).Equals(guid);
+
+ _server.Given(Request.Create().WithPath("/2").UsingGet())
+ .WithGuid(guid)
+ .RespondWith(Response.Create().WithStatusCode(500));
+
+ Check.That(mappings).HasSize(1);
+ Check.That(mappings.First().Guid).Equals(guid);
+ }
+
+ [Fact]
+ public async Task FluentMockServer_Admin_Mappings_AtPriority()
+ {
+ _server = FluentMockServer.Start();
+
+ // given
+ _server.Given(Request.Create().WithPath("/1").UsingGet())
+ .AtPriority(2)
+ .RespondWith(Response.Create().WithStatusCode(200));
+
+ _server.Given(Request.Create().WithPath("/1").UsingGet())
+ .AtPriority(1)
+ .RespondWith(Response.Create().WithStatusCode(400));
+
+ var mappings = _server.Mappings.ToArray();
+ Check.That(mappings).HasSize(2);
+ Check.That(mappings[0].Priority).Equals(2);
+ Check.That(mappings[1].Priority).Equals(1);
+
+ // when
+ var response = await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/1");
+
+ // then
+ Check.That((int)response.StatusCode).IsEqualTo(400);
+ }
+
+ [Fact]
+ public async Task FluentMockServer_Admin_Requests_Get()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ // when
+ await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
+
+ // then
+ Check.That(_server.LogEntries).HasSize(1);
+ var requestLogged = _server.LogEntries.First();
+ Check.That(requestLogged.RequestMessage.Method).IsEqualTo("get");
+ Check.That(requestLogged.RequestMessage.BodyAsBytes).IsNull();
+ }
+
+ [Fact]
+ public async Task Should_respond_to_request_bodyAsString()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ _server
+ .Given(Request.Create()
+ .WithPath("/foo")
+ .UsingGet())
+ .RespondWith(Response.Create()
+ .WithStatusCode(200)
+ .WithBody("Hello world!"));
+
+ // when
+ var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
+
+ // then
+ Check.That(response).IsEqualTo("Hello world!");
+ }
+
+ [Fact]
+ public async Task Should_respond_to_request_bodyAsBase64()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ _server.Given(Request.Create().WithPath("/foo").UsingGet()).RespondWith(Response.Create().WithBodyFromBase64("SGVsbG8gV29ybGQ/"));
+
+ // when
+ var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
+
+ // then
+ Check.That(response).IsEqualTo("Hello World?");
+ }
+
+ [Fact]
+ public async Task Should_respond_to_request_bodyAsBytes()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ _server.Given(Request.Create().WithPath("/foo").UsingGet()).RespondWith(Response.Create().WithBody(new byte[] { 48, 49 }));
+
+ // when
+ var responseAsString = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
+ var responseAsBytes = await new HttpClient().GetByteArrayAsync("http://localhost:" + _server.Ports[0] + "/foo");
+
+ // then
+ Check.That(responseAsString).IsEqualTo("01");
+ Check.That(responseAsBytes).ContainsExactly(new byte[] { 48, 49 });
+ }
+
+ [Fact]
+ public async Task Should_respond_404_for_unexpected_request()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ // when
+ var response = await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
+
+ // then
+ Check.That(response.StatusCode).IsEqualTo(HttpStatusCode.NotFound);
+ Check.That((int)response.StatusCode).IsEqualTo(404);
+ }
+
+ [Fact]
+ public async Task Should_find_a_request_satisfying_a_request_spec()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ // when
+ await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
+ await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/bar");
+
+ // then
+ var result = _server.FindLogEntries(Request.Create().WithPath(new RegexMatcher("^/b.*"))).ToList();
+ Check.That(result).HasSize(1);
+
+ var requestLogged = result.First();
+ Check.That(requestLogged.RequestMessage.Path).IsEqualTo("/bar");
+ Check.That(requestLogged.RequestMessage.Url).IsEqualTo("http://localhost:" + _server.Ports[0] + "/bar");
+ }
+
+ [Fact]
+ public async Task Should_reset_requestlogs()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ // when
+ await new HttpClient().GetAsync("http://localhost:" + _server.Ports[0] + "/foo");
+ _server.ResetLogEntries();
+
+ // then
+ Check.That(_server.LogEntries).IsEmpty();
+ }
+
+ [Fact]
+ public void Should_reset_mappings()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ _server
+ .Given(Request.Create()
+ .WithPath("/foo")
+ .UsingGet())
+ .RespondWith(Response.Create()
+ .WithBody(@"{ msg: ""Hello world!""}"));
+
+ // when
+ _server.ResetMappings();
+
+ // then
+ Check.That(_server.Mappings).IsEmpty();
+ Check.ThatAsyncCode(() => new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo"))
+ .ThrowsAny();
+ }
+
+ [Fact]
+ public async Task Should_respond_a_redirect_without_body()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ _server
+ .Given(Request.Create()
+ .WithPath("/foo")
+ .UsingGet())
+ .RespondWith(Response.Create()
+ .WithStatusCode(307)
+ .WithHeader("Location", "/bar"));
+ _server
+ .Given(Request.Create()
+ .WithPath("/bar")
+ .UsingGet())
+ .RespondWith(Response.Create()
+ .WithStatusCode(200)
+ .WithBody("REDIRECT SUCCESSFUL"));
+
+ // when
+ var response = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
+
+ // then
+ Check.That(response).IsEqualTo("REDIRECT SUCCESSFUL");
+ }
+
+ [Fact]
+ public async Task Should_delay_responses_for_a_given_route()
+ {
+ // given
+ _server = FluentMockServer.Start();
+
+ _server
+ .Given(Request.Create()
+ .WithPath("/*"))
+ .RespondWith(Response.Create()
+ .WithBody(@"{ msg: ""Hello world!""}")
+ .WithDelay(TimeSpan.FromMilliseconds(200)));
+
+ // when
+ var watch = new Stopwatch();
+ watch.Start();
+ await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
+ watch.Stop();
+
+ // then
+ Check.That(watch.ElapsedMilliseconds).IsStrictlyGreaterThan(200);
+ }
+
+ [Fact]
+ public async Task Should_delay_responses()
+ {
+ // given
+ _server = FluentMockServer.Start();
+ _server.AddGlobalProcessingDelay(TimeSpan.FromMilliseconds(200));
+ _server
+ .Given(Request.Create().WithPath("/*"))
+ .RespondWith(Response.Create().WithBody(@"{ msg: ""Hello world!""}"));
+
+ // when
+ var watch = new Stopwatch();
+ watch.Start();
+ await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/foo");
+ watch.Stop();
+
+ // then
+ Check.That(watch.ElapsedMilliseconds).IsStrictlyGreaterThan(200);
+ }
+
+ [Fact]
+ public async Task Should_proxy_responses()
+ {
+ // given
+ _server = FluentMockServer.Start();
+ _server
+ .Given(Request.Create().WithPath("/*"))
+ .RespondWith(Response.Create().WithProxy("http://www.google.com"));
+
+ // when
+ var result = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/search?q=test");
+
+ // then
+ Check.That(result).Contains("google");
+ }
+
+ //Leaving commented as this requires an actual certificate with password, along with a service that expects a client certificate
+ //[Fact]
+ //public async Task Should_proxy_responses_with_client_certificate()
+ //{
+ // // given
+ // _server = FluentMockServer.Start();
+ // _server
+ // .Given(Request.Create().WithPath("/*"))
+ // .RespondWith(Response.Create().WithProxy("https://server-that-expects-a-client-certificate", @"\\yourclientcertificatecontainingprivatekey.pfx", "yourclientcertificatepassword"));
+
+ // // when
+ // var result = await new HttpClient().GetStringAsync("http://localhost:" + _server.Ports[0] + "/someurl?someQuery=someValue");
+
+ // // then
+ // Check.That(result).Contains("google");
+ //}
+
+ [Fact]
+ public async Task FluentMockServer_Logging_SetMaxRequestLogCount()
+ {
+ // Assign
+ var client = new HttpClient();
+ // Act
+ _server = FluentMockServer.Start();
+ _server.SetMaxRequestLogCount(2);
+
+ await client.GetAsync("http://localhost:" + _server.Ports[0] + "/foo1");
+ await client.GetAsync("http://localhost:" + _server.Ports[0] + "/foo2");
+ await client.GetAsync("http://localhost:" + _server.Ports[0] + "/foo3");
+
+ // Assert
+ Check.That(_server.LogEntries).HasSize(2);
+
+ var requestLoggedA = _server.LogEntries.First();
+ Check.That(requestLoggedA.RequestMessage.Path).EndsWith("/foo2");
+
+ var requestLoggedB = _server.LogEntries.Last();
+ Check.That(requestLoggedB.RequestMessage.Path).EndsWith("/foo3");
+ }
+
+ public void Dispose()
+ {
+ _server?.Stop();
+ }
+ }
}
\ No newline at end of file
diff --git a/test/WireMock.Net.Tests/ResponseTests.cs b/test/WireMock.Net.Tests/ResponseTests.cs
index 18635575..6a74dd7e 100644
--- a/test/WireMock.Net.Tests/ResponseTests.cs
+++ b/test/WireMock.Net.Tests/ResponseTests.cs
@@ -70,14 +70,52 @@ namespace WireMock.Net.Tests
}
[Fact]
- public async Task Response_ProvideResponse_Encoding_Body()
+ public async Task Response_ProvideResponse_WithBody_Bytes_Encoding_Destination_String()
{
// given
string bodyAsString = "abc";
byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", clientIP, body, bodyAsString, Encoding.UTF8);
- var response = Response.Create().WithBody("test", Encoding.ASCII);
+ var response = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.String, Encoding.ASCII);
+
+ // act
+ var responseMessage = await response.ProvideResponseAsync(request);
+
+ // then
+ Check.That(responseMessage.Body).Equals("01");
+ Check.That(responseMessage.BodyAsBytes).IsNull();
+ Check.That(responseMessage.BodyEncoding).Equals(Encoding.ASCII);
+ }
+
+ [Fact]
+ public async Task Response_ProvideResponse_WithBody_Bytes_Encoding_Destination_Bytes()
+ {
+ // given
+ string bodyAsString = "abc";
+ byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
+ var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", clientIP, body, bodyAsString, Encoding.UTF8);
+
+ var response = Response.Create().WithBody(new byte[] { 48, 49 }, BodyDestinationFormat.SameAsSource, Encoding.ASCII);
+
+ // act
+ var responseMessage = await response.ProvideResponseAsync(request);
+
+ // then
+ Check.That(responseMessage.BodyAsBytes).ContainsExactly(new byte[] { 48, 49 });
+ Check.That(responseMessage.Body).IsNull();
+ Check.That(responseMessage.BodyEncoding).IsNull();
+ }
+
+ [Fact]
+ public async Task Response_ProvideResponse_WithBody_String_Encoding()
+ {
+ // given
+ string bodyAsString = "abc";
+ byte[] body = Encoding.UTF8.GetBytes(bodyAsString);
+ var request = new RequestMessage(new Uri("http://localhost/foo"), "POST", clientIP, body, bodyAsString, Encoding.UTF8);
+
+ var response = Response.Create().WithBody("test", null, Encoding.ASCII);
// act
var responseMessage = await response.ProvideResponseAsync(request);
@@ -88,7 +126,7 @@ namespace WireMock.Net.Tests
}
[Fact]
- public async Task Response_ProvideResponse_Encoding_JsonBody()
+ public async Task Response_ProvideResponse_WithBody_Object_Encoding()
{
// given
string bodyAsString = "abc";