Ocelot/test/Ocelot.UnitTests/Middleware/SimpleJsonResponseAggregatorTests.cs
Thiago Loureiro cfa3fedc53
Release/13.2.0 (#834)
* Fix formatting in getting started page (#752)

* updated release docs (#745)

* Update README.md (#756)

Fixed typo "Ocleot"

* Fixed typo there => their (#763)

* Some Typo fixes (#765)

* Typo algorythm => algorithm (#764)

* Typo querystring => query string (#766)

* Typo usual => usually (#767)

* Typos (#768)

* kubernetes provider (#772)

* feat: Kubernetes ServiceDiscoveryProvider

* 编写k8s测试例子

* feat:fix kube config

* feat: remove port

* feat : complete the k8s test

* feat :  add kubeserviceDiscovery test

* feat : add kube provider unittest

* feat :add kubetnetes docs

how to use ocelot with kubetnetes docs

* keep the configuration as simple as possible, no qos, no cache

* fix: use http

* add PollingKubeServiceDiscovery

* feat : refactor logger

* feat : add  pollkube docs

* feat:Remove unnecessary code

* feat : code-block json

* fix issue #661 for Advanced aggregations (#704)

* Add Advanced Aggregation Feature

* fix overwrite error

* distinct data for better performance

* remove constructor parameter

* fix tests issue

* fix tests

* fix tests issue

* Add UnitTest and AcceptanceTest

* fix responseKeys typo

* Update SimpleJsonResponseAggregator.cs

* change port

* Fix code example for SSL Errors (#780)

DangerousAcceptAnyServerCertificateValidator has to be set to "true" to disable certification validation, not "false".

* Changed wording for ease of reading (#776)

Just some wording changes for clarification.

* Ignore response content if null (fix #785) (#786)

* fix bug #791 (#795)

* Update loadbalancer.rst (#796)

* UriBuilder - remove leading question mark #747 (#794)

* Update qualityofservice.rst (#801)

Tiny typo

* K8s package (#804)

* feat: Kubernetes ServiceDiscoveryProvider

* 编写k8s测试例子

* feat:fix kube config

* feat: remove port

* feat : complete the k8s test

* feat :  add kubeserviceDiscovery test

* feat : add kube provider unittest

* feat :add kubetnetes docs

how to use ocelot with kubetnetes docs

* keep the configuration as simple as possible, no qos, no cache

* fix: use http

* add PollingKubeServiceDiscovery

* feat : refactor logger

* feat : add  pollkube docs

* feat:Remove unnecessary code

* feat : code-block json

* feat: publish package Ocelot.Provider.Kubernetes

* Okta integration (#807)

Okta integration

* update cliamsParser (#798)

* update cliamsParser

* update using

* IOcelotBuilder opens the IMvcCoreBuilder property for easy customization (#790)

* IOcelotBuilder opens the IMvcCoreBuilder property for easy customization

* Adjustment code

* nuget package (#809)

* feat: Kubernetes ServiceDiscoveryProvider

* 编写k8s测试例子

* feat:fix kube config

* feat: remove port

* feat : complete the k8s test

* feat :  add kubeserviceDiscovery test

* feat : add kube provider unittest

* feat :add kubetnetes docs

how to use ocelot with kubetnetes docs

* keep the configuration as simple as possible, no qos, no cache

* fix: use http

* add PollingKubeServiceDiscovery

* feat : refactor logger

* feat : add  pollkube docs

* feat:Remove unnecessary code

* feat : code-block json

* feat: publish package Ocelot.Provider.Kubernetes

* feat : nuget package

* fix: Namesapce Spelling wrong

* fix:Namesapce Spelling Wrong

* Fix: errors when using rate limiting (#811)

* Fix: errors when using rate limiting
Add: QuotaExceededError class for requesting too much
Add: QuotaExceededError error code
Add: Add an error when limit is reached
Reflact: Extract GetResponseMessage method for getting default or configured response message for requ

* Fix: modify check_we_have_considered_all_errors_in_these_tests for adding a new OcelotErrorCode

* added missing COPY csproj files (#821)

* Add note on In-Process hosting (#816)

When using ASP.NET Core 2.2 with In-Process hosting in IIS it's important to use .UseIIS() instead of .UseIISIntegration().

* Fix bug: (#810)

If the registered Consul node is unexpectedly down and not restarted immediately, other services should continue to find the registered service.

* Fixed Dockerfile (missing Kubernetes)

* Revert "Fix bug: (#810)" (#823)

This reverts commit 19c80afb05290fac3a144f652cd663c8b513a559.

* remove duplicate `IHttpRequester` register (#819)

* remove duplicate `IHttpRequester` register

* reserve the first

* fix HttpRequesterMiddleware does not call next bug (#830)

call next so that we can do something with the response, such as add some custom header etc...

* Removed Packing to fix issues, will be sorted out after create a nuget package on Nuget.Org (#831)

* Allows access to unpass node (#825)

* Fix bug:
If the registered Consul node is unexpectedly down and not restarted immediately, other services should continue to find the registered service.

* fix bug:
If the registered Consul node is unexpectedly down and not restarted immediately, other services should continue to find the registered service.

* Updated FluentValidations Nuget Package (#833)
2019-03-22 23:39:53 +01:00

225 lines
9.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Text;
using Castle.Components.DictionaryAdapter;
using Microsoft.AspNetCore.Http;
using Ocelot.Configuration;
using Ocelot.Configuration.Builder;
using Ocelot.Configuration.File;
using Ocelot.Middleware;
using Ocelot.Middleware.Multiplexer;
using Ocelot.UnitTests.Responder;
using Ocelot.Values;
using Shouldly;
using TestStack.BDDfy;
using Xunit;
namespace Ocelot.UnitTests.Middleware
{
public class SimpleJsonResponseAggregatorTests
{
private readonly SimpleJsonResponseAggregator _aggregator;
private List<DownstreamContext> _downstreamContexts;
private DownstreamContext _upstreamContext;
private ReRoute _reRoute;
public SimpleJsonResponseAggregatorTests()
{
_aggregator = new SimpleJsonResponseAggregator();
}
[Fact]
public void should_aggregate_n_responses_and_set_response_content_on_upstream_context_withConfig()
{
var commentsDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Comments").Build();
var userDetailsDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("UserDetails")
.WithUpstreamPathTemplate(new UpstreamPathTemplate("", 0, false, "/v1/users/{userId}"))
.Build();
var downstreamReRoutes = new List<DownstreamReRoute>
{
commentsDownstreamReRoute,
userDetailsDownstreamReRoute
};
var reRoute = new ReRouteBuilder()
.WithDownstreamReRoutes(downstreamReRoutes)
.WithAggregateReRouteConfig(new List<AggregateReRouteConfig>()
{
new AggregateReRouteConfig(){ReRouteKey = "UserDetails",JsonPath = "$[*].writerId",Parameter = "userId"}
})
.Build();
var commentsResponseContent = @"[{""id"":1,""writerId"":1,""postId"":1,""text"":""text1""},{""id"":2,""writerId"":2,""postId"":2,""text"":""text2""},{""id"":3,""writerId"":2,""postId"":1,""text"":""text21""}]";
var commentsDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse = new DownstreamResponse(new StringContent(commentsResponseContent, Encoding.UTF8, "application/json"), HttpStatusCode.OK, new EditableList<KeyValuePair<string, IEnumerable<string>>>(), "some reason"),
DownstreamReRoute = commentsDownstreamReRoute
};
var userDetailsResponseContent = @"[{""id"":1,""firstName"":""abolfazl"",""lastName"":""rajabpour""},{""id"":2,""firstName"":""reza"",""lastName"":""rezaei""}]";
var userDetailsDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse = new DownstreamResponse(new StringContent(userDetailsResponseContent, Encoding.UTF8, "application/json"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"),
DownstreamReRoute = userDetailsDownstreamReRoute
};
var downstreamContexts = new List<DownstreamContext> { commentsDownstreamContext, userDetailsDownstreamContext };
var expected = "{\"Comments\":" + commentsResponseContent + ",\"UserDetails\":" + userDetailsResponseContent + "}";
this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
.And(x => GivenTheReRoute(reRoute))
.And(x => GivenTheDownstreamContext(downstreamContexts))
.When(x => WhenIAggregate())
.Then(x => ThenTheContentIs(expected))
.And(x => ThenTheContentTypeIs("application/json"))
.And(x => ThenTheReasonPhraseIs("cannot return from aggregate..which reason phrase would you use?"))
.BDDfy();
}
[Fact]
public void should_aggregate_n_responses_and_set_response_content_on_upstream_context()
{
var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
var downstreamReRoutes = new List<DownstreamReRoute>
{
billDownstreamReRoute,
georgeDownstreamReRoute
};
var reRoute = new ReRouteBuilder()
.WithDownstreamReRoutes(downstreamReRoutes)
.Build();
var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse = new DownstreamResponse(new StringContent("Bill says hi"), HttpStatusCode.OK, new EditableList<KeyValuePair<string, IEnumerable<string>>>(), "some reason"),
DownstreamReRoute = billDownstreamReRoute
};
var georgeDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse = new DownstreamResponse(new StringContent("George says hi"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"),
DownstreamReRoute = georgeDownstreamReRoute
};
var downstreamContexts = new List<DownstreamContext> { billDownstreamContext, georgeDownstreamContext };
var expected = "{\"Bill\":Bill says hi,\"George\":George says hi}";
this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
.And(x => GivenTheReRoute(reRoute))
.And(x => GivenTheDownstreamContext(downstreamContexts))
.When(x => WhenIAggregate())
.Then(x => ThenTheContentIs(expected))
.And(x => ThenTheContentTypeIs("application/json"))
.And(x => ThenTheReasonPhraseIs("cannot return from aggregate..which reason phrase would you use?"))
.BDDfy();
}
[Fact]
public void should_return_error_if_any_downstreams_have_errored()
{
var billDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("Bill").Build();
var georgeDownstreamReRoute = new DownstreamReRouteBuilder().WithKey("George").Build();
var downstreamReRoutes = new List<DownstreamReRoute>
{
billDownstreamReRoute,
georgeDownstreamReRoute
};
var reRoute = new ReRouteBuilder()
.WithDownstreamReRoutes(downstreamReRoutes)
.Build();
var billDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse = new DownstreamResponse(new StringContent("Bill says hi"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"),
DownstreamReRoute = billDownstreamReRoute
};
var georgeDownstreamContext = new DownstreamContext(new DefaultHttpContext())
{
DownstreamResponse = new DownstreamResponse(new StringContent("Error"), HttpStatusCode.OK, new List<KeyValuePair<string, IEnumerable<string>>>(), "some reason"),
DownstreamReRoute = georgeDownstreamReRoute,
};
georgeDownstreamContext.Errors.Add(new AnyError());
var downstreamContexts = new List<DownstreamContext> { billDownstreamContext, georgeDownstreamContext };
var expected = "Error";
this.Given(x => GivenTheUpstreamContext(new DownstreamContext(new DefaultHttpContext())))
.And(x => GivenTheReRoute(reRoute))
.And(x => GivenTheDownstreamContext(downstreamContexts))
.When(x => WhenIAggregate())
.Then(x => ThenTheContentIs(expected))
.And(x => ThenTheErrorIsMapped())
.BDDfy();
}
private void ThenTheReasonPhraseIs(string expected)
{
_upstreamContext.DownstreamResponse.ReasonPhrase.ShouldBe(expected);
}
private void ThenTheErrorIsMapped()
{
_upstreamContext.Errors.ShouldBe(_downstreamContexts[1].Errors);
_upstreamContext.DownstreamResponse.ShouldBe(_downstreamContexts[1].DownstreamResponse);
}
private void GivenTheReRoute(ReRoute reRoute)
{
_reRoute = reRoute;
}
private void GivenTheUpstreamContext(DownstreamContext upstreamContext)
{
_upstreamContext = upstreamContext;
}
private void GivenTheDownstreamContext(List<DownstreamContext> downstreamContexts)
{
_downstreamContexts = downstreamContexts;
}
private void WhenIAggregate()
{
_aggregator.Aggregate(_reRoute, _upstreamContext, _downstreamContexts).GetAwaiter().GetResult();
}
private void ThenTheContentIs(string expected)
{
var content = _upstreamContext.DownstreamResponse.Content.ReadAsStringAsync()
.GetAwaiter()
.GetResult();
content.ShouldBe(expected);
}
private void ThenTheContentTypeIs(string expected)
{
_upstreamContext.DownstreamResponse.Content.Headers.ContentType.MediaType.ShouldBe(expected);
}
private void ThenTheUpstreamContextIsMappedForNonAggregate()
{
_upstreamContext.DownstreamRequest.ShouldBe(_downstreamContexts[0].DownstreamRequest);
_upstreamContext.DownstreamResponse.ShouldBe(_downstreamContexts[0].DownstreamResponse);
_upstreamContext.Errors.ShouldBe(_downstreamContexts[0].Errors);
}
}
}