more simplification is that a word

This commit is contained in:
TomPallister 2016-09-07 20:40:56 +01:00
parent 15d7cafa1c
commit 71b7e7743e
18 changed files with 56 additions and 262 deletions

View File

@ -6,9 +6,9 @@ namespace Ocelot.Library.Infrastructure.Configuration
{ {
public Configuration() public Configuration()
{ {
Routes = new List<Route>(); ReRoutes = new List<ReRoute>();
} }
public List<Route> Routes { get; set; } public List<ReRoute> ReRoutes { get; set; }
} }
} }

View File

@ -0,0 +1,8 @@
namespace Ocelot.Library.Infrastructure.Configuration
{
public class ReRoute
{
public string DownstreamTemplate { get; set; }
public string UpstreamTemplate { get; set; }
}
}

View File

@ -1,8 +0,0 @@
namespace Ocelot.Library.Infrastructure.Configuration
{
public class Route
{
public string Downstream { get; set; }
public string Upstream { get; set; }
}
}

View File

@ -2,6 +2,6 @@ namespace Ocelot.Library.Infrastructure.UrlMatcher
{ {
public interface IUrlPathToUrlTemplateMatcher public interface IUrlPathToUrlTemplateMatcher
{ {
UrlMatch Match(string downstreamUrlPath, string downstreamUrlTemplate); UrlMatch Match(string upstreamUrlPath, string upstreamUrlTemplate);
} }
} }

View File

@ -5,31 +5,31 @@ namespace Ocelot.Library.Infrastructure.UrlMatcher
{ {
public class UrlPathToUrlTemplateMatcher : IUrlPathToUrlTemplateMatcher public class UrlPathToUrlTemplateMatcher : IUrlPathToUrlTemplateMatcher
{ {
public UrlMatch Match(string downstreamUrlPath, string downstreamUrlTemplate) public UrlMatch Match(string upstreamUrlPath, string upstreamUrlTemplate)
{ {
var urlPathTemplateCopy = downstreamUrlTemplate; var urlPathTemplateCopy = upstreamUrlTemplate;
var templateKeysAndValues = new List<TemplateVariableNameAndValue>(); var templateKeysAndValues = new List<TemplateVariableNameAndValue>();
int counterForUrl = 0; int counterForUrl = 0;
for (int counterForTemplate = 0; counterForTemplate < downstreamUrlTemplate.Length; counterForTemplate++) for (int counterForTemplate = 0; counterForTemplate < upstreamUrlTemplate.Length; counterForTemplate++)
{ {
if (CharactersDontMatch(downstreamUrlTemplate[counterForTemplate], downstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,downstreamUrlPath.Length)) if (CharactersDontMatch(upstreamUrlTemplate[counterForTemplate], upstreamUrlPath[counterForUrl]) && ContinueScanningUrl(counterForUrl,upstreamUrlPath.Length))
{ {
if (IsPlaceholder(downstreamUrlTemplate[counterForTemplate])) if (IsPlaceholder(upstreamUrlTemplate[counterForTemplate]))
{ {
var variableName = GetPlaceholderVariableName(downstreamUrlTemplate, counterForTemplate); var variableName = GetPlaceholderVariableName(upstreamUrlTemplate, counterForTemplate);
var variableValue = GetPlaceholderVariableValue(downstreamUrlPath, counterForUrl); var variableValue = GetPlaceholderVariableValue(upstreamUrlPath, counterForUrl);
var templateVariableNameAndValue = new TemplateVariableNameAndValue(variableName, variableValue); var templateVariableNameAndValue = new TemplateVariableNameAndValue(variableName, variableValue);
templateKeysAndValues.Add(templateVariableNameAndValue); templateKeysAndValues.Add(templateVariableNameAndValue);
counterForTemplate = GetNextCounterPosition(downstreamUrlTemplate, counterForTemplate, '}'); counterForTemplate = GetNextCounterPosition(upstreamUrlTemplate, counterForTemplate, '}');
counterForUrl = GetNextCounterPosition(downstreamUrlPath, counterForUrl, '/'); counterForUrl = GetNextCounterPosition(upstreamUrlPath, counterForUrl, '/');
continue; continue;
} }

View File

@ -5,11 +5,11 @@ namespace Ocelot.Library.Infrastructure.UrlTemplateReplacer
{ {
public class DownstreamUrlTemplateVariableReplacer : IDownstreamUrlTemplateVariableReplacer public class DownstreamUrlTemplateVariableReplacer : IDownstreamUrlTemplateVariableReplacer
{ {
public string ReplaceTemplateVariable(string downstreamPathTemplate, UrlMatch urlMatch) public string ReplaceTemplateVariable(UrlMatch urlMatch)
{ {
var upstreamUrl = new StringBuilder(); var upstreamUrl = new StringBuilder();
upstreamUrl.Append(downstreamPathTemplate); upstreamUrl.Append(urlMatch.DownstreamUrlTemplate);
foreach (var templateVarAndValue in urlMatch.TemplateVariableNameAndValues) foreach (var templateVarAndValue in urlMatch.TemplateVariableNameAndValues)
{ {

View File

@ -4,6 +4,6 @@ namespace Ocelot.Library.Infrastructure.UrlTemplateReplacer
{ {
public interface IDownstreamUrlTemplateVariableReplacer public interface IDownstreamUrlTemplateVariableReplacer
{ {
string ReplaceTemplateVariable(string downstreamPathTemplate, UrlMatch urlMatch); string ReplaceTemplateVariable(UrlMatch urlMatch);
} }
} }

View File

@ -1,12 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public class DownstreamUrlTemplateAlreadyExists : Error
{
public DownstreamUrlTemplateAlreadyExists()
: base("This key has already been used")
{
}
}
}

View File

@ -1,12 +0,0 @@
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public class DownstreamUrlTemplateDoesNotExist : Error
{
public DownstreamUrlTemplateDoesNotExist()
: base("This key does not exist")
{
}
}
}

View File

@ -1,11 +0,0 @@
using System.Collections.Generic;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public interface IUrlTemplateMapRepository
{
Response AddUrlTemplateMap(UrlTemplateMap urlPathMap);
Response<List<UrlTemplateMap>> All { get; }
}
}

View File

@ -1,39 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Ocelot.Library.Infrastructure.Responses;
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public class InMemoryUrlTemplateMapRepository : IUrlTemplateMapRepository
{
private readonly Dictionary<string, string> _urlTemplates;
public InMemoryUrlTemplateMapRepository()
{
_urlTemplates = new Dictionary<string,string>();
}
public Response<List<UrlTemplateMap>> All
{
get
{
var routes = _urlTemplates
.Select(r => new UrlTemplateMap(r.Key, r.Value))
.ToList();
return new OkResponse<List<UrlTemplateMap>>(routes);
}
}
public Response AddUrlTemplateMap(UrlTemplateMap urlMap)
{
if(_urlTemplates.ContainsKey(urlMap.DownstreamUrlTemplate))
{
return new ErrorResponse(new List<Error>(){new DownstreamUrlTemplateAlreadyExists()});
}
_urlTemplates.Add(urlMap.DownstreamUrlTemplate, urlMap.UpstreamUrlPathTemplate);
return new OkResponse();
}
}
}

View File

@ -1,14 +0,0 @@
namespace Ocelot.Library.Infrastructure.UrlTemplateRepository
{
public class UrlTemplateMap
{
public UrlTemplateMap(string downstreamUrlTemplate, string upstreamUrlPathTemplate)
{
DownstreamUrlTemplate = downstreamUrlTemplate;
UpstreamUrlPathTemplate = upstreamUrlPathTemplate;
}
public string DownstreamUrlTemplate {get;private set;}
public string UpstreamUrlPathTemplate {get;private set;}
}
}

View File

@ -1,7 +1,6 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Ocelot.Library.Infrastructure.UrlMatcher; using Ocelot.Library.Infrastructure.UrlMatcher;
using Ocelot.Library.Infrastructure.UrlTemplateRepository;
using Ocelot.Library.Infrastructure.UrlTemplateReplacer; using Ocelot.Library.Infrastructure.UrlTemplateReplacer;
namespace Ocelot.Library.Middleware namespace Ocelot.Library.Middleware
@ -14,40 +13,31 @@ namespace Ocelot.Library.Middleware
{ {
private readonly RequestDelegate _next; private readonly RequestDelegate _next;
private readonly IUrlPathToUrlTemplateMatcher _urlMatcher; private readonly IUrlPathToUrlTemplateMatcher _urlMatcher;
private readonly IUrlTemplateMapRepository _urlTemplateMapRepository;
private readonly IDownstreamUrlTemplateVariableReplacer _urlReplacer; private readonly IDownstreamUrlTemplateVariableReplacer _urlReplacer;
private readonly IOptions<Configuration> _optionsAccessor; private readonly IOptions<Configuration> _configuration;
public ProxyMiddleware(RequestDelegate next, public ProxyMiddleware(RequestDelegate next,
IUrlPathToUrlTemplateMatcher urlMatcher, IUrlPathToUrlTemplateMatcher urlMatcher,
IUrlTemplateMapRepository urlPathRepository, IDownstreamUrlTemplateVariableReplacer urlReplacer, IOptions<Configuration> configuration)
IDownstreamUrlTemplateVariableReplacer urlReplacer, IOptions<Configuration> optionsAccessor)
{ {
_next = next; _next = next;
_urlMatcher = urlMatcher; _urlMatcher = urlMatcher;
_urlTemplateMapRepository = urlPathRepository;
_urlReplacer = urlReplacer; _urlReplacer = urlReplacer;
_optionsAccessor = optionsAccessor; _configuration = configuration;
} }
public async Task Invoke(HttpContext context) public async Task Invoke(HttpContext context)
{ {
var upstreamUrlPath = context.Request.Path.ToString();
var downstreamUrlPath = context.Request.Path.ToString();
var upstreamUrlTemplates = _urlTemplateMapRepository.All;
UrlMatch urlMatch = null; UrlMatch urlMatch = null;
string downstreamUrlTemplate = string.Empty; foreach (var template in _configuration.Value.ReRoutes)
foreach (var template in upstreamUrlTemplates.Data)
{ {
urlMatch = _urlMatcher.Match(downstreamUrlPath, template.DownstreamUrlTemplate); urlMatch = _urlMatcher.Match(upstreamUrlPath, template.UpstreamTemplate);
if (urlMatch.Match) if (urlMatch.Match)
{ {
downstreamUrlTemplate = template.DownstreamUrlTemplate;
break; break;
} }
} }
@ -58,7 +48,7 @@ namespace Ocelot.Library.Middleware
return; return;
} }
var downstreamUrl = _urlReplacer.ReplaceTemplateVariable(downstreamUrlTemplate, urlMatch); var downstreamUrl = _urlReplacer.ReplaceTemplateVariable(urlMatch);
//make a http request to this endpoint...maybe bring in a library //make a http request to this endpoint...maybe bring in a library

View File

@ -10,7 +10,6 @@ namespace Ocelot
using Library.Infrastructure.Configuration; using Library.Infrastructure.Configuration;
using Library.Infrastructure.UrlMatcher; using Library.Infrastructure.UrlMatcher;
using Library.Infrastructure.UrlTemplateReplacer; using Library.Infrastructure.UrlTemplateReplacer;
using Library.Infrastructure.UrlTemplateRepository;
public class Startup public class Startup
{ {
@ -37,7 +36,6 @@ namespace Ocelot
// Add framework services. // Add framework services.
services.AddSingleton<IUrlPathToUrlTemplateMatcher, UrlPathToUrlTemplateMatcher>(); services.AddSingleton<IUrlPathToUrlTemplateMatcher, UrlPathToUrlTemplateMatcher>();
services.AddSingleton<IDownstreamUrlTemplateVariableReplacer, DownstreamUrlTemplateVariableReplacer>(); services.AddSingleton<IDownstreamUrlTemplateVariableReplacer, DownstreamUrlTemplateVariableReplacer>();
services.AddSingleton<IUrlTemplateMapRepository, InMemoryUrlTemplateMapRepository>();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.

View File

@ -41,12 +41,12 @@ namespace Ocelot.AcceptanceTests
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879")) this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879"))
.And(x => x.GivenThereIsAConfiguration(new Configuration .And(x => x.GivenThereIsAConfiguration(new Configuration
{ {
Routes = new List<Route> ReRoutes = new List<ReRoute>
{ {
new Route new ReRoute
{ {
Downstream = "http://localhost:51879/", DownstreamTemplate = "http://localhost:51879/",
Upstream = "/heee" UpstreamTemplate = "/"
} }
} }
})) }))

View File

@ -1,3 +1,3 @@
Routes: ReRoutes:
- Downstream: http://localhost:51879/ - DownstreamTemplate: http://localhost:51879/
Upstream: /heee UpstreamTemplate: /

View File

@ -10,7 +10,6 @@ namespace Ocelot.UnitTests
public class UpstreamUrlPathTemplateVariableReplacerTests public class UpstreamUrlPathTemplateVariableReplacerTests
{ {
private string _downstreamUrlTemplate;
private UrlMatch _urlMatch; private UrlMatch _urlMatch;
private string _result; private string _result;
private readonly IDownstreamUrlTemplateVariableReplacer _downstreamUrlPathReplacer; private readonly IDownstreamUrlTemplateVariableReplacer _downstreamUrlPathReplacer;
@ -23,18 +22,25 @@ namespace Ocelot.UnitTests
[Fact] [Fact]
public void can_replace_no_template_variables() public void can_replace_no_template_variables()
{ {
this.Given(x => x.GivenThereIsADownstreamUrl("")) this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "")))
.And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned(""))
.BDDfy(); .BDDfy();
} }
[Fact]
public void can_replace_no_template_variables_with_slash()
{
this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "/")))
.When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("/"))
.BDDfy();
}
[Fact] [Fact]
public void can_replace_url_no_slash() public void can_replace_url_no_slash()
{ {
this.Given(x => x.GivenThereIsADownstreamUrl("api")) this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api")))
.And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api"))
.BDDfy(); .BDDfy();
@ -43,8 +49,7 @@ namespace Ocelot.UnitTests
[Fact] [Fact]
public void can_replace_url_one_slash() public void can_replace_url_one_slash()
{ {
this.Given(x => x.GivenThereIsADownstreamUrl("api/")) this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api/")))
.And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api/")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/"))
.BDDfy(); .BDDfy();
@ -53,8 +58,7 @@ namespace Ocelot.UnitTests
[Fact] [Fact]
public void can_replace_url_multiple_slash() public void can_replace_url_multiple_slash()
{ {
this.Given(x => x.GivenThereIsADownstreamUrl("api/product/products/")) this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api/product/products/")))
.And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, new List<TemplateVariableNameAndValue>(), "api/product/products/")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("api/product/products/"))
.BDDfy(); .BDDfy();
@ -68,8 +72,7 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{productId}", "1") new TemplateVariableNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenThereIsADownstreamUrl("productservice/products/{productId}/")) this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "productservice/products/{productId}/")))
.And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "api/products/{productId}/")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/"))
.BDDfy(); .BDDfy();
@ -83,8 +86,7 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{productId}", "1") new TemplateVariableNameAndValue("{productId}", "1")
}; };
this.Given(x => x.GivenThereIsADownstreamUrl("productservice/products/{productId}/variants")) this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "productservice/products/{productId}/variants")))
.And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "api/products/{productId}/")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants"))
.BDDfy(); .BDDfy();
@ -99,8 +101,7 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{variantId}", "12") new TemplateVariableNameAndValue("{variantId}", "12")
}; };
this.Given(x => x.GivenThereIsADownstreamUrl("productservice/products/{productId}/variants/{variantId}")) this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "productservice/products/{productId}/variants/{variantId}")))
.And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "api/products/{productId}/{variantId}")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/products/1/variants/12"))
.BDDfy(); .BDDfy();
@ -116,18 +117,12 @@ namespace Ocelot.UnitTests
new TemplateVariableNameAndValue("{categoryId}", "34") new TemplateVariableNameAndValue("{categoryId}", "34")
}; };
this.Given(x => x.GivenThereIsADownstreamUrl("productservice/category/{categoryId}/products/{productId}/variants/{variantId}")) this.Given(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "productservice/category/{categoryId}/products/{productId}/variants/{variantId}")))
.And(x => x.GivenThereIsAUrlMatch(new UrlMatch(true, templateVariables, "api/products/{categoryId}/{productId}/{variantId}")))
.When(x => x.WhenIReplaceTheTemplateVariables()) .When(x => x.WhenIReplaceTheTemplateVariables())
.Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12")) .Then(x => x.ThenTheDownstreamUrlPathIsReturned("productservice/category/34/products/1/variants/12"))
.BDDfy(); .BDDfy();
} }
private void GivenThereIsADownstreamUrl(string downstreamUrlTemplate)
{
_downstreamUrlTemplate = downstreamUrlTemplate;
}
private void GivenThereIsAUrlMatch(UrlMatch urlMatch) private void GivenThereIsAUrlMatch(UrlMatch urlMatch)
{ {
_urlMatch = urlMatch; _urlMatch = urlMatch;
@ -135,7 +130,7 @@ namespace Ocelot.UnitTests
private void WhenIReplaceTheTemplateVariables() private void WhenIReplaceTheTemplateVariables()
{ {
_result = _downstreamUrlPathReplacer.ReplaceTemplateVariable(_downstreamUrlTemplate, _urlMatch); _result = _downstreamUrlPathReplacer.ReplaceTemplateVariable(_urlMatch);
} }
private void ThenTheDownstreamUrlPathIsReturned(string expected) private void ThenTheDownstreamUrlPathIsReturned(string expected)

View File

@ -1,101 +0,0 @@
using System.Collections.Generic;
using Ocelot.Library.Infrastructure.Responses;
using Ocelot.Library.Infrastructure.UrlTemplateRepository;
using Shouldly;
using Xunit;
namespace Ocelot.UnitTests
{
using TestStack.BDDfy;
public class UrlPathTemplateMapRepositoryTests
{
private string _upstreamUrlPathTemplate;
private string _downstreamUrlTemplate;
private IUrlTemplateMapRepository _repository;
private Response _response;
private Response<List<UrlTemplateMap>> _listResponse;
public UrlPathTemplateMapRepositoryTests()
{
_repository = new InMemoryUrlTemplateMapRepository();
}
[Fact]
public void can_add_url_path()
{
this.Given(x => x.GivenIHaveAnUpstreamUrlPathTemplate("/api/products/products/{productId}"))
.And(x => x.GivenADownstreamUrlTemplate("/api/products/{productId}"))
.When(x => x.WhenIAddTheConfiguration())
.Then(x => x.ThenTheResponseIsSuccesful())
.BDDfy();
}
[Fact]
public void can_get_all_urls()
{
this.Given(x => x.GivenIHaveSetUpADownstreamUrlTemplateAndAnUpstreamUrlPathTemplate("/api2", "http://www.someapi.com/api2"))
.When(x => x.WhenIRetrieveTheUrls())
.Then(x => x.ThenTheUrlsAreReturned())
.BDDfy();
}
[Fact]
public void should_return_error_response_when_url_path_already_used()
{
this.Given(x => x.GivenIHaveSetUpADownstreamUrlTemplateAndAnUpstreamUrlPathTemplate("/api2", "http://www.someapi.com/api2"))
.When(x => x.WhenITryToUseTheSameDownstreamUrl())
.Then(x => x.ThenTheDownstreamUrlAlreadyBeenUsed())
.BDDfy();
}
private void WhenITryToUseTheSameDownstreamUrl()
{
WhenIAddTheConfiguration();
}
private void ThenTheDownstreamUrlAlreadyBeenUsed()
{
_response.ShouldNotBeNull();
_response.ShouldBeOfType<ErrorResponse>();
_response.Errors[0].Message.ShouldBe("This key has already been used");
}
private void WhenIRetrieveTheUrls()
{
_listResponse = _repository.All;
}
private void ThenTheUrlsAreReturned()
{
_listResponse.Data.Count.ShouldBeGreaterThan(0);
}
private void GivenIHaveSetUpADownstreamUrlTemplateAndAnUpstreamUrlPathTemplate(string downstreamUrlTemplate, string upstreamUrlPathTemplate)
{
GivenIHaveAnUpstreamUrlPathTemplate(upstreamUrlPathTemplate);
GivenADownstreamUrlTemplate(downstreamUrlTemplate);
WhenIAddTheConfiguration();
}
private void GivenIHaveAnUpstreamUrlPathTemplate(string upstreamUrlPathTemplate)
{
_upstreamUrlPathTemplate = upstreamUrlPathTemplate;
}
private void GivenADownstreamUrlTemplate(string downstreamUrlTemplate)
{
_downstreamUrlTemplate = downstreamUrlTemplate;
}
private void WhenIAddTheConfiguration()
{
_response = _repository.AddUrlTemplateMap(new UrlTemplateMap(_downstreamUrlTemplate, _upstreamUrlPathTemplate));
}
private void ThenTheResponseIsSuccesful()
{
_response.ShouldBeOfType<OkResponse>();
}
}
}