Skip to content

Commit 0f32a07

Browse files
Add async bundle method
Add async overload for registering a bundle. Relates to #442.
1 parent 18758ba commit 0f32a07

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed

src/HttpClientInterception/BundleExtensions.cs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,58 @@ public static HttpClientInterceptorOptions RegisterBundle(
6666

6767
var bundle = BundleFactory.Create(path);
6868

69+
return options.RegisterBundle(bundle, templateValues);
70+
}
71+
72+
/// <summary>
73+
/// Registers a bundle of HTTP request interceptions from a specified JSON file.
74+
/// </summary>
75+
/// <param name="options">The <see cref="HttpClientInterceptorOptions"/> to register the bundle with.</param>
76+
/// <param name="path">The path of the JSON file containing the serialized bundle.</param>
77+
/// <param name="templateValues">The optional template values to specify.</param>
78+
/// <param name="cancellationToken">The optional <see cref="CancellationToken"/> to use.</param>
79+
/// <returns>
80+
/// The value specified by <paramref name="options"/>.
81+
/// </returns>
82+
/// <exception cref="ArgumentNullException">
83+
/// <paramref name="options"/>, <paramref name="path"/> or <paramref name="templateValues"/> is <see langword="null"/>.
84+
/// </exception>
85+
/// <exception cref="NotSupportedException">
86+
/// The version of the serialized bundle is not supported.
87+
/// </exception>
88+
public static async Task<HttpClientInterceptorOptions> RegisterBundleAsync(
89+
this HttpClientInterceptorOptions options,
90+
string path,
91+
IEnumerable<KeyValuePair<string, string>>? templateValues = default,
92+
CancellationToken cancellationToken = default)
93+
{
94+
if (options is null)
95+
{
96+
throw new ArgumentNullException(nameof(options));
97+
}
98+
99+
if (path is null)
100+
{
101+
throw new ArgumentNullException(nameof(path));
102+
}
103+
104+
templateValues ??= Array.Empty<KeyValuePair<string, string>>();
105+
106+
var bundle = await BundleFactory.CreateAsync(path, cancellationToken).ConfigureAwait(false);
107+
108+
return options.RegisterBundle(bundle!, templateValues);
109+
}
110+
111+
private static HttpClientInterceptorOptions RegisterBundle(
112+
this HttpClientInterceptorOptions options,
113+
Bundle? bundle,
114+
IEnumerable<KeyValuePair<string, string>> templateValues)
115+
{
116+
if (bundle is null)
117+
{
118+
throw new InvalidOperationException("No HTTP request interception bundle was deserialized.");
119+
}
120+
69121
if (bundle.Version != 1)
70122
{
71123
throw new NotSupportedException($"HTTP request interception bundles of version {bundle.Version} are not supported.");

src/HttpClientInterception/Bundles/BundleFactory.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,24 @@ internal static class BundleFactory
2727
/// <returns>
2828
/// The <see cref="Bundle"/> deserialized from the file specified by <paramref name="path"/>.
2929
/// </returns>
30-
public static Bundle Create(string path)
30+
public static Bundle? Create(string path)
3131
{
3232
string json = File.ReadAllText(path);
3333
return JsonSerializer.Deserialize<Bundle>(json, Settings);
3434
}
35+
36+
/// <summary>
37+
/// Creates a <see cref="Bundle"/> from the specified JSON file as an asynchronous operation.
38+
/// </summary>
39+
/// <param name="path">The path of the JSON file containing the bundle.</param>
40+
/// <param name="cancellationToken">The <see cref="CancellationToken"/> to use.</param>
41+
/// <returns>
42+
/// A <see cref="ValueTask{Bundle}"/> representing the asynchronous operation which
43+
/// returns the bundle deserialized from the file specified by <paramref name="path"/>.
44+
/// </returns>
45+
public static async ValueTask<Bundle?> CreateAsync(string path, CancellationToken cancellationToken)
46+
{
47+
using var stream = File.OpenRead(path);
48+
return await JsonSerializer.DeserializeAsync<Bundle>(stream, Settings, cancellationToken).ConfigureAwait(false);
49+
}
3550
}

src/HttpClientInterception/PublicAPI.Shipped.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ JustEat.HttpClientInterception.SystemTextJsonExtensions
8282
override JustEat.HttpClientInterception.InterceptingHttpMessageHandler.SendAsync(System.Net.Http.HttpRequestMessage! request, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task<System.Net.Http.HttpResponseMessage!>!
8383
static JustEat.HttpClientInterception.BundleExtensions.RegisterBundle(this JustEat.HttpClientInterception.HttpClientInterceptorOptions! options, string! path) -> JustEat.HttpClientInterception.HttpClientInterceptorOptions!
8484
static JustEat.HttpClientInterception.BundleExtensions.RegisterBundle(this JustEat.HttpClientInterception.HttpClientInterceptorOptions! options, string! path, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string!, string!>>! templateValues) -> JustEat.HttpClientInterception.HttpClientInterceptorOptions!
85+
static JustEat.HttpClientInterception.BundleExtensions.RegisterBundleAsync(this JustEat.HttpClientInterception.HttpClientInterceptorOptions! options, string! path, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string!, string!>>? templateValues = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<JustEat.HttpClientInterception.HttpClientInterceptorOptions!>!
8586
static JustEat.HttpClientInterception.HttpClientInterceptorOptionsExtensions.CreateHttpClient(this JustEat.HttpClientInterception.HttpClientInterceptorOptions! options, string! baseAddress) -> System.Net.Http.HttpClient!
8687
static JustEat.HttpClientInterception.HttpClientInterceptorOptionsExtensions.CreateHttpClient(this JustEat.HttpClientInterception.HttpClientInterceptorOptions! options, System.Uri! baseAddress, System.Net.Http.HttpMessageHandler? innerHandler = null) -> System.Net.Http.HttpClient!
8788
static JustEat.HttpClientInterception.HttpClientInterceptorOptionsExtensions.DeregisterGet(this JustEat.HttpClientInterception.HttpClientInterceptorOptions! options, string! uriString) -> JustEat.HttpClientInterception.HttpClientInterceptorOptions!

tests/HttpClientInterception.Tests/Bundles/BundleExtensionsTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,28 @@ public static async Task Can_Intercept_Http_Requests_From_Bundle_File()
5151
await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat", headers: headers, mediaType: "application/json");
5252
}
5353

54+
[Fact]
55+
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_Async()
56+
{
57+
// Arrange
58+
var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration();
59+
60+
var headers = new Dictionary<string, string>()
61+
{
62+
["accept"] = "application/vnd.github.v3+json",
63+
["authorization"] = "token my-token",
64+
["user-agent"] = "My-App/1.0.0",
65+
};
66+
67+
// Act
68+
await options.RegisterBundleAsync(Path.Join("Bundles", "http-request-bundle.json"));
69+
70+
// Assert
71+
await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/", mediaType: "text/html");
72+
await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/order-history");
73+
await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat", headers: headers, mediaType: "application/json");
74+
}
75+
5476
[Fact]
5577
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_String()
5678
{

0 commit comments

Comments
 (0)