public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_Templated_Json() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); var templateValues = new Dictionary <string, string>() { ["AvatarUrl"] = "https://avatars.githubusercontent.com/u/1516790?v=4", ["BlogUrl"] = "https://tech.justeattakeaway.com/", }; // Act options.RegisterBundle(Path.Join("Bundles", "templated-bundle-json.json"), templateValues); // Assert string content = await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat"); content .Replace(" ", string.Empty, StringComparison.Ordinal) .Replace("\n", string.Empty, StringComparison.Ordinal) .Replace("\r", string.Empty, StringComparison.Ordinal) .ShouldBe(@"{""id"":1516790,""login"":""justeat"",""url"":""https://api.github.com/orgs/justeat"",""avatar_url"":""https://avatars.githubusercontent.com/u/1516790?v=4"",""name"":""JustEatTakeaway"",""blog"":""https://tech.justeattakeaway.com/""}"); // Assert content = await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat/repos"); content .Replace(" ", string.Empty, StringComparison.Ordinal) .Replace("\n", string.Empty, StringComparison.Ordinal) .Replace("\r", string.Empty, StringComparison.Ordinal) .ShouldBe(@"[{""id"":123456,""name"":""httpclient-interception"",""full_name"":""justeat/httpclient-interception"",""private"":false,""owner"":{""login"":""justeat"",""id"":1516790}}]"); }
public static async Task Can_Skip_Bundle_Items() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); // Act options.RegisterBundle(Path.Join("Bundles", "skipped-item-bundle.json")); // Assert await Assert.ThrowsAsync <HttpRequestNotInterceptedException>( () => HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/")); }
public static async Task Can_Use_Extensibility_For_Request_Header_Matching() { // Arrange var builder = new HttpRequestInterceptionBuilder() .ForHttps() .ForHost("api.github.com") .ForPath("orgs/justeat/repos") .ForQuery("type=private"); var options = new HeaderMatchingOptions( (p) => p.Accept.FirstOrDefault()?.MediaType == "application/vnd.github.v3+json" && p.Authorization?.Scheme == "token" && p.Authorization?.Parameter == "my-token" && p.UserAgent?.FirstOrDefault()?.Product.Name == "My-App" && p.UserAgent?.FirstOrDefault()?.Product.Version == "1.0.0"); options.Register(builder); var url = "https://api.github.com/orgs/justeat/repos?type=private"; var headers = new Dictionary <string, string>() { ["accept"] = "application/vnd.github.v3+json", ["authorization"] = "token my-token", ["user-agent"] = "My-App/1.0.0", }; // Act and Assert await HttpAssert.GetAsync(options, url, headers : headers); await Should.ThrowAsync <HttpRequestException>(() => HttpAssert.GetAsync(options, url)); // Arrange headers = new Dictionary <string, string>() { ["accept"] = "application/vnd.github.v3+json", ["authorization"] = "token my-token", ["user-agent"] = "My-App/2.0.0", }; // Act and Assert await Should.ThrowAsync <HttpRequestException>(() => HttpAssert.GetAsync(options, url, headers: headers)); // Arrange headers = new Dictionary <string, string>() { ["accept"] = "application/vnd.github.v3+json", ["user-agent"] = "My-App/1.0.0", }; // Act and Assert await Should.ThrowAsync <HttpRequestException>(() => HttpAssert.GetAsync(options, url, headers: headers)); }
public static async Task Options_Can_Be_Cloned() { // Arrange var url = "https://google.com/"; var payload = new MyObject() { Message = "Hello world!" }; var options = new HttpClientInterceptorOptions() .RegisterGetJson(url, payload, statusCode: HttpStatusCode.NotFound); // Act var clone = options.Clone() .RegisterGetJson(url, payload, statusCode: HttpStatusCode.InternalServerError); // Assert clone.OnMissingRegistration.ShouldBe(options.OnMissingRegistration); clone.OnSend.ShouldBe(options.OnSend); clone.ThrowOnMissingRegistration.ShouldBe(options.ThrowOnMissingRegistration); await HttpAssert.GetAsync(options, url, HttpStatusCode.NotFound); await HttpAssert.GetAsync(clone, url, HttpStatusCode.InternalServerError); // Arrange options.OnMissingRegistration = (_) => Task.FromResult <HttpResponseMessage>(null); options.OnSend = (_) => Task.CompletedTask; options.ThrowOnMissingRegistration = true; options.Clear(); // Act and Assert clone.ThrowOnMissingRegistration.ShouldNotBe(options.ThrowOnMissingRegistration); clone.OnMissingRegistration.ShouldNotBe(options.OnMissingRegistration); clone.OnSend.ShouldNotBe(options.OnSend); await Should.ThrowAsync <HttpRequestNotInterceptedException>(() => HttpAssert.GetAsync(options, url, HttpStatusCode.InternalServerError)); await HttpAssert.GetAsync(clone, url, HttpStatusCode.InternalServerError); // Arrange options = new HttpClientInterceptorOptions() .ThrowsOnMissingRegistration(); // Act clone = options.Clone(); // Assert clone.ThrowOnMissingRegistration.ShouldBe(options.ThrowOnMissingRegistration); clone.OnMissingRegistration.ShouldBe(options.OnMissingRegistration); clone.OnSend.ShouldBe(options.OnSend); }
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_If_No_Content() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); // Act options.RegisterBundle(Path.Join("Bundles", "no-content.json")); // Assert string content = await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/"); content.ShouldBe(string.Empty); }
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_String_Encoded_As_Base64() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); // Act options.RegisterBundle(Path.Join("Bundles", "content-as-html-base64.json")); // Assert string content = await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/"); content.ShouldBe("<html><head><title>Just Eat</title></head></html>"); }
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_Non_Default_Status_Codes() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); // Act options.RegisterBundle(Path.Join("Bundles", "http-status-codes.json")); // Assert await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/1", HttpStatusCode.NotFound); await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/2", HttpStatusCode.NotFound); }
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_Null_Json() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); // Act options.RegisterBundle(Path.Join("Bundles", "content-as-null-json.json")); // Assert string content = await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat"); content.ShouldBe(string.Empty); }
public static async Task RegisterGet_For_Plaintext_String_With_Custom_Status_Code_Registers_Interception() { // Arrange string requestUri = "https://google.com/"; string expected = "foo"; var options = new HttpClientInterceptorOptions().RegisterGet(requestUri, expected); // Act string actual = await HttpAssert.GetAsync(options, requestUri); // Assert actual.ShouldBe(expected); }
public static async Task RegisterGet_For_Html_With_Custom_Media_Type_Registers_Interception() { // Arrange string requestUri = "https://google.com/"; string mediaType = "text/html"; string expected = "<html>foo></html>"; var options = new HttpClientInterceptorOptions().RegisterGet(requestUri, expected, mediaType: mediaType); // Act string actual = await HttpAssert.GetAsync(options, requestUri, mediaType : mediaType); // Assert actual.ShouldBe(expected); }
public static async Task RegisterGet_If_Content_String_Is_Null_Registers_Interception() { // Arrange string requestUri = "https://google.com/"; string content = null; string expected = string.Empty; var options = new HttpClientInterceptorOptions().RegisterGet(requestUri, content); // Act string actual = await HttpAssert.GetAsync(options, requestUri); // Assert actual.ShouldBe(expected); }
public static async Task RegisterGetJson_For_With_Defaults_Registers_Interception() { // Arrange string requestUri = "https://google.com/"; string[] expected = new[] { "foo", "bar" }; var options = new HttpClientInterceptorOptions().RegisterGetJson(requestUri, expected); // Act string[] actual = await HttpAssert.GetAsync <string[]>(options, requestUri); // Assert actual.ShouldBe(expected); }
public static async Task SendAsync_Calls_OnMissingRegistration_With_RequestMessage() { // Arrange var header = "x-request"; var requestUrl = "https://google.com/foo"; var options = new HttpClientInterceptorOptions(); int expected = 7; int actual = 0; var requestIds = new ConcurrentBag <string>(); options.OnMissingRegistration = (p) => { Interlocked.Increment(ref actual); requestIds.Add(p.Headers.GetValues(header).FirstOrDefault()); var response = new HttpResponseMessage(HttpStatusCode.Accepted) { Content = new StringContent(string.Empty), }; return(Task.FromResult(response)); }; Task GetAsync(int id) { var headers = new Dictionary <string, string>() { [header] = id.ToString(CultureInfo.InvariantCulture), }; return(HttpAssert.GetAsync(options, requestUrl, HttpStatusCode.Accepted, headers: headers)); } // Act var tasks = Enumerable.Range(0, expected) .Select(GetAsync) .ToArray(); await Task.WhenAll(tasks); // Assert actual.ShouldBe(expected); requestIds.Count.ShouldBe(expected); requestIds.ShouldBeUnique(); }
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_Templated_Json() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); // Act options.RegisterBundle(Path.Join("Bundles", "templated-bundle-json.json")); // Assert string content = await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat"); content .Replace(" ", string.Empty, StringComparison.Ordinal) .Replace("\n", string.Empty, StringComparison.Ordinal) .Replace("\r", string.Empty, StringComparison.Ordinal) .ShouldBe(@"{""id"":1516790,""login"":""justeat"",""url"":""https://api.github.com/orgs/justeat""}"); }
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_Json_Array() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); // Act options.RegisterBundle(Path.Join("Bundles", "content-as-json-array.json")); // Assert string content = await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat/repos"); content .Replace(" ", string.Empty, StringComparison.Ordinal) .Replace("\n", string.Empty, StringComparison.Ordinal) .Replace("\r", string.Empty, StringComparison.Ordinal) .ShouldBe(@"[""httpclient-interception""]"); }
public static async Task Can_Intercept_Http_Requests_With_Different_Path_If_The_Uri_Query_String() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); // Act options.RegisterBundle(Path.Join("Bundles", "ignoring-query.json")); // Assert string content = await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat?foo=bar"); content .Replace(" ", string.Empty, StringComparison.Ordinal) .Replace("\n", string.Empty, StringComparison.Ordinal) .Replace("\r", string.Empty, StringComparison.Ordinal) .ShouldBe(@"{""id"":1516790,""login"":""justeat"",""url"":""https://api.github.com/orgs/justeat""}"); }
public static async Task Can_Intercept_Http_Requests_From_Bundle_File_With_Templated_String() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); var headers = new Dictionary <string, string>() { { "user-agent", "My-App/1.0.0" }, }; // Act options.RegisterBundle(Path.Join("Bundles", "templated-bundle-string.json")); // Assert string content = await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/", headers : headers); content.ShouldBe("<html><head><title>Just Eat</title></head></html>"); }
public static async Task HttpClient_Registrations_Can_Be_Removed() { // Arrange var options = new HttpClientInterceptorOptions() .RegisterGetJson("https://google.com/", new { message = "Hello world!" }) .RegisterGetJson("https://google.co.uk/", new { message = "Hello world!" }); // Act and Assert await HttpAssert.GetAsync(options, "https://google.com/"); await HttpAssert.GetAsync(options, "https://google.com/"); await HttpAssert.GetAsync(options, "https://google.co.uk/"); await HttpAssert.GetAsync(options, "https://google.co.uk/"); // Arrange options.DeregisterGet("https://google.com/") .DeregisterGet("https://google.com/"); // Act and Assert await Should.ThrowAsync <HttpRequestException>(() => HttpAssert.GetAsync(options, "https://google.com/")); await Should.ThrowAsync <HttpRequestException>(() => HttpAssert.GetAsync(options, "https://google.com/")); await HttpAssert.GetAsync(options, "https://google.co.uk/"); await HttpAssert.GetAsync(options, "https://google.co.uk/"); // Arrange var builder = new HttpRequestInterceptionBuilder() .ForHttps() .ForGet() .ForHost("bing.com"); options.ThrowOnMissingRegistration = true; options.Register(builder); await HttpAssert.GetAsync(options, "https://bing.com/"); options.Deregister(builder); await Should.ThrowAsync <HttpRequestNotInterceptedException>(() => HttpAssert.GetAsync(options, "https://bing.com/")); }
public static async Task SendAsync_Calls_OnSend_With_RequestMessage() { // Arrange var header = "x-request"; var requestUrl = "https://google.com/foo"; var options = new HttpClientInterceptorOptions() .RegisterByteArray(HttpMethod.Get, new Uri(requestUrl), () => Array.Empty <byte>()); int expected = 7; int actual = 0; var requestIds = new ConcurrentBag <string>(); options.OnSend = (p) => { Interlocked.Increment(ref actual); requestIds.Add(p.Headers.GetValues(header).FirstOrDefault()); return(Task.CompletedTask); }; Task GetAsync(int id) { var headers = new Dictionary <string, string>() { [header] = id.ToString(CultureInfo.InvariantCulture), }; return(HttpAssert.GetAsync(options, requestUrl, headers: headers)); } // Act var tasks = Enumerable.Range(0, expected) .Select(GetAsync) .ToArray(); await Task.WhenAll(tasks); // Assert actual.ShouldBe(expected); requestIds.Count.ShouldBe(expected); requestIds.ShouldBeUnique(); }
public static async Task Options_Can_Be_Scoped() { // Arrange var url = "https://google.com/"; var payload = new MyObject() { Message = "Hello world!" }; var options = new HttpClientInterceptorOptions() .RegisterGetJson(url, payload, statusCode: HttpStatusCode.NotFound); // Act - begin first scope using (options.BeginScope()) { // Assert - original registration await HttpAssert.GetAsync(options, url, HttpStatusCode.NotFound); // Arrange - first update to registration options.RegisterGetJson(url, payload, statusCode: HttpStatusCode.InternalServerError); // Assert - first updated registration await HttpAssert.GetAsync(options, url, HttpStatusCode.InternalServerError); // Act - begin second scope using (options.BeginScope()) { // Arrange - second update to registration options.RegisterGetJson(url, payload, statusCode: HttpStatusCode.RequestTimeout); // Assert - second updated registration await HttpAssert.GetAsync(options, url, HttpStatusCode.RequestTimeout); } // Assert - first updated registration await HttpAssert.GetAsync(options, url, HttpStatusCode.InternalServerError); } // Assert - original registration await HttpAssert.GetAsync(options, url, HttpStatusCode.NotFound); }
public static async Task Can_Intercept_Http_Requests_From_Bundle_File() { // Arrange var options = new HttpClientInterceptorOptions().ThrowsOnMissingRegistration(); var headers = new Dictionary <string, string>() { { "accept", "application/vnd.github.v3+json" }, { "authorization", "token my-token" }, { "user-agent", "My-App/1.0.0" }, }; // Act options.RegisterBundle(Path.Join("Bundles", "http-request-bundle.json")); // Assert await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/", mediaType : "text/html"); await HttpAssert.GetAsync(options, "https://www.just-eat.co.uk/order-history"); await HttpAssert.GetAsync(options, "https://api.github.com/orgs/justeat", headers : headers, mediaType : "application/json"); }