Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: vNext #120

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using MockHttp.Responses;
using MockHttp.Response;

// ReSharper disable once CheckNamespace : BREAKING - change namespace with next release. (remove Extensions)
namespace MockHttp.Json.Extensions;
Expand Down
11 changes: 8 additions & 3 deletions src/MockHttp.Json/Extensions/ResponseBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using MockHttp.Json.Extensions;
using MockHttp.Language.Flow.Response;
using MockHttp.Language.Response;
using MockHttp.Responses;
using MockHttp.Response;

namespace MockHttp.Json;

Expand Down Expand Up @@ -71,7 +71,12 @@ internal JsonContentBehavior
_adapter = adapter;
}

public Task HandleAsync(MockHttpRequestContext requestContext, HttpResponseMessage responseMessage, ResponseHandlerDelegate next, CancellationToken cancellationToken)
public Task HandleAsync(
MockHttpRequestContext requestContext,
HttpResponseMessage responseMessage,
ResponseHandler nextHandler,
CancellationToken cancellationToken
)
{
IJsonAdapter jsonSerializerAdapter = _adapter ?? requestContext.GetAdapter();
object? value = _jsonContentFactory();
Expand All @@ -84,7 +89,7 @@ public Task HandleAsync(MockHttpRequestContext requestContext, HttpResponseMessa
}
};

return next(requestContext, responseMessage, cancellationToken);
return nextHandler(requestContext, responseMessage, cancellationToken);
}
}
}
2 changes: 1 addition & 1 deletion src/MockHttp.Json/JsonContentMatcher.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using MockHttp.Json.Extensions;
using MockHttp.Json.SystemTextJson;
using MockHttp.Matchers;
using MockHttp.Responses;
using MockHttp.Response;

namespace MockHttp.Json;

Expand Down
54 changes: 9 additions & 45 deletions src/MockHttp.Server/MockHttpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,8 @@ public sealed class MockHttpServer
private IWebHost? _host;

/// <summary>
/// Initializes a new instance of the <see cref="MockHttpServer" /> using specified <paramref name="mockHttpHandler" /> and configures it to listen on specified <paramref name="hostUrl" />.
/// </summary>
/// <param name="mockHttpHandler">The mock http handler.</param>
/// <param name="hostUrl">The host URL the mock HTTP server will listen on.</param>
[Obsolete("Use the overload accepting an System.Uri.")]
public MockHttpServer(MockHttpHandler mockHttpHandler, string hostUrl)
: this(mockHttpHandler, GetHostUrl(hostUrl))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="MockHttpServer" /> using specified <paramref name="mockHttpHandler" /> and configures it to listen on specified <paramref name="hostUri" />.
/// Initializes a new instance of the <see cref="MockHttpServer" /> using specified <paramref name="mockHttpHandler" /> and configures it to
/// listen on specified <paramref name="hostUri" />.
/// </summary>
/// <param name="mockHttpHandler">The mock http handler.</param>
/// <param name="hostUri">The host URI the mock HTTP server will listen on.</param>
Expand All @@ -53,25 +43,19 @@ public MockHttpServer(MockHttpHandler mockHttpHandler, Uri hostUri)
}

/// <summary>
/// Initializes a new instance of the <see cref="MockHttpServer" /> using specified <paramref name="mockHttpHandler" /> and configures it to listen on specified <paramref name="hostUrl" />.
/// </summary>
/// <param name="mockHttpHandler">The mock http handler.</param>
/// <param name="loggerFactory">The logger factory to use to log pipeline requests to.</param>
/// <param name="hostUrl">The host URL the mock HTTP server will listen on.</param>
[Obsolete("Use the overload accepting an System.Uri.")]
public MockHttpServer(MockHttpHandler mockHttpHandler, ILoggerFactory? loggerFactory, string hostUrl)
: this(mockHttpHandler, loggerFactory, GetHostUrl(hostUrl))
{
}

/// <summary>
/// Initializes a new instance of the <see cref="MockHttpServer" /> using specified <paramref name="mockHttpHandler" /> and configures it to listen on specified <paramref name="hostUri" />.
/// Initializes a new instance of the <see cref="MockHttpServer" /> using specified <paramref name="mockHttpHandler" /> and configures it to
/// listen on specified <paramref name="hostUri" />.
/// </summary>
/// <param name="mockHttpHandler">The mock http handler.</param>
/// <param name="loggerFactory">The logger factory to use to log pipeline requests to.</param>
/// <param name="hostUri">The host URI the mock HTTP server will listen on.</param>
public MockHttpServer(MockHttpHandler mockHttpHandler, ILoggerFactory? loggerFactory, Uri hostUri)
{
if (hostUri is null)
{
throw new ArgumentNullException(nameof(hostUri));
}

Handler = mockHttpHandler ?? throw new ArgumentNullException(nameof(mockHttpHandler));
_webHostBuilder = CreateWebHostBuilder(loggerFactory);
_hostUri = new Uri(hostUri, "/"); // Ensure base URL.
Expand Down Expand Up @@ -102,14 +86,6 @@ public async ValueTask DisposeAsync()
/// </summary>
public MockHttpHandler Handler { get; }

/// <summary>
/// Gets the host URL the mock HTTP server will listen on.
/// </summary>
[Obsolete("Use the HostUri instead.")]
#pragma warning disable CA1056 // URI-like properties should not be strings
public string HostUrl => HostUri.ToString().TrimEnd('/');
#pragma warning restore CA1056 // URI-like properties should not be strings

/// <summary>
/// Gets the host URI the mock HTTP server will listen on.
/// </summary>
Expand Down Expand Up @@ -237,18 +213,6 @@ internal void Configure(Action<IApplicationBuilder> configureAppBuilder)
_configureAppBuilder = configureAppBuilder;
}

private static Uri GetHostUrl(string hostUrl)
{
if (hostUrl is null)
{
throw new ArgumentNullException(nameof(hostUrl));
}

return Uri.TryCreate(hostUrl, UriKind.Absolute, out Uri? uri)
? uri
: throw new ArgumentException(Resources.Error_HostUrlIsNotValid, nameof(hostUrl));
}

private void AddMockHttpServerHeader(IApplicationBuilder applicationBuilder)
{
applicationBuilder.Use(async (context, next) =>
Expand Down
9 changes: 0 additions & 9 deletions src/MockHttp.Server/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions src/MockHttp.Server/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,6 @@
<data name="Debug_HandlingRequest" xml:space="preserve">
<value>MockHttpServer received request.</value>
</data>
<data name="Error_HostUrlIsNotValid" xml:space="preserve">
<value>Specify a host URL.</value>
</data>
<data name="MissingHttpResponseFeature" xml:space="preserve">
<value>HTTP response feature missing.</value>
</data>
Expand Down
1 change: 0 additions & 1 deletion src/MockHttp/Extensions/IRespondsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using MockHttp.Language.Flow;
using MockHttp.Language.Flow.Response;
using MockHttp.Response;
using MockHttp.Responses;

namespace MockHttp;

Expand Down
6 changes: 2 additions & 4 deletions src/MockHttp/IInvokedHttpRequestCollection.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using MockHttp.Threading;

namespace MockHttp;
namespace MockHttp;

/// <summary>
/// Represents a collection of invoked HTTP requests.
/// </summary>
public interface IInvokedHttpRequestCollection : IConcurrentReadOnlyCollection<IInvokedHttpRequest>
public interface IInvokedHttpRequestCollection : IReadOnlyList<IInvokedHttpRequest>
{
/// <summary>
/// Clears the invoked requests collection.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using MockHttp.Matchers;
using MockHttp.Responses;
using MockHttp.Response;

namespace MockHttp.Extensions;

Expand Down
2 changes: 1 addition & 1 deletion src/MockHttp/Internal/HttpCall.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.ObjectModel;
using System.Text;
using MockHttp.Matchers;
using MockHttp.Responses;
using MockHttp.Response;

namespace MockHttp;

Expand All @@ -11,7 +11,7 @@
internal class HttpCall
{
private IResponseStrategy? _responseStrategy;
private string? _verifiableBecause;

Check warning on line 14 in src/MockHttp/Internal/HttpCall.cs

View workflow job for this annotation

GitHub Actions / analysis

Remove this unread private field '_verifiableBecause' or refactor the code to use its value. (https://rules.sonarsource.com/csharp/RSPEC-4487)

Check warning on line 14 in src/MockHttp/Internal/HttpCall.cs

View workflow job for this annotation

GitHub Actions / analysis

Remove this unread private field '_verifiableBecause' or refactor the code to use its value. (https://rules.sonarsource.com/csharp/RSPEC-4487)

Check warning on line 14 in src/MockHttp/Internal/HttpCall.cs

View workflow job for this annotation

GitHub Actions / analysis

Remove this unread private field '_verifiableBecause' or refactor the code to use its value. (https://rules.sonarsource.com/csharp/RSPEC-4487)
private IReadOnlyCollection<IAsyncHttpRequestMatcher>? _matchers;

public IReadOnlyCollection<IAsyncHttpRequestMatcher> Matchers
Expand Down
2 changes: 1 addition & 1 deletion src/MockHttp/Internal/HttpCallSequence.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using MockHttp.Responses;
using MockHttp.Response;

namespace MockHttp;

Expand Down
13 changes: 8 additions & 5 deletions src/MockHttp/Internal/Response/Behaviors/HttpContentBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using MockHttp.Responses;

namespace MockHttp.Response.Behaviors;
namespace MockHttp.Response.Behaviors;

internal sealed class HttpContentBehavior
: IResponseBehavior
Expand All @@ -12,9 +10,14 @@ public HttpContentBehavior(Func<CancellationToken, Task<HttpContent>> httpConten
_httpContentFactory = httpContentFactory ?? throw new ArgumentNullException(nameof(httpContentFactory));
}

public async Task HandleAsync(MockHttpRequestContext requestContext, HttpResponseMessage responseMessage, ResponseHandlerDelegate next, CancellationToken cancellationToken)
public async Task HandleAsync(
MockHttpRequestContext requestContext,
HttpResponseMessage responseMessage,
ResponseHandler nextHandler,
CancellationToken cancellationToken
)
{
responseMessage.Content = await _httpContentFactory(cancellationToken).ConfigureAwait(false);
await next(requestContext, responseMessage, cancellationToken).ConfigureAwait(false);
await nextHandler(requestContext, responseMessage, cancellationToken).ConfigureAwait(false);
}
}
10 changes: 7 additions & 3 deletions src/MockHttp/Internal/Response/Behaviors/HttpHeaderBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using MockHttp.Http;
using MockHttp.Responses;

namespace MockHttp.Response.Behaviors;

Expand Down Expand Up @@ -37,15 +36,20 @@ public HttpHeaderBehavior(IEnumerable<KeyValuePair<string, IEnumerable<string?>>
_headers = headers?.ToList() ?? throw new ArgumentNullException(nameof(headers));
}

public Task HandleAsync(MockHttpRequestContext requestContext, HttpResponseMessage responseMessage, ResponseHandlerDelegate next, CancellationToken cancellationToken)
public Task HandleAsync(
MockHttpRequestContext requestContext,
HttpResponseMessage responseMessage,
ResponseHandler nextHandler,
CancellationToken cancellationToken
)
{
// ReSharper disable once UseDeconstruction
foreach (KeyValuePair<string, IEnumerable<string?>> header in _headers)
{
Add(header, responseMessage);
}

return next(requestContext, responseMessage, cancellationToken);
return nextHandler(requestContext, responseMessage, cancellationToken);
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using MockHttp.Responses;

namespace MockHttp.Response.Behaviors;
namespace MockHttp.Response.Behaviors;

internal sealed class NetworkLatencyBehavior
: IResponseBehavior
Expand All @@ -12,8 +10,13 @@ public NetworkLatencyBehavior(NetworkLatency networkLatency)
_networkLatency = networkLatency ?? throw new ArgumentNullException(nameof(networkLatency));
}

public Task HandleAsync(MockHttpRequestContext requestContext, HttpResponseMessage responseMessage, ResponseHandlerDelegate next, CancellationToken cancellationToken)
public Task HandleAsync(
MockHttpRequestContext requestContext,
HttpResponseMessage responseMessage,
ResponseHandler nextHandler,
CancellationToken cancellationToken
)
{
return _networkLatency.SimulateAsync(() => next(requestContext, responseMessage, cancellationToken), cancellationToken);
return _networkLatency.SimulateAsync(() => nextHandler(requestContext, responseMessage, cancellationToken), cancellationToken);
}
}
10 changes: 7 additions & 3 deletions src/MockHttp/Internal/Response/Behaviors/StatusCodeBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Net;
using MockHttp.Responses;

namespace MockHttp.Response.Behaviors;

Expand All @@ -20,14 +19,19 @@ public StatusCodeBehavior(HttpStatusCode statusCode, string? reasonPhrase)
_reasonPhrase = reasonPhrase;
}

public Task HandleAsync(MockHttpRequestContext requestContext, HttpResponseMessage responseMessage, ResponseHandlerDelegate next, CancellationToken cancellationToken)
public Task HandleAsync(
MockHttpRequestContext requestContext,
HttpResponseMessage responseMessage,
ResponseHandler nextHandler,
CancellationToken cancellationToken
)
{
responseMessage.StatusCode = _statusCode;
if (_reasonPhrase is not null)
{
responseMessage.ReasonPhrase = _reasonPhrase;
}

return next(requestContext, responseMessage, cancellationToken);
return nextHandler(requestContext, responseMessage, cancellationToken);
}
}
8 changes: 6 additions & 2 deletions src/MockHttp/Internal/Response/Behaviors/TimeoutBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Runtime.InteropServices;
using MockHttp.Responses;
using MockHttp.Threading;

namespace MockHttp.Response.Behaviors;
Expand All @@ -19,7 +18,12 @@
_timeoutAfter = timeoutAfter;
}

public Task HandleAsync(MockHttpRequestContext requestContext, HttpResponseMessage responseMessage, ResponseHandlerDelegate next, CancellationToken cancellationToken)
public Task HandleAsync(
MockHttpRequestContext requestContext,
HttpResponseMessage responseMessage,
ResponseHandler nextHandler,
CancellationToken cancellationToken
)
{
// It is somewhat unintuitive to throw TaskCanceledException but this is what HttpClient does,
// so we simulate same behavior.
Expand All @@ -36,7 +40,7 @@
isNotNet5OrGreater = RuntimeInformation.FrameworkDescription.StartsWith(".NET Core 3", StringComparison.OrdinalIgnoreCase); // Shim for .NET 5 being EOL and no longer producing an assembly for it.
#endif

if (cancellationToken.IsCancellationRequested || isNotNet5OrGreater)

Check warning on line 43 in src/MockHttp/Internal/Response/Behaviors/TimeoutBehavior.cs

View workflow job for this annotation

GitHub Actions / analysis

Change this condition so that it does not always evaluate to 'True'. Some code paths are unreachable. (https://rules.sonarsource.com/csharp/RSPEC-2583)
{
tcs.TrySetCanceled();
}
Expand Down
10 changes: 7 additions & 3 deletions src/MockHttp/Internal/Response/Behaviors/TransferRateBehavior.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Net;
using MockHttp.IO;
using MockHttp.Responses;

namespace MockHttp.Response.Behaviors;

Expand All @@ -18,9 +17,14 @@ public TransferRateBehavior(int bitRate)
_bitRate = bitRate;
}

public async Task HandleAsync(MockHttpRequestContext requestContext, HttpResponseMessage responseMessage, ResponseHandlerDelegate next, CancellationToken cancellationToken)
public async Task HandleAsync(
MockHttpRequestContext requestContext,
HttpResponseMessage responseMessage,
ResponseHandler nextHandler,
CancellationToken cancellationToken
)
{
await next(requestContext, responseMessage, cancellationToken).ConfigureAwait(false);
await nextHandler(requestContext, responseMessage, cancellationToken).ConfigureAwait(false);
responseMessage.Content = new RateLimitedHttpContent(responseMessage.Content, _bitRate);
}

Expand Down
4 changes: 1 addition & 3 deletions src/MockHttp/Internal/Response/ExceptionStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using MockHttp.Responses;

namespace MockHttp.Response;
namespace MockHttp.Response;

internal sealed class ExceptionStrategy : IResponseStrategy
{
Expand Down
4 changes: 1 addition & 3 deletions src/MockHttp/Internal/Response/ResponseFuncStrategy.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using MockHttp.Responses;

namespace MockHttp.Response;
namespace MockHttp.Response;

internal sealed class ResponseFuncStrategy : IResponseStrategy
{
Expand Down
2 changes: 1 addition & 1 deletion src/MockHttp/Internal/Threading/ConcurrentCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace MockHttp.Threading;

internal class ConcurrentCollection<T> : IConcurrentReadOnlyCollection<T>
internal class ConcurrentCollection<T> : IReadOnlyList<T>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private readonly object _syncLock = new();
Expand Down
Loading
Loading