Skip to content

Introducing BFF V4

86a1aa5
Select commit
Loading
Failed to load commit list.
Sign in for the full log view
Merged

Bff V4 multi-frontend support #2032

Introducing BFF V4
86a1aa5
Select commit
Loading
Failed to load commit list.
GitHub Actions / Test Report - test/Bff.Tests succeeded Jun 3, 2025 in 0s

253 passed, 0 failed and 3 skipped

Tests passed successfully

✅ bff/test/Bff.Tests/TestResults/test/Bff.Tests-tests.trx

256 tests were completed in 36s with 253 passed, 0 failed and 3 skipped.

Test suite Passed Failed Skipped Time
Bff.Tests.Blazor.BffBlazorTests 3✅ 336ms
Bff.Tests.Blazor.ServerSideTokenStoreTests 1✅ 44ms
Bff.Tests.PublicApiVerificationTests 5✅ 1s
Duende.Bff.Blazor.Client.UnitTests.AntiForgeryHandlerTests 1✅ 7ms
Duende.Bff.Blazor.Client.UnitTests.BffClientAuthenticationStateProviderTests 4✅ 81ms
Duende.Bff.Blazor.Client.UnitTests.FetchUserServiceTests 2✅ 252ms
Duende.Bff.Blazor.Client.UnitTests.ServiceCollectionExtensionsTests 18✅ 260ms
Duende.Bff.EntityFramework.Tests.UserSessionStoreTests 22✅ 1s
Duende.Bff.Tests.BffFrontendIndexTests 6✅ 5s
Duende.Bff.Tests.BffFrontendMatchingTests 4✅ 2s
Duende.Bff.Tests.BffFrontendSigninTests 13✅ 16s
Duende.Bff.Tests.BffRemoteApiTests 7✅ 5s
Duende.Bff.Tests.BffWithoutExplicitFrontendTests 1✅ 733ms
Duende.Bff.Tests.Configuration.BffBuilderTests 12✅ 1⚪ 8s
Duende.Bff.Tests.ConventionTests 10✅ 49ms
Duende.Bff.Tests.Endpoints.DpopRemoteEndpointTests 2✅ 2s
Duende.Bff.Tests.Endpoints.DPoPTestsWithManualAuthentication 2✅ 1s
Duende.Bff.Tests.Endpoints.LocalEndpointTests 1✅ 6s
Duende.Bff.Tests.Endpoints.Management.BackchannelLogoutEndpointTests 6✅ 5s
Duende.Bff.Tests.Endpoints.Management.LoginEndpointTests 13✅ 12s
Duende.Bff.Tests.Endpoints.Management.LogoutEndpointTests 10✅ 8s
Duende.Bff.Tests.Endpoints.Management.ManagementBasePathTests 5✅ 281ms
Duende.Bff.Tests.Endpoints.Management.UserEndpointTests 5✅ 161ms
Duende.Bff.Tests.Endpoints.RemoteEndpointTests 21✅ 2s
Duende.Bff.Tests.Endpoints.YarpTests 18✅ 10s
Duende.Bff.Tests.GenericHostTests 1✅ 12ms
Duende.Bff.Tests.Headers.ApiAndBffUseForwardedHeaders 2✅ 2s
Duende.Bff.Tests.Headers.ApiUseForwardedHeaders 2✅ 1s
Duende.Bff.Tests.Headers.General 3✅ 78ms
Duende.Bff.Tests.IAccessTokenRetriever_Extensibility_tests 2✅ 170ms
Duende.Bff.Tests.MultiFrontend.FrontendSelectorTests 11✅ 157ms
Duende.Bff.Tests.MultiFrontend.LocalFrontEndStoreTests 4✅ 2⚪ 3s
Duende.Bff.Tests.MultiFrontend.OriginTests 18✅ 4ms
Duende.Bff.Tests.MultiFrontend.PathMapperTests 6✅ 1ms
Duende.Bff.Tests.SessionManagement.CookieSlidingTests 4✅ 460ms
Duende.Bff.Tests.SessionManagement.RevokeRefreshTokenTests 4✅ 583ms
Duende.Bff.Tests.SessionManagement.ServerSideTicketStoreTests 1✅ 143ms
Duende.Bff.Tests.TestInfra.TestInfraTests 3✅ 4s

✅ Bff.Tests.Blazor.BffBlazorTests

✅ Can_get_home
✅ Can_get_secure_when_logged_in
✅ Cannot_get_secure_without_loggin_in

✅ Bff.Tests.Blazor.ServerSideTokenStoreTests

✅ Can_add_retrieve_and_remove_tokens

✅ Bff.Tests.PublicApiVerificationTests

✅ VerifyPublicApi_Bff
✅ VerifyPublicApi_Bff_Blazor
✅ VerifyPublicApi_Bff_Blazor_Client
✅ VerifyPublicApi_Bff_EntityFramework
✅ VerifyPublicApi_Bff_Yarp

✅ Duende.Bff.Blazor.Client.UnitTests.AntiForgeryHandlerTests

✅ Adds_expected_header

✅ Duende.Bff.Blazor.Client.UnitTests.BffClientAuthenticationStateProviderTests

✅ timer_stops_when_user_logs_out
✅ when_anonymous_user_in_persistent_state_GetAuthState_returns_anonymous_and_does_not_poll
✅ when_no_user_in_persistent_state_GetAuthState_polls_user_endpoint
✅ when_user_in_persistent_state_GetAuthState_returns_that_user_and_then_polls_user_endpoint

✅ Duende.Bff.Blazor.Client.UnitTests.FetchUserServiceTests

✅ GetUserAsync_maps_claims_into_ClaimsPrincipal
✅ GetUserAsync_returns_anonymous_when_http_request_fails

✅ Duende.Bff.Blazor.Client.UnitTests.ServiceCollectionExtensionsTests

✅ AddBffBlazorClient_can_set_options_with_callback
✅ AddLocalApiHttpClient_configures_HttpClient_base_address
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com", configuredRemotePath: "custom/route/to/apis", expectedBaseAddress: "https://example.com/custom/route/to/apis/")
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com", configuredRemotePath: null, expectedBaseAddress: "https://example.com/remote-apis/")
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com/", configuredRemotePath: "remote-apis", expectedBaseAddress: "https://example.com/remote-apis/")
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com/", configuredRemotePath: null, expectedBaseAddress: "https://example.com/remote-apis/")
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com/with/base/path", configuredRemotePath: "/custom/route/to/apis", expectedBaseAddress: "https://example.com/with/base/path/custom/route/to"···)
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com/with/base/path", configuredRemotePath: "custom/route/to/apis", expectedBaseAddress: "https://example.com/with/base/path/custom/route/to"···)
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com/with/base/path", configuredRemotePath: null, expectedBaseAddress: "https://example.com/with/base/path/remote-apis/")
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com/with/base/path/", configuredRemotePath: "/custom/route/to/apis", expectedBaseAddress: "https://example.com/with/base/path/custom/route/to"···)
✅ AddRemoteApiHttpClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com/with/base/path/", configuredRemotePath: "custom/route/to/apis", expectedBaseAddress: "https://example.com/with/base/path/custom/route/to"···)
✅ When_base_address_option_is_default_AddBffBlazorClient_configures_HttpClient_base_address_from_host_env
✅ When_base_address_option_is_default_AddRemoteApiHttpClient_configures_HttpClient_base_address_from_host_env
✅ When_base_address_option_is_default_AddRemoteApiHttpClient_configures_HttpClient_base_address_from_host_env_and_config_callback_is_respected
✅ When_base_address_option_is_default_AddRemoteApiHttpClient_for_typed_clients_configures_HttpClient_base_address_from_host_env
✅ When_base_address_option_is_default_AddRemoteApiHttpClient_for_typed_clients_configures_HttpClient_base_address_from_host_env_and_config_callback_is_respected
✅ When_base_address_option_is_set_AddBffBlazorClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com", expectedBaseAddress: "https://example.com/")
✅ When_base_address_option_is_set_AddBffBlazorClient_configures_HttpClient_base_address(configuredRemoteAddress: "https://example.com/", expectedBaseAddress: "https://example.com/")

✅ Duende.Bff.EntityFramework.Tests.UserSessionStoreTests

✅ concurrent_deletes_with_exception_handler_and_detatching_should_succeed
✅ CreateUserSessionAsync_should_succeed
✅ DeleteUserSessionAsync_for_invalid_key_should_succeed
✅ DeleteUserSessionAsync_for_valid_key_should_succeed
✅ DeleteUserSessionsAsync_for_invalid_sid_should_do_nothing
✅ DeleteUserSessionsAsync_for_invalid_sub_and_sid_should_succeed
✅ DeleteUserSessionsAsync_for_invalid_sub_should_do_nothing
✅ DeleteUserSessionsAsync_for_missing_sub_and_sid_should_throw
✅ DeleteUserSessionsAsync_for_valid_sid_should_succeed
✅ DeleteUserSessionsAsync_for_valid_sub_and_sid_should_succeed
✅ DeleteUserSessionsAsync_for_valid_sub_should_succeed
✅ GetUserSessionAsync_for_invalid_key_should_return_null
✅ GetUserSessionAsync_for_valid_key_should_succeed
✅ GetUserSessionsAsync_for_invalid_sid_should_return_empty
✅ GetUserSessionsAsync_for_invalid_sub_and_sid_should_succeed
✅ GetUserSessionsAsync_for_invalid_sub_should_return_empty
✅ GetUserSessionsAsync_for_missing_sub_and_sid_should_throw
✅ GetUserSessionsAsync_for_valid_sid_should_succeed
✅ GetUserSessionsAsync_for_valid_sub_and_sid_should_succeed
✅ GetUserSessionsAsync_for_valid_sub_should_succeed
✅ UpdateUserSessionAsync_for_invalid_key_should_succeed
✅ UpdateUserSessionAsync_should_succeed

✅ Duende.Bff.Tests.BffFrontendIndexTests

✅ After_login_index_document_is_returned
✅ Can_customize_index_html
✅ Given_index_can_call_local_api
✅ Given_index_can_call_proxied_endpoint
✅ Index_document_is_returned_on_fallback_path
✅ IndexHtml_is_cached_but_refreshed_when_modifying_frontend

✅ Duende.Bff.Tests.BffFrontendMatchingTests

✅ Can_match_frontend_on_path
✅ Can_select_frontend_based_on_domain_name
✅ Given_single_frontend_then_is_selected
✅ When_no_frontend_matched_then_show_frontend_returns_none

✅ Duende.Bff.Tests.BffFrontendSigninTests

✅ Can_add_frontends_using_AddFrontends_ExtensionMethod
✅ Can_get_home
✅ Can_login
✅ can_signin_with_path_based_frontend
✅ cannot_access_secret_page_without_logging_in
✅ Default_settings_augment_frontend_settings
✅ Event_handlers_are_used
✅ Event_handlers_are_used_from_bff_defaults
✅ given_path_based_frontend_cannot_login_on_root
✅ given_path_based_frontend_login_endpoint_should_challenge_and_redirect_to_root_with_custom_prefix
✅ given_path_based_frontend_then_can_perform_silent_signin
✅ When_creating_new_frontend_old_config_is_not_reused
✅ When_updating_frontend_then_subsequent_login_uses_new_settings

✅ Duende.Bff.Tests.BffRemoteApiTests

✅ When_logged_in_can_proxy_and_get_subject(requiredTokenType: User)
✅ When_logged_in_can_proxy_and_get_subject(requiredTokenType: UserOrClient)
✅ When_logged_in_can_proxy_and_get_subject(requiredTokenType: UserOrNone)
✅ When_not_logged_in_can_get_token(requiredTokenType: Client)
✅ When_not_logged_in_can_get_token(requiredTokenType: UserOrClient)
✅ When_not_logged_in_can_get_token(requiredTokenType: UserOrNone)
✅ When_not_logged_in_cannot_get_required_user_token

✅ Duende.Bff.Tests.BffWithoutExplicitFrontendTests

✅ Can_login

✅ Duende.Bff.Tests.Configuration.BffBuilderTests

✅ Can_add_frontends_in_multiple_calls
✅ Can_add_multiple_frontends
✅ Can_configure_frontends_in_configuration_as_string
✅ Can_load_default_cookie_configuration
✅ Can_load_default_oidc_configuration
✅ Can_load_frontend_with_all_possible_values_from_configuration
✅ Can_load_frontend_with_all_values_from_configuration
✅ Can_load_frontend_with_minimal_values_from_configuration
✅ Cannot_add_duplicate_frontends
✅ When_config_file_is_updated_then_frontend_store_is_updated
✅ when_loading_frontend_default_config_is_applied
✅ When_updating_frontends_in_config_then_are_removed_from_Oidc_cache
⚪ Will_reject_invalid_configuration

✅ Duende.Bff.Tests.ConventionTests

✅ AccessTokenManagement_is_not_exposed
✅ All_async_methods_should_end_with_Async_and_have_cancellation_token_as_last_parameter
✅ All_interface_async_methods_should_have_cancellation_token_with_default
✅ All_strongly_typed_strings_are_readonly_struct
✅ All_strongly_typed_strings_have_internal_create_method
✅ All_strongly_typed_strings_Have_private_value
✅ All_strongly_typed_strings_should_have_only_expected_constructors
✅ All_strongly_typed_strings_should_have_public_constructor_that_throws
✅ All_types_in_Internal_namespace_should_be_internal
✅ All_types_not_in_Internal_namespace_should_be_sealed_or_static

✅ Duende.Bff.Tests.Endpoints.DpopRemoteEndpointTests

✅ Can_login_with_dpop_enabled
✅ When_calling_api_endpoint_with_dpop_enabled_then_dpop_headers_are_sent

✅ Duende.Bff.Tests.Endpoints.DPoPTestsWithManualAuthentication

✅ When_calling_api_endpoint_with_dpop_enabled_then_dpop_headers_are_sent
✅ When_logging_in_then_dpop_is_sent

✅ Duende.Bff.Tests.Endpoints.LocalEndpointTests

✅ calls_to_authorized_local_endpoint_should_succeed

✅ Duende.Bff.Tests.Endpoints.Management.BackchannelLogoutEndpointTests

✅ backchannel_logout_endpoint_for_incorrect_sid_should_not_logout_user
✅ backchannel_logout_endpoint_for_incorrect_sub_should_not_logout_user
✅ backchannel_logout_endpoint_should_signout
✅ backchannel_logout_should_allow_anonymous
✅ when_BackchannelLogoutAllUserSessions_is_false_backchannel_logout_should_logout_all_sessions
✅ when_BackchannelLogoutAllUserSessions_is_false_backchannel_logout_should_only_logout_one_session

✅ Duende.Bff.Tests.Endpoints.Management.LoginEndpointTests

✅ can_issue_silent_login_with_prompt_none
✅ can_use_prompt_supported_by_IdentityServer
✅ login_endpoint_should_accept_returnUrl
✅ login_endpoint_should_authenticatre_and_redirect_to_root
✅ login_endpoint_should_challenge_and_redirect_to_root_with_custom_prefix
✅ login_endpoint_should_challenge_and_redirect_to_root_with_custom_prefix_trailing_slash
✅ login_endpoint_should_challenge_and_redirect_to_root_with_root_prefix
✅ login_endpoint_should_not_accept_non_local_returnUrl
✅ login_endpoint_with_existing_session_should_challenge
✅ login_should_allow_anonymous
✅ login_with_unsupported_prompt_is_rejected
✅ silent_login_should_challenge_and_return_silent_login_html
✅ when_unauthenticated_silent_login_should_return_isLoggedIn_false

✅ Duende.Bff.Tests.Endpoints.Management.LogoutEndpointTests

✅ can_logout_twice
✅ logout_endpoint_for_anonymous_user_without_sid_should_succeed
✅ logout_endpoint_for_authenticated_should_require_sid
✅ logout_endpoint_for_authenticated_user_without_sid_should_succeed
✅ logout_endpoint_for_authenticated_when_require_option_is_false_should_not_require_sid
✅ logout_endpoint_should_accept_returnUrl
✅ logout_endpoint_should_allow_anonymous
✅ logout_endpoint_should_redirect_to_external_signout_and_return_to_root
✅ logout_endpoint_should_reject_non_local_returnUrl
✅ logout_endpoint_should_signout

✅ Duende.Bff.Tests.Endpoints.Management.ManagementBasePathTests

✅ custom_ManagementBasePath_should_affect_basepath(path: "/login")
✅ custom_ManagementBasePath_should_affect_basepath(path: "/logout")
✅ custom_ManagementBasePath_should_affect_basepath(path: "/silent-login-callback")
✅ custom_ManagementBasePath_should_affect_basepath(path: "/silent-login")
✅ custom_ManagementBasePath_should_affect_basepath(path: "/user")

✅ Duende.Bff.Tests.Endpoints.Management.UserEndpointTests

✅ user_endpoint_for_authenticated_user_should_return_claims
✅ user_endpoint_for_authenticated_user_with_sid_should_return_claims_including_logout
✅ user_endpoint_for_authenticated_user_without_csrf_header_should_fail
✅ user_endpoint_for_unauthenticated_user_should_fail
✅ when_configured_user_endpoint_for_unauthenticated_user_should_return_200_and_empty

✅ Duende.Bff.Tests.Endpoints.RemoteEndpointTests

✅ calls_to_remote_api_that_returns_forbidden_will_return_forbidden
✅ calls_to_remote_api_that_returns_unauthorized_will_return_unauthorized
✅ calls_to_remote_endpoint_expecting_token_but_without_token_should_fail
✅ calls_to_remote_endpoint_should_fail_when_token_retrieval_fails
✅ calls_to_remote_endpoint_should_forward_client_token_to_api
✅ calls_to_remote_endpoint_should_forward_user_or_anonymous_to_api
✅ calls_to_remote_endpoint_should_forward_user_or_client_to_api
✅ calls_to_remote_endpoint_should_forward_user_to_api
✅ calls_to_remote_endpoint_should_require_csrf
✅ calls_to_remote_endpoint_should_send_token_from_token_retriever_when_token_retrieval_succeeds
✅ calls_to_remote_endpoint_with_anon_should_be_anon
✅ calls_to_remote_endpoint_with_useraccesstokenparameters_having_not_stored_corresponding_named_token_finds_no_matching_token_should_fail
✅ calls_to_remote_endpoint_with_useraccesstokenparameters_having_stored_named_token_should_forward_user_to_api
✅ can_disable_anti_forgery_check
✅ endpoint_can_be_configured_with_custom_transform
✅ endpoints_that_disable_csrf_should_not_require_csrf_header
✅ post_to_remote_endpoint_should_forward_user_to_api
✅ put_to_remote_endpoint_should_forward_user_to_api
✅ response_status_401_from_remote_endpoint_should_return_401_from_bff
✅ response_status_403_from_remote_endpoint_should_return_403_from_bff
✅ unauthenticated_calls_to_remote_endpoint_should_return_401

✅ Duende.Bff.Tests.Endpoints.YarpTests

✅ anonymous_call_to_no_token_requirement_route_should_succeed
✅ anonymous_call_to_optional_user_token_route_should_succeed
✅ anonymous_call_to_user_token_requirement_route_should_fail
✅ anonymous_call_with_no_csrf_header_to_csrf_route_should_fail
✅ anonymous_call_with_no_csrf_header_to_no_token_requirement_no_csrf_route_should_succeed
✅ authenticated_GET_should_forward_user_to_api(requiredTokenType: User)
✅ authenticated_GET_should_forward_user_to_api(requiredTokenType: UserOrNone)
✅ authenticated_Post_should_forward_user_to_api(requiredTokenType: User)
✅ authenticated_Post_should_forward_user_to_api(requiredTokenType: UserOrNone)
✅ authenticated_PUT_should_forward_user_to_api(requiredTokenType: User)
✅ authenticated_PUT_should_forward_user_to_api(requiredTokenType: UserOrNone)
✅ call_to_client_token_route_should_forward_client_token_to_api
✅ call_to_user_or_client_token_route_should_forward_user_or_client_token_to_api
✅ can_disable_anti_forgery_check
✅ old_anonymous_call_to_optional_user_token_route_should_succeed
✅ response_status_401_from_remote_endpoint_should_return_401_from_bff
✅ response_status_403_from_remote_endpoint_should_return_403_from_bff
✅ yarp_works_with_path_based_routing

✅ Duende.Bff.Tests.GenericHostTests

✅ Test1

✅ Duende.Bff.Tests.Headers.ApiAndBffUseForwardedHeaders

✅ bff_host_name_should_propagate_to_api
✅ forwarded_host_name_with_header_forwarding_should_propagate_to_api

✅ Duende.Bff.Tests.Headers.ApiUseForwardedHeaders

✅ bff_host_name_should_propagate_to_api
✅ forwarded_host_name_should_not_propagate_to_api

✅ Duende.Bff.Tests.Headers.General

✅ custom_header_should_be_forwarded
✅ custom_header_should_be_forwarded_and_xforwarded_headers_should_be_created
✅ local_endpoint_should_receive_standard_headers

✅ Duende.Bff.Tests.IAccessTokenRetriever_Extensibility_tests

✅ When_calling_custom_endpoint_then_AccessTokenRetrievalContext_has_api_address_and_localpath
✅ When_calling_sub_custom_endpoint_then_AccessTokenRetrievalContext_has_api_address_and_localpath

✅ Duende.Bff.Tests.MultiFrontend.FrontendSelectorTests

✅ TryMapFrontend_EmptyStore_ReturnsFalse
✅ TryMapFrontend_FallbackToDefaultFrontend_ReturnsTrue
✅ TryMapFrontend_MatchesByOrigin_ReturnsTrue
✅ TryMapFrontend_MatchesByOriginAndPath_ReturnsTrue
✅ TryMapFrontend_MatchesByPath_logs_warning_on_invalid_case
✅ TryMapFrontend_MatchesByPath_ReturnsTrue
✅ TryMapFrontend_MultipleOrigins_MatchesMostSpecific
✅ TryMapFrontend_MultiplePaths_MatchesMostSpecific
✅ TryMapFrontend_NoMatches_ReturnsFalse
✅ TryMapFrontend_NoOriginSpecified_MatchesByPath
✅ TryMapFrontend_Will_return_first

✅ Duende.Bff.Tests.MultiFrontend.LocalFrontEndStoreTests

✅ Can_load_frontends_from_config
✅ Can_load_frontends_from_constructor
⚪ Cookie_Config_precedence_is_programmatic_defaults_then_configured_defaults_then_frontend_specific
⚪ ODIC_Config_precedence_is_programmatic_defaults_then_configured_defaults_then_frontend_specific
✅ When_frontend_is_removed_then_event_is_raised
✅ When_frontend_is_updated_then_event_is_raised

✅ Duende.Bff.Tests.MultiFrontend.OriginTests

✅ Equals_can_handle_default_ports
✅ Equals_can_handle_explicit_ports
✅ Equals_HostComparisonIsCaseInsensitive
✅ Equals_IgnoresPathInRequest
✅ Equals_SchemeComparisonIsCaseInsensitive
✅ Equals_WithDifferentHost_ReturnsFalse
✅ Equals_WithDifferentPort_ReturnsFalse
✅ Equals_WithDifferentScheme_ReturnsFalse
✅ Equals_WithMatchingHttpRequest_ReturnsTrue
✅ Equals_WithNullRequest_ReturnsFalse
✅ Origin_WithExplicitInitialization_SetsProperties
✅ Parse_WithCustomPort_SetsCorrectPort
✅ Parse_WithFragment_IgnoresFragment
✅ Parse_WithInvalidUrl_ThrowsUriFormatException
✅ Parse_WithPath_IgnoresPath
✅ Parse_WithQuery_IgnoresQuery
✅ Parse_WithValidHttpsUrl_SetsCorrectProperties
✅ Parse_WithValidHttpUrl_SetsCorrectProperties

✅ Duende.Bff.Tests.MultiFrontend.PathMapperTests

✅ MapPath_WithCaseInsensitiveMatch_UpdatesPathBaseAndPath
✅ MapPath_WithEmptyPathBase_AddsMatchingPathToPathBase
✅ MapPath_WithExactMatchingPath_UpdatesPathBaseAndLeavesEmptyPath
✅ MapPath_WithMatchingPath_UpdatesPathBaseAndPath
✅ MapPath_WithNoMatchingPath_Returns404
✅ MapPath_WithNoMatchingPaths_DoesNotModifyPathBaseOrPath

✅ Duende.Bff.Tests.SessionManagement.CookieSlidingTests

✅ user_endpoint_cookie_should_slide
✅ user_endpoint_when_sliding_flag_is_passed_cookie_should_not_slide
✅ user_endpoint_when_uservalidate_renews_and_sliding_flag_is_passed_cookie_should_not_slide
✅ user_endpoint_when_uservalidate_renews_cookie_should_slide

✅ Duende.Bff.Tests.SessionManagement.RevokeRefreshTokenTests

✅ backchannel_logout_endpoint_should_revoke_refreshtoken
✅ logout_should_revoke_refreshtoken
✅ when_setting_disabled_backchannel_logout_endpoint_should_not_revoke_refreshtoken
✅ when_setting_disabled_logout_should_not_revoke_refreshtoken

✅ Duende.Bff.Tests.SessionManagement.ServerSideTicketStoreTests

✅ StoreAsync_should_remove_conflicting_entries_prior_to_creating_new_entry

✅ Duende.Bff.Tests.TestInfra.TestInfraTests

✅ Can_add_api_endpoint_to_bff_host
✅ Can_login_to_bff_host
✅ Can_login_to_identity_server