mirror of
https://github.com/bitwarden/server.git
synced 2024-11-24 12:35:25 +01:00
4377c7a897
* Rewrite Icon fetching * Move validation to IconUri, Uri, or UriBuilder * `dotnet format` 🤖 * PR suggestions * Add not null compiler hint * Add twitter to test case * Move Uri manipulation to UriService * Implement MockedHttpClient Presents better, fluent handling of message matching and response building. * Add redirect handling tests * Add testing to models * More aggressively dispose content in icon link * Format 🤖 * Update icon lockfile * Convert to cloned stream for HttpResponseBuilder Content was being disposed when HttResponseMessage was being disposed. This avoids losing our reference to our content and allows multiple usages of the same `MockedHttpMessageResponse` * Move services to extension Extension is shared by testing and allows access to services from our service tests * Remove unused `using` * Prefer awaiting asyncs for better exception handling * `dotnet format` 🤖 * Await async * Update tests to use test TLD and ip ranges * Remove unused interfaces * Make assignments static when possible * Prefer invariant comparer to downcasing * Prefer injecting interface services to implementations * Prefer comparer set in HashSet initialization * Allow SVG icons * Filter out icons with unknown formats * Seek to beginning of MemoryStream after writing it * More appropriate to not return icon if it's invalid * Add svg icon test
105 lines
3.5 KiB
C#
105 lines
3.5 KiB
C#
#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;
|
|
}
|
|
}
|