public static async Task Match_Any_Host_Name() { // Arrange string expected = @"{""id"":12}"; string actual; var builder = new HttpRequestInterceptionBuilder() .ForHttp() .ForAnyHost() .ForPath("orders") .ForQuery("id=12") .WithStatus(HttpStatusCode.OK) .WithContent(expected); var options = new HttpClientInterceptorOptions().Register(builder); using (var client = options.CreateHttpClient()) { // Act actual = await client.GetStringAsync("http://myhost.net/orders?id=12"); } // Assert actual.ShouldBe(expected); using (var client = options.CreateHttpClient()) { // Act actual = await client.GetStringAsync("http://myotherhost.net/orders?id=12"); } // Assert actual.ShouldBe(expected); }
public static async Task Intercept_Http_Requests_Registered_Using_A_Bundle_File() { // Arrange var options = new HttpClientInterceptorOptions() .RegisterBundle("example-bundle.json") .ThrowsOnMissingRegistration(); // Act string content; using (var client = options.CreateHttpClient()) { content = await client.GetStringAsync("https://www.just-eat.co.uk/"); } // Assert content.ShouldBe("<html><head><title>Just Eat</title></head></html>"); // Act using (var client = options.CreateHttpClient()) { client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json"); client.DefaultRequestHeaders.Add("Authorization", "bearer my-token"); client.DefaultRequestHeaders.Add("User-Agent", "My-App/1.0.0"); content = await client.GetStringAsync("https://api.github.com/orgs/justeat"); } // Assert var organization = JObject.Parse(content); organization.Value <int>("id").ShouldBe(1516790); organization.Value <string>("login").ShouldBe("justeat"); organization.Value <string>("url").ShouldBe("https://api.github.com/orgs/justeat"); }
public InterceptionBenchmarks() { _options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); var builder = new HttpRequestInterceptionBuilder(); builder .Requests() .ForHttp() .ForHost("www.google.co.uk") .ForPath("search") .ForQuery("q=Just+Eat") .Responds() .WithMediaType("text/html") .WithContent(@"<!DOCTYPE html><html dir=""ltr"" lang=""en""><head><title>Just Eat</title></head></html>") .RegisterWith(_options); builder .Requests() .ForHttps() .ForHost("files.domain.com") .ForPath("setup.exe") .ForQuery(string.Empty) .Responds() .WithMediaType("application/octet-stream") .WithContent(() => new byte[] { 0, 1, 2, 3, 4 }) .RegisterWith(_options); builder .Requests() .ForHttps() .ForHost("api.github.com") .ForPath("orgs/justeat") .ForQuery(string.Empty) .Responds() .WithMediaType("application/json") .WithJsonContent(new { id = 1516790, login = "******", url = "https://api.github.com/orgs/justeat" }) .RegisterWith(_options); builder .Requests() .ForQuery("page=1") .Responds() .WithContentStream(() => File.OpenRead("organization.json")) .RegisterWith(_options); var refitSettings = new RefitSettings() { ContentSerializer = new SystemTextJsonContentSerializer(), }; #pragma warning disable CA2000 _client = _options.CreateHttpClient(); _serviceNewtonsoftJson = RestService.For <IGitHub>(_options.CreateHttpClient("https://api.github.com")); _serviceSystemTextJson = RestService.For <IGitHub>(_options.CreateHttpClient("https://api.github.com"), refitSettings); #pragma warning restore CA2000 }
public static async Task Register_For_Array_Registers_Interceptions() { // Arrange var builder1 = new HttpRequestInterceptionBuilder() .ForGet() .ForUrl("https://google.com/") .WithContent("foo"); var builder2 = new HttpRequestInterceptionBuilder() .ForGet() .ForUrl("https://bing.com/") .WithContent("bar"); var options = new HttpClientInterceptorOptions() .Register(builder1, builder2); string actual1; string actual2; // Act using (var httpClient = options.CreateHttpClient()) { actual1 = await httpClient.GetStringAsync("https://google.com/"); actual2 = await httpClient.GetStringAsync("https://bing.com/"); } // Assert actual1.ShouldBe("foo"); actual2.ShouldBe("bar"); }
public static async Task Use_Custom_Request_Matching_With_Priorities() { // Arrange var options = new HttpClientInterceptorOptions() .ThrowsOnMissingRegistration(); var builder = new HttpRequestInterceptionBuilder() .Requests().For((request) => request.RequestUri.Host == "google.com").HavingPriority(1) .Responds().WithContent(@"First") .RegisterWith(options) .Requests().For((request) => request.RequestUri.Host.Contains("google", StringComparison.OrdinalIgnoreCase)).HavingPriority(2) .Responds().WithContent(@"Second") .RegisterWith(options) .Requests().For((request) => request.RequestUri.PathAndQuery.Contains("html", StringComparison.OrdinalIgnoreCase)).HavingPriority(3) .Responds().WithContent(@"Third") .RegisterWith(options) .Requests().For((request) => true).HavingPriority(null) .Responds().WithContent(@"Fourth") .RegisterWith(options); using (var client = options.CreateHttpClient()) { // Act and Assert (await client.GetStringAsync("https://google.com/")).ShouldBe("First"); (await client.GetStringAsync("https://google.co.uk")).ShouldContain("Second"); (await client.GetStringAsync("https://example.org/index.html")).ShouldContain("Third"); (await client.GetStringAsync("https://www.just-eat.co.uk/")).ShouldContain("Fourth"); } }
public static async Task Intercept_Http_Post_For_Json_String() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForPost() .ForHttps() .ForHost("public.je-apis.com") .ForPath("consumer") .WithStatus(HttpStatusCode.Created) .WithContent(@"{ ""id"": 123 }"); var options = new HttpClientInterceptorOptions() .Register(builder); using var client = options.CreateHttpClient(); using var body = new StringContent(@"{ ""FirstName"": ""John"" }"); // Act using var response = await client.PostAsync("https://public.je-apis.com/consumer", body); string json = await response.Content.ReadAsStringAsync(); // Assert response.StatusCode.ShouldBe(HttpStatusCode.Created); var content = JObject.Parse(json); content.Value <int>("id").ShouldBe(123); }
public static async Task Intercept_Custom_Http_Method() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForMethod(new HttpMethod("custom")) .ForHost("custom.domain.com") .ForQuery("length=2") .WithContent(() => new byte[] { 0, 1 }); var options = new HttpClientInterceptorOptions() .Register(builder); byte[] content; using (var client = options.CreateHttpClient()) { using (var message = new HttpRequestMessage(new HttpMethod("custom"), "http://custom.domain.com?length=2")) { // Act using (var response = await client.SendAsync(message)) { content = await response.Content.ReadAsByteArrayAsync(); } } } // Assert content.ShouldBe(new byte[] { 0, 1 }); }
public static async Task Intercept_Http_Get_For_Json_Object_Based_On_Request_Headers() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForGet() .ForHttps() .ForHost("public.je-apis.com") .ForPath("terms") .ForRequestHeader("Accept-Tenant", "uk") .WithJsonContent(new { Id = 1, Link = "https://www.just-eat.co.uk/privacy-policy" }); var options = new HttpClientInterceptorOptions() .Register(builder); string json; using (var client = options.CreateHttpClient()) { client.DefaultRequestHeaders.Add("Accept-Tenant", "uk"); // Act json = await client.GetStringAsync("https://public.je-apis.com/terms"); } // Assert var content = JObject.Parse(json); content.Value <int>("Id").ShouldBe(1); content.Value <string>("Link").ShouldBe("https://www.just-eat.co.uk/privacy-policy"); }
public static async Task Inject_Latency_For_Http_Get() { // Arrange var latency = TimeSpan.FromMilliseconds(50); var builder = new HttpRequestInterceptionBuilder() .ForHost("www.google.co.uk") .WithInterceptionCallback((_) => Task.Delay(latency)); var options = new HttpClientInterceptorOptions() .Register(builder); var stopwatch = new Stopwatch(); using (var client = options.CreateHttpClient()) { stopwatch.Start(); // Act await client.GetStringAsync("http://www.google.co.uk"); stopwatch.Stop(); } // Assert stopwatch.Elapsed.ShouldBeGreaterThanOrEqualTo(latency); }
public static async Task Intercept_Http_Get_To_Stream_Content_From_Disk() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForHost("xunit.github.io") .ForPath("settings.json") .WithContentStream(() => File.OpenRead("xunit.runner.json")); var options = new HttpClientInterceptorOptions() .Register(builder); string json; using (var client = options.CreateHttpClient()) { // Act json = await client.GetStringAsync("http://xunit.github.io/settings.json"); } // Assert json.ShouldNotBeNullOrWhiteSpace(); var config = JObject.Parse(json); config.Value <string>("methodDisplay").ShouldBe("method"); }
public static async Task Use_Scopes_To_Change_And_Then_Restore_Behavior() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForHost("public.je-apis.com") .WithJsonContent(new { value = 1 }); var options = new HttpClientInterceptorOptions() .Register(builder); string json1; string json2; string json3; // Act using (var client = options.CreateHttpClient()) { json1 = await client.GetStringAsync("http://public.je-apis.com"); using (options.BeginScope()) { options.Register(builder.WithJsonContent(new { value = 2 })); json2 = await client.GetStringAsync("http://public.je-apis.com"); } json3 = await client.GetStringAsync("http://public.je-apis.com"); } // Assert json1.ShouldNotBe(json2); json1.ShouldBe(json3); }
public static async Task SendAsync_Calls_Inner_Handler_If_Registration_Missing() { // Arrange var options = new HttpClientInterceptorOptions() .Register(HttpMethod.Get, new Uri("https://google.com/foo"), () => Array.Empty <byte>()) .Register(HttpMethod.Options, new Uri("http://google.com/foo"), () => Array.Empty <byte>()) .Register(HttpMethod.Options, new Uri("https://google.com/FOO"), () => Array.Empty <byte>()); options.OnMissingRegistration = (request) => Task.FromResult <HttpResponseMessage>(null); var mock = new Mock <HttpMessageHandler>(); using (var expected = new HttpResponseMessage(HttpStatusCode.OK)) { using (var request = new HttpRequestMessage(HttpMethod.Options, "https://google.com/foo")) { mock.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", request, ItExpr.IsAny <CancellationToken>()) .ReturnsAsync(expected); using (var httpClient = options.CreateHttpClient(mock.Object)) { // Act var actual = await httpClient.SendAsync(request, CancellationToken.None); // Asert actual.ShouldBe(expected); } } } }
public static void CreateHttpClient_Throws_If_Options_Is_Null() { // Arrange var baseAddress = new Uri("https://google.com"); HttpClientInterceptorOptions options = null; // Act and Assert Assert.Throws <ArgumentNullException>("options", () => options.CreateHttpClient(baseAddress)); }
public InterceptionBenchmarks() { var builderForBytes = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("files.domain.com") .ForPath("setup.exe") .WithMediaType("application/octet-stream") .WithContent(() => new byte[] { 0, 1, 2, 3, 4 }); var builderForHtml = new HttpRequestInterceptionBuilder() .ForHttp() .ForHost("www.google.co.uk") .ForPath("search") .ForQuery("q=Just+Eat") .WithMediaType("text/html") .WithContent(@"<!DOCTYPE html><html dir=""ltr"" lang=""en""><head><title>Just Eat</title></head></html>"); var builderForJson = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("api.github.com") .ForPath("orgs/justeat") .WithMediaType("application/json") .WithJsonContent(new { id = 1516790, login = "******", url = "https://api.github.com/orgs/justeat" }); var builderForStream = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("api.github.com") .ForPath("orgs/justeat") .ForQuery("page=1") .WithMediaType("application/json") .WithContentStream(() => File.OpenRead("organization.json")); _options = new HttpClientInterceptorOptions() .Register(builderForBytes) .Register(builderForHtml) .Register(builderForJson) .Register(builderForStream); _client = _options.CreateHttpClient(); _service = RestService.For <IGitHub>(_options.CreateHttpClient("https://api.github.com")); }
/// <summary> /// Creates an <see cref="HttpClient"/> that uses the interceptors registered for the specified options and base address. /// </summary> /// <param name="options">The <see cref="HttpClientInterceptorOptions"/> to set up.</param> /// <param name="baseAddress">The base address to use for the created HTTP client.</param> /// <param name="innerHandler">The optional inner <see cref="HttpMessageHandler"/>.</param> /// <returns> /// The <see cref="HttpClient"/> that uses the specified <see cref="HttpClientInterceptorOptions"/>. /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="options"/> is <see langword="null"/>. /// </exception> public static HttpClient CreateHttpClient(this HttpClientInterceptorOptions options, Uri baseAddress, HttpMessageHandler innerHandler = null) { if (options == null) { throw new ArgumentNullException(nameof(options)); } var client = options.CreateHttpClient(innerHandler); client.BaseAddress = baseAddress; return(client); }
public static async Task SendAsync_Throws_If_Registration_Missing_Get() { // Arrange var options = new HttpClientInterceptorOptions() .ThrowsOnMissingRegistration(); using (var target = options.CreateHttpClient()) { // Act var exception = await Assert.ThrowsAsync <InvalidOperationException>(() => target.GetAsync("https://google.com/")); // Assert exception.Message.ShouldBe("No HTTP response is configured for GET https://google.com/."); } }
public static async Task Inject_Fault_For_Http_Get() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForHost("www.google.co.uk") .WithStatus(HttpStatusCode.InternalServerError); var options = new HttpClientInterceptorOptions() .Register(builder); using var client = options.CreateHttpClient(); // Act and Assert await Should.ThrowAsync <HttpRequestException>(() => client.GetStringAsync("http://www.google.co.uk")); }
public static async Task Use_Default_Response_For_Unmatched_Requests() { // Arrange var options = new HttpClientInterceptorOptions() { OnMissingRegistration = (request) => Task.FromResult(new HttpResponseMessage(HttpStatusCode.NotFound)), }; using var client = options.CreateHttpClient(); // Act using var response = await client.GetAsync("https://google.com/"); // Assert response.StatusCode.ShouldBe(HttpStatusCode.NotFound); }
public static async Task Use_Custom_Request_Matching() { // Arrange var builder = new HttpRequestInterceptionBuilder() .Requests().For((request) => request.RequestUri.Host == "google.com") .Responds().WithContent(@"<!DOCTYPE html><html dir=""ltr"" lang=""en""><head><title>Google Search</title></head></html>"); var options = new HttpClientInterceptorOptions().Register(builder); using var client = options.CreateHttpClient(); // Act and Assert (await client.GetStringAsync("https://google.com/")).ShouldContain("Google Search"); (await client.GetStringAsync("https://google.com/search")).ShouldContain("Google Search"); (await client.GetStringAsync("https://google.com/search?q=foo")).ShouldContain("Google Search"); }
public static async Task Conditionally_Intercept_Http_Post_For_Json_Object() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForPost() .ForHttps() .ForHost("public.je-apis.com") .ForPath("consumer") .WithStatus(HttpStatusCode.Created) .WithContent(@"{ ""id"": 123 }") .WithInterceptionCallback( async(request) => { string requestBody = await request.Content.ReadAsStringAsync(); var body = JObject.Parse(requestBody); return(body.Value <string>("FirstName") == "John"); }); var options = new HttpClientInterceptorOptions() .ThrowsOnMissingRegistration() .Register(builder); HttpStatusCode status; string json; using (var client = options.CreateHttpClient()) { using (var body = new StringContent(@"{ ""FirstName"": ""John"" }")) { // Act using (var response = await client.PostAsync("https://public.je-apis.com/consumer", body)) { status = response.StatusCode; json = await response.Content.ReadAsStringAsync(); } } } // Assert status.ShouldBe(HttpStatusCode.Created); var content = JObject.Parse(json); content.Value <int>("id").ShouldBe(123); }
public static async Task Register_For_Builder_With_All_Defaults_Registers_Interception() { // Arrange var builder = new HttpRequestInterceptionBuilder(); var options = new HttpClientInterceptorOptions().Register(builder); string actual; using (var client = options.CreateHttpClient()) { // Act actual = await client.GetStringAsync("http://localhost"); } // Assert actual.ShouldBe(string.Empty); }
internal static async Task <string> SendAsync( HttpClientInterceptorOptions target, HttpMethod httpMethod, string requestUri, HttpContent content = null, HttpStatusCode statusCode = HttpStatusCode.OK, string mediaType = null, IDictionary <string, string> headers = null) { using (var httpClient = target.CreateHttpClient(ErroringHandler.Handler)) { using (var request = new HttpRequestMessage(httpMethod, requestUri)) { if (content != null) { request.Content = content; } if (headers != null) { foreach (var pair in headers) { request.Headers.Add(pair.Key, pair.Value); } } using (var response = await httpClient.SendAsync(request)) { response.StatusCode.ShouldBe(statusCode); if (mediaType != null) { response.Content.Headers.ContentType.MediaType.ShouldBe(mediaType); } if (response.Content == null) { return(null); } return(await response.Content.ReadAsStringAsync()); } } } }
public static async Task Intercept_Http_Delete() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForDelete() .ForHttps() .ForHost("public.je-apis.com") .ForPath("baskets/123/orderitems/456") .WithStatus(HttpStatusCode.NoContent); var options = new HttpClientInterceptorOptions() .Register(builder); using var client = options.CreateHttpClient(); // Act using var response = await client.DeleteAsync("https://public.je-apis.com/baskets/123/orderitems/456"); // Assert response.StatusCode.ShouldBe(HttpStatusCode.NoContent); }
public static async Task Use_With_Refit() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("api.github.com") .ForPath("orgs/justeat") .WithJsonContent(new { id = 1516790, login = "******", url = "https://api.github.com/orgs/justeat" }); var options = new HttpClientInterceptorOptions().Register(builder); var service = RestService.For <IGitHub>(options.CreateHttpClient("https://api.github.com")); // Act Organization actual = await service.GetOrganizationAsync("justeat"); // Assert actual.ShouldNotBeNull(); actual.Id.ShouldBe("1516790"); actual.Login.ShouldBe("justeat"); actual.Url.ShouldBe("https://api.github.com/orgs/justeat"); }
public static async Task Intercept_Http_Get_For_Json_Object() { // Arrange var options = new HttpClientInterceptorOptions(); var builder = new HttpRequestInterceptionBuilder(); builder.Requests().ForGet().ForHttps().ForHost("public.je-apis.com").ForPath("terms") .Responds().WithJsonContent(new { Id = 1, Link = "https://www.just-eat.co.uk/privacy-policy" }) .RegisterWith(options); using var client = options.CreateHttpClient(); // Act string json = await client.GetStringAsync("https://public.je-apis.com/terms"); // Assert var content = JObject.Parse(json); content.Value <int>("Id").ShouldBe(1); content.Value <string>("Link").ShouldBe("https://www.just-eat.co.uk/privacy-policy"); }
public static async Task Intercept_Http_Get_For_Json_Object_Using_System_Text_Json() { // Arrange var options = new HttpClientInterceptorOptions(); var builder = new HttpRequestInterceptionBuilder(); builder.Requests().ForGet().ForHttps().ForHost("public.je-apis.com").ForPath("terms") .Responds().WithJsonContent(new { Id = 1, Link = "https://www.just-eat.co.uk/privacy-policy" }) .RegisterWith(options); using var client = options.CreateHttpClient(); // Act using var utf8Json = await client.GetStreamAsync("https://public.je-apis.com/terms"); // Assert using var content = await JsonDocument.ParseAsync(utf8Json); content.RootElement.GetProperty("Id").GetInt32().ShouldBe(1); content.RootElement.GetProperty("Link").GetString().ShouldBe("https://www.just-eat.co.uk/privacy-policy"); }
public static async Task Intercept_Http_Get_For_Raw_Bytes() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("files.domain.com") .ForPath("setup.exe") .WithMediaType("application/octet-stream") .WithContent(() => new byte[] { 0, 1, 2, 3, 4 }); var options = new HttpClientInterceptorOptions() .Register(builder); using var client = options.CreateHttpClient(); // Act byte[] content = await client.GetByteArrayAsync("https://files.domain.com/setup.exe"); // Assert content.ShouldBe(new byte[] { 0, 1, 2, 3, 4 }); }
public static async Task Intercept_Http_Get_For_Html_String() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForHost("www.google.co.uk") .ForPath("search") .ForQuery("q=Just+Eat") .WithMediaType("text/html") .WithContent(@"<!DOCTYPE html><html dir=""ltr"" lang=""en""><head><title>Just Eat</title></head></html>"); var options = new HttpClientInterceptorOptions() .Register(builder); using var client = options.CreateHttpClient(); // Act string html = await client.GetStringAsync("http://www.google.co.uk/search?q=Just+Eat"); // Assert html.ShouldContain("Just Eat"); }
public static async Task Use_The_Same_Builder_For_Multiple_Registrations_On_The_Same_Host() { // Arrange var options = new HttpClientInterceptorOptions(); // Configure a response for https://api.github.com/orgs/justeat var builder = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("api.github.com") .ForPath("orgs/justeat") .WithJsonContent(new { id = 1516790, login = "******", url = "https://api.github.com/orgs/justeat" }); options.Register(builder); // Update the same builder to configure a response for https://api.github.com/orgs/dotnet builder.ForPath("orgs/dotnet") .WithJsonContent(new { id = 9141961, login = "******", url = "https://api.github.com/orgs/dotnet" }); options.Register(builder); var service = RestService.For <IGitHub>(options.CreateHttpClient("https://api.github.com")); // Act Organization justEatOrg = await service.GetOrganizationAsync("justeat"); Organization dotnetOrg = await service.GetOrganizationAsync("dotnet"); // Assert justEatOrg.ShouldNotBeNull(); justEatOrg.Id.ShouldBe("1516790"); justEatOrg.Login.ShouldBe("justeat"); justEatOrg.Url.ShouldBe("https://api.github.com/orgs/justeat"); // Assert dotnetOrg.ShouldNotBeNull(); dotnetOrg.Id.ShouldBe("9141961"); dotnetOrg.Login.ShouldBe("dotnet"); dotnetOrg.Url.ShouldBe("https://api.github.com/orgs/dotnet"); }
public static async Task Use_Multiple_Registrations() { // Arrange var justEat = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("api.github.com") .ForPath("orgs/justeat") .WithJsonContent(new { id = 1516790, login = "******", url = "https://api.github.com/orgs/justeat" }); var dotnet = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("api.github.com") .ForPath("orgs/dotnet") .WithJsonContent(new { id = 9141961, login = "******", url = "https://api.github.com/orgs/dotnet" }); var options = new HttpClientInterceptorOptions() .Register(justEat, dotnet); var service = RestService.For <IGitHub>(options.CreateHttpClient("https://api.github.com")); // Act Organization justEatOrg = await service.GetOrganizationAsync("justeat"); Organization dotnetOrg = await service.GetOrganizationAsync("dotnet"); // Assert justEatOrg.ShouldNotBeNull(); justEatOrg.Id.ShouldBe("1516790"); justEatOrg.Login.ShouldBe("justeat"); justEatOrg.Url.ShouldBe("https://api.github.com/orgs/justeat"); // Assert dotnetOrg.ShouldNotBeNull(); dotnetOrg.Id.ShouldBe("9141961"); dotnetOrg.Login.ShouldBe("dotnet"); dotnetOrg.Url.ShouldBe("https://api.github.com/orgs/dotnet"); }