mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 08:18:16 +08:00
Merge remote-tracking branch 'origin/develop' into feature/#128-cookie-proxying-and-auto-redirect-configuration
This commit is contained in:
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Ocelot.Configuration.File;
|
||||
using Shouldly;
|
||||
using TestStack.BDDfy;
|
||||
using Xunit;
|
||||
|
||||
@ -15,6 +16,7 @@ namespace Ocelot.AcceptanceTests
|
||||
{
|
||||
private IWebHost _builder;
|
||||
private readonly Steps _steps;
|
||||
private string _downstreamPath;
|
||||
|
||||
public RoutingTests()
|
||||
{
|
||||
@ -232,6 +234,34 @@ namespace Ocelot.AcceptanceTests
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_not_add_trailing_slash_to_downstream_url()
|
||||
{
|
||||
var configuration = new FileConfiguration
|
||||
{
|
||||
ReRoutes = new List<FileReRoute>
|
||||
{
|
||||
new FileReRoute
|
||||
{
|
||||
DownstreamPathTemplate = "/api/products/{productId}",
|
||||
DownstreamScheme = "http",
|
||||
DownstreamHost = "localhost",
|
||||
DownstreamPort = 51879,
|
||||
UpstreamPathTemplate = "/products/{productId}",
|
||||
UpstreamHttpMethod = new List<string> { "Get" },
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.Given(x => GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
|
||||
.And(x => _steps.GivenThereIsAConfiguration(configuration))
|
||||
.And(x => _steps.GivenOcelotIsRunning())
|
||||
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/products/1"))
|
||||
.Then(x => ThenTheDownstreamUrlPathShouldBe("/api/products/1"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_response_201_with_simple_url()
|
||||
{
|
||||
@ -379,11 +409,11 @@ namespace Ocelot.AcceptanceTests
|
||||
.UseKestrel()
|
||||
.UseContentRoot(Directory.GetCurrentDirectory())
|
||||
.UseIISIntegration()
|
||||
.UseUrls(url)
|
||||
.Configure(app =>
|
||||
{
|
||||
app.Run(async context =>
|
||||
{
|
||||
_downstreamPath = context.Request.PathBase.Value;
|
||||
context.Response.StatusCode = statusCode;
|
||||
await context.Response.WriteAsync(responseBody);
|
||||
});
|
||||
@ -393,6 +423,11 @@ namespace Ocelot.AcceptanceTests
|
||||
_builder.Start();
|
||||
}
|
||||
|
||||
internal void ThenTheDownstreamUrlPathShouldBe(string expectedDownstreamPath)
|
||||
{
|
||||
_downstreamPath.ShouldBe(expectedDownstreamPath);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_builder?.Dispose();
|
||||
|
@ -36,7 +36,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
[Fact]
|
||||
public void should_return_route()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher"))
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher/"))
|
||||
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(
|
||||
new List<UrlPathPlaceholderNameAndValue>())))
|
||||
@ -65,6 +65,39 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_append_slash_to_upstream_url_path()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("matchInUrlMatcher"))
|
||||
.And(x =>x.GivenTheTemplateVariableAndNameFinderReturns(
|
||||
new OkResponse<List<UrlPathPlaceholderNameAndValue>>(
|
||||
new List<UrlPathPlaceholderNameAndValue>())))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamPathTemplate("someUpstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.WithUpstreamTemplatePattern("someUpstreamPath")
|
||||
.Build()
|
||||
}, string.Empty
|
||||
))
|
||||
.And(x => x.GivenTheUrlMatcherReturns(new OkResponse<UrlMatch>(new UrlMatch(true))))
|
||||
.And(x => x.GivenTheUpstreamHttpMethodIs("Get"))
|
||||
.When(x => x.WhenICallTheFinder())
|
||||
.Then(
|
||||
x => x.ThenTheFollowingIsReturned(new DownstreamRoute(
|
||||
new List<UrlPathPlaceholderNameAndValue>(),
|
||||
new ReRouteBuilder()
|
||||
.WithDownstreamPathTemplate("someDownstreamPath")
|
||||
.WithUpstreamHttpMethod(new List<string> { "Get" })
|
||||
.Build()
|
||||
)))
|
||||
.And(x => x.ThenTheUrlMatcherIsCalledCorrectly("matchInUrlMatcher/"))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_route_if_upstream_path_and_upstream_template_are_the_same()
|
||||
{
|
||||
@ -137,7 +170,7 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
[Fact]
|
||||
public void should_not_return_route()
|
||||
{
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("dontMatchPath"))
|
||||
this.Given(x => x.GivenThereIsAnUpstreamUrlPath("dontMatchPath/"))
|
||||
.And(x => x.GivenTheConfigurationIs(new List<ReRoute>
|
||||
{
|
||||
new ReRouteBuilder()
|
||||
@ -269,6 +302,12 @@ namespace Ocelot.UnitTests.DownstreamRouteFinder
|
||||
.Verify(x => x.Match(_upstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheUrlMatcherIsCalledCorrectly(string expectedUpstreamUrlPath)
|
||||
{
|
||||
_mockMatcher
|
||||
.Verify(x => x.Match(expectedUpstreamUrlPath, _reRoutesConfig[0].UpstreamPathTemplate.Value), Times.Once);
|
||||
}
|
||||
|
||||
private void ThenTheUrlMatcherIsNotCalled()
|
||||
{
|
||||
_mockMatcher
|
||||
|
124
test/Ocelot.UnitTests/Infrastructure/ScopesAuthoriserTests.cs
Normal file
124
test/Ocelot.UnitTests/Infrastructure/ScopesAuthoriserTests.cs
Normal file
@ -0,0 +1,124 @@
|
||||
using Xunit;
|
||||
using Shouldly;
|
||||
using Ocelot.Authorisation;
|
||||
using Ocelot.Infrastructure.Claims.Parser;
|
||||
using Moq;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using Ocelot.Responses;
|
||||
using TestStack.BDDfy;
|
||||
using Ocelot.Errors;
|
||||
|
||||
namespace Ocelot.UnitTests.Infrastructure
|
||||
{
|
||||
public class ScopesAuthoriserTests
|
||||
{
|
||||
private ScopesAuthoriser _authoriser;
|
||||
public Mock<IClaimsParser> _parser;
|
||||
private ClaimsPrincipal _principal;
|
||||
private List<string> _allowedScopes;
|
||||
private Response<bool> _result;
|
||||
|
||||
public ScopesAuthoriserTests()
|
||||
{
|
||||
_parser = new Mock<IClaimsParser>();
|
||||
_authoriser = new ScopesAuthoriser(_parser.Object);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_ok_if_no_allowed_scopes()
|
||||
{
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheFollowing(new List<string>()))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public void should_return_ok_if_null_allowed_scopes()
|
||||
{
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheFollowing((List<string>)null))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_return_error_if_claims_parser_returns_error()
|
||||
{
|
||||
var fakeError = new FakeError();
|
||||
this.Given(_ => GivenTheFollowing(new ClaimsPrincipal()))
|
||||
.And(_ => GivenTheParserReturns(new ErrorResponse<List<string>>(fakeError)))
|
||||
.And(_ => GivenTheFollowing(new List<string>(){"doesntmatter"}))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_match_scopes_and_return_ok_result()
|
||||
{
|
||||
var claimsPrincipal = new ClaimsPrincipal();
|
||||
var allowedScopes = new List<string>(){"someScope"};
|
||||
|
||||
this.Given(_ => GivenTheFollowing(claimsPrincipal))
|
||||
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(allowedScopes)))
|
||||
.And(_ => GivenTheFollowing(allowedScopes))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new OkResponse<bool>(true)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void should_not_match_scopes_and_return_error_result()
|
||||
{
|
||||
var fakeError = new FakeError();
|
||||
var claimsPrincipal = new ClaimsPrincipal();
|
||||
var allowedScopes = new List<string>(){"someScope"};
|
||||
var userScopes = new List<string>(){"anotherScope"};
|
||||
|
||||
this.Given(_ => GivenTheFollowing(claimsPrincipal))
|
||||
.And(_ => GivenTheParserReturns(new OkResponse<List<string>>(userScopes)))
|
||||
.And(_ => GivenTheFollowing(allowedScopes))
|
||||
.When(_ => WhenIAuthorise())
|
||||
.Then(_ => ThenTheFollowingIsReturned(new ErrorResponse<bool>(fakeError)))
|
||||
.BDDfy();
|
||||
}
|
||||
|
||||
private void GivenTheParserReturns(Response<List<string>> response)
|
||||
{
|
||||
_parser.Setup(x => x.GetValuesByClaimType(It.IsAny<IEnumerable<Claim>>(), It.IsAny<string>())).Returns(response);
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(ClaimsPrincipal principal)
|
||||
{
|
||||
_principal = principal;
|
||||
}
|
||||
|
||||
private void GivenTheFollowing(List<string> allowedScopes)
|
||||
{
|
||||
_allowedScopes = allowedScopes;
|
||||
}
|
||||
|
||||
private void WhenIAuthorise()
|
||||
{
|
||||
_result = _authoriser.Authorise(_principal, _allowedScopes);
|
||||
}
|
||||
|
||||
private void ThenTheFollowingIsReturned(Response<bool> expected)
|
||||
{
|
||||
_result.Data.ShouldBe(expected.Data);
|
||||
_result.IsError.ShouldBe(expected.IsError);
|
||||
}
|
||||
}
|
||||
|
||||
public class FakeError : Error
|
||||
{
|
||||
public FakeError() : base("fake error", OcelotErrorCode.CannotAddDataError)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user