mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-01-11 22:30:41 +01:00
Cookie #9
This commit is contained in:
@@ -57,6 +57,7 @@ WireMock supports matching of requests to stubs and verification queries using t
|
||||
* HTTP Method
|
||||
* Query parameters
|
||||
* Headers
|
||||
* Cookies
|
||||
* Request body
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
@@ -23,8 +24,11 @@ namespace WireMock
|
||||
string bodyAsString = body != null ? listenerRequest.ContentEncoding.GetString(body) : null;
|
||||
var listenerHeaders = listenerRequest.Headers;
|
||||
var headers = listenerHeaders.AllKeys.ToDictionary(k => k, k => listenerHeaders[k]);
|
||||
var cookies = new Dictionary<string, string>();
|
||||
foreach (Cookie cookie in listenerRequest.Cookies)
|
||||
cookies.Add(cookie.Name, cookie.Value);
|
||||
|
||||
return new RequestMessage(url, verb, body, bodyAsString, headers);
|
||||
return new RequestMessage(url, verb, body, bodyAsString, headers, cookies);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
65
src/WireMock/Matchers/Request/RequestMessageCookieMatcher.cs
Normal file
65
src/WireMock/Matchers/Request/RequestMessageCookieMatcher.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
{
|
||||
/// <summary>
|
||||
/// The request cookie matcher.
|
||||
/// </summary>
|
||||
public class RequestMessageCookieMatcher : IRequestMatcher
|
||||
{
|
||||
private readonly string _name;
|
||||
|
||||
private readonly IMatcher _matcher;
|
||||
|
||||
private readonly Func<IDictionary<string, string>, bool> _cookieFunc;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">The ignoreCase.</param>
|
||||
public RequestMessageCookieMatcher([NotNull] string name, [NotNull] string pattern, bool ignoreCase = true)
|
||||
{
|
||||
Check.NotNull(name, nameof(name));
|
||||
Check.NotNull(pattern, nameof(pattern));
|
||||
|
||||
_name = name;
|
||||
_matcher = new WildcardMatcher(pattern, ignoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessageCookieMatcher"/> class.
|
||||
/// </summary>
|
||||
/// <param name="func">
|
||||
/// The func.
|
||||
/// </param>
|
||||
public RequestMessageCookieMatcher([NotNull] Func<IDictionary<string, string>, bool> func)
|
||||
{
|
||||
Check.NotNull(func, nameof(func));
|
||||
_cookieFunc = func;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified RequestMessage is match.
|
||||
/// </summary>
|
||||
/// <param name="requestMessage">The RequestMessage.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified RequestMessage is match; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public bool IsMatch(RequestMessage requestMessage)
|
||||
{
|
||||
if (_cookieFunc != null)
|
||||
return _cookieFunc(requestMessage.Cookies);
|
||||
|
||||
if (requestMessage.Cookies == null)
|
||||
return false;
|
||||
|
||||
string headerValue = requestMessage.Cookies[_name];
|
||||
return _matcher.IsMatch(headerValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,9 @@ namespace WireMock.Matchers.Request
|
||||
if (_headerFunc != null)
|
||||
return _headerFunc(requestMessage.Headers);
|
||||
|
||||
if (requestMessage.Headers == null)
|
||||
return false;
|
||||
|
||||
string headerValue = requestMessage.Headers[_name];
|
||||
return _matcher.IsMatch(headerValue);
|
||||
}
|
||||
|
||||
@@ -40,12 +40,12 @@ namespace WireMock.Matchers
|
||||
/// <summary>
|
||||
/// Copy/paste from http://www.codeproject.com/Tips/57304/Use-wildcard-characters-and-to-compare-strings
|
||||
/// </summary>
|
||||
private bool MatchWildcardString(string pattern, string input)
|
||||
private bool MatchWildcardString([NotNull] string pattern, string input)
|
||||
{
|
||||
if (input != null && _ignoreCase)
|
||||
input = input.ToLower();
|
||||
|
||||
if (pattern != null && _ignoreCase)
|
||||
if (_ignoreCase)
|
||||
pattern = pattern.ToLower();
|
||||
|
||||
if (string.CompareOrdinal(pattern, input) == 0)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
/// <summary>
|
||||
/// The HeadersAndCookieRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IHeadersAndCookiesRequestBuilder : IBodyRequestBuilder, IRequestMatcher, IParamsRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">ignore Case</param>
|
||||
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
|
||||
IHeadersAndCookiesRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true);
|
||||
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// </summary>
|
||||
/// <param name="func">The headers func.</param>
|
||||
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
|
||||
IHeadersAndCookiesRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string>, bool>[] func);
|
||||
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">ignore Case</param>
|
||||
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
|
||||
IHeadersAndCookiesRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true);
|
||||
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// </summary>
|
||||
/// <param name="cookieFunc">The func.</param>
|
||||
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
|
||||
IHeadersAndCookiesRequestBuilder WithCookie([NotNull] params Func<IDictionary<string, string>, bool>[] cookieFunc);
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Matchers.Request;
|
||||
|
||||
namespace WireMock.RequestBuilders
|
||||
{
|
||||
/// <summary>
|
||||
/// The HeadersRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IHeadersRequestBuilder : IBodyRequestBuilder, IRequestMatcher, IParamsRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// The name.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// The value.
|
||||
/// </param>
|
||||
/// <param name="ignoreCase">ignore Case</param>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder WithHeader(string name, string value, bool ignoreCase = true);
|
||||
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// </summary>
|
||||
/// <param name="func">
|
||||
/// The headers func.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder WithHeader([NotNull] params Func<IDictionary<string, string>, bool>[] func);
|
||||
}
|
||||
}
|
||||
@@ -5,61 +5,61 @@ namespace WireMock.RequestBuilders
|
||||
/// <summary>
|
||||
/// The VerbRequestBuilder interface.
|
||||
/// </summary>
|
||||
public interface IVerbRequestBuilder : IHeadersRequestBuilder
|
||||
public interface IVerbRequestBuilder : IHeadersAndCookiesRequestBuilder
|
||||
{
|
||||
/// <summary>
|
||||
/// The using get.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder UsingGet();
|
||||
IHeadersAndCookiesRequestBuilder UsingGet();
|
||||
|
||||
/// <summary>
|
||||
/// The using post.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder UsingPost();
|
||||
IHeadersAndCookiesRequestBuilder UsingPost();
|
||||
|
||||
/// <summary>
|
||||
/// The using delete.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder UsingDelete();
|
||||
IHeadersAndCookiesRequestBuilder UsingDelete();
|
||||
|
||||
/// <summary>
|
||||
/// The using put.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder UsingPut();
|
||||
IHeadersAndCookiesRequestBuilder UsingPut();
|
||||
|
||||
/// <summary>
|
||||
/// The using head.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder UsingHead();
|
||||
IHeadersAndCookiesRequestBuilder UsingHead();
|
||||
|
||||
/// <summary>
|
||||
/// The using any verb.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
IHeadersRequestBuilder UsingAnyVerb();
|
||||
IHeadersAndCookiesRequestBuilder UsingAnyVerb();
|
||||
|
||||
/// <summary>
|
||||
/// The using verb.
|
||||
/// </summary>
|
||||
/// <param name="verbs">The verb.</param>
|
||||
/// <returns>The <see cref="IHeadersRequestBuilder"/>.</returns>
|
||||
IHeadersRequestBuilder UsingVerb([NotNull] params string[] verbs);
|
||||
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
|
||||
IHeadersAndCookiesRequestBuilder UsingVerb([NotNull] params string[] verbs);
|
||||
}
|
||||
}
|
||||
@@ -112,9 +112,9 @@ namespace WireMock.RequestBuilders
|
||||
/// The using get.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder UsingGet()
|
||||
public IHeadersAndCookiesRequestBuilder UsingGet()
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageVerbMatcher("get"));
|
||||
return this;
|
||||
@@ -124,9 +124,9 @@ namespace WireMock.RequestBuilders
|
||||
/// The using post.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder UsingPost()
|
||||
public IHeadersAndCookiesRequestBuilder UsingPost()
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageVerbMatcher("post"));
|
||||
return this;
|
||||
@@ -136,9 +136,9 @@ namespace WireMock.RequestBuilders
|
||||
/// The using put.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder UsingPut()
|
||||
public IHeadersAndCookiesRequestBuilder UsingPut()
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageVerbMatcher("put"));
|
||||
return this;
|
||||
@@ -148,9 +148,9 @@ namespace WireMock.RequestBuilders
|
||||
/// The using delete.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder UsingDelete()
|
||||
public IHeadersAndCookiesRequestBuilder UsingDelete()
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageVerbMatcher("delete"));
|
||||
return this;
|
||||
@@ -160,9 +160,9 @@ namespace WireMock.RequestBuilders
|
||||
/// The using head.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder UsingHead()
|
||||
public IHeadersAndCookiesRequestBuilder UsingHead()
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageVerbMatcher("head"));
|
||||
return this;
|
||||
@@ -172,9 +172,9 @@ namespace WireMock.RequestBuilders
|
||||
/// The using any verb.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// The <see cref="IHeadersAndCookiesRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder UsingAnyVerb()
|
||||
public IHeadersAndCookiesRequestBuilder UsingAnyVerb()
|
||||
{
|
||||
var matchers = _requestMatchers.Where(m => m is RequestMessageVerbMatcher).ToList();
|
||||
foreach (var matcher in matchers)
|
||||
@@ -189,8 +189,8 @@ namespace WireMock.RequestBuilders
|
||||
/// The using verb.
|
||||
/// </summary>
|
||||
/// <param name="verbs">The verbs.</param>
|
||||
/// <returns>The <see cref="IHeadersRequestBuilder"/>.</returns>
|
||||
public IHeadersRequestBuilder UsingVerb(params string[] verbs)
|
||||
/// <returns>The <see cref="IHeadersAndCookiesRequestBuilder"/>.</returns>
|
||||
public IHeadersAndCookiesRequestBuilder UsingVerb(params string[] verbs)
|
||||
{
|
||||
var or = new RequestMessageCompositeMatcher(verbs.Select(verb => new RequestMessageVerbMatcher(verb)), CompositeMatcherType.Or);
|
||||
_requestMatchers.Add(or);
|
||||
@@ -305,37 +305,55 @@ namespace WireMock.RequestBuilders
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// With header.
|
||||
/// </summary>
|
||||
/// <param name="name">
|
||||
/// The name.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// The value.
|
||||
/// </param>
|
||||
/// <param name="ignoreCase">ignore Case</param>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder WithHeader(string name, string value, bool ignoreCase = true)
|
||||
/// <param name="name">The name.</param>
|
||||
/// <param name="pattern">The pattern.</param>
|
||||
/// <param name="ignoreCase">if set to <c>true</c> [ignore case].</param>
|
||||
/// <returns></returns>
|
||||
public IHeadersAndCookiesRequestBuilder WithHeader(string name, string pattern, bool ignoreCase = true)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, value, ignoreCase));
|
||||
_requestMatchers.Add(new RequestMessageHeaderMatcher(name, pattern, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The with header.
|
||||
/// With header.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The func.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="IHeadersRequestBuilder"/>.
|
||||
/// </returns>
|
||||
public IHeadersRequestBuilder WithHeader(params Func<IDictionary<string, string>, bool>[] funcs)
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
/// <returns></returns>
|
||||
public IHeadersAndCookiesRequestBuilder WithHeader(params Func<IDictionary<string, string>, bool>[] funcs)
|
||||
{
|
||||
var or = new RequestMessageCompositeMatcher(funcs.Select(func => new RequestMessageHeaderMatcher(func)), CompositeMatcherType.Or);
|
||||
_requestMatchers.Add(or);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// With cookie.
|
||||
/// </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></returns>
|
||||
public IHeadersAndCookiesRequestBuilder WithCookie(string name, string pattern, bool ignoreCase = true)
|
||||
{
|
||||
_requestMatchers.Add(new RequestMessageCookieMatcher(name, pattern, ignoreCase));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// With header.
|
||||
/// </summary>
|
||||
/// <param name="funcs">The funcs.</param>
|
||||
/// <returns></returns>
|
||||
public IHeadersAndCookiesRequestBuilder WithCookie(params Func<IDictionary<string, string>, bool>[] funcs)
|
||||
{
|
||||
var or = new RequestMessageCompositeMatcher(funcs.Select(func => new RequestMessageCookieMatcher(func)), CompositeMatcherType.Or);
|
||||
_requestMatchers.Add(or);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Extensions;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
@@ -33,6 +32,11 @@ namespace WireMock
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Headers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cookies.
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Cookies { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the query.
|
||||
/// </summary>
|
||||
@@ -56,7 +60,8 @@ namespace WireMock
|
||||
/// <param name="bodyAsBytes">The bodyAsBytes byte[].</param>
|
||||
/// <param name="body">The body string.</param>
|
||||
/// <param name="headers">The headers.</param>
|
||||
public RequestMessage([NotNull] Uri url, [NotNull] string verb, [CanBeNull] byte[] bodyAsBytes, [CanBeNull] string body, [CanBeNull] IDictionary<string, string> headers = null)
|
||||
/// <param name="cookies">The cookies.</param>
|
||||
public RequestMessage([NotNull] Uri url, [NotNull] string verb, [CanBeNull] byte[] bodyAsBytes, [CanBeNull] string body, [CanBeNull] IDictionary<string, string> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
||||
{
|
||||
Check.NotNull(url, nameof(url));
|
||||
Check.NotNull(verb, nameof(verb));
|
||||
@@ -67,6 +72,7 @@ namespace WireMock
|
||||
BodyAsBytes = bodyAsBytes;
|
||||
Body = body;
|
||||
Headers = headers;
|
||||
Cookies = cookies;
|
||||
|
||||
string query = url.Query;
|
||||
if (!string.IsNullOrEmpty(query))
|
||||
|
||||
@@ -250,6 +250,19 @@ namespace WireMock.Net.Tests
|
||||
Check.That(spec.IsMatch(request)).IsTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_specify_requests_matching_given_cookies()
|
||||
{
|
||||
// given
|
||||
var spec = Request.Create().WithUrl("/foo").UsingAnyVerb().WithCookie("session", "a*");
|
||||
|
||||
// when
|
||||
var request = new RequestMessage(new Uri("http://localhost/foo"), "PUT", null, null, null, new Dictionary<string, string> { { "session", "abc" } });
|
||||
|
||||
// then
|
||||
Check.That(spec.IsMatch(request)).IsTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Should_specify_requests_matching_given_body()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user