// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.IO; using System.Net; using System.Net.Http; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Hosting.Startup; using Microsoft.AspNet.Http; using Microsoft.Framework.Configuration; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Logging; using Xunit; namespace Microsoft.AspNet.TestHost { public class TestServerTests { [Fact] public void CreateWithDelegate() { // Arrange // Act & Assert (Does not throw) TestServer.Create(app => { }); } [Fact] public void ThrowsIfNoApplicationEnvironmentIsRegisteredWithTheProvider() { // Arrange var services = new ServiceCollection().BuildServiceProvider(); // Act & Assert Assert.Throws( () => TestServer.Create( services, new ConfigurationBuilder().Build(), new Startup().Configure, configureServices: null)); } [Fact] public async Task RequestServicesAutoCreated() { TestServer server = TestServer.Create(app => { app.Run(context => { return context.Response.WriteAsync("RequestServices:" + (context.RequestServices != null)); }); }); string result = await server.CreateClient().GetStringAsync("/path"); Assert.Equal("RequestServices:True", result); } public class TestService { } public class TestRequestServiceMiddleware { private RequestDelegate _next; public TestRequestServiceMiddleware(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext) { var services = new ServiceCollection(); services.AddTransient(); httpContext.RequestServices = services.BuildServiceProvider(); return _next.Invoke(httpContext); } } public class RequestServicesFilter : IStartupFilter { public Action Configure(Action next) { return builder => { builder.UseMiddleware(); next(builder); }; } } [Fact] public async Task ExistingRequestServicesWillNotBeReplaced() { var server = TestServer.Create(app => { app.Run(context => { var service = context.RequestServices.GetService(); return context.Response.WriteAsync("Found:" + (service != null)); }); }, services => services.AddTransient()); string result = await server.CreateClient().GetStringAsync("/path"); Assert.Equal("Found:True", result); } [Fact] public async Task CanAccessLogger() { var server = TestServer.Create(app => { app.Run(context => { var logger = app.ApplicationServices.GetRequiredService>(); return context.Response.WriteAsync("FoundLogger:" + (logger != null)); }); }); string result = await server.CreateClient().GetStringAsync("/path"); Assert.Equal("FoundLogger:True", result); } [Fact] public async Task CanAccessHttpContext() { TestServer server = TestServer.Create(app => { app.Run(context => { var accessor = app.ApplicationServices.GetRequiredService(); return context.Response.WriteAsync("HasContext:"+(accessor.HttpContext != null)); }); }); string result = await server.CreateClient().GetStringAsync("/path"); Assert.Equal("HasContext:True", result); } public class ContextHolder { public ContextHolder(IHttpContextAccessor accessor) { Accessor = accessor; } public IHttpContextAccessor Accessor { get; set; } } [Fact] public async Task CanAddNewHostServices() { TestServer server = TestServer.Create(app => { app.Run(context => { var accessor = app.ApplicationServices.GetRequiredService(); return context.Response.WriteAsync("HasContext:" + (accessor.Accessor.HttpContext != null)); }); }, services => services.AddSingleton()); string result = await server.CreateClient().GetStringAsync("/path"); Assert.Equal("HasContext:True", result); } [Fact] public async Task CreateInvokesApp() { TestServer server = TestServer.Create(app => { app.Run(context => { return context.Response.WriteAsync("CreateInvokesApp"); }); }); string result = await server.CreateClient().GetStringAsync("/path"); Assert.Equal("CreateInvokesApp", result); } [Fact] public void WebRootCanBeResolvedWhenNotInTheProjectJson() { TestServer server = TestServer.Create(app => { var env = app.ApplicationServices.GetRequiredService(); Assert.Equal(Directory.GetCurrentDirectory(), env.WebRootPath); }); } [Fact] public async Task DisposeStreamIgnored() { TestServer server = TestServer.Create(app => { app.Run(async context => { await context.Response.WriteAsync("Response"); context.Response.Body.Dispose(); }); }); HttpResponseMessage result = await server.CreateClient().GetAsync("/"); Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal("Response", await result.Content.ReadAsStringAsync()); } [Fact] public async Task DisposedServerThrows() { TestServer server = TestServer.Create(app => { app.Run(async context => { await context.Response.WriteAsync("Response"); context.Response.Body.Dispose(); }); }); HttpResponseMessage result = await server.CreateClient().GetAsync("/"); Assert.Equal(HttpStatusCode.OK, result.StatusCode); server.Dispose(); await Assert.ThrowsAsync(() => server.CreateClient().GetAsync("/")); } [Fact] public void CancelAborts() { TestServer server = TestServer.Create(app => { app.Run(context => { TaskCompletionSource tcs = new TaskCompletionSource(); tcs.SetCanceled(); return tcs.Task; }); }); Assert.Throws(() => { string result = server.CreateClient().GetStringAsync("/path").Result; }); } [Fact] public async Task CanCreateViaStartupType() { TestServer server = new TestServer(TestServer.CreateBuilder().UseStartup()); HttpResponseMessage result = await server.CreateClient().GetAsync("/"); Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal("FoundService:True", await result.Content.ReadAsStringAsync()); } [Fact] public async Task CanCreateViaStartupTypeAndSpecifyEnv() { TestServer server = new TestServer(TestServer.CreateBuilder() .UseStartup() .UseEnvironment("Foo")); HttpResponseMessage result = await server.CreateClient().GetAsync("/"); Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal("FoundFoo:False", await result.Content.ReadAsStringAsync()); } public class Startup { public void Configure(IApplicationBuilder builder) { builder.Run(ctx => ctx.Response.WriteAsync("Startup")); } } public class SimpleService { public SimpleService() { } public string Message { get; set; } } public class TestStartup { public void ConfigureServices(IServiceCollection services) { services.AddSingleton(); } public void ConfigureFooServices(IServiceCollection services) { } public void Configure(IApplicationBuilder app) { app.Run(context => { var service = app.ApplicationServices.GetRequiredService(); return context.Response.WriteAsync("FoundService:" + (service != null)); }); } public void ConfigureFoo(IApplicationBuilder app) { app.Run(context => { var service = app.ApplicationServices.GetService(); return context.Response.WriteAsync("FoundFoo:" + (service != null)); }); } } } }