diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs index b8b6c33d7c..ca2ea995c7 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Application/Volo/Abp/FeatureManagement/FeatureAppService.cs @@ -45,7 +45,7 @@ namespace Volo.Abp.FeatureManagement { Name = featureDefinition.Name, ValueType = featureDefinition.ValueType, - Description = featureDefinition.Description.Localize(_stringLocalizerFactory), + Description = featureDefinition.Description?.Localize(_stringLocalizerFactory), ParentName = featureDefinition.Parent?.Name, Value = await _featureManager.GetOrNullAsync(featureDefinition.Name, providerName, providerKey) }); diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs new file mode 100644 index 0000000000..5198ea7277 --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureAppService_Tests.cs @@ -0,0 +1,80 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute; +using Shouldly; +using Volo.Abp.Features; +using Volo.Abp.Users; +using Xunit; + +namespace Volo.Abp.FeatureManagement +{ + public class FeatureAppService_Tests : FeatureManagementApplicationTestBase + { + private readonly IFeatureAppService _featureAppService; + private readonly IFeatureValueRepository _featureValueRepository; + private ICurrentUser _currentUser; + private readonly FeatureManagementTestData _testData; + + + public FeatureAppService_Tests() + { + _featureAppService = GetRequiredService(); + _featureValueRepository = GetRequiredService(); + _testData = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + _currentUser = Substitute.For(); + services.AddSingleton(_currentUser); + } + + [Fact] + public async Task GetAsync() + { + Login(_testData.User1Id); + + var featureList = await _featureAppService.GetAsync(EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N")); + + featureList.ShouldNotBeNull(); + featureList.Features.ShouldContain(feature => feature.Name == TestFeatureDefinitionProvider.SocialLogins); + } + + [Fact] + public async Task UpdateAsync() + { + Login(_testData.User1Id); + + await _featureAppService.UpdateAsync(EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"), new UpdateFeaturesDto() + { + Features = new List() + { + new UpdateFeatureDto() + { + Name = TestFeatureDefinitionProvider.SocialLogins, + Value = false.ToString().ToLowerInvariant() + } + } + }); + + (await _featureAppService.GetAsync(EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).Features.Any(x => + x.Name == TestFeatureDefinitionProvider.SocialLogins && + x.Value == false.ToString().ToLowerInvariant()) + .ShouldBeTrue(); + + } + + private void Login(Guid userId) + { + _currentUser.Id.Returns(userId); + _currentUser.IsAuthenticated.Returns(true); + } + } +} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureManagementApplicationTestBase.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureManagementApplicationTestBase.cs new file mode 100644 index 0000000000..f9e74aed57 --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureManagementApplicationTestBase.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Volo.Abp.FeatureManagement +{ + public class FeatureManagementApplicationTestBase : FeatureManagementTestBase + { + + } +} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationTestModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureManagementApplicationTestModule.cs similarity index 75% rename from modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationTestModule.cs rename to modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureManagementApplicationTestModule.cs index fb65739dca..2952c7da60 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/AbpFeatureManagementApplicationTestModule.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Application.Tests/Volo/Abp/FeatureManagement/FeatureManagementApplicationTestModule.cs @@ -6,7 +6,7 @@ namespace Volo.Abp.FeatureManagement typeof(AbpFeatureManagementApplicationModule), typeof(AbpFeatureManagementDomainTestModule) )] - public class AbpFeatureManagementApplicationTestModule : AbpModule + public class FeatureManagementApplicationTestModule : AbpModule { } diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.Domain.Tests/Volo/Abp/FeatureManagement/FeatureValueCacheItemInvalidator_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.Domain.Tests/Volo/Abp/FeatureManagement/FeatureValueCacheItemInvalidator_Tests.cs new file mode 100644 index 0000000000..d6666c6c09 --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.Domain.Tests/Volo/Abp/FeatureManagement/FeatureValueCacheItemInvalidator_Tests.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Caching; +using Volo.Abp.Features; +using Xunit; + +namespace Volo.Abp.FeatureManagement +{ + public class FeatureValueCacheItemInvalidator_Tests : FeatureManagementTestBase + { + private IDistributedCache _cache; + private IFeatureValueRepository _featureValueRepository; + private IFeatureManagementStore _featureManagementStore; + + public FeatureValueCacheItemInvalidator_Tests() + { + _cache = GetRequiredService>(); + _featureValueRepository = GetRequiredService(); + _featureManagementStore = GetRequiredService(); + } + + [Fact] + public async Task Cache_Should_Invalidator_WhenFeatureChanged() + { + // Arrange cache feature. + await _featureManagementStore.GetOrNullAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N")); + + var feature = await _featureValueRepository.FindAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N")); + + // Act + await _featureValueRepository.DeleteAsync(feature); + + // Assert + (await _cache.GetAsync(FeatureValueCacheItem.CalculateCacheKey(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N")))).ShouldBeNull(); + + } + } +} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs index 7a1eef410e..d5c573a360 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/AbpFeatureManagementEntityFrameworkCoreTestModule.cs @@ -8,7 +8,7 @@ using Volo.Abp.Modularity; namespace Volo.Abp.FeatureManagement.EntityFrameworkCore { [DependsOn( - typeof(AbpFeatureManagementTestBaseModule), + typeof(FeatureManagementTestBaseModule), typeof(AbpFeatureManagementEntityFrameworkCoreModule) )] public class AbpFeatureManagementEntityFrameworkCoreTestModule : AbpModule diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/FeatureManagementStore_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/FeatureManagementStore_Tests.cs new file mode 100644 index 0000000000..78f27fa222 --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.EntityFrameworkCore.Tests/Volo/Abp/FeatureManagement/EntityFrameworkCore/FeatureManagementStore_Tests.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Volo.Abp.FeatureManagement.EntityFrameworkCore +{ + public class FeatureManagementStore_Tests : FeatureManagementStore_Tests + { + + } +} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs index bc5dfa0b52..6c39cf74ae 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/AbpFeatureManagementMongoDbTestModule.cs @@ -5,7 +5,7 @@ using Volo.Abp.Modularity; namespace Volo.Abp.FeatureManagement.MongoDB { [DependsOn( - typeof(AbpFeatureManagementTestBaseModule), + typeof(FeatureManagementTestBaseModule), typeof(AbpFeatureManagementMongoDbModule) )] public class AbpFeatureManagementMongoDbTestModule : AbpModule diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureManagementStore_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureManagementStore_Tests.cs new file mode 100644 index 0000000000..7df6e3516b --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.MongoDB.Tests/Volo/Abp/FeatureManagement/MongoDB/FeatureManagementStore_Tests.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Volo.Abp.FeatureManagement.MongoDB +{ + public class FeatureManagementStore_Tests : FeatureManagementStore_Tests + { + + } +} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementStore_Tests.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementStore_Tests.cs new file mode 100644 index 0000000000..c03c5dea65 --- /dev/null +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementStore_Tests.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Shouldly; +using Volo.Abp.Features; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.Abp.FeatureManagement +{ + public abstract class FeatureManagementStore_Tests : FeatureManagementTestBase + where TStartupModule : IAbpModule + { + private IFeatureManagementStore FeatureManagementStore { get; set; } + private IFeatureValueRepository FeatureValueRepository { get; set; } + + protected FeatureManagementStore_Tests() + { + FeatureManagementStore = GetRequiredService(); + FeatureValueRepository = GetRequiredService(); + } + + [Fact] + public async Task GetOrNullAsync() + { + // Act + (await FeatureManagementStore.GetOrNullAsync(Guid.NewGuid().ToString("N"), + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).ShouldBeNull(); + + (await FeatureManagementStore.GetOrNullAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).ShouldNotBeNull(); + } + + [Fact] + public async Task Should_Get_Null_Where_Feature_Deleted() + { + // Arrange + (await FeatureManagementStore.GetOrNullAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).ShouldNotBeNull(); + + // Act + await FeatureManagementStore.DeleteAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N")); + + // Assert + (await FeatureManagementStore.GetOrNullAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).ShouldBeNull(); + } + + [Fact] + public async Task SetAsync() + { + // Arrange + (await FeatureValueRepository.FindAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).Value.ShouldBe(true.ToString().ToLowerInvariant()); + + // Act + await FeatureManagementStore.SetAsync(TestFeatureDefinitionProvider.SocialLogins, + false.ToString().ToUpperInvariant(), + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N")); + + // Assert + (await FeatureValueRepository.FindAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).Value.ShouldBe(false.ToString().ToUpperInvariant()); + } + + [Fact] + public async Task DeleteAsync() + { + // Arrange + (await FeatureValueRepository.FindAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).ShouldNotBeNull(); + + // Act + await FeatureManagementStore.DeleteAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N")); + + + // Assert + (await FeatureValueRepository.FindAsync(TestFeatureDefinitionProvider.SocialLogins, + EditionFeatureValueProvider.ProviderName, + TestEditionIds.Regular.ToString("N"))).ShouldBeNull(); + + + } + } +} diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/AbpFeatureManagementTestBaseModule.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementTestBaseModule.cs similarity index 66% rename from modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/AbpFeatureManagementTestBaseModule.cs rename to modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementTestBaseModule.cs index bf6169b488..48a90400c8 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/AbpFeatureManagementTestBaseModule.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementTestBaseModule.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Authorization; using Volo.Abp.Autofac; +using Volo.Abp.Features; using Volo.Abp.Modularity; namespace Volo.Abp.FeatureManagement @@ -11,7 +12,7 @@ namespace Volo.Abp.FeatureManagement typeof(AbpAuthorizationModule), typeof(AbpFeatureManagementDomainModule) )] - public class AbpFeatureManagementTestBaseModule : AbpModule + public class FeatureManagementTestBaseModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { @@ -23,6 +24,15 @@ namespace Volo.Abp.FeatureManagement SeedTestData(context); } + public override void PostConfigureServices(ServiceConfigurationContext context) + { + context.Services.Configure(options => + { + //TODO: Any value can pass. After completing the permission unit test, look at it again. + options.ProviderPolicies[EditionFeatureValueProvider.ProviderName] = EditionFeatureValueProvider.ProviderName; + }); + } + private static void SeedTestData(ApplicationInitializationContext context) { using (var scope = context.ServiceProvider.CreateScope()) diff --git a/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementTestData.cs b/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementTestData.cs index e6d2273307..ede4af5f2a 100644 --- a/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementTestData.cs +++ b/modules/feature-management/test/Volo.Abp.FeatureManagement.TestBase/Volo/Abp/FeatureManagement/FeatureManagementTestData.cs @@ -1,9 +1,10 @@ -using Volo.Abp.DependencyInjection; +using System; +using Volo.Abp.DependencyInjection; namespace Volo.Abp.FeatureManagement { public class FeatureManagementTestData : ISingletonDependency { - + public Guid User1Id { get; } = Guid.NewGuid(); } }