/* * Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0) * See https://github.com/openiddict/openiddict-core for more information concerning * the license and the contributors participating to this project. */ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Xunit; namespace OpenIddict.Core.Tests; public class OpenIddictCoreBuilderTests { [Fact] public void Constructor_ThrowsAnExceptionForNullServices() { // Arrange var services = (IServiceCollection) null!; // Act and assert var exception = Assert.Throws(() => new OpenIddictCoreBuilder(services)); Assert.Equal("services", exception.ParamName); } [Fact] public void ReplaceApplicationManager_ThrowsAnExceptionForInvalidManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.ReplaceApplicationManager(typeof(object))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); } [Fact] public void ReplaceApplicationManager_ThrowsAnExceptionForClosedSourceManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.ReplaceApplicationManager(typeof(ClosedGenericApplicationManager))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); } [Fact] public void ReplaceApplicationManager_OverridesDefaultOpenGenericManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.ReplaceApplicationManager(typeof(OpenGenericApplicationManager<>)); // Assert var descriptor = Assert.Single(services, service => service.Lifetime == ServiceLifetime.Scoped && service.ServiceType == typeof(OpenIddictApplicationManager<>)); Assert.Equal(typeof(OpenGenericApplicationManager<>), descriptor.ImplementationType); } [Fact] public void ReplaceAuthorizationManager_ThrowsAnExceptionForInvalidManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.ReplaceAuthorizationManager(typeof(object))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); } [Fact] public void ReplaceAuthorizationManager_ThrowsAnExceptionForClosedSourceManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.ReplaceAuthorizationManager(typeof(ClosedGenericAuthorizationManager))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); } [Fact] public void ReplaceAuthorizationManager_OverridesDefaultOpenGenericManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.ReplaceAuthorizationManager(typeof(OpenGenericAuthorizationManager<>)); // Assert var descriptor = Assert.Single(services, service => service.Lifetime == ServiceLifetime.Scoped && service.ServiceType == typeof(OpenIddictAuthorizationManager<>)); Assert.Equal(typeof(OpenGenericAuthorizationManager<>), descriptor.ImplementationType); } [Fact] public void ReplaceScopeManager_ThrowsAnExceptionForInvalidManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.ReplaceScopeManager(typeof(object))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); } [Fact] public void ReplaceScopeManager_ThrowsAnExceptionForClosedSourceManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.ReplaceScopeManager(typeof(ClosedGenericScopeManager))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); } [Fact] public void ReplaceScopeManager_OverridesDefaultOpenGenericManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.ReplaceScopeManager(typeof(OpenGenericScopeManager<>)); // Assert var descriptor = Assert.Single(services, service => service.Lifetime == ServiceLifetime.Scoped && service.ServiceType == typeof(OpenIddictScopeManager<>)); Assert.Equal(typeof(OpenGenericScopeManager<>), descriptor.ImplementationType); } [Fact] public void ReplaceTokenManager_ThrowsAnExceptionForInvalidManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.ReplaceTokenManager(typeof(object))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); } [Fact] public void ReplaceTokenManager_ThrowsAnExceptionForClosedSourceManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.ReplaceTokenManager(typeof(ClosedGenericTokenManager))); Assert.Equal("type", exception.ParamName); Assert.StartsWith(SR.GetResourceString(SR.ID0232), exception.Message); } [Fact] public void ReplaceTokenManager_OverridesDefaultOpenGenericManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.ReplaceTokenManager(typeof(OpenGenericTokenManager<>)); // Assert var descriptor = Assert.Single(services, service => service.Lifetime == ServiceLifetime.Scoped && service.ServiceType == typeof(OpenIddictTokenManager<>)); Assert.Equal(typeof(OpenGenericTokenManager<>), descriptor.ImplementationType); } [Fact] public void DisableAdditionalFiltering_FilteringIsCorrectlyDisabled() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.DisableAdditionalFiltering(); // Assert var provider = services.BuildServiceProvider(); var options = provider.GetRequiredService>().CurrentValue; Assert.True(options.DisableAdditionalFiltering); } [Fact] public void DisableEntityCaching_CachingIsCorrectlyDisabled() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.DisableEntityCaching(); // Assert var provider = services.BuildServiceProvider(); var options = provider.GetRequiredService>().CurrentValue; Assert.True(options.DisableEntityCaching); } [Fact] public void SetDefaultApplicationEntity_ReplacesUntypedManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.SetDefaultApplicationEntity(); // Assert Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped && service.ServiceType == typeof(IOpenIddictApplicationManager) && service.ImplementationFactory is not null); } [Fact] public void SetDefaultAuthorizationEntity_ReplacesUntypedManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.SetDefaultAuthorizationEntity(); // Assert Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped && service.ServiceType == typeof(IOpenIddictAuthorizationManager) && service.ImplementationFactory is not null); } [Fact] public void SetDefaultScopeEntity_ReplacesUntypedManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.SetDefaultScopeEntity(); // Assert Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped && service.ServiceType == typeof(IOpenIddictScopeManager) && service.ImplementationFactory is not null); } [Fact] public void SetDefaultTokenEntity_ReplacesUntypedManager() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.SetDefaultTokenEntity(); // Assert Assert.Contains(services, service => service.Lifetime == ServiceLifetime.Scoped && service.ServiceType == typeof(IOpenIddictTokenManager) && service.ImplementationFactory is not null); } [Theory] [InlineData(-10)] [InlineData(0)] [InlineData(9)] public void SetEntityCacheLimit_ThrowsAnExceptionForInvalidLimit(int limit) { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act and assert var exception = Assert.Throws(() => builder.SetEntityCacheLimit(limit)); Assert.Equal("limit", exception.ParamName); } [Fact] public void SetEntityCacheLimit_LimitIsCorrectlyDisabled() { // Arrange var services = CreateServices(); var builder = CreateBuilder(services); // Act builder.SetEntityCacheLimit(42); // Assert var provider = services.BuildServiceProvider(); var options = provider.GetRequiredService>().CurrentValue; Assert.Equal(42, options.EntityCacheLimit); } private static OpenIddictCoreBuilder CreateBuilder(IServiceCollection services) => services.AddOpenIddict().AddCore(); private static ServiceCollection CreateServices() { var services = new ServiceCollection(); services.AddOptions(); return services; } private class CustomApplication { } private class CustomAuthorization { } private class CustomScope { } private class CustomToken { } private class ClosedGenericApplicationManager : OpenIddictApplicationManager { public ClosedGenericApplicationManager( IOpenIddictApplicationCache cache, ILogger> logger, IOptionsMonitor options, IOpenIddictApplicationStore store) : base(cache, logger, options, store) { } } private class OpenGenericApplicationManager : OpenIddictApplicationManager where TApplication : class { public OpenGenericApplicationManager( IOpenIddictApplicationCache cache, ILogger> logger, IOptionsMonitor options, IOpenIddictApplicationStore store) : base(cache, logger, options, store) { } } private class ClosedGenericAuthorizationManager : OpenIddictAuthorizationManager { public ClosedGenericAuthorizationManager( IOpenIddictAuthorizationCache cache, ILogger> logger, IOptionsMonitor options, IOpenIddictAuthorizationStore store) : base(cache, logger, options, store) { } } private class OpenGenericAuthorizationManager : OpenIddictAuthorizationManager where TAuthorization : class { public OpenGenericAuthorizationManager( IOpenIddictAuthorizationCache cache, ILogger> logger, IOptionsMonitor options, IOpenIddictAuthorizationStore store) : base(cache, logger, options, store) { } } private class ClosedGenericScopeManager : OpenIddictScopeManager { public ClosedGenericScopeManager( IOpenIddictScopeCache cache, ILogger> logger, IOptionsMonitor options, IOpenIddictScopeStore store) : base(cache, logger, options, store) { } } private class OpenGenericScopeManager : OpenIddictScopeManager where TScope : class { public OpenGenericScopeManager( IOpenIddictScopeCache cache, ILogger> logger, IOptionsMonitor options, IOpenIddictScopeStore store) : base(cache, logger, options, store) { } } private class ClosedGenericTokenManager : OpenIddictTokenManager { public ClosedGenericTokenManager( IOpenIddictTokenCache cache, ILogger> logger, IOptionsMonitor options, IOpenIddictTokenStore store) : base(cache, logger, options, store) { } } private class OpenGenericTokenManager : OpenIddictTokenManager where TToken : class { public OpenGenericTokenManager( IOpenIddictTokenCache cache, ILogger> logger, IOptionsMonitor options, IOpenIddictTokenStore store) : base(cache, logger, options, store) { } } }