// Copyright (c) Microsoft Open Technologies, Inc. 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.Diagnostics; using System.IO; using System.Net; using System.Net.Http; using System.Runtime.Versioning; using System.Threading.Tasks; using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Hosting.Startup; using Microsoft.AspNet.Http; using Microsoft.Framework.ConfigurationModel; using Microsoft.Framework.DependencyInjection; using Microsoft.Framework.Logging; using Microsoft.Framework.Runtime; using Microsoft.Framework.Runtime.Infrastructure; 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 Configuration(), 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); } [Fact] public async Task CanChangeApplicationName() { var fallbackServices = CallContextServiceLocator.Locator.ServiceProvider; var appName = "gobblegobble"; var builder = TestServer.CreateBuilder(fallbackServices, new Configuration(), app => { app.Run(context => { var appEnv = app.ApplicationServices.GetRequiredService(); return context.Response.WriteAsync("AppName:" + appEnv.ApplicationName); }); }, configureServices: null); builder.ApplicationName = appName; var server = builder.Build(); string result = await server.CreateClient().GetStringAsync("/path"); Assert.Equal("AppName:" + appName, result); } [Fact] public async Task CanChangeAppPath() { var fallbackServices = CallContextServiceLocator.Locator.ServiceProvider; var appPath = "."; var builder = TestServer.CreateBuilder(fallbackServices, new Configuration(), app => { app.Run(context => { var env = app.ApplicationServices.GetRequiredService(); return context.Response.WriteAsync("AppPath:" + env.ApplicationBasePath); }); }, configureServices: null); builder.ApplicationBasePath = appPath; var server = builder.Build(); string result = await server.CreateClient().GetStringAsync("/path"); Assert.Equal("AppPath:" + appPath, result); } [Fact] public async Task CanAccessLogger() { TestServer 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 = TestServer.Create(); 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() { var builder = TestServer.CreateBuilder(); builder.Environment = "Foo"; var server = builder.Build(); 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)); }); } } } }