mirror of
https://github.com/DuendeSoftware/products
synced 2026-05-24 09:28:24 +00:00
Adds tests for yarp transformers and makes the request config configurable. (#2071)
* integration test for yarp transform * introduce tests for timeouts
This commit is contained in:
parent
6cd370ebc6
commit
346cb75d43
11 changed files with 178 additions and 73 deletions
|
|
@ -6,6 +6,7 @@ using Microsoft.AspNetCore.Builder;
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Yarp.ReverseProxy.Forwarder;
|
||||
using Yarp.ReverseProxy.Transforms.Builder;
|
||||
|
||||
namespace Duende.Bff.Yarp;
|
||||
|
|
@ -18,19 +19,31 @@ public static class RouteBuilderExtensions
|
|||
/// <summary>
|
||||
/// Adds a remote BFF API endpoint
|
||||
/// </summary>
|
||||
/// <param name="endpoints"></param>
|
||||
/// <param name="localPath"></param>
|
||||
/// <param name="apiAddress"></param>
|
||||
/// <param name="yarpTransformBuilder"></param>
|
||||
/// <returns></returns>
|
||||
/// <param name="endpoints">The endpoint route builder to add the endpoint to.</param>
|
||||
/// <param name="localPath">The local path pattern for the BFF API endpoint.</param>
|
||||
/// <param name="apiAddress">The remote API address to which requests will be forwarded.</param>
|
||||
/// <param name="yarpTransformBuilder">
|
||||
/// Optional. An action to configure YARP transforms for this proxy request.
|
||||
/// If not provided, a default transform builder is used.
|
||||
/// </param>
|
||||
/// <param name="requestConfig">
|
||||
/// Optional. Additional configuration for the forwarded request, such as timeouts or activity propagation.
|
||||
/// If not specified, the default yarp configuration is used.
|
||||
/// </param>
|
||||
/// <returns>An <see cref="IEndpointConventionBuilder"/> for further configuration of the endpoint.</returns>
|
||||
public static IEndpointConventionBuilder MapRemoteBffApiEndpoint(
|
||||
this IEndpointRouteBuilder endpoints,
|
||||
PathString localPath,
|
||||
Uri apiAddress,
|
||||
Action<TransformBuilderContext>? yarpTransformBuilder = null)
|
||||
Action<TransformBuilderContext>? yarpTransformBuilder = null,
|
||||
ForwarderRequestConfig? requestConfig = null
|
||||
)
|
||||
{
|
||||
endpoints.CheckLicense();
|
||||
|
||||
// See if a default request config is registered in DI, otherwise use an empty one
|
||||
requestConfig ??= endpoints.ServiceProvider.GetService<ForwarderRequestConfig>() ?? ForwarderRequestConfig.Empty;
|
||||
|
||||
// Configure the yarp transform pipeline. Either use the one provided or the default
|
||||
yarpTransformBuilder ??= context =>
|
||||
{
|
||||
|
|
@ -45,7 +58,8 @@ public static class RouteBuilderExtensions
|
|||
|
||||
// Try to resolve the ITransformBuilder from DI. If it is not registered,
|
||||
// throw a clearer exception. Otherwise, the call below fails with a less clear exception.
|
||||
var _ = endpoints.ServiceProvider.GetService<ITransformBuilder>() ?? throw new InvalidOperationException("No ITransformBuilder has been registered. Have you called BffBuilder.AddRemoteApis()");
|
||||
_ = endpoints.ServiceProvider.GetService<ITransformBuilder>()
|
||||
?? throw new InvalidOperationException("No ITransformBuilder has been registered. Have you called BffBuilder.AddRemoteApis()");
|
||||
|
||||
return endpoints.MapForwarder(
|
||||
pattern: localPath.Add("/{**catch-all}").Value!,
|
||||
|
|
@ -53,7 +67,8 @@ public static class RouteBuilderExtensions
|
|||
configureTransform: context =>
|
||||
{
|
||||
yarpTransformBuilder(context);
|
||||
})
|
||||
},
|
||||
requestConfig: requestConfig)
|
||||
.WithMetadata(new BffRemoteApiEndpointMetadata());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public class BffFrontendIndexTests : BffTestBase
|
|||
await Bff.BrowserClient.Login()
|
||||
.CheckResponseContent(Cdn.IndexHtml);
|
||||
|
||||
var result = await Bff.BrowserClient.CallBffHostApi(The.SubPath);
|
||||
var result = await Bff.BrowserClient.CallBffHostApi(The.PathAndSubPath);
|
||||
}
|
||||
[Fact]
|
||||
public async Task Given_index_can_call_local_api()
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ public class BffRemoteApiTests : BffTestBase
|
|||
|
||||
await Bff.BrowserClient.Login();
|
||||
|
||||
ApiCallDetails result = await Bff.BrowserClient.CallBffHostApi(The.SubPath);
|
||||
ApiCallDetails result = await Bff.BrowserClient.CallBffHostApi(The.PathAndSubPath);
|
||||
result.Sub.ShouldBe(The.Sub);
|
||||
}
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ public class BffRemoteApiTests : BffTestBase
|
|||
})
|
||||
);
|
||||
|
||||
ApiCallDetails result = await Bff.BrowserClient.CallBffHostApi(The.SubPath);
|
||||
ApiCallDetails result = await Bff.BrowserClient.CallBffHostApi(The.PathAndSubPath);
|
||||
result.Sub.ShouldBeNull();
|
||||
|
||||
if (requiredTokenType == RequiredTokenType.UserOrClient || requiredTokenType == RequiredTokenType.Client)
|
||||
|
|
@ -90,7 +90,7 @@ public class BffRemoteApiTests : BffTestBase
|
|||
})
|
||||
);
|
||||
|
||||
await Bff.BrowserClient.CallBffHostApi(The.SubPath,
|
||||
await Bff.BrowserClient.CallBffHostApi(The.PathAndSubPath,
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public class DPoPTestsWithManualAuthentication : BffTestBase, IAsyncLifetime
|
|||
{
|
||||
|
||||
ApiCallDetails callToApi = await Bff.BrowserClient.CallBffHostApi(
|
||||
url: Bff.Url(The.SubPath)
|
||||
url: Bff.Url(The.PathAndSubPath)
|
||||
);
|
||||
|
||||
callToApi.RequestHeaders["DPoP"].First().ShouldNotBeNullOrEmpty();
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public class DpopRemoteEndpointTests : BffTestBase, IAsyncLifetime
|
|||
{
|
||||
|
||||
ApiCallDetails callToApi = await Bff.BrowserClient.CallBffHostApi(
|
||||
url: Bff.Url(The.SubPath)
|
||||
url: Bff.Url(The.PathAndSubPath)
|
||||
);
|
||||
|
||||
callToApi.RequestHeaders["DPoP"].First().ShouldNotBeNullOrEmpty();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System.Net;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Json;
|
||||
using Duende.Bff.AccessTokenManagement;
|
||||
using Duende.Bff.Configuration;
|
||||
using Duende.Bff.DynamicFrontends;
|
||||
|
|
@ -16,6 +15,7 @@ using Duende.IdentityServer.Services;
|
|||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Xunit.Abstractions;
|
||||
using Yarp.ReverseProxy.Forwarder;
|
||||
using Yarp.ReverseProxy.Transforms;
|
||||
using Yarp.ReverseProxy.Transforms.Builder;
|
||||
using Resource = Duende.Bff.AccessTokenManagement.Resource;
|
||||
|
|
@ -611,57 +611,146 @@ public class RemoteEndpointTests : BffTestBase
|
|||
}
|
||||
|
||||
[Theory, MemberData(nameof(AllSetups))]
|
||||
public async Task endpoint_can_be_configured_with_custom_transform(BffSetupType setup)
|
||||
public async Task MapRemoteBffApiEndpoint_can_override_default_transform(BffSetupType setup)
|
||||
{
|
||||
Bff.OnConfigureEndpoints += app =>
|
||||
{
|
||||
app.MapRemoteBffApiEndpoint(The.Path, Api.Url(The.Path),
|
||||
c =>
|
||||
app.MapRemoteBffApiEndpoint(The.Path, Api.Url(The.Path), c =>
|
||||
{
|
||||
DefaultBffYarpTransformerBuilders.DirectProxyWithAccessToken(The.Path, c);
|
||||
c.AddRequestHeader("custom", "with value");
|
||||
// Add a transform that adds the catchall route value to a header
|
||||
c.AddRequestTransform(async context =>
|
||||
{
|
||||
c.CopyRequestHeaders = true;
|
||||
DefaultBffYarpTransformerBuilders.DirectProxyWithAccessToken(The.Path, c);
|
||||
})
|
||||
.WithAccessToken(RequiredTokenType.UserOrClient)
|
||||
.SkipAntiforgery();
|
||||
// One of our customers asked how to access the catch-all route value in subsequent transforms
|
||||
if (context.HttpContext.Request.RouteValues.TryGetValue("catch-all", out var value) && value is string s)
|
||||
{
|
||||
context.ProxyRequest.Headers.Add("catch-all", "/" + s);
|
||||
}
|
||||
await Task.CompletedTask;
|
||||
});
|
||||
})
|
||||
.WithAccessToken();
|
||||
};
|
||||
ConfigureBff(setup);
|
||||
|
||||
await InitializeAsync();
|
||||
await Bff.BrowserClient.Login();
|
||||
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, Bff.Url(The.Path));
|
||||
req.Headers.Add("x-csrf", "1");
|
||||
req.Headers.Add("my-header-to-be-copied-by-yarp", "copied-value");
|
||||
var response = await Bff.BrowserClient.SendAsync(req);
|
||||
ApiCallDetails result = await Bff.BrowserClient.CallBffHostApi(
|
||||
url: Bff.Url(The.PathAndSubPath)
|
||||
);
|
||||
|
||||
response.IsSuccessStatusCode.ShouldBeTrue();
|
||||
response.Content.Headers.ContentType!.MediaType.ShouldBe("application/json");
|
||||
var json = await response.Content.ReadAsStringAsync();
|
||||
var apiResult = JsonSerializer.Deserialize<ApiCallDetails>(json).ShouldNotBeNull();
|
||||
apiResult.RequestHeaders["my-header-to-be-copied-by-yarp"].First().ShouldBe("copied-value");
|
||||
result.RequestHeaders.Keys.ShouldNotContain("added-by-custom-default-transform");
|
||||
result.RequestHeaders.TryGetValue("custom", out var customValue).ShouldBeTrue();
|
||||
customValue.ShouldBe(["with value"],
|
||||
"The custom header should be added by the custom transform registered in the test.");
|
||||
|
||||
response.Content.Headers.Select(x => x.Key).ShouldNotContain("added-by-custom-default-transform",
|
||||
"a custom transform doesn't run the defaults");
|
||||
result.RequestHeaders.TryGetValue("catch-all", out var catchAll).ShouldBeTrue();
|
||||
catchAll.ShouldBe([The.SubPath],
|
||||
"The catch-all route value should be added to the request headers by the custom transform registered in the test.");
|
||||
}
|
||||
|
||||
// now I don't like timeouts in tests, but I don't know of a better way to create http timeouts.
|
||||
[Theory, MemberData(nameof(AllSetups))]
|
||||
public async Task can_disable_anti_forgery_check(BffSetupType setup)
|
||||
public async Task Can_register_default_forwarder_config_for_MapRemoteBffApiEndpoint(BffSetupType setup)
|
||||
{
|
||||
var shouldDelay = false;
|
||||
|
||||
Api.OnConfigure += app =>
|
||||
{
|
||||
app.Use(async (c, n) =>
|
||||
{
|
||||
if (shouldDelay)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
await n();
|
||||
});
|
||||
};
|
||||
|
||||
Bff.OnConfigureServices += services =>
|
||||
{
|
||||
// Add a default ForwarderRequestConfig that has a 100 ms timeout
|
||||
services.AddSingleton(new ForwarderRequestConfig()
|
||||
{
|
||||
ActivityTimeout = TimeSpan.FromMilliseconds(100)
|
||||
});
|
||||
};
|
||||
|
||||
Bff.OnConfigureEndpoints += app =>
|
||||
{
|
||||
app.MapRemoteBffApiEndpoint(The.Path, Api.Url(The.Path))
|
||||
.WithAccessToken(RequiredTokenType.None);
|
||||
app.MapRemoteBffApiEndpoint(
|
||||
localPath: The.Path,
|
||||
apiAddress: Api.Url(The.Path))
|
||||
.WithAccessToken();
|
||||
};
|
||||
|
||||
ConfigureBff(setup);
|
||||
|
||||
await InitializeAsync();
|
||||
await Bff.BrowserClient.Login();
|
||||
|
||||
Bff.BffOptions.DisableAntiForgeryCheck = (c) => true;
|
||||
// first, ensure that the 'normal' process works, becuase delay's are turned off.
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
url: Bff.Url(The.PathAndSubPath)
|
||||
);
|
||||
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, Bff.Url(The.Path));
|
||||
var response = await Bff.BrowserClient.SendAsync(req);
|
||||
// turn on delays. Now the timeout of 100 ms should kick in.
|
||||
shouldDelay = true;
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
url: Bff.Url(The.PathAndSubPath),
|
||||
expectedStatusCode: HttpStatusCode.BadGateway
|
||||
);
|
||||
}
|
||||
|
||||
// now I don't like timeouts in tests, but I don't know of a better way to create http timeouts.
|
||||
[Theory, MemberData(nameof(AllSetups))]
|
||||
public async Task MapRemoteBffApiEndpoint_can_override_config_to_configure_a_timeout(BffSetupType setup)
|
||||
{
|
||||
var shouldDelay = false;
|
||||
|
||||
Api.OnConfigure += app =>
|
||||
{
|
||||
app.Use(async (c, n) =>
|
||||
{
|
||||
if (shouldDelay)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromSeconds(5));
|
||||
}
|
||||
await n();
|
||||
});
|
||||
};
|
||||
|
||||
Bff.OnConfigureEndpoints += app =>
|
||||
{
|
||||
app.MapRemoteBffApiEndpoint(
|
||||
localPath: The.Path,
|
||||
apiAddress: Api.Url(The.Path),
|
||||
requestConfig: new ForwarderRequestConfig()
|
||||
{
|
||||
// 100 ms timeout, which is not too short that the normal process might fail,
|
||||
// but not too long that the test will take forever
|
||||
ActivityTimeout = TimeSpan.FromMilliseconds(100)
|
||||
})
|
||||
.WithAccessToken();
|
||||
};
|
||||
|
||||
ConfigureBff(setup);
|
||||
await InitializeAsync();
|
||||
await Bff.BrowserClient.Login();
|
||||
|
||||
// first, ensure that the 'normal' process works, becuase delay's are turned off.
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
url: Bff.Url(The.PathAndSubPath)
|
||||
);
|
||||
|
||||
// turn on delays. Now the timeout of 100 ms should kick in.
|
||||
shouldDelay = true;
|
||||
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
url: Bff.Url(The.PathAndSubPath),
|
||||
expectedStatusCode: HttpStatusCode.BadGateway
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ public class YarpTests : BffTestBase
|
|||
await InitializeAsync();
|
||||
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
expectedStatusCode: HttpStatusCode.OK
|
||||
);
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ public class YarpTests : BffTestBase
|
|||
ConfigureYarp(Some.RouteConfig().WithAntiforgeryCheck());
|
||||
await InitializeAsync();
|
||||
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, The.SubPath);
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, The.PathAndSubPath);
|
||||
var response = await Bff.BrowserClient.SendAsync(req);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.Unauthorized);
|
||||
|
|
@ -70,7 +70,7 @@ public class YarpTests : BffTestBase
|
|||
ConfigureYarp(Some.RouteConfig().WithAntiforgeryCheck());
|
||||
await InitializeAsync();
|
||||
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, The.SubPath);
|
||||
var req = new HttpRequestMessage(HttpMethod.Get, The.PathAndSubPath);
|
||||
var response = await Bff.BrowserClient.SendAsync(req);
|
||||
|
||||
response.StatusCode.ShouldBe(HttpStatusCode.OK);
|
||||
|
|
@ -85,7 +85,7 @@ public class YarpTests : BffTestBase
|
|||
await InitializeAsync();
|
||||
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
expectedStatusCode: HttpStatusCode.OK
|
||||
);
|
||||
}
|
||||
|
|
@ -99,7 +99,7 @@ public class YarpTests : BffTestBase
|
|||
await InitializeAsync();
|
||||
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
}
|
||||
|
|
@ -113,12 +113,12 @@ public class YarpTests : BffTestBase
|
|||
await InitializeAsync();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
expectedStatusCode: HttpStatusCode.OK
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Get);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBeNull();
|
||||
apiResult.ClientId.ShouldBeNull();
|
||||
}
|
||||
|
|
@ -136,12 +136,12 @@ public class YarpTests : BffTestBase
|
|||
await InitializeAsync();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
expectedStatusCode: HttpStatusCode.OK
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Get);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBeNull();
|
||||
apiResult.ClientId.ShouldBeNull();
|
||||
}
|
||||
|
|
@ -156,11 +156,11 @@ public class YarpTests : BffTestBase
|
|||
await Bff.BrowserClient.Login();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath
|
||||
path: The.PathAndSubPath
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Get);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBe(The.Sub);
|
||||
apiResult.ClientId.ShouldBe(The.ClientId);
|
||||
}
|
||||
|
|
@ -178,12 +178,12 @@ public class YarpTests : BffTestBase
|
|||
await Bff.BrowserClient.Login();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
method: HttpMethod.Put
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Put);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBe(The.Sub);
|
||||
apiResult.ClientId.ShouldBe(The.ClientId);
|
||||
}
|
||||
|
|
@ -198,12 +198,12 @@ public class YarpTests : BffTestBase
|
|||
await Bff.BrowserClient.Login();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
method: HttpMethod.Post
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Post);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBe(The.Sub);
|
||||
apiResult.ClientId.ShouldBe(The.ClientId);
|
||||
}
|
||||
|
|
@ -218,12 +218,12 @@ public class YarpTests : BffTestBase
|
|||
await Bff.BrowserClient.Login();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
method: HttpMethod.Post
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Post);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBe(The.Sub);
|
||||
apiResult.ClientId.ShouldBe(The.ClientId);
|
||||
}
|
||||
|
|
@ -238,11 +238,11 @@ public class YarpTests : BffTestBase
|
|||
await Bff.BrowserClient.Login();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath
|
||||
path: The.PathAndSubPath
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Get);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBeNull();
|
||||
apiResult.ClientId.ShouldBe(The.ClientId);
|
||||
}
|
||||
|
|
@ -257,11 +257,11 @@ public class YarpTests : BffTestBase
|
|||
await Bff.BrowserClient.Login();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath
|
||||
path: The.PathAndSubPath
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Get);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBe(The.Sub);
|
||||
apiResult.ClientId.ShouldBe(The.ClientId);
|
||||
}
|
||||
|
|
@ -288,11 +288,11 @@ public class YarpTests : BffTestBase
|
|||
|
||||
await Bff.BrowserClient.Login("/somepath");
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(
|
||||
path: "/somepath" + The.SubPath
|
||||
path: "/somepath" + The.PathAndSubPath
|
||||
);
|
||||
|
||||
apiResult.Method.ShouldBe(HttpMethod.Get);
|
||||
apiResult.Path.ShouldBe(The.SubPath);
|
||||
apiResult.Path.ShouldBe(The.PathAndSubPath);
|
||||
apiResult.Sub.ShouldBe(The.Sub);
|
||||
apiResult.ClientId.ShouldBe(The.ClientId);
|
||||
}
|
||||
|
|
@ -308,7 +308,7 @@ public class YarpTests : BffTestBase
|
|||
await Bff.BrowserClient.Login();
|
||||
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
expectedStatusCode: HttpStatusCode.Unauthorized
|
||||
);
|
||||
}
|
||||
|
|
@ -324,7 +324,7 @@ public class YarpTests : BffTestBase
|
|||
await Bff.BrowserClient.Login();
|
||||
|
||||
await Bff.BrowserClient.CallBffHostApi(
|
||||
path: The.SubPath,
|
||||
path: The.PathAndSubPath,
|
||||
expectedStatusCode: HttpStatusCode.Forbidden
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ public class ApiAndBffUseForwardedHeaders : BffTestBase, IAsyncLifetime
|
|||
public async Task bff_host_name_should_propagate_to_api()
|
||||
{
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(The.SubPath);
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(The.PathAndSubPath);
|
||||
|
||||
var host = apiResult.RequestHeaders["Host"].Single();
|
||||
host.ShouldBe(Bff.Url().Host);
|
||||
|
|
@ -55,7 +55,7 @@ public class ApiAndBffUseForwardedHeaders : BffTestBase, IAsyncLifetime
|
|||
[Fact]
|
||||
public async Task forwarded_host_name_with_header_forwarding_should_propagate_to_api()
|
||||
{
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(The.SubPath,
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(The.PathAndSubPath,
|
||||
headers: new()
|
||||
{
|
||||
["x-csrf"] = "1",
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class ApiUseForwardedHeaders : BffTestBase
|
|||
{
|
||||
await InitializeAsync();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(The.SubPath);
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(The.PathAndSubPath);
|
||||
|
||||
var host = apiResult.RequestHeaders["Host"].Single();
|
||||
host.ShouldBe(Bff.Url().Host);
|
||||
|
|
@ -47,7 +47,7 @@ public class ApiUseForwardedHeaders : BffTestBase
|
|||
{
|
||||
await InitializeAsync();
|
||||
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(The.SubPath,
|
||||
ApiCallDetails apiResult = await Bff.BrowserClient.CallBffHostApi(The.PathAndSubPath,
|
||||
headers: new()
|
||||
{
|
||||
["x-csrf"] = "1",
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@
|
|||
}
|
||||
public static class RouteBuilderExtensions
|
||||
{
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapRemoteBffApiEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, Microsoft.AspNetCore.Http.PathString localPath, System.Uri apiAddress, System.Action<Yarp.ReverseProxy.Transforms.Builder.TransformBuilderContext>? yarpTransformBuilder = null) { }
|
||||
public static Microsoft.AspNetCore.Builder.IEndpointConventionBuilder MapRemoteBffApiEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, Microsoft.AspNetCore.Http.PathString localPath, System.Uri apiAddress, System.Action<Yarp.ReverseProxy.Transforms.Builder.TransformBuilderContext>? yarpTransformBuilder = null, Yarp.ReverseProxy.Forwarder.ForwarderRequestConfig? requestConfig = null) { }
|
||||
}
|
||||
public sealed class UserAccessTokenParameters : System.IEquatable<Duende.Bff.Yarp.UserAccessTokenParameters>
|
||||
{
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ public class TestData
|
|||
public Origin Origin = Origin.Parse($"https://{PropertyName()}:1234");
|
||||
public int Port = 1234;
|
||||
public PathString Path = new PathString($"/{PropertyName()}");
|
||||
public PathString SubPath = new PathString($"/{PropertyName(nameof(Path))}/{PropertyName()}");
|
||||
public PathString SubPath = new PathString($"/{PropertyName()}");
|
||||
public PathString PathAndSubPath = new PathString($"/{PropertyName(nameof(Path))}/{PropertyName(nameof(SubPath))}");
|
||||
public string Scope = PropertyName();
|
||||
public string RouteId = PropertyName();
|
||||
public string ClusterId = PropertyName();
|
||||
|
|
|
|||
Loading…
Reference in a new issue