implemented adding claims as query strings to downstream route, removed some of the middleware injection optiosn as i have currently have no use case for them, general refactoring to use the OcelotMiddleware a bit more

This commit is contained in:
TomPallister
2016-10-29 19:45:50 +01:00
parent 3a1dd1f9bc
commit f7f4a392f0
46 changed files with 851 additions and 289 deletions

View File

@ -0,0 +1,100 @@
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection;
using Moq;
using Ocelot.Infrastructure.RequestData;
using Ocelot.Request.Builder;
using Ocelot.Request.Middleware;
using Ocelot.Responses;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Request
{
public class HttpRequestBuilderMiddlewareTests : IDisposable
{
private readonly Mock<IRequestBuilder> _requestBuilder;
private readonly Mock<IRequestScopedDataRepository> _scopedRepository;
private readonly string _url;
private readonly TestServer _server;
private readonly HttpClient _client;
private HttpResponseMessage _result;
private OkResponse<Ocelot.Request.Request> _request;
private OkResponse<string> _downstreamUrl;
public HttpRequestBuilderMiddlewareTests()
{
_url = "http://localhost:51879";
_requestBuilder = new Mock<IRequestBuilder>();
_scopedRepository = new Mock<IRequestScopedDataRepository>();
var builder = new WebHostBuilder()
.ConfigureServices(x =>
{
x.AddSingleton(_requestBuilder.Object);
x.AddSingleton(_scopedRepository.Object);
})
.UseUrls(_url)
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseUrls(_url)
.Configure(app =>
{
app.UseHttpRequestBuilderMiddleware();
});
_server = new TestServer(builder);
_client = _server.CreateClient();
}
[Fact]
public void happy_path()
{
this.Given(x => x.GivenTheDownStreamUrlIs("any old string"))
.And(x => x.GivenTheRequestBuilderReturns(new Ocelot.Request.Request(new HttpRequestMessage(), new CookieContainer())))
.When(x => x.WhenICallTheMiddleware())
.Then(x => x.ThenTheScopedDataRepositoryIsCalledCorrectly())
.BDDfy();
}
private void GivenTheRequestBuilderReturns(Ocelot.Request.Request request)
{
_request = new OkResponse<Ocelot.Request.Request>(request);
_requestBuilder
.Setup(x => x.Build(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Stream>(), It.IsAny<IHeaderDictionary>(),
It.IsAny<IRequestCookieCollection>(), It.IsAny<QueryString>(), It.IsAny<string>()))
.ReturnsAsync(_request);
}
private void ThenTheScopedDataRepositoryIsCalledCorrectly()
{
_scopedRepository
.Verify(x => x.Add("Request", _request.Data), Times.Once());
}
private void WhenICallTheMiddleware()
{
_result = _client.GetAsync(_url).Result;
}
private void GivenTheDownStreamUrlIs(string downstreamUrl)
{
_downstreamUrl = new OkResponse<string>(downstreamUrl);
_scopedRepository
.Setup(x => x.Get<string>(It.IsAny<string>()))
.Returns(_downstreamUrl);
}
public void Dispose()
{
_client.Dispose();
_server.Dispose();
}
}
}

View File

@ -0,0 +1,241 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Ocelot.Request.Builder;
using Ocelot.Responses;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Request
{
public class RequestBuilderTests
{
private string _httpMethod;
private string _downstreamUrl;
private HttpContent _content;
private IHeaderDictionary _headers;
private IRequestCookieCollection _cookies;
private QueryString _query;
private string _contentType;
private readonly IRequestBuilder _requestBuilder;
private Response<Ocelot.Request.Request> _result;
public RequestBuilderTests()
{
_content = new StringContent(string.Empty);
_requestBuilder = new HttpRequestBuilder();
}
[Fact]
public void should_user_downstream_url()
{
this.Given(x => x.GivenIHaveHttpMethod("GET"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectDownstreamUrlIsUsed("http://www.bbc.co.uk/"))
.BDDfy();
}
[Fact]
public void should_use_http_method()
{
this.Given(x => x.GivenIHaveHttpMethod("POST"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectHttpMethodIsUsed(HttpMethod.Post))
.BDDfy();
}
[Fact]
public void should_use_http_content()
{
this.Given(x => x.GivenIHaveHttpMethod("POST"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
.And(x => x.GivenTheContentTypeIs("application/json"))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom")))
.BDDfy();
}
[Fact]
public void should_use_http_content_headers()
{
this.Given(x => x.GivenIHaveHttpMethod("POST"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
.And(x => x.GivenTheContentTypeIs("application/json"))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary
{
{
"Content-Type", "application/json"
}
}))
.BDDfy();
}
[Fact]
public void should_use_unvalidated_http_content_headers()
{
this.Given(x => x.GivenIHaveHttpMethod("POST"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenIHaveTheHttpContent(new StringContent("Hi from Tom")))
.And(x => x.GivenTheContentTypeIs("application/json; charset=utf-8"))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectContentHeadersAreUsed(new HeaderDictionary
{
{
"Content-Type", "application/json; charset=utf-8"
}
}))
.BDDfy();
}
[Fact]
public void should_use_headers()
{
this.Given(x => x.GivenIHaveHttpMethod("GET"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenTheHttpHeadersAre(new HeaderDictionary
{
{"ChopSticks", "Bubbles" }
}))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectHeadersAreUsed(new HeaderDictionary
{
{"ChopSticks", "Bubbles" }
}))
.BDDfy();
}
[Fact]
public void should_use_cookies()
{
this.Given(x => x.GivenIHaveHttpMethod("GET"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenTheCookiesAre(new RequestCookieCollection(new Dictionary<string, string>
{
{ "TheCookie","Monster" }
})))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectCookiesAreUsed(new RequestCookieCollection(new Dictionary<string, string>
{
{ "TheCookie","Monster" }
})))
.BDDfy();
}
[Fact]
public void should_user_query_string()
{
this.Given(x => x.GivenIHaveHttpMethod("POST"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenTheQueryStringIs(new QueryString("?jeff=1&geoff=2")))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectQueryStringIsUsed("?jeff=1&geoff=2"))
.BDDfy();
}
private void GivenTheContentTypeIs(string contentType)
{
_contentType = contentType;
}
private void ThenTheCorrectQueryStringIsUsed(string expected)
{
_result.Data.HttpRequestMessage.RequestUri.Query.ShouldBe(expected);
}
private void GivenTheQueryStringIs(QueryString query)
{
_query = query;
}
private void ThenTheCorrectCookiesAreUsed(IRequestCookieCollection expected)
{
var resultCookies = _result.Data.CookieContainer.GetCookies(new Uri(_downstreamUrl + _query));
var resultDictionary = resultCookies.Cast<Cookie>().ToDictionary(cook => cook.Name, cook => cook.Value);
foreach (var expectedCookie in expected)
{
var resultCookie = resultDictionary[expectedCookie.Key];
resultCookie.ShouldBe(expectedCookie.Value);
}
}
private void GivenTheCookiesAre(IRequestCookieCollection cookies)
{
_cookies = cookies;
}
private void ThenTheCorrectHeadersAreUsed(IHeaderDictionary expected)
{
var expectedHeaders = expected.Select(x => new KeyValuePair<string, string[]>(x.Key, x.Value));
foreach (var expectedHeader in expectedHeaders)
{
_result.Data.HttpRequestMessage.Headers.ShouldContain(x => x.Key == expectedHeader.Key && x.Value.First() == expectedHeader.Value[0]);
}
}
private void ThenTheCorrectContentHeadersAreUsed(IHeaderDictionary expected)
{
var expectedHeaders = expected.Select(x => new KeyValuePair<string, string[]>(x.Key, x.Value));
foreach (var expectedHeader in expectedHeaders)
{
_result.Data.HttpRequestMessage.Content.Headers.ShouldContain(x => x.Key == expectedHeader.Key
&& x.Value.First() == expectedHeader.Value[0]
);
}
}
private void GivenTheHttpHeadersAre(IHeaderDictionary headers)
{
_headers = headers;
}
private void GivenIHaveTheHttpContent(HttpContent content)
{
_content = content;
}
private void GivenIHaveHttpMethod(string httpMethod)
{
_httpMethod = httpMethod;
}
private void GivenIHaveDownstreamUrl(string downstreamUrl)
{
_downstreamUrl = downstreamUrl;
}
private void WhenICreateARequest()
{
_result = _requestBuilder.Build(_httpMethod, _downstreamUrl, _content?.ReadAsStreamAsync().Result, _headers,
_cookies, _query, _contentType).Result;
}
private void ThenTheCorrectDownstreamUrlIsUsed(string expected)
{
_result.Data.HttpRequestMessage.RequestUri.AbsoluteUri.ShouldBe(expected);
}
private void ThenTheCorrectHttpMethodIsUsed(HttpMethod expected)
{
_result.Data.HttpRequestMessage.Method.Method.ShouldBe(expected.Method);
}
private void ThenTheCorrectContentIsUsed(HttpContent expected)
{
_result.Data.HttpRequestMessage.Content.ReadAsStringAsync().Result.ShouldBe(expected.ReadAsStringAsync().Result);
}
}
}