brought in flurl and stated adding tests for the requester

This commit is contained in:
TomPallister 2016-09-13 20:29:00 +01:00
parent 8423199754
commit 0627e9399b
11 changed files with 163 additions and 38 deletions

View File

@ -1,21 +1,17 @@
using System.Net.Http; using System.IO;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Flurl.Http;
namespace Ocelot.Library.Infrastructure.Requester namespace Ocelot.Library.Infrastructure.Requester
{ {
public class HttpClientHttpRequester : IHttpRequester public class HttpClientHttpRequester : IHttpRequester
{ {
public async Task<HttpResponseMessage> GetResponse(string httpMethod, string downstreamUrl) public async Task<HttpResponseMessage> GetResponse(string httpMethod, string downstreamUrl, Stream content = null)
{ {
var method = new HttpMethod(httpMethod); var method = new HttpMethod(httpMethod);
var httpRequestMessage = new HttpRequestMessage(method, downstreamUrl); return await downstreamUrl.SendAsync(method, new StreamContent(content));
using (var httpClient = new HttpClient())
{
var response = await httpClient.SendAsync(httpRequestMessage);
return response;
}
} }
} }
} }

View File

@ -1,4 +1,5 @@
using System.Net.Http; using System.IO;
using System.Net.Http;
using System.Threading.Tasks; using System.Threading.Tasks;
using Flurl.Http; using Flurl.Http;
@ -6,6 +7,6 @@ namespace Ocelot.Library.Infrastructure.Requester
{ {
public interface IHttpRequester public interface IHttpRequester
{ {
Task<HttpResponseMessage> GetResponse(string httpMethod, string downstreamUrl); Task<HttpResponseMessage> GetResponse(string httpMethod, string downstreamUrl, Stream content = null);
} }
} }

View File

@ -7,7 +7,7 @@ namespace Ocelot.Library.Infrastructure.Responder
{ {
public class HttpContextResponder : IHttpResponder public class HttpContextResponder : IHttpResponder
{ {
public async Task<HttpContext> CreateSuccessResponse(HttpContext context, HttpResponseMessage response) public async Task<HttpContext> CreateResponse(HttpContext context, HttpResponseMessage response)
{ {
if (response.IsSuccessStatusCode) if (response.IsSuccessStatusCode)
{ {

View File

@ -6,7 +6,7 @@ namespace Ocelot.Library.Infrastructure.Responder
{ {
public interface IHttpResponder public interface IHttpResponder
{ {
Task<HttpContext> CreateSuccessResponse(HttpContext context, HttpResponseMessage response); Task<HttpContext> CreateResponse(HttpContext context, HttpResponseMessage response);
Task<HttpContext> CreateNotFoundResponse(HttpContext context); Task<HttpContext> CreateNotFoundResponse(HttpContext context);
} }

View File

@ -47,9 +47,9 @@ namespace Ocelot.Library.Middleware
var downstreamUrl = _urlReplacer.ReplaceTemplateVariables(downstreamRoute.Data); var downstreamUrl = _urlReplacer.ReplaceTemplateVariables(downstreamRoute.Data);
var response = await _requester.GetResponse(context.Request.Method, downstreamUrl); var response = await _requester.GetResponse(context.Request.Method, downstreamUrl, context.Request.Body);
context = await _responder.CreateSuccessResponse(context, response); await _responder.CreateResponse(context, response);
await _next.Invoke(context); await _next.Invoke(context);
} }

View File

@ -5,11 +5,11 @@ using Shouldly;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
namespace Ocelot.UnitTests namespace Ocelot.UnitTests.Configuration
{ {
public class ConfigurationValidationTests public class ConfigurationValidationTests
{ {
private Configuration _configuration; private Library.Infrastructure.Configuration.Configuration _configuration;
private readonly IConfigurationValidator _configurationValidator; private readonly IConfigurationValidator _configurationValidator;
private Response<ConfigurationValidationResult> _result; private Response<ConfigurationValidationResult> _result;
@ -21,7 +21,7 @@ namespace Ocelot.UnitTests
[Fact] [Fact]
public void configuration_is_valid_with_one_reroute() public void configuration_is_valid_with_one_reroute()
{ {
this.Given(x => x.GivenAConfiguration(new Configuration() this.Given(x => x.GivenAConfiguration(new Library.Infrastructure.Configuration.Configuration()
{ {
ReRoutes = new List<ReRoute> ReRoutes = new List<ReRoute>
{ {
@ -40,7 +40,7 @@ namespace Ocelot.UnitTests
[Fact] [Fact]
public void configuration_is_not_valid_with_duplicate_reroutes() public void configuration_is_not_valid_with_duplicate_reroutes()
{ {
this.Given(x => x.GivenAConfiguration(new Configuration() this.Given(x => x.GivenAConfiguration(new Library.Infrastructure.Configuration.Configuration()
{ {
ReRoutes = new List<ReRoute> ReRoutes = new List<ReRoute>
{ {
@ -62,7 +62,7 @@ namespace Ocelot.UnitTests
.BDDfy(); .BDDfy();
} }
private void GivenAConfiguration(Configuration configuration) private void GivenAConfiguration(Library.Infrastructure.Configuration.Configuration configuration)
{ {
_configuration = configuration; _configuration = configuration;
} }

View File

@ -1,7 +1,4 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Moq; using Moq;
using Ocelot.Library.Infrastructure.Configuration; using Ocelot.Library.Infrastructure.Configuration;
@ -12,31 +9,31 @@ using Shouldly;
using TestStack.BDDfy; using TestStack.BDDfy;
using Xunit; using Xunit;
namespace Ocelot.UnitTests namespace Ocelot.UnitTests.DownstreamRouteFinder
{ {
public class DownstreamRouteFinderTests public class DownstreamRouteFinderTests
{ {
private readonly IDownstreamRouteFinder _downstreamRouteFinder; private readonly IDownstreamRouteFinder _downstreamRouteFinder;
private readonly Mock<IOptions<Configuration>> _mockConfig; private readonly Mock<IOptions<Library.Infrastructure.Configuration.Configuration>> _mockConfig;
private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher; private readonly Mock<IUrlPathToUrlTemplateMatcher> _mockMatcher;
private string _upstreamUrlPath; private string _upstreamUrlPath;
private Response<DownstreamRoute> _result; private Response<DownstreamRoute> _result;
private Response<DownstreamRoute> _response; private Response<DownstreamRoute> _response;
private Configuration _configuration; private Library.Infrastructure.Configuration.Configuration _configuration;
private UrlMatch _match; private UrlMatch _match;
public DownstreamRouteFinderTests() public DownstreamRouteFinderTests()
{ {
_mockConfig = new Mock<IOptions<Configuration>>(); _mockConfig = new Mock<IOptions<Library.Infrastructure.Configuration.Configuration>>();
_mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>(); _mockMatcher = new Mock<IUrlPathToUrlTemplateMatcher>();
_downstreamRouteFinder = new DownstreamRouteFinder(_mockConfig.Object, _mockMatcher.Object); _downstreamRouteFinder = new Library.Infrastructure.DownstreamRouteFinder.DownstreamRouteFinder(_mockConfig.Object, _mockMatcher.Object);
} }
[Fact] [Fact]
public void should_return_route() public void should_return_route()
{ {
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath")) this.Given(x => x.GivenThereIsAnUpstreamUrlPath("someUpstreamPath"))
.And(x => x.GivenTheConfigurationIs(new Configuration { .And(x => x.GivenTheConfigurationIs(new Library.Infrastructure.Configuration.Configuration {
ReRoutes = new List<ReRoute> ReRoutes = new List<ReRoute>
{ {
new ReRoute() new ReRoute()
@ -58,7 +55,7 @@ namespace Ocelot.UnitTests
public void should_not_return_route() public void should_not_return_route()
{ {
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("somePath")) this.Given(x => x.GivenThereIsAnUpstreamUrlPath("somePath"))
.And(x => x.GivenTheConfigurationIs(new Configuration .And(x => x.GivenTheConfigurationIs(new Library.Infrastructure.Configuration.Configuration
{ {
ReRoutes = new List<ReRoute> ReRoutes = new List<ReRoute>
{ {
@ -96,7 +93,7 @@ namespace Ocelot.UnitTests
.Returns(_match); .Returns(_match);
} }
private void GivenTheConfigurationIs(Configuration configuration) private void GivenTheConfigurationIs(Library.Infrastructure.Configuration.Configuration configuration)
{ {
_configuration = configuration; _configuration = configuration;
_mockConfig _mockConfig

View File

@ -0,0 +1,119 @@
using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Flurl.Http.Testing;
using Ocelot.Library.Infrastructure.Requester;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Requester
{
public class RequesterTests : IDisposable
{
private readonly IHttpRequester _httpRequester;
private readonly HttpTest _httpTest;
private string _httpMethod;
private string _downstreamUrl;
private HttpResponseMessage _result;
private HttpContent _content;
public RequesterTests()
{
_httpTest = new HttpTest();
_httpRequester = new HttpClientHttpRequester();
}
[Fact]
public void should_call_downstream_url_correctly()
{
this.Given(x => x.GivenIHaveHttpMethod("GET"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenTheDownstreamServerReturns(HttpStatusCode.OK))
.When(x => x.WhenIMakeARequest())
.Then(x => x.ThenTheFollowingIsReturned(HttpStatusCode.OK))
.And(x => x.ThenTheDownstreamServerIsCalledCorrectly())
.BDDfy();
}
[Fact]
public void should_obey_http_method()
{
this.Given(x => x.GivenIHaveHttpMethod("POST"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenTheDownstreamServerReturns(HttpStatusCode.Created))
.When(x => x.WhenIMakeARequest())
.Then(x => x.ThenTheFollowingIsReturned(HttpStatusCode.Created))
.And(x => x.ThenTheDownstreamServerIsCalledCorrectly())
.And(x => x.ThenTheCorrectHttpMethodIsUsed(HttpMethod.Post))
.BDDfy();
}
[Fact]
public void should_forward_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.GivenTheDownstreamServerReturns(HttpStatusCode.Created))
.When(x => x.WhenIMakeARequest())
.Then(x => x.ThenTheFollowingIsReturned(HttpStatusCode.Created))
.And(x => x.ThenTheDownstreamServerIsCalledCorrectly())
.And(x => x.ThenTheCorrectHttpMethodIsUsed(HttpMethod.Post))
.And(x => x.ThenTheCorrectContentIsUsed(new StringContent("Hi from Tom")))
.BDDfy();
}
private void GivenIHaveTheHttpContent(HttpContent content)
{
_content = content;
}
private void GivenIHaveHttpMethod(string httpMethod)
{
_httpMethod = httpMethod;
}
private void GivenIHaveDownstreamUrl(string downstreamUrl)
{
_downstreamUrl = downstreamUrl;
}
private void GivenTheDownstreamServerReturns(HttpStatusCode statusCode)
{
_httpTest.RespondWith(_content != null ? _content.ReadAsStringAsync().Result : string.Empty, (int)statusCode);
}
private void WhenIMakeARequest()
{
_result = _httpRequester.GetResponse(_httpMethod, _downstreamUrl, _content != null ? _content.ReadAsStreamAsync().Result : Stream.Null).Result;
}
private void ThenTheFollowingIsReturned(HttpStatusCode expected)
{
_result.StatusCode.ShouldBe(expected);
}
private void ThenTheDownstreamServerIsCalledCorrectly()
{
_httpTest.ShouldHaveCalled(_downstreamUrl);
}
private void ThenTheCorrectHttpMethodIsUsed(HttpMethod expected)
{
_httpTest.CallLog[0].Request.Method.ShouldBe(expected);
}
private void ThenTheCorrectContentIsUsed(HttpContent content)
{
_httpTest.CallLog[0].Response.Content.ReadAsStringAsync().Result.ShouldBe(content.ReadAsStringAsync().Result);
}
public void Dispose()
{
_httpTest.Dispose();
}
}
}

View File

@ -0,0 +1,14 @@
using Microsoft.AspNetCore.Http;
using Xunit;
namespace Ocelot.UnitTests.Responder
{
public class ResponderTests
{
[Fact]
public void should_do_something()
{
}
}
}

View File

@ -2,12 +2,11 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Ocelot.Library.Infrastructure.UrlMatcher; using Ocelot.Library.Infrastructure.UrlMatcher;
using Shouldly; using Shouldly;
using TestStack.BDDfy;
using Xunit; using Xunit;
namespace Ocelot.UnitTests namespace Ocelot.UnitTests.UrlMatcher
{ {
using TestStack.BDDfy;
public class UrlPathToUrlTemplateMatcherTests public class UrlPathToUrlTemplateMatcherTests
{ {
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher; private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;

View File

@ -3,12 +3,11 @@ using Ocelot.Library.Infrastructure.DownstreamRouteFinder;
using Ocelot.Library.Infrastructure.UrlMatcher; using Ocelot.Library.Infrastructure.UrlMatcher;
using Ocelot.Library.Infrastructure.UrlTemplateReplacer; using Ocelot.Library.Infrastructure.UrlTemplateReplacer;
using Shouldly; using Shouldly;
using TestStack.BDDfy;
using Xunit; using Xunit;
namespace Ocelot.UnitTests namespace Ocelot.UnitTests.UrlTemplateReplacer
{ {
using TestStack.BDDfy;
public class UpstreamUrlPathTemplateVariableReplacerTests public class UpstreamUrlPathTemplateVariableReplacerTests
{ {
private DownstreamRoute _downstreamRoute; private DownstreamRoute _downstreamRoute;