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: Add Fluent response API #10

Merged
merged 6 commits into from
May 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## v3.1.0-rcX

- Added new fluent response API which provides more flexibility and control over the response. This new API replaces the current `.Respond()` API, and as such most of the old methods/overloads are now deprecated and will be removed in v4.
- Added `RateLimitedStream` helper to simulate network transfer rates.

## v3.0.1

- fix: stop evaluating next matchers as soon as a failed match is encountered.
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ mockHttp
.Method("GET")
.RequestUri("http://localhost/controller/*")
)
.RespondJson(HttpStatusCode.OK, new { id = 123, firstName = "John", lastName = "Doe" })
.Respond(with => with
.StatusCode(200)
.JsonBody(new { id = 123, firstName = "John", lastName = "Doe" })
)
.Verifiable();

var client = new HttpClient(mockHttp);
Expand Down
6 changes: 0 additions & 6 deletions src/MockHttp.Json/Constants.cs

This file was deleted.

6 changes: 6 additions & 0 deletions src/MockHttp.Json/DeprecationWarnings.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace MockHttp.Json;

internal static class DeprecationWarnings
{
public const string RespondsExtensions = "Obsolete, will be removed in next major release. Use the .Respond(with => with.JsonBody(..)) extension methods.";
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using MockHttp.Responses;

// ReSharper disable once CheckNamespace : BREAKING - change namespace with next release. (remove Extensions)
namespace MockHttp.Json.Extensions;

internal static class MockHttpRequestContextExtensions
Expand Down
61 changes: 61 additions & 0 deletions src/MockHttp.Json/Extensions/ResponseBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Net.Http.Headers;
using System.Text;
using MockHttp.Json.Extensions;
using MockHttp.Language.Flow.Response;
using MockHttp.Language.Response;
using MockHttp.Responses;

namespace MockHttp.Json;

/// <summary>
/// Response builder extensions.
/// </summary>
public static class ResponseBuilderExtensions
{
/// <summary>
/// Sets the JSON content for the response.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="jsonContent">The object to be returned as JSON.</param>
/// <param name="encoding">The optional JSON encoding.</param>
/// <param name="adapter">The optional JSON adapter. When null uses the default adapter.</param>
/// <returns>The builder to continue chaining additional behaviors.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="builder" /> is <see langword="null" />.</exception>
public static IWithContentResult JsonBody<T>(this IWithContent builder, T jsonContent, Encoding? encoding = null, IJsonAdapter? adapter = null)
{
return builder.JsonBody(_ => jsonContent, encoding, adapter);
}

/// <summary>
/// Sets the JSON content for the response using a factory returning a new instance of <typeparamref name="T"/> on each invocation.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="jsonContentFactory">The factory which creates an object to be returned as JSON.</param>
/// <param name="encoding">The optional JSON encoding.</param>
/// <param name="adapter">The optional JSON adapter. When null uses the default adapter.</param>
/// <returns>The builder to continue chaining additional behaviors.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="builder" /> or <paramref name="jsonContentFactory" /> is <see langword="null" />.</exception>
public static IWithContentResult JsonBody<T>(this IWithContent builder, Func<MockHttpRequestContext, T> jsonContentFactory, Encoding? encoding = null, IJsonAdapter? adapter = null)
{
if (jsonContentFactory is null)
{
throw new ArgumentNullException(nameof(jsonContentFactory));
}

return builder.Body(requestContext =>
{
IJsonAdapter jsonSerializerAdapter = adapter ?? requestContext.GetAdapter();
object? value = jsonContentFactory(requestContext);

var httpContent = new StringContent(jsonSerializerAdapter.Serialize(value), encoding)
{
Headers =
{
ContentType = new MediaTypeHeaderValue(MediaTypes.JsonMediaType) { CharSet = (encoding ?? Encoding.UTF8).WebName }
}
};

return Task.FromResult<HttpContent>(httpContent);
});
}
}
55 changes: 0 additions & 55 deletions src/MockHttp.Json/JsonResponseStrategy.cs

This file was deleted.

6 changes: 6 additions & 0 deletions src/MockHttp.Json/MediaTypes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace MockHttp.Json;

internal static class MediaTypes
{
public const string JsonMediaType = "application/json";
}
7 changes: 3 additions & 4 deletions src/MockHttp.Json/MockHttp.Json.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@
<PackageProjectUrl>https://github.com/skwasjer/MockHttp</PackageProjectUrl>
<PackageTags>json mediatypeformatter httpclient test mock fake stub httpmock mockhttp httpmessagehandler moq</PackageTags>
<PackageReleaseNotes>
v3.0.0
- Changed to System.Text.Json as default serializer, JSON.NET can be configured as default if desired (mockHttpHandler.UseNewtonsoftJson()).
- Added .NET 6.0 and .NET Framework 4.8/4.7.2/4.6.2 target framework support.
- Removed .NET Standard &lt; 2 and .NET Framework 4.5 support.
v3.1.0-alpha1
- Added new fluent response API which provides more flexibility and control over the response. This new API replaces the current `.Respond()` API, and as such most of the old methods/overloads are now deprecated and will be removed in v4.
- Added `RateLimitedStream` helper to simulate network transfer rates.
</PackageReleaseNotes>
<PackageReadmeFile>README.md</PackageReadmeFile>
</PropertyGroup>
Expand Down
2 changes: 2 additions & 0 deletions src/MockHttp.Json/MockHttp.Json.csproj.DotSettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=extensions/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
5 changes: 5 additions & 0 deletions src/MockHttp.Json/Newtonsoft/RespondsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ namespace MockHttp.Json.Newtonsoft;
/// <summary>
/// JSON extensions for <see cref="IResponds{TResult}" />.
/// </summary>
[Obsolete(DeprecationWarnings.RespondsExtensions, false)]
public static class RespondsExtensions
{
/// <summary>
Expand All @@ -18,6 +19,7 @@ public static class RespondsExtensions
/// <param name="content">The response content.</param>
/// <param name="mediaType">The media type. Can be null, in which case the default JSON content type will be used.</param>
/// <param name="serializerSettings">The serializer settings.</param>
[Obsolete(DeprecationWarnings.RespondsExtensions, false)]
public static TResult RespondJson<T, TResult>
(
this IResponds<TResult> responds,
Expand All @@ -36,6 +38,7 @@ public static TResult RespondJson<T, TResult>
/// <param name="content">The response content.</param>
/// <param name="mediaType">The media type. Can be null, in which case the default JSON content type will be used.</param>
/// <param name="serializerSettings">The serializer settings.</param>
[Obsolete(DeprecationWarnings.RespondsExtensions, false)]
public static TResult RespondJson<T, TResult>
(
this IResponds<TResult> responds,
Expand All @@ -55,6 +58,7 @@ public static TResult RespondJson<T, TResult>
/// <param name="content">The response content.</param>
/// <param name="mediaType">The media type. Can be null, in which case the default JSON content type will be used.</param>
/// <param name="serializerSettings">The serializer settings.</param>
[Obsolete(DeprecationWarnings.RespondsExtensions, false)]
public static TResult RespondJson<T, TResult>
(
this IResponds<TResult> responds,
Expand All @@ -75,6 +79,7 @@ public static TResult RespondJson<T, TResult>
/// <param name="content">The response content.</param>
/// <param name="mediaType">The media type. Can be null, in which case the default JSON content type will be used.</param>
/// <param name="serializerSettings">The serializer settings.</param>
[Obsolete(DeprecationWarnings.RespondsExtensions, false)]
public static TResult RespondJson<T, TResult>
(
this IResponds<TResult> responds,
Expand Down
54 changes: 54 additions & 0 deletions src/MockHttp.Json/Newtonsoft/ResponseBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using System.Text;
using MockHttp.Language.Flow.Response;
using MockHttp.Language.Response;
using MockHttp.Responses;
using Newtonsoft.Json;

namespace MockHttp.Json.Newtonsoft;

/// <summary>
/// Response builder extensions.
/// </summary>
public static class ResponseBuilderExtensions
{
/// <summary>
/// Sets the JSON content for the response.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="jsonContent">The object to be returned as JSON.</param>
/// <param name="encoding">The optional JSON encoding.</param>
/// <param name="serializerSettings">The optional JSON serializer settings. When null uses the default serializer settings.</param>
/// <returns>The builder to continue chaining additional behaviors.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="builder" /> is <see langword="null" />.</exception>
public static IWithContentResult JsonBody<T>
(
this IWithContent builder,
T jsonContent,
Encoding? encoding = null,
JsonSerializerSettings? serializerSettings = null
)
{
return builder.JsonBody(_ => jsonContent, encoding, serializerSettings);
}

/// <summary>
/// Sets the JSON content for the response using a factory returning a new instance of <typeparamref name="T"/> on each invocation.
/// </summary>
/// <param name="builder">The builder.</param>
/// <param name="jsonContentFactory">The factory which creates an object to be returned as JSON.</param>
/// <param name="encoding">The optional JSON encoding.</param>
/// <param name="serializerSettings">The optional JSON serializer settings. When null uses the default serializer settings.</param>
/// <returns>The builder to continue chaining additional behaviors.</returns>
/// <exception cref="ArgumentNullException">Thrown when <paramref name="builder" /> or <paramref name="jsonContentFactory" /> is <see langword="null" />.</exception>
// ReSharper disable once MemberCanBePrivate.Global
public static IWithContentResult JsonBody<T>
(
this IWithContent builder,
Func<MockHttpRequestContext, T> jsonContentFactory,
Encoding? encoding = null,
JsonSerializerSettings? serializerSettings = null
)
{
return builder.JsonBody(jsonContentFactory, encoding, new NewtonsoftAdapter(serializerSettings));
}
}
6 changes: 5 additions & 1 deletion src/MockHttp.Json/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ mockHttp
.Method("GET")
.RequestUri("http://localhost/controller/*")
)
.RespondJson(HttpStatusCode.OK, new { id = 123, firstName = "John", lastName = "Doe" })
.Respond(with => with
.StatusCode(200)
.JsonBody("<b>Hello world</b>")
.ContentType("text/html")
)
.Verifiable();

var client = new HttpClient(mockHttp);
Expand Down
Loading