1
0
mirror of https://github.com/bitwarden/server.git synced 2024-11-28 13:15:12 +01:00
bitwarden-server/test/Common/MockedHttpClient/HttpRequestMatcher.cs

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

105 lines
3.5 KiB
C#
Raw Normal View History

#nullable enable
using System.Net;
namespace Bit.Test.Common.MockedHttpClient;
public class HttpRequestMatcher : IHttpRequestMatcher
{
private readonly Func<HttpRequestMessage, bool> _matcher;
private HttpRequestMatcher? _childMatcher;
private MockedHttpResponse _mockedResponse = new(HttpStatusCode.OK);
private bool _responseSpecified = false;
public int NumberOfMatches { get; private set; }
/// <summary>
/// Returns whether or not the provided request can be handled by this matcher chain.
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public bool Matches(HttpRequestMessage request) => _matcher(request) && (_childMatcher == null || _childMatcher.Matches(request));
public HttpRequestMatcher(HttpMethod method)
{
_matcher = request => request.Method == method;
}
public HttpRequestMatcher(string uri)
{
_matcher = request => request.RequestUri == new Uri(uri);
}
public HttpRequestMatcher(Uri uri)
{
_matcher = request => request.RequestUri == uri;
}
public HttpRequestMatcher(HttpMethod method, string uri)
{
_matcher = request => request.Method == method && request.RequestUri == new Uri(uri);
}
public HttpRequestMatcher(Func<HttpRequestMessage, bool> matcher)
{
_matcher = matcher;
}
public HttpRequestMatcher WithHeader(string name, string value)
{
return AddChild(request => request.Headers.TryGetValues(name, out var values) && values.Contains(value));
}
public HttpRequestMatcher WithQueryParameters(Dictionary<string, string> requiredQueryParameters) =>
WithQueryParameters(requiredQueryParameters.Select(x => $"{x.Key}={x.Value}").ToArray());
public HttpRequestMatcher WithQueryParameters(string name, string value) =>
WithQueryParameters($"{name}={value}");
public HttpRequestMatcher WithQueryParameters(params string[] queryKeyValues)
{
bool matcher(HttpRequestMessage request)
{
var query = request.RequestUri?.Query;
if (query == null)
{
return false;
}
return queryKeyValues.All(queryKeyValue => query.Contains(queryKeyValue));
}
return AddChild(matcher);
}
/// <summary>
/// Configure how this matcher should respond to matching HttpRequestMessages.
/// Note, after specifying a response, you can no longer further specify match criteria.
/// </summary>
/// <param name="statusCode"></param>
/// <returns></returns>
public MockedHttpResponse RespondWith(HttpStatusCode statusCode)
{
_responseSpecified = true;
_mockedResponse = new MockedHttpResponse(statusCode);
return _mockedResponse;
}
/// <summary>
/// Called to produce an HttpResponseMessage for the given request. This is probably something you want to leave alone
/// </summary>
/// <param name="request"></param>
public async Task<HttpResponseMessage> RespondToAsync(HttpRequestMessage request)
{
NumberOfMatches++;
return await (_childMatcher == null ? _mockedResponse.RespondToAsync(request) : _childMatcher.RespondToAsync(request));
}
private HttpRequestMatcher AddChild(Func<HttpRequestMessage, bool> matcher)
{
if (_responseSpecified)
{
throw new Exception("Cannot continue to configure a matcher after a response has been specified");
}
_childMatcher = new HttpRequestMatcher(matcher);
return _childMatcher;
}
}