public async Task AllowVersionPlaceholder() { // Arrange const string version = "v1"; const string key = "projects"; var httpContext = GetHttpContext(requestPath: $"/{version}/{key}"); var next = new TestRequestDelegate(); // What is being tested var swaggerForOcelotOptions = new SwaggerForOcelotUIOptions(); var swaggerEndpointOptions = CreateSwaggerEndpointOptions(key, version); var rerouteOptions = new TestReRouteOptions(new List <ReRouteOptions> { new ReRouteOptions { SwaggerKey = "projects", UpstreamPathTemplate = "/api/{version}/projects/Values/{everything}", DownstreamPathTemplate = "/api/{version}/Values/{everything}", }, new ReRouteOptions { SwaggerKey = "projects", UpstreamPathTemplate = "/api/projects/Projects", DownstreamPathTemplate = "/api/Projects", }, new ReRouteOptions { SwaggerKey = "projects", UpstreamPathTemplate = "/api/projects/Projects/{everything}", DownstreamPathTemplate = "/api/Projects/{everything}", } }); // downstreamSwagger is returned when client.GetStringAsync is called by the middleware. var downstreamSwagger = await GetBaseOpenApi("OpenApiWithVersionPlaceholderBase"); var httClientMock = GetHttpClient(downstreamSwagger); var httpClientFactory = new TestHttpClientFactory(httClientMock); // upstreamSwagger is returned after swaggerJsonTransformer transforms the downstreamSwagger var expectedSwagger = await GetBaseOpenApi("OpenApiWithVersionPlaceholderBaseTransformed"); var swaggerJsonTransformerMock = new Mock <ISwaggerJsonTransformer>(); swaggerJsonTransformerMock .Setup(x => x.Transform( It.IsAny <string>(), It.IsAny <IEnumerable <ReRouteOptions> >(), It.IsAny <string>())) .Returns(( string swaggerJson, IEnumerable <ReRouteOptions> reRouteOptions, string hostOverride) => new SwaggerJsonTransformer() .Transform(swaggerJson, reRouteOptions, hostOverride)); var swaggerForOcelotMiddleware = new SwaggerForOcelotMiddleware( next.Invoke, swaggerForOcelotOptions, rerouteOptions, swaggerEndpointOptions, httpClientFactory, swaggerJsonTransformerMock.Object); // Act await swaggerForOcelotMiddleware.Invoke(httpContext); httpContext.Response.Body.Seek(0, SeekOrigin.Begin); // Assert using (var streamReader = new StreamReader(httpContext.Response.Body)) { var transformedUpstreamSwagger = await streamReader.ReadToEndAsync(); AreEqual(transformedUpstreamSwagger, expectedSwagger); } swaggerJsonTransformerMock.Verify(x => x.Transform( It.IsAny <string>(), It.IsAny <IEnumerable <ReRouteOptions> >(), It.IsAny <string>()), Times.Once); }
public void Factory_CreateClient_FiltersCanDecorateBuilder() { // Arrange var expected = new HttpMessageHandler[] { Mock.Of <DelegatingHandler>(), // Added by filter1 Mock.Of <DelegatingHandler>(), // Added by filter2 Mock.Of <DelegatingHandler>(), // Added by filter3 Mock.Of <DelegatingHandler>(), // Added in options Mock.Of <DelegatingHandler>(), // Added by filter3 Mock.Of <DelegatingHandler>(), // Added by filter2 Mock.Of <DelegatingHandler>(), // Added by filter1 Mock.Of <HttpMessageHandler>(), // Set as primary handler by options }; Options.Get("github").HttpMessageHandlerBuilderActions.Add(b => { b.PrimaryHandler = expected[7]; b.AdditionalHandlers.Add((DelegatingHandler)expected[3]); }); var filter1 = new Mock <IHttpMessageHandlerBuilderFilter>(); filter1 .Setup(f => f.Configure(It.IsAny <Action <HttpMessageHandlerBuilder> >())) .Returns <Action <HttpMessageHandlerBuilder> >(next => (b) => { next(b); // Calls filter2 b.AdditionalHandlers.Insert(0, (DelegatingHandler)expected[0]); b.AdditionalHandlers.Add((DelegatingHandler)expected[6]); }); var filter2 = new Mock <IHttpMessageHandlerBuilderFilter>(); filter2 .Setup(f => f.Configure(It.IsAny <Action <HttpMessageHandlerBuilder> >())) .Returns <Action <HttpMessageHandlerBuilder> >(next => (b) => { next(b); // Calls filter3 b.AdditionalHandlers.Insert(0, (DelegatingHandler)expected[1]); b.AdditionalHandlers.Add((DelegatingHandler)expected[5]); }); var filter3 = new Mock <IHttpMessageHandlerBuilderFilter>(); filter3 .Setup(f => f.Configure(It.IsAny <Action <HttpMessageHandlerBuilder> >())) .Returns <Action <HttpMessageHandlerBuilder> >(next => (b) => { b.AdditionalHandlers.Add((DelegatingHandler)expected[2]); next(b); // Calls options b.AdditionalHandlers.Add((DelegatingHandler)expected[4]); }); var factory = new TestHttpClientFactory(Services, LoggerFactory, Options, new[] { filter1.Object, filter2.Object, filter3.Object, }); // Act var handler = (HttpMessageHandler)factory.CreateHandlerEntry("github").Handler; // Assert // // The outer-most handler is always a lifetime tracking handler. Assert.IsType <LifetimeTrackingHttpMessageHandler>(handler); handler = Assert.IsAssignableFrom <DelegatingHandler>(handler).InnerHandler; for (var i = 0; i < expected.Length - 1; i++) { Assert.Same(expected[i], handler); handler = Assert.IsAssignableFrom <DelegatingHandler>(handler).InnerHandler; } Assert.Same(expected[7], handler); }
public async void PostAsyncTests( Uri endpoint, SoapVersion version, IEnumerable <XElement> bodies, IEnumerable <XElement> headers, string action) { // Setup var testFactory = new TestHttpClientFactory(); var sut = new SoapClient(testFactory); // Exercise var result = await sut.PostAsync(endpoint, version, bodies, headers, action); // Verify outcome var actual = testFactory.Handler.CallStack.Single(); Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal(endpoint, actual.Uri); // Assert action and version var actualHeaders = actual.Headers; if (actualHeaders.Contains("ActionHeader")) { var actualVersion = SoapVersion.Soap11; Assert.Equal(version, actualVersion); Assert.Equal(action, actualHeaders.GetValues("ActionHeader").Single()); } else { var actionParam = actualHeaders.ContentType?.Parameters?.SingleOrDefault(e => e.Name == "ActionParameter"); if (actionParam != null) { var actualVersion = SoapVersion.Soap12; Assert.Equal(version, actualVersion); Assert.Equal($"\"{action}\"", actionParam.Value); } } // Assert namespace var actualEnvelope = XElement.Parse(actual.Body); var expectedNamespace = new SoapMessageConfiguration(version).Schema; Assert.Equal("Envelope", actualEnvelope.Name.LocalName); Assert.Equal(expectedNamespace, actualEnvelope.Name.Namespace.NamespaceName); // Assert Headers if (headers != null && headers.Any()) { var actualHeader = actualEnvelope.Elements() .Where(e => e.Name.LocalName == "Header") .Where(e => e.Name.Namespace.NamespaceName == expectedNamespace) .Single(); Assert.Equal( headers.Select(e => e.ToString()), actualHeader.Elements().Select(e => e.ToString())); } // Assert Bodies var actualBody = actualEnvelope.Elements() .Where(e => e.Name.LocalName == "Body") .Where(e => e.Name.Namespace.NamespaceName == expectedNamespace) .Single(); Assert.Equal( bodies.Select(e => e.ToString()), actualBody.Elements().Select(e => e.ToString())); }
private async Task <ExpiredHandlerTrackingEntry> SimulateClientUse_Factory_CleanupCycle_DisposesEligibleHandler(TestHttpClientFactory factory) { // Create a handler and move it to the expired state var client1 = factory.CreateClient("github"); var kvp = Assert.Single(factory.ActiveEntryState); kvp.Value.Item1.SetResult(kvp.Key); await kvp.Value.Item2; // Our handler is now in the cleanup state. var cleanupEntry = Assert.Single(factory._expiredHandlers); Assert.True(factory.CleanupTimerStarted.IsSet, "Cleanup timer started"); // We need to make sure that the outer handler actually gets GCed, so drop our references to it. // This is important because the factory relies on this possibility for correctness. We need to ensure that // the factory isn't keeping any references. kvp = default; client1 = null; return(cleanupEntry); }
public UserControllerTests(ITestOutputHelper output) { _HttpClient = TestHttpClientFactory.Create(); _Output = output; }