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 Newtonsoft.Json; using Ocelot.Configuration.File; using Ocelot.ManualTest; using Shouldly; using TestStack.BDDfy; using Xunit; namespace Ocelot.IntegrationTests { public class AdministrationTests : IDisposable { private readonly HttpClient _httpClient; private HttpResponseMessage _response; private IWebHost _builder; private readonly string _ocelotBaseUrl; private BearerToken _token; public AdministrationTests() { _httpClient = new HttpClient(); _ocelotBaseUrl = "http://localhost:5000"; _httpClient.BaseAddress = new Uri(_ocelotBaseUrl); } [Fact] public void should_return_response_401_with_call_re_routes_controller() { var configuration = new FileConfiguration { GlobalConfiguration = new FileGlobalConfiguration { AdministrationPath = "/administration" } }; this.Given(x => GivenThereIsAConfiguration(configuration)) .And(x => GivenOcelotIsRunning()) .When(x => WhenIGetUrlOnTheApiGateway("/administration/configuration")) .Then(x => ThenTheStatusCodeShouldBe(HttpStatusCode.Unauthorized)) .BDDfy(); } [Fact] public void should_return_response_200_with_call_re_routes_controller() { var configuration = new FileConfiguration { GlobalConfiguration = new FileGlobalConfiguration { AdministrationPath = "/administration" } }; this.Given(x => GivenThereIsAConfiguration(configuration)) .And(x => GivenOcelotIsRunning()) .And(x => GivenIHaveAnOcelotToken("/administration")) .And(x => GivenIHaveAddedATokenToMyRequest()) .When(x => WhenIGetUrlOnTheApiGateway("/administration/configuration")) .Then(x => ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .BDDfy(); } [Fact] public void should_return_file_configuration() { var configuration = new FileConfiguration { GlobalConfiguration = new FileGlobalConfiguration { AdministrationPath = "/administration" }, ReRoutes = new List() { new FileReRoute() { DownstreamHost = "localhost", DownstreamPort = 80, DownstreamScheme = "https", DownstreamPathTemplate = "/", UpstreamHttpMethod = "get", UpstreamPathTemplate = "/" }, new FileReRoute() { DownstreamHost = "localhost", DownstreamPort = 80, DownstreamScheme = "https", DownstreamPathTemplate = "/", UpstreamHttpMethod = "get", UpstreamPathTemplate = "/test" } } }; this.Given(x => GivenThereIsAConfiguration(configuration)) .And(x => GivenOcelotIsRunning()) .And(x => GivenIHaveAnOcelotToken("/administration")) .And(x => GivenIHaveAddedATokenToMyRequest()) .When(x => WhenIGetUrlOnTheApiGateway("/administration/configuration")) .Then(x => ThenTheStatusCodeShouldBe(HttpStatusCode.OK)) .And(x => ThenTheResponseShouldBe(configuration)) .BDDfy(); } private void ThenTheResponseShouldBe(FileConfiguration expected) { var response = JsonConvert.DeserializeObject(_response.Content.ReadAsStringAsync().Result); response.GlobalConfiguration.AdministrationPath.ShouldBe(expected.GlobalConfiguration.AdministrationPath); response.GlobalConfiguration.RequestIdKey.ShouldBe(expected.GlobalConfiguration.RequestIdKey); response.GlobalConfiguration.ServiceDiscoveryProvider.Host.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Host); response.GlobalConfiguration.ServiceDiscoveryProvider.Port.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Port); response.GlobalConfiguration.ServiceDiscoveryProvider.Provider.ShouldBe(expected.GlobalConfiguration.ServiceDiscoveryProvider.Provider); for (var i = 0; i < response.ReRoutes.Count; i++) { response.ReRoutes[i].DownstreamHost.ShouldBe(expected.ReRoutes[i].DownstreamHost); response.ReRoutes[i].DownstreamPathTemplate.ShouldBe(expected.ReRoutes[i].DownstreamPathTemplate); response.ReRoutes[i].DownstreamPort.ShouldBe(expected.ReRoutes[i].DownstreamPort); response.ReRoutes[i].DownstreamScheme.ShouldBe(expected.ReRoutes[i].DownstreamScheme); response.ReRoutes[i].UpstreamPathTemplate.ShouldBe(expected.ReRoutes[i].UpstreamPathTemplate); response.ReRoutes[i].UpstreamHttpMethod.ShouldBe(expected.ReRoutes[i].UpstreamHttpMethod); } } private void GivenIHaveAddedATokenToMyRequest() { _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _token.AccessToken); } private void GivenIHaveAnOcelotToken(string adminPath) { var tokenUrl = $"{adminPath}/connect/token"; var formData = new List> { new KeyValuePair("client_id", "admin"), new KeyValuePair("client_secret", "secret"), new KeyValuePair("scope", "admin"), new KeyValuePair("username", "admin"), new KeyValuePair("password", "admin"), new KeyValuePair("grant_type", "password") }; var content = new FormUrlEncodedContent(formData); var response = _httpClient.PostAsync(tokenUrl, content).Result; var responseContent = response.Content.ReadAsStringAsync().Result; response.EnsureSuccessStatusCode(); _token = JsonConvert.DeserializeObject(responseContent); } private void GivenOcelotIsRunning() { _builder = new WebHostBuilder() .UseUrls(_ocelotBaseUrl) .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseStartup() .Build(); _builder.Start(); } private void GivenThereIsAConfiguration(FileConfiguration fileConfiguration) { var configurationPath = $"{Directory.GetCurrentDirectory()}/configuration.json"; var jsonConfiguration = JsonConvert.SerializeObject(fileConfiguration); if (File.Exists(configurationPath)) { File.Delete(configurationPath); } File.WriteAllText(configurationPath, jsonConfiguration); configurationPath = $"{AppContext.BaseDirectory}/configuration.json"; if (File.Exists(configurationPath)) { File.Delete(configurationPath); } File.WriteAllText(configurationPath, jsonConfiguration); } private void WhenIGetUrlOnTheApiGateway(string url) { _response = _httpClient.GetAsync(url).Result; } private void ThenTheStatusCodeShouldBe(HttpStatusCode expectedHttpStatusCode) { _response.StatusCode.ShouldBe(expectedHttpStatusCode); } public void Dispose() { _builder?.Dispose(); _httpClient?.Dispose(); } } }