mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 17:10:50 +08:00 
			
		
		
		
	refactoring acceptance tests..they need some tlc
This commit is contained in:
		@@ -2,265 +2,214 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Net.Http.Headers;
 | 
			
		||||
using System.Text.Encodings.Web;
 | 
			
		||||
using System.Security.Claims;
 | 
			
		||||
using IdentityServer4.Models;
 | 
			
		||||
using IdentityServer4.Services.InMemory;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.TestHost;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using Ocelot.Configuration.Yaml;
 | 
			
		||||
using Ocelot.ManualTest;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using YamlDotNet.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    using System.Security.Claims;
 | 
			
		||||
 | 
			
		||||
    public class AuthenticationTests : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private TestServer _ocelotServer;
 | 
			
		||||
        private HttpClient _ocelotClient;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private readonly string _configurationPath;
 | 
			
		||||
        private StringContent _postContent;
 | 
			
		||||
        private IWebHost _servicebuilder;
 | 
			
		||||
 | 
			
		||||
        // Sadly we need to change this when we update the netcoreapp version to make the test update the config correctly
 | 
			
		||||
        private double _netCoreAppVersion = 1.4;
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
        private BearerToken _token;
 | 
			
		||||
        private IWebHost _identityServerBuilder;
 | 
			
		||||
        private string _identityServerRootUrl = "http://localhost:51888";
 | 
			
		||||
        private string _downstreamServiceRootUrl = "http://localhost:51876/";
 | 
			
		||||
 | 
			
		||||
        public AuthenticationTests()
 | 
			
		||||
        {
 | 
			
		||||
            _configurationPath = $"./bin/Debug/netcoreapp{_netCoreAppVersion}/configuration.yaml";
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_401_using_identity_server_access_token()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 201, string.Empty))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
            var yamlConfiguration = new YamlConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new YamlReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamTemplate = "http://localhost:51876/",
 | 
			
		||||
                            DownstreamTemplate = _downstreamServiceRootUrl,
 | 
			
		||||
                            UpstreamTemplate = "/",
 | 
			
		||||
                            UpstreamHttpMethod = "Post",
 | 
			
		||||
                            AuthenticationOptions = new YamlAuthenticationOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                AdditionalScopes =  new List<string>(),
 | 
			
		||||
                                Provider = "IdentityServer",
 | 
			
		||||
                                ProviderRootUrl = "http://localhost:51888", 
 | 
			
		||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
			
		||||
                                RequireHttps = false,
 | 
			
		||||
                                ScopeName = "api",
 | 
			
		||||
                                ScopeSecret = "secret"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning())
 | 
			
		||||
                .And(x => x.GivenThePostHasContent("postContent"))
 | 
			
		||||
                .When(x => x.WhenIPostUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 201, string.Empty))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(yamlConfiguration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenThePostHasContent("postContent"))
 | 
			
		||||
                .When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_401_using_identity_server_reference_token()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Reference))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 201, string.Empty))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
            var yamlConfiguration = new YamlConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new YamlReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamTemplate = "http://localhost:51876/",
 | 
			
		||||
                            DownstreamTemplate = _downstreamServiceRootUrl,
 | 
			
		||||
                            UpstreamTemplate = "/",
 | 
			
		||||
                            UpstreamHttpMethod = "Post",
 | 
			
		||||
                            AuthenticationOptions = new YamlAuthenticationOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                AdditionalScopes =  new List<string>(),
 | 
			
		||||
                                Provider = "IdentityServer",
 | 
			
		||||
                                ProviderRootUrl = "http://localhost:51888",
 | 
			
		||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
			
		||||
                                RequireHttps = false,
 | 
			
		||||
                                ScopeName = "api",
 | 
			
		||||
                                ScopeSecret = "secret"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning())
 | 
			
		||||
                .And(x => x.GivenThePostHasContent("postContent"))
 | 
			
		||||
                .When(x => x.WhenIPostUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Reference))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 201, string.Empty))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(yamlConfiguration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenThePostHasContent("postContent"))
 | 
			
		||||
                .When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_using_identity_server()
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => x.GivenIHaveAToken("http://localhost:51888"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
            var yamlConfiguration = new YamlConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new YamlReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamTemplate = "http://localhost:51876/",
 | 
			
		||||
                            DownstreamTemplate = _downstreamServiceRootUrl,
 | 
			
		||||
                            UpstreamTemplate = "/",
 | 
			
		||||
                            UpstreamHttpMethod = "Get",
 | 
			
		||||
                            AuthenticationOptions = new YamlAuthenticationOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                AdditionalScopes =  new List<string>(),
 | 
			
		||||
                                Provider = "IdentityServer",
 | 
			
		||||
                                ProviderRootUrl = "http://localhost:51888",
 | 
			
		||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
			
		||||
                                RequireHttps = false,
 | 
			
		||||
                                ScopeName = "api",
 | 
			
		||||
                                ScopeSecret = "secret"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning())
 | 
			
		||||
                .And(x => x.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .When(x => x.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => x.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(yamlConfiguration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_201_using_identity_server_access_token()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 201, string.Empty))
 | 
			
		||||
                .And(x => x.GivenIHaveAToken("http://localhost:51888"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
            var yamlConfiguration = new YamlConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new YamlReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamTemplate = "http://localhost:51876/",
 | 
			
		||||
                            DownstreamTemplate = _downstreamServiceRootUrl,
 | 
			
		||||
                            UpstreamTemplate = "/",
 | 
			
		||||
                            UpstreamHttpMethod = "Post",
 | 
			
		||||
                            AuthenticationOptions = new YamlAuthenticationOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                AdditionalScopes =  new List<string>(),
 | 
			
		||||
                                Provider = "IdentityServer",
 | 
			
		||||
                                ProviderRootUrl = "http://localhost:51888",
 | 
			
		||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
			
		||||
                                RequireHttps = false,
 | 
			
		||||
                                ScopeName = "api",
 | 
			
		||||
                                ScopeSecret = "secret"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning())
 | 
			
		||||
                .And(x => x.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .And(x => x.GivenThePostHasContent("postContent"))
 | 
			
		||||
                .When(x => x.WhenIPostUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 201, string.Empty))
 | 
			
		||||
                .And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(yamlConfiguration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .And(x => _steps.GivenThePostHasContent("postContent"))
 | 
			
		||||
                .When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_201_using_identity_server_reference_token()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Reference))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 201, string.Empty))
 | 
			
		||||
                .And(x => x.GivenIHaveAToken("http://localhost:51888"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
            var yamlConfiguration = new YamlConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
                        new YamlReRoute
 | 
			
		||||
                        {
 | 
			
		||||
                            DownstreamTemplate = "http://localhost:51876/",
 | 
			
		||||
                            DownstreamTemplate = _downstreamServiceRootUrl,
 | 
			
		||||
                            UpstreamTemplate = "/",
 | 
			
		||||
                            UpstreamHttpMethod = "Post",
 | 
			
		||||
                            AuthenticationOptions = new YamlAuthenticationOptions
 | 
			
		||||
                            {
 | 
			
		||||
                                AdditionalScopes = new List<string>(),
 | 
			
		||||
                                Provider = "IdentityServer",
 | 
			
		||||
                                ProviderRootUrl = "http://localhost:51888",
 | 
			
		||||
                                ProviderRootUrl = _identityServerRootUrl,
 | 
			
		||||
                                RequireHttps = false,
 | 
			
		||||
                                ScopeName = "api",
 | 
			
		||||
                                ScopeSecret = "secret"
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning())
 | 
			
		||||
                .And(x => x.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .And(x => x.GivenThePostHasContent("postContent"))
 | 
			
		||||
                .When(x => x.WhenIPostUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn(_identityServerRootUrl, "api", AccessTokenType.Reference))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn(_downstreamServiceRootUrl, 201, string.Empty))
 | 
			
		||||
                .And(x => _steps.GivenIHaveAToken(_identityServerRootUrl))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(yamlConfiguration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .And(x => _steps.GivenThePostHasContent("postContent"))
 | 
			
		||||
                .When(x => _steps.WhenIPostUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Created))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIGetUrlOnTheApiGateway(string url)
 | 
			
		||||
        {   
 | 
			
		||||
            _response = _ocelotClient.GetAsync(url).Result;     
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIPostUrlOnTheApiGateway(string url)
 | 
			
		||||
        {
 | 
			
		||||
            _response = _ocelotClient.PostAsync(url, _postContent).Result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResponseBodyShouldBe(string expectedBody)
 | 
			
		||||
        {
 | 
			
		||||
            _response.Content.ReadAsStringAsync().Result.ShouldBe(expectedBody);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThePostHasContent(string postcontent)
 | 
			
		||||
        {
 | 
			
		||||
            _postContent = new StringContent(postcontent);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This is annoying cos it should be in the constructor but we need to set up the yaml file before calling startup so its a step.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private void GivenTheApiGatewayIsRunning()
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotServer = new TestServer(new WebHostBuilder()
 | 
			
		||||
                .UseStartup<Startup>());
 | 
			
		||||
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAConfiguration(YamlConfiguration yamlConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var serializer = new Serializer();
 | 
			
		||||
 | 
			
		||||
            if (File.Exists(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(_configurationPath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (TextWriter writer = File.CreateText(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, yamlConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
 | 
			
		||||
        {
 | 
			
		||||
            _servicebuilder = new WebHostBuilder()
 | 
			
		||||
@@ -351,71 +300,14 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
 | 
			
		||||
            _identityServerBuilder.Start();
 | 
			
		||||
 | 
			
		||||
            VerifyIdentiryServerStarted(url);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void VerifyIdentiryServerStarted(string url)
 | 
			
		||||
        {
 | 
			
		||||
            using (var httpClient = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                var response = httpClient.GetAsync($"{url}/.well-known/openid-configuration").Result;
 | 
			
		||||
                response.EnsureSuccessStatusCode();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenIHaveAToken(string url)
 | 
			
		||||
        {
 | 
			
		||||
            var tokenUrl = $"{url}/connect/token";
 | 
			
		||||
            var formData = new List<KeyValuePair<string, string>>
 | 
			
		||||
            {
 | 
			
		||||
                new KeyValuePair<string, string>("client_id", "client"),
 | 
			
		||||
                new KeyValuePair<string, string>("client_secret", "secret"),
 | 
			
		||||
                new KeyValuePair<string, string>("scope", "api"),
 | 
			
		||||
                new KeyValuePair<string, string>("username", "test"),
 | 
			
		||||
                new KeyValuePair<string, string>("password", "test"),
 | 
			
		||||
                new KeyValuePair<string, string>("grant_type", "password")
 | 
			
		||||
            };
 | 
			
		||||
            var content = new FormUrlEncodedContent(formData);
 | 
			
		||||
 | 
			
		||||
            using (var httpClient = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                var response = httpClient.PostAsync(tokenUrl, content).Result;
 | 
			
		||||
                response.EnsureSuccessStatusCode();
 | 
			
		||||
                var responseContent = response.Content.ReadAsStringAsync().Result;
 | 
			
		||||
                _token = JsonConvert.DeserializeObject<BearerToken>(responseContent);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenIHaveAddedATokenToMyRequest()
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token.AccessToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheStatusCodeShouldBe(HttpStatusCode expectedHttpStatusCode)
 | 
			
		||||
        {
 | 
			
		||||
            _response.StatusCode.ShouldBe(expectedHttpStatusCode);
 | 
			
		||||
            _steps.VerifyIdentiryServerStarted(url);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            _servicebuilder?.Dispose();
 | 
			
		||||
            _ocelotClient?.Dispose();
 | 
			
		||||
            _ocelotServer?.Dispose();
 | 
			
		||||
            _steps.Dispose();
 | 
			
		||||
            _identityServerBuilder?.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // ReSharper disable once ClassNeverInstantiated.Local
 | 
			
		||||
        class BearerToken
 | 
			
		||||
        {
 | 
			
		||||
            [JsonProperty("access_token")]
 | 
			
		||||
            public string AccessToken { get; set; }
 | 
			
		||||
 | 
			
		||||
            [JsonProperty("expires_in")]
 | 
			
		||||
            public int ExpiresIn { get; set; }
 | 
			
		||||
 | 
			
		||||
            [JsonProperty("token_type")]
 | 
			
		||||
            public string TokenType { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,54 +2,34 @@ using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Net.Http.Headers;
 | 
			
		||||
using System.Text.Encodings.Web;
 | 
			
		||||
using System.Security.Claims;
 | 
			
		||||
using IdentityServer4.Models;
 | 
			
		||||
using IdentityServer4.Services.InMemory;
 | 
			
		||||
using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.TestHost;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using Ocelot.Configuration.Yaml;
 | 
			
		||||
using Ocelot.ManualTest;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using YamlDotNet.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    using System.Security.Claims;
 | 
			
		||||
 | 
			
		||||
    public class AuthorisationTests : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private TestServer _ocelotServer;
 | 
			
		||||
        private HttpClient _ocelotClient;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private readonly string _configurationPath;
 | 
			
		||||
        private StringContent _postContent;
 | 
			
		||||
        private IWebHost _servicebuilder;
 | 
			
		||||
 | 
			
		||||
        // Sadly we need to change this when we update the netcoreapp version to make the test update the config correctly
 | 
			
		||||
        private double _netCoreAppVersion = 1.4;
 | 
			
		||||
        private BearerToken _token;
 | 
			
		||||
        private IWebHost _identityServerBuilder;
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
 | 
			
		||||
        public AuthorisationTests()
 | 
			
		||||
        {
 | 
			
		||||
            _configurationPath = $"./bin/Debug/netcoreapp{_netCoreAppVersion}/configuration.yaml";
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_authorising_route()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => x.GivenIHaveAToken("http://localhost:51888"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
            var yamlConfiguration = new YamlConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -86,22 +66,24 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning())
 | 
			
		||||
                .And(x => x.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .When(x => x.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => x.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(yamlConfiguration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_403_authorising_route()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => x.GivenIHaveAToken("http://localhost:51888"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
            var yamlConfiguration = new YamlConfiguration
 | 
			
		||||
            {
 | 
			
		||||
                ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -137,50 +119,19 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning())
 | 
			
		||||
                .And(x => x.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .When(x => x.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:51888", "api", AccessTokenType.Jwt))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:51876", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => _steps.GivenIHaveAToken("http://localhost:51888"))
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(yamlConfiguration))
 | 
			
		||||
                .And(x => _steps.GivenOcelotIsRunning())
 | 
			
		||||
                .And(x => _steps.GivenIHaveAddedATokenToMyRequest())
 | 
			
		||||
                .When(x => _steps.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.Forbidden))
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void WhenIGetUrlOnTheApiGateway(string url)
 | 
			
		||||
        {   
 | 
			
		||||
            _response = _ocelotClient.GetAsync(url).Result;     
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheResponseBodyShouldBe(string expectedBody)
 | 
			
		||||
        {
 | 
			
		||||
            _response.Content.ReadAsStringAsync().Result.ShouldBe(expectedBody);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This is annoying cos it should be in the constructor but we need to set up the yaml file before calling startup so its a step.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private void GivenTheApiGatewayIsRunning()
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotServer = new TestServer(new WebHostBuilder()
 | 
			
		||||
                .UseStartup<Startup>());
 | 
			
		||||
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAConfiguration(YamlConfiguration yamlConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var serializer = new Serializer();
 | 
			
		||||
 | 
			
		||||
            if (File.Exists(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(_configurationPath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (TextWriter writer = File.CreateText(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, yamlConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
 | 
			
		||||
        {
 | 
			
		||||
            _servicebuilder = new WebHostBuilder()
 | 
			
		||||
@@ -272,71 +223,15 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
 | 
			
		||||
            _identityServerBuilder.Start();
 | 
			
		||||
 | 
			
		||||
            VerifyIdentiryServerStarted(url);
 | 
			
		||||
            _steps.VerifyIdentiryServerStarted(url);
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void VerifyIdentiryServerStarted(string url)
 | 
			
		||||
        {
 | 
			
		||||
            using (var httpClient = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                var response = httpClient.GetAsync($"{url}/.well-known/openid-configuration").Result;
 | 
			
		||||
                response.EnsureSuccessStatusCode();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenIHaveAToken(string url)
 | 
			
		||||
        {
 | 
			
		||||
            var tokenUrl = $"{url}/connect/token";
 | 
			
		||||
            var formData = new List<KeyValuePair<string, string>>
 | 
			
		||||
            {
 | 
			
		||||
                new KeyValuePair<string, string>("client_id", "client"),
 | 
			
		||||
                new KeyValuePair<string, string>("client_secret", "secret"),
 | 
			
		||||
                new KeyValuePair<string, string>("scope", "api"),
 | 
			
		||||
                new KeyValuePair<string, string>("username", "test"),
 | 
			
		||||
                new KeyValuePair<string, string>("password", "test"),
 | 
			
		||||
                new KeyValuePair<string, string>("grant_type", "password")
 | 
			
		||||
            };
 | 
			
		||||
            var content = new FormUrlEncodedContent(formData);
 | 
			
		||||
 | 
			
		||||
            using (var httpClient = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                var response = httpClient.PostAsync(tokenUrl, content).Result;
 | 
			
		||||
                response.EnsureSuccessStatusCode();
 | 
			
		||||
                var responseContent = response.Content.ReadAsStringAsync().Result;
 | 
			
		||||
                _token = JsonConvert.DeserializeObject<BearerToken>(responseContent);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenIHaveAddedATokenToMyRequest()
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token.AccessToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheStatusCodeShouldBe(HttpStatusCode expectedHttpStatusCode)
 | 
			
		||||
        {
 | 
			
		||||
            _response.StatusCode.ShouldBe(expectedHttpStatusCode);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            _servicebuilder?.Dispose();
 | 
			
		||||
            _ocelotClient?.Dispose();
 | 
			
		||||
            _ocelotServer?.Dispose();
 | 
			
		||||
            _steps.Dispose();
 | 
			
		||||
            _identityServerBuilder?.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // ReSharper disable once ClassNeverInstantiated.Local
 | 
			
		||||
        class BearerToken
 | 
			
		||||
        {
 | 
			
		||||
            [JsonProperty("access_token")]
 | 
			
		||||
            public string AccessToken { get; set; }
 | 
			
		||||
 | 
			
		||||
            [JsonProperty("expires_in")]
 | 
			
		||||
            public int ExpiresIn { get; set; }
 | 
			
		||||
 | 
			
		||||
            [JsonProperty("token_type")]
 | 
			
		||||
            public string TokenType { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								test/Ocelot.AcceptanceTests/BearerToken.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								test/Ocelot.AcceptanceTests/BearerToken.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    class BearerToken
 | 
			
		||||
    {
 | 
			
		||||
        [JsonProperty("access_token")]
 | 
			
		||||
        public string AccessToken { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("expires_in")]
 | 
			
		||||
        public int ExpiresIn { get; set; }
 | 
			
		||||
 | 
			
		||||
        [JsonProperty("token_type")]
 | 
			
		||||
        public string TokenType { get; set; }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -19,7 +19,6 @@ using Ocelot.ManualTest;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using YamlDotNet.Serialization;
 | 
			
		||||
 | 
			
		||||
[assembly: CollectionBehavior(DisableTestParallelization = true)]
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
@@ -29,17 +28,14 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        private TestServer _ocelotServer;
 | 
			
		||||
        private HttpClient _ocelotClient;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private readonly string _configurationPath;
 | 
			
		||||
        private IWebHost _servicebuilder;
 | 
			
		||||
 | 
			
		||||
        // Sadly we need to change this when we update the netcoreapp version to make the test update the config correctly
 | 
			
		||||
        private double _netCoreAppVersion = 1.4;
 | 
			
		||||
        private BearerToken _token;
 | 
			
		||||
        private IWebHost _identityServerBuilder;
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
 | 
			
		||||
        public ClaimsToHeadersForwardingTests()
 | 
			
		||||
        {
 | 
			
		||||
            _configurationPath = $"./bin/Debug/netcoreapp{_netCoreAppVersion}/configuration.yaml";
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
@@ -61,7 +57,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            this.Given(x => x.GivenThereIsAnIdentityServerOn("http://localhost:52888", "api", AccessTokenType.Jwt, user))
 | 
			
		||||
                .And(x => x.GivenThereIsAServiceRunningOn("http://localhost:52876", 200))
 | 
			
		||||
                .And(x => x.GivenIHaveAToken("http://localhost:52888"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                {
 | 
			
		||||
                    ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -121,21 +117,6 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAConfiguration(YamlConfiguration yamlConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var serializer = new Serializer();
 | 
			
		||||
 | 
			
		||||
            if (File.Exists(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(_configurationPath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (TextWriter writer = File.CreateText(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, yamlConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string url, int statusCode)
 | 
			
		||||
        {
 | 
			
		||||
            _servicebuilder = new WebHostBuilder()
 | 
			
		||||
 
 | 
			
		||||
@@ -7,38 +7,31 @@ using Microsoft.AspNetCore.Builder;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.Http;
 | 
			
		||||
using Microsoft.AspNetCore.TestHost;
 | 
			
		||||
using Ocelot.Configuration.Yaml;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using YamlDotNet.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    using System.Linq;
 | 
			
		||||
    using System.Threading.Tasks;
 | 
			
		||||
    using DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.Configuration;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
using Microsoft.Extensions.Logging;
 | 
			
		||||
    using Microsoft.Extensions.Primitives;
 | 
			
		||||
    using Middleware;
 | 
			
		||||
    using ScopedData;
 | 
			
		||||
using Ocelot.Configuration.Yaml;
 | 
			
		||||
using Ocelot.DependencyInjection;
 | 
			
		||||
using Ocelot.Middleware;
 | 
			
		||||
using Ocelot.ScopedData;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    public class CustomMiddlewareTests : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private TestServer _server;
 | 
			
		||||
        private HttpClient _client;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private readonly string _configurationPath;
 | 
			
		||||
        private StringContent _postContent;
 | 
			
		||||
        private IWebHost _builder;
 | 
			
		||||
 | 
			
		||||
        // Sadly we need to change this when we update the netcoreapp version to make the test update the config correctly
 | 
			
		||||
        private double _netCoreAppVersion = 1.4;
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
 | 
			
		||||
        public CustomMiddlewareTests()
 | 
			
		||||
        {
 | 
			
		||||
            _steps = new Steps();;
 | 
			
		||||
            _configurationPath = $"configuration.yaml";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -54,7 +47,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:41879", 200))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                {
 | 
			
		||||
                    ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -65,8 +58,8 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            UpstreamHttpMethod = "Get",
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning(configuration))
 | 
			
		||||
                }, _configurationPath))
 | 
			
		||||
                .And(x => x.GivenOcelotIsRunning(configuration))
 | 
			
		||||
                .When(x => x.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => x.ThenTheResponseBodyShouldBe("PreHttpResponderMiddleware"))
 | 
			
		||||
@@ -81,13 +74,12 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                PreHttpRequesterMiddleware = async (ctx, next) =>
 | 
			
		||||
                {
 | 
			
		||||
                    var service = ctx.RequestServices.GetService<IScopedRequestDataRepository>();
 | 
			
		||||
                    service.Add("Response",
 | 
			
		||||
                        new HttpResponseMessage {Content = new StringContent("PreHttpRequesterMiddleware")});
 | 
			
		||||
                    service.Add("Response", new HttpResponseMessage {Content = new StringContent("PreHttpRequesterMiddleware")});
 | 
			
		||||
                }
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:41879", 200))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                {
 | 
			
		||||
                    ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -98,8 +90,8 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
                            UpstreamHttpMethod = "Get",
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning(configuration))
 | 
			
		||||
                }, _configurationPath))
 | 
			
		||||
                .And(x => x.GivenOcelotIsRunning(configuration))
 | 
			
		||||
                .When(x => x.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
 | 
			
		||||
                .And(x => x.ThenTheResponseBodyShouldBe("PreHttpRequesterMiddleware"))
 | 
			
		||||
@@ -111,7 +103,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This is annoying cos it should be in the constructor but we need to set up the yaml file before calling startup so its a step.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        private void GivenTheApiGatewayIsRunning(OcelotMiddlewareConfiguration ocelotMiddlewareConfig)
 | 
			
		||||
        private void GivenOcelotIsRunning(OcelotMiddlewareConfiguration ocelotMiddlewareConfig)
 | 
			
		||||
        {
 | 
			
		||||
            var builder = new ConfigurationBuilder()
 | 
			
		||||
                .SetBasePath(Directory.GetCurrentDirectory())
 | 
			
		||||
@@ -141,21 +133,6 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            _client = _server.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAConfiguration(YamlConfiguration yamlConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var serializer = new Serializer();
 | 
			
		||||
 | 
			
		||||
            if (File.Exists(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(_configurationPath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (TextWriter writer = File.CreateText(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, yamlConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string url, int statusCode)
 | 
			
		||||
        {
 | 
			
		||||
            _builder = new WebHostBuilder()
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,6 @@ using Ocelot.ManualTest;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using YamlDotNet.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
@@ -20,22 +19,19 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        private TestServer _ocelotServer;
 | 
			
		||||
        private HttpClient _ocelotClient;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private readonly string _configurationPath;
 | 
			
		||||
        private IWebHost _servicebuilder;
 | 
			
		||||
 | 
			
		||||
        // Sadly we need to change this when we update the netcoreapp version to make the test update the config correctly
 | 
			
		||||
        private double _netCoreAppVersion = 1.4;
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
 | 
			
		||||
        public ReturnsErrorTests()
 | 
			
		||||
        {
 | 
			
		||||
            _configurationPath = $"./bin/Debug/netcoreapp{_netCoreAppVersion}/configuration.yaml";
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_200_and_foward_claim_as_header()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:53876"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                {
 | 
			
		||||
                    ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -74,21 +70,6 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAConfiguration(YamlConfiguration yamlConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var serializer = new Serializer();
 | 
			
		||||
 | 
			
		||||
            if (File.Exists(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(_configurationPath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (TextWriter writer = File.CreateText(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, yamlConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string url)
 | 
			
		||||
        {
 | 
			
		||||
            _servicebuilder = new WebHostBuilder()
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,6 @@ using Ocelot.ManualTest;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using TestStack.BDDfy;
 | 
			
		||||
using Xunit;
 | 
			
		||||
using YamlDotNet.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
@@ -21,22 +20,19 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        private TestServer _server;
 | 
			
		||||
        private HttpClient _client;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private readonly string _configurationPath;
 | 
			
		||||
        private StringContent _postContent;
 | 
			
		||||
        private IWebHost _builder;
 | 
			
		||||
 | 
			
		||||
        // Sadly we need to change this when we update the netcoreapp version to make the test update the config correctly
 | 
			
		||||
        private double _netCoreAppVersion = 1.4;
 | 
			
		||||
        private readonly Steps _steps;
 | 
			
		||||
 | 
			
		||||
        public RoutingTests()
 | 
			
		||||
        {
 | 
			
		||||
            _configurationPath = $"./bin/Debug/netcoreapp{_netCoreAppVersion}/configuration.yaml";
 | 
			
		||||
            _steps = new Steps();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void should_return_response_404_when_no_configuration_at_all()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAConfiguration(new YamlConfiguration()))
 | 
			
		||||
            this.Given(x => _steps.GivenThereIsAConfiguration(new YamlConfiguration()))
 | 
			
		||||
                .And(x => x.GivenTheApiGatewayIsRunning())
 | 
			
		||||
                .When(x => x.WhenIGetUrlOnTheApiGateway("/"))
 | 
			
		||||
                .Then(x => x.ThenTheStatusCodeShouldBe(HttpStatusCode.NotFound))
 | 
			
		||||
@@ -47,7 +43,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        public void should_return_response_200_with_simple_url()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                {
 | 
			
		||||
                    ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -70,7 +66,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        public void should_return_response_200_with_complex_url()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879/api/products/1", 200, "Some Product"))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                {
 | 
			
		||||
                    ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -93,7 +89,7 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
        public void should_return_response_201_with_simple_url()
 | 
			
		||||
        {
 | 
			
		||||
            this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 201, string.Empty))
 | 
			
		||||
                .And(x => x.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                .And(x => _steps.GivenThereIsAConfiguration(new YamlConfiguration
 | 
			
		||||
                {
 | 
			
		||||
                    ReRoutes = new List<YamlReRoute>
 | 
			
		||||
                    {
 | 
			
		||||
@@ -128,21 +124,6 @@ namespace Ocelot.AcceptanceTests
 | 
			
		||||
            _client = _server.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAConfiguration(YamlConfiguration yamlConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var serializer = new Serializer();
 | 
			
		||||
 | 
			
		||||
            if (File.Exists(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(_configurationPath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (TextWriter writer = File.CreateText(_configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, yamlConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
 | 
			
		||||
        {
 | 
			
		||||
            _builder = new WebHostBuilder()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										129
									
								
								test/Ocelot.AcceptanceTests/Steps.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								test/Ocelot.AcceptanceTests/Steps.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.IO;
 | 
			
		||||
using System.Net;
 | 
			
		||||
using System.Net.Http;
 | 
			
		||||
using System.Net.Http.Headers;
 | 
			
		||||
using Microsoft.AspNetCore.Hosting;
 | 
			
		||||
using Microsoft.AspNetCore.TestHost;
 | 
			
		||||
using Newtonsoft.Json;
 | 
			
		||||
using Ocelot.Configuration.Yaml;
 | 
			
		||||
using Ocelot.ManualTest;
 | 
			
		||||
using Shouldly;
 | 
			
		||||
using YamlDotNet.Serialization;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    public class Steps : IDisposable
 | 
			
		||||
    {
 | 
			
		||||
        private TestServer _ocelotServer;
 | 
			
		||||
        private HttpClient _ocelotClient;
 | 
			
		||||
        private HttpResponseMessage _response;
 | 
			
		||||
        private HttpContent _postContent;
 | 
			
		||||
        private BearerToken _token;
 | 
			
		||||
 | 
			
		||||
        public HttpClient OcelotClient => _ocelotClient;
 | 
			
		||||
 | 
			
		||||
        public void GivenThereIsAConfiguration(YamlConfiguration yamlConfiguration)
 | 
			
		||||
        {
 | 
			
		||||
            var configurationPath = TestConfiguration.ConfigurationPath;
 | 
			
		||||
 | 
			
		||||
            var serializer = new Serializer();
 | 
			
		||||
 | 
			
		||||
            if (File.Exists(configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(configurationPath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (TextWriter writer = File.CreateText(configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, yamlConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void GivenThereIsAConfiguration(YamlConfiguration yamlConfiguration, string configurationPath)
 | 
			
		||||
        {
 | 
			
		||||
            var serializer = new Serializer();
 | 
			
		||||
 | 
			
		||||
            if (File.Exists(configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                File.Delete(configurationPath);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            using (TextWriter writer = File.CreateText(configurationPath))
 | 
			
		||||
            {
 | 
			
		||||
                serializer.Serialize(writer, yamlConfiguration);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// This is annoying cos it should be in the constructor but we need to set up the yaml file before calling startup so its a step.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        public void GivenOcelotIsRunning()
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotServer = new TestServer(new WebHostBuilder()
 | 
			
		||||
                .UseStartup<Startup>());
 | 
			
		||||
 | 
			
		||||
            _ocelotClient = _ocelotServer.CreateClient();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void GivenIHaveAddedATokenToMyRequest()
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token.AccessToken);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void GivenIHaveAToken(string url)
 | 
			
		||||
        {
 | 
			
		||||
            var tokenUrl = $"{url}/connect/token";
 | 
			
		||||
            var formData = new List<KeyValuePair<string, string>>
 | 
			
		||||
            {
 | 
			
		||||
                new KeyValuePair<string, string>("client_id", "client"),
 | 
			
		||||
                new KeyValuePair<string, string>("client_secret", "secret"),
 | 
			
		||||
                new KeyValuePair<string, string>("scope", "api"),
 | 
			
		||||
                new KeyValuePair<string, string>("username", "test"),
 | 
			
		||||
                new KeyValuePair<string, string>("password", "test"),
 | 
			
		||||
                new KeyValuePair<string, string>("grant_type", "password")
 | 
			
		||||
            };
 | 
			
		||||
            var content = new FormUrlEncodedContent(formData);
 | 
			
		||||
 | 
			
		||||
            using (var httpClient = new HttpClient())
 | 
			
		||||
            {
 | 
			
		||||
                var response = httpClient.PostAsync(tokenUrl, content).Result;
 | 
			
		||||
                response.EnsureSuccessStatusCode();
 | 
			
		||||
                var responseContent = response.Content.ReadAsStringAsync().Result;
 | 
			
		||||
                _token = JsonConvert.DeserializeObject<BearerToken>(responseContent);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void WhenIGetUrlOnTheApiGateway(string url)
 | 
			
		||||
        {
 | 
			
		||||
            _response = _ocelotClient.GetAsync(url).Result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void WhenIPostUrlOnTheApiGateway(string url)
 | 
			
		||||
        {
 | 
			
		||||
            _response = _ocelotClient.PostAsync(url, _postContent).Result;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void GivenThePostHasContent(string postcontent)
 | 
			
		||||
        {
 | 
			
		||||
            _postContent = new StringContent(postcontent);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ThenTheResponseBodyShouldBe(string expectedBody)
 | 
			
		||||
        {
 | 
			
		||||
            _response.Content.ReadAsStringAsync().Result.ShouldBe(expectedBody);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ThenTheStatusCodeShouldBe(HttpStatusCode expectedHttpStatusCode)
 | 
			
		||||
        {
 | 
			
		||||
            _response.StatusCode.ShouldBe(expectedHttpStatusCode);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Dispose()
 | 
			
		||||
        {
 | 
			
		||||
            _ocelotClient?.Dispose();
 | 
			
		||||
            _ocelotServer?.Dispose();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										8
									
								
								test/Ocelot.AcceptanceTests/TestConfiguration.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								test/Ocelot.AcceptanceTests/TestConfiguration.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
namespace Ocelot.AcceptanceTests
 | 
			
		||||
{
 | 
			
		||||
    public static class TestConfiguration
 | 
			
		||||
    {
 | 
			
		||||
        public static double Version => 1.4;
 | 
			
		||||
        public static string ConfigurationPath => $"./bin/Debug/netcoreapp{Version}/configuration.yaml";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -42,29 +42,6 @@ namespace Ocelot.UnitTests.Configuration
 | 
			
		||||
                .BDDfy();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// long runnnig unit test to make sure repo thread safeok on
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void repo_is_thread_safe()
 | 
			
		||||
        {
 | 
			
		||||
            var tasks = new Task[100000];
 | 
			
		||||
            for (int i = 0; i < tasks.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                tasks[i] = Fire();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Task.WaitAll(tasks);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private async Task Fire()
 | 
			
		||||
        {
 | 
			
		||||
            var taskGuid = Guid.NewGuid().ToString();
 | 
			
		||||
            _repo.AddOrReplace(new FakeConfig(taskGuid));
 | 
			
		||||
            var configuration = _repo.Get();
 | 
			
		||||
            configuration.Data.ReRoutes[0].DownstreamTemplate.ShouldBe(taskGuid);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ThenTheConfigurationIsReturned()
 | 
			
		||||
        {
 | 
			
		||||
            _getResult.Data.ReRoutes[0].DownstreamTemplate.ShouldBe("initial");
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user