From 6c384008277ed5ebe6a72e5ba258d1bf2e54d5d2 Mon Sep 17 00:00:00 2001 From: Alastair Crabtree Date: Sat, 18 Nov 2017 11:03:13 +0000 Subject: [PATCH] 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 --- appveyor.yml | 2 +- src/WireMock.Net/RequestMessage.cs | 314 ++++++++++-------- .../ResponseTests.Handlebars.cs | 19 ++ 3 files changed, 189 insertions(+), 146 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 2b16eca7..e522ffde 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -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' - codecov -f "coverage.xml" - coveralls.net\tools\csmacnz.Coveralls.exe --opencover -i .\coverage.xml \ No newline at end of file diff --git a/src/WireMock.Net/RequestMessage.cs b/src/WireMock.Net/RequestMessage.cs index f672de81..20af990a 100644 --- a/src/WireMock.Net/RequestMessage.cs +++ b/src/WireMock.Net/RequestMessage.cs @@ -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 -{ - /// - /// The request. - /// - public class RequestMessage - { - /// - /// Gets the Client IP Address. - /// - public string ClientIP { get; } - - /// - /// Gets the url. - /// - public string Url { get; } - - /// - /// Gets the DateTime. - /// - public DateTime DateTime { get; set; } - - /// - /// Gets the path. - /// - public string Path { get; } - - /// - /// Gets the method. - /// - public string Method { get; } - - /// - /// Gets the headers. - /// - public IDictionary> Headers { get; } - - /// - /// Gets the cookies. - /// - public IDictionary Cookies { get; } - - /// - /// Gets the query. - /// - public IDictionary> Query { get; } - - /// - /// Gets the bodyAsBytes. - /// - public byte[] BodyAsBytes { get; } - - /// - /// Gets the body. - /// - public string Body { get; } - - /// - /// Gets the body encoding. - /// - public Encoding BodyEncoding { get; } - - /// - /// Initializes a new instance of the class. - /// - /// The original url. - /// The HTTP method. - /// The client IP Address. - /// The bodyAsBytes byte[]. - /// The body string. - /// The body encoding - /// The headers. - /// The cookies. - 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 headers = null, [CanBeNull] IDictionary 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(header.Value)); - Cookies = cookies; - Query = ParseQuery(url.Query); - } - - private IDictionary> ParseQuery(string queryString) - { - if (string.IsNullOrEmpty(queryString)) - { - 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; - }); - } - - /// - /// The get a query parameter. - /// - /// The key. - /// The query parameter. - public List 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 +{ + /// + /// The request. + /// + public class RequestMessage + { + /// + /// Gets the Client IP Address. + /// + public string ClientIP { get; } + + /// + /// Gets the url. + /// + public string Url { get; } + + /// + /// Gets the DateTime. + /// + public DateTime DateTime { get; set; } + + /// + /// Gets the path. + /// + public string Path { get; } + + /// + /// Gets the method. + /// + public string Method { get; } + + /// + /// Gets the headers. + /// + public IDictionary> Headers { get; } + + /// + /// Gets the cookies. + /// + public IDictionary Cookies { get; } + + /// + /// Gets the query. + /// + public IDictionary> Query { get; } + + /// + /// Gets the bodyAsBytes. + /// + public byte[] BodyAsBytes { get; } + + /// + /// Gets the body. + /// + public string Body { get; } + + /// + /// Gets the Host + /// + public string Host { get; } + + /// + /// Gets the protocol + /// + public string Protocol { get; } + + /// + /// Gets the port + /// + public int Port { get; } + + /// + /// Gets the origin + /// + public string Origin { get; } + + /// + /// Gets the body encoding. + /// + public Encoding BodyEncoding { get; } + + /// + /// Initializes a new instance of the class. + /// + /// The original url. + /// The HTTP method. + /// The client IP Address. + /// The bodyAsBytes byte[]. + /// The body string. + /// The body encoding + /// The headers. + /// The cookies. + 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 headers = null, [CanBeNull] IDictionary 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(header.Value)); + Cookies = cookies; + Query = ParseQuery(url.Query); + } + + private IDictionary> ParseQuery(string queryString) + { + if (string.IsNullOrEmpty(queryString)) + { + 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; + }); + } + + /// + /// The get a query parameter. + /// + /// The key. + /// The query parameter. + public List GetParameter(string key) + { + if (Query == null) + { + return null; + } + + return Query.ContainsKey(key) ? Query[key] : null; + } + } } \ No newline at end of file diff --git a/test/WireMock.Net.Tests/ResponseTests.Handlebars.cs b/test/WireMock.Net.Tests/ResponseTests.Handlebars.cs index c794af20..daf793b8 100644 --- a/test/WireMock.Net.Tests/ResponseTests.Handlebars.cs +++ b/test/WireMock.Net.Tests/ResponseTests.Handlebars.cs @@ -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"); + } } } \ No newline at end of file