Removing TestClient from TestServer
This commit is contained in:
parent
630abe6a5d
commit
904eeb76f9
|
|
@ -1,209 +0,0 @@
|
||||||
// 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.Collections.Generic;
|
|
||||||
using System.Globalization;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNet.Http;
|
|
||||||
using Microsoft.AspNet.FeatureModel;
|
|
||||||
using Microsoft.AspNet.HttpFeature;
|
|
||||||
using Microsoft.AspNet.PipelineCore;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.TestHost
|
|
||||||
{
|
|
||||||
public class TestClient
|
|
||||||
{
|
|
||||||
private readonly Func<object, Task> _pipeline;
|
|
||||||
|
|
||||||
public TestClient(Func<object, Task> pipeline)
|
|
||||||
{
|
|
||||||
_pipeline = pipeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> SendAsync(string method,
|
|
||||||
string url,
|
|
||||||
IDictionary<string, string[]> headers = null,
|
|
||||||
Stream body = null,
|
|
||||||
Action<HttpRequest> onSendingRequest = null)
|
|
||||||
{
|
|
||||||
return await SendAsync(method, new Uri(url), headers, body, onSendingRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> SendAsync(string method,
|
|
||||||
Uri uri,
|
|
||||||
IDictionary<string, string[]> headers = null,
|
|
||||||
Stream body = null,
|
|
||||||
Action<HttpRequest> onSendingRequest = null)
|
|
||||||
{
|
|
||||||
var request = CreateRequest(method, uri, headers, body);
|
|
||||||
var response = new ResponseFeature();
|
|
||||||
|
|
||||||
var features = new FeatureCollection();
|
|
||||||
features.Add(typeof(IHttpRequestFeature), request);
|
|
||||||
features.Add(typeof(IHttpResponseFeature), response);
|
|
||||||
var httpContext = new DefaultHttpContext(features);
|
|
||||||
|
|
||||||
if (onSendingRequest != null)
|
|
||||||
{
|
|
||||||
onSendingRequest(httpContext.Request);
|
|
||||||
}
|
|
||||||
await _pipeline(features);
|
|
||||||
|
|
||||||
response.Body.Seek(0, SeekOrigin.Begin);
|
|
||||||
return httpContext.Response;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static IHttpRequestFeature CreateRequest(
|
|
||||||
string method,
|
|
||||||
Uri uri,
|
|
||||||
IDictionary<string, string[]> headers,
|
|
||||||
Stream body)
|
|
||||||
{
|
|
||||||
var request = new RequestFeature();
|
|
||||||
request.Method = method;
|
|
||||||
request.Scheme = uri.Scheme;
|
|
||||||
request.Path = PathString.FromUriComponent(uri).Value;
|
|
||||||
request.QueryString = QueryString.FromUriComponent(uri).Value;
|
|
||||||
request.Headers = headers ?? request.Headers;
|
|
||||||
if (!request.Headers.ContainsKey("Host"))
|
|
||||||
{
|
|
||||||
var host = new string[1];
|
|
||||||
if (uri.IsDefaultPort)
|
|
||||||
{
|
|
||||||
host[0] = uri.Host;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
host[0] = uri.GetComponents(UriComponents.HostAndPort, UriFormat.UriEscaped);
|
|
||||||
}
|
|
||||||
request.Headers["Host"] = host;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (body != null)
|
|
||||||
{
|
|
||||||
EnsureContentLength(request.Headers, body);
|
|
||||||
request.Body = body;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
request.Body = Stream.Null;
|
|
||||||
}
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> GetAsync(string url)
|
|
||||||
{
|
|
||||||
var uri = new Uri(url);
|
|
||||||
return await GetAsync(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> GetAsync(Uri uri)
|
|
||||||
{
|
|
||||||
return await SendAsync("GET", uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetStringAsync(string url)
|
|
||||||
{
|
|
||||||
var uri = new Uri(url);
|
|
||||||
return await GetStringAsync(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<string> GetStringAsync(Uri uri)
|
|
||||||
{
|
|
||||||
var response = await GetAsync(uri);
|
|
||||||
return await new StreamReader(response.Body).ReadToEndAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Stream> GetStreamAsync(string url)
|
|
||||||
{
|
|
||||||
var uri = new Uri(url);
|
|
||||||
return await GetStreamAsync(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<Stream> GetStreamAsync(Uri uri)
|
|
||||||
{
|
|
||||||
var response = await GetAsync(uri);
|
|
||||||
return response.Body;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> PostAsync(
|
|
||||||
string url,
|
|
||||||
string content,
|
|
||||||
string contentType,
|
|
||||||
Action<HttpRequest> onSendingRequest = null)
|
|
||||||
{
|
|
||||||
return await PostAsync(new Uri(url), content, contentType, onSendingRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> PostAsync(
|
|
||||||
Uri url,
|
|
||||||
string content,
|
|
||||||
string contentType,
|
|
||||||
Action<HttpRequest> onSendingRequest = null)
|
|
||||||
{
|
|
||||||
var bytes = GetBytes(content);
|
|
||||||
var headers = CreateContentHeaders(contentType, bytes.Length);
|
|
||||||
var body = new MemoryStream(bytes);
|
|
||||||
|
|
||||||
return await SendAsync("POST", url, headers, body, onSendingRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> PutAsync(
|
|
||||||
string url,
|
|
||||||
string content,
|
|
||||||
string contentType,
|
|
||||||
Action<HttpRequest> onSendingRequest = null)
|
|
||||||
{
|
|
||||||
return await PutAsync(new Uri(url), content, contentType, onSendingRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> PutAsync(
|
|
||||||
Uri url,
|
|
||||||
string content,
|
|
||||||
string contentType,
|
|
||||||
Action<HttpRequest> onSendingRequest = null)
|
|
||||||
{
|
|
||||||
var bytes = GetBytes(content);
|
|
||||||
var headers = CreateContentHeaders(contentType, bytes.Length);
|
|
||||||
var body = new MemoryStream(bytes);
|
|
||||||
|
|
||||||
return await SendAsync("PUT", url, headers, body, onSendingRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> DeleteAsync(string url)
|
|
||||||
{
|
|
||||||
return await DeleteAsync(new Uri(url));
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<HttpResponse> DeleteAsync(Uri uri)
|
|
||||||
{
|
|
||||||
return await SendAsync("DELETE", uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void EnsureContentLength(IDictionary<string, string[]> dictionary, Stream body)
|
|
||||||
{
|
|
||||||
if (!dictionary.ContainsKey("Content-Length"))
|
|
||||||
{
|
|
||||||
dictionary["Content-Length"] = new[] { body.Length.ToString(CultureInfo.InvariantCulture) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static byte[] GetBytes(string content)
|
|
||||||
{
|
|
||||||
var bytes = Encoding.UTF8.GetBytes(content);
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Dictionary<string, string[]> CreateContentHeaders(string contentType, int contentLength)
|
|
||||||
{
|
|
||||||
return new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
{ "Content-Type", new [] { contentType } },
|
|
||||||
{ "Content-Length", new [] { contentLength.ToString(CultureInfo.InvariantCulture) } }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -20,7 +20,6 @@ namespace Microsoft.AspNet.TestHost
|
||||||
private static readonly string ServerName = typeof(TestServer).FullName;
|
private static readonly string ServerName = typeof(TestServer).FullName;
|
||||||
private static readonly ServerInformation ServerInfo = new ServerInformation();
|
private static readonly ServerInformation ServerInfo = new ServerInformation();
|
||||||
private Func<object, Task> _appDelegate;
|
private Func<object, Task> _appDelegate;
|
||||||
private TestClient _handler;
|
|
||||||
private IDisposable _appInstance;
|
private IDisposable _appInstance;
|
||||||
private bool _disposed = false;
|
private bool _disposed = false;
|
||||||
|
|
||||||
|
|
@ -45,19 +44,6 @@ namespace Microsoft.AspNet.TestHost
|
||||||
_appInstance = engine.Start(hostContext);
|
_appInstance = engine.Start(hostContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TestClient Handler
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_handler == null)
|
|
||||||
{
|
|
||||||
_handler = new TestClient(Invoke);
|
|
||||||
}
|
|
||||||
|
|
||||||
return _handler;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TestServer Create(Action<IBuilder> app)
|
public static TestServer Create(Action<IBuilder> app)
|
||||||
{
|
{
|
||||||
return Create(provider: CallContextServiceLocator.Locator.ServiceProvider, app: app);
|
return Create(provider: CallContextServiceLocator.Locator.ServiceProvider, app: app);
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNet.Builder;
|
using Microsoft.AspNet.Builder;
|
||||||
using Microsoft.AspNet.Http;
|
using Microsoft.AspNet.Http;
|
||||||
|
|
@ -25,114 +25,41 @@ namespace Microsoft.AspNet.TestHost
|
||||||
.AddSingleton<IApplicationEnvironment, TestApplicationEnvironment>()
|
.AddSingleton<IApplicationEnvironment, TestApplicationEnvironment>()
|
||||||
.BuildServiceProvider();
|
.BuildServiceProvider();
|
||||||
|
|
||||||
_server = TestServer.Create(_services, app => app.Run(async ctx => { }));
|
_server = TestServer.Create(_services, app => app.Run(ctx => Task.FromResult(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task SendAsync_ConfiguresRequestProperly()
|
public async Task GetAsyncWorks()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
var client = _server.Handler;
|
var expected = "GET Response";
|
||||||
|
RequestDelegate appDelegate = ctx =>
|
||||||
|
ctx.Response.WriteAsync(expected);
|
||||||
|
var server = TestServer.Create(_services, app => app.Run(appDelegate));
|
||||||
|
var client = server.CreateClient();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await client.SendAsync("GET", "http://localhost:12345/Home/Index?id=3&name=peter#fragment");
|
var actual = await client.GetStringAsync("http://localhost:12345");
|
||||||
var request = response.HttpContext.Request;
|
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.NotNull(request);
|
Assert.Equal(expected, actual);
|
||||||
Assert.Equal("HTTP/1.1", request.Protocol);
|
|
||||||
Assert.Equal("GET", request.Method);
|
|
||||||
Assert.Equal("http", request.Scheme);
|
|
||||||
Assert.Equal("localhost:12345", request.Host.Value);
|
|
||||||
Assert.Equal("", request.PathBase.Value);
|
|
||||||
Assert.True(request.Path.HasValue);
|
|
||||||
Assert.Equal("/Home/Index", request.Path.Value);
|
|
||||||
Assert.Equal("?id=3&name=peter", request.QueryString.Value);
|
|
||||||
Assert.Null(request.ContentLength);
|
|
||||||
Assert.Equal(1, request.Headers.Count);
|
|
||||||
Assert.True(request.Headers.ContainsKey("Host"));
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SendAsync_InvokesCallbackWhenPassed()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var client = _server.Handler;
|
|
||||||
var invoked = false;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.SendAsync("GET", "http://localhost:12345/", null, null, _ => invoked = true);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.True(invoked);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SendAsync_RespectsExistingHost()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var client = _server.Handler;
|
|
||||||
var headers = new Dictionary<string, string[]> { { "Host", new string[] { "server:12345" } } };
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.SendAsync("GET", "http://localhost:12345/Home/", headers);
|
|
||||||
var request = response.HttpContext.Request;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal("server:12345", request.Host.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SendAsync_RespectsArgumentBody()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var client = _server.Handler;
|
|
||||||
var headers = new Dictionary<string, string[]> { { "Content-Type", new string[] { "text/plain" } } };
|
|
||||||
var body = new MemoryStream();
|
|
||||||
new StreamWriter(body).Write("Hello world");
|
|
||||||
body.Position = 0;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.SendAsync("POST", "http://host/", headers, body);
|
|
||||||
var request = response.HttpContext.Request;
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Same(body, request.Body);
|
|
||||||
Assert.Equal(0, request.Body.Position);
|
|
||||||
Assert.Equal(body.Length, request.ContentLength);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public async Task SendAsync_RewindsTheResponseStream()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
var server = TestServer.Create(_services, app => app.Run(ctx => ctx.Response.WriteAsync("Hello world")));
|
|
||||||
var client = server.Handler;
|
|
||||||
|
|
||||||
// Act
|
|
||||||
var response = await client.SendAsync("GET", "http://localhost");
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
Assert.Equal(0, response.Body.Position);
|
|
||||||
Assert.Equal("Hello world", new StreamReader(response.Body).ReadToEnd());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task PutAsyncWorks()
|
public async Task PutAsyncWorks()
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
RequestDelegate appDelegate = async ctx =>
|
RequestDelegate appDelegate = ctx =>
|
||||||
await ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd());
|
ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd() + " PUT Response");
|
||||||
var server = TestServer.Create(_services, app => app.Run(appDelegate));
|
var server = TestServer.Create(_services, app => app.Run(appDelegate));
|
||||||
var client = server.Handler;
|
var client = server.CreateClient();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await client.PutAsync("http://localhost:12345", "Hello world", "text/plain");
|
var content = new StringContent("Hello world");
|
||||||
var request = response.HttpContext.Request;
|
var response = await client.PutAsync("http://localhost:12345", content);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("PUT", request.Method);
|
Assert.Equal("Hello world PUT Response", await response.Content.ReadAsStringAsync());
|
||||||
Assert.Equal("Hello world", new StreamReader(response.Body).ReadToEnd());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -140,17 +67,16 @@ namespace Microsoft.AspNet.TestHost
|
||||||
{
|
{
|
||||||
// Arrange
|
// Arrange
|
||||||
RequestDelegate appDelegate = async ctx =>
|
RequestDelegate appDelegate = async ctx =>
|
||||||
await ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd());
|
await ctx.Response.WriteAsync(new StreamReader(ctx.Request.Body).ReadToEnd() + " POST Response");
|
||||||
var server = TestServer.Create(_services, app => app.Run(appDelegate));
|
var server = TestServer.Create(_services, app => app.Run(appDelegate));
|
||||||
var client = server.Handler;
|
var client = server.CreateClient();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
var response = await client.PostAsync("http://localhost:12345", "Hello world", "text/plain");
|
var content = new StringContent("Hello world");
|
||||||
var request = response.HttpContext.Request;
|
var response = await client.PostAsync("http://localhost:12345", content);
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
Assert.Equal("POST", request.Method);
|
Assert.Equal("Hello world POST Response", await response.Content.ReadAsStringAsync());
|
||||||
Assert.Equal("Hello world", new StreamReader(response.Body).ReadToEnd());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue