diff --git a/src/Volo.Abp.Session/Volo/Abp/Session/UserSettingContributor.cs b/src/Volo.Abp.Session/Volo/Abp/Session/UserSettingContributor.cs index 009b59bd81..931e08ef7f 100644 --- a/src/Volo.Abp.Session/Volo/Abp/Session/UserSettingContributor.cs +++ b/src/Volo.Abp.Session/Volo/Abp/Session/UserSettingContributor.cs @@ -1,4 +1,5 @@ -using System.Threading.Tasks; +using System; +using System.Threading.Tasks; using Volo.Abp.Settings; namespace Volo.Abp.Session @@ -19,19 +20,19 @@ namespace Volo.Abp.Session CurrentUser = currentUser; } - public override async Task GetOrNullAsync(string name, bool fallback) + public override async Task GetOrNullAsync(SettingDefinition setting, string entityId) { - if (CurrentUser.Id == null) + if (entityId == null) { - return null; - } + if (CurrentUser.Id == null) + { + return null; + } - return await SettingStore.GetOrNullAsync(name, EntityType, CurrentUser.Id.Value.ToString()); - } + entityId = CurrentUser.Id.ToString(); + } - public override async Task GetOrNullAsync(string name, string entityId, bool fallback = true) - { - return await SettingStore.GetOrNullAsync(name, EntityType, entityId); + return await SettingStore.GetOrNullAsync(setting.Name, EntityType, entityId); } } } \ No newline at end of file diff --git a/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingContributor.cs b/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingContributor.cs index 0b48f06839..9a90e42f8d 100644 --- a/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingContributor.cs +++ b/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingContributor.cs @@ -1,4 +1,5 @@ using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.Settings { @@ -6,8 +7,6 @@ namespace Volo.Abp.Settings { string EntityType { get; } - Task GetOrNullAsync(string name, bool fallback); - - Task GetOrNullAsync(string name, string entityId, bool fallback = true); + Task GetOrNullAsync(SettingDefinition setting, [CanBeNull] string entityId); } } \ No newline at end of file diff --git a/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingManager.cs b/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingManager.cs index d51da5b1f2..96f2f5648e 100644 --- a/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingManager.cs +++ b/src/Volo.Abp.Settings/Volo/Abp/Settings/ISettingManager.cs @@ -1,20 +1,21 @@ using System.Collections.Generic; using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.Settings { public interface ISettingManager { - Task GetOrNullAsync(string name, bool fallback = true); + Task GetOrNullAsync([NotNull]string name); - Task GetOrNullAsync(string name, string entityType, string entityId, bool fallback = true); + Task GetOrNullAsync([NotNull]string name, [NotNull] string entityType, string entityId, bool fallback = true); Task> GetAllAsync(); - Task> GetAllAsync(string entityType, string entityId, bool fallback = true); + Task> GetAllAsync([NotNull] string entityType, string entityId, bool fallback = true); - Task SetAsync(string name, string value); + Task SetAsync([NotNull] string name, string value, bool forceToSet = false); - Task SetAsync(string name, string value, string entityType, string entityId); + Task SetAsync([NotNull] string name, string value, [NotNull] string entityType, string entityId, bool forceToSet = false); } } \ No newline at end of file diff --git a/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingContributor.cs b/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingContributor.cs index f3c7a226d5..ba8129e972 100644 --- a/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingContributor.cs +++ b/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingContributor.cs @@ -14,8 +14,6 @@ namespace Volo.Abp.Settings SettingStore = settingStore; } - public abstract Task GetOrNullAsync(string name, bool fallback); - - public abstract Task GetOrNullAsync(string name, string entityId, bool fallback = true); + public abstract Task GetOrNullAsync(SettingDefinition setting, string entityId); } } \ No newline at end of file diff --git a/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs b/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs index b059bfe18a..18ebba6cc0 100644 --- a/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs +++ b/src/Volo.Abp.Settings/Volo/Abp/Settings/SettingManager.cs @@ -37,18 +37,15 @@ namespace Volo.Abp.Settings ); } - public Task GetOrNullAsync(string name, bool fallback = true) + public async Task GetOrNullAsync(string name) { - return GetOrNullAsync(name, null, null, fallback); - } + Check.NotNull(name, nameof(name)); - public async Task GetOrNullAsync(string name, string entityType, string entityId, bool fallback = true) - { - var settingDefinition = SettingDefinitionManager.Get(name); + var setting = SettingDefinitionManager.Get(name); - foreach (var contributor in GetContributors(entityType, fallback)) + foreach (var contributor in Enumerable.Reverse(Contributors.Value)) { - var value = await GetContributorValue(contributor, name, entityId, fallback); + var value = await contributor.GetOrNullAsync(setting, null); if (value != null) { return value; @@ -61,17 +58,42 @@ namespace Volo.Abp.Settings return defaultStoreValue; } + return setting.DefaultValue; + } + + public virtual async Task GetOrNullAsync(string name, string entityType, string entityId, bool fallback = true) + { + Check.NotNull(name, nameof(name)); + Check.NotNull(entityType, nameof(entityType)); + + var setting = SettingDefinitionManager.Get(name); + + foreach (var contributor in GetFilteredContributors(entityType, fallback)) + { + var value = await contributor.GetOrNullAsync(setting, entityId); + if (value != null) + { + return value; + } + } + if (!fallback) { return null; } - return settingDefinition.DefaultValue; + var defaultStoreValue = await SettingStore.GetOrNullAsync(name, null, null); + if (defaultStoreValue != null) + { + return defaultStoreValue; + } + + return setting.DefaultValue; } - + public Task> GetAllAsync() { - throw new System.NotImplementedException(); + return GetAllAsync(null, null); } public Task> GetAllAsync(string entityType, string entityId, bool fallback = true) @@ -79,36 +101,21 @@ namespace Volo.Abp.Settings throw new System.NotImplementedException(); } - public Task SetAsync(string name, string value) + public Task SetAsync(string name, string value, bool forceToSet = false) { throw new System.NotImplementedException(); } - public Task SetAsync(string name, string value, string entityType, string entityId) + public Task SetAsync(string name, string value, string entityType, string entityId, bool forceToSet = false) { throw new System.NotImplementedException(); } - private static async Task GetContributorValue(ISettingContributor contributor, string name, string entityId, bool fallback) - { - if (entityId != null) - { - return await contributor.GetOrNullAsync(name, entityId, fallback); - } - else - { - return await contributor.GetOrNullAsync(name, fallback); - } - } - - private IEnumerable GetContributors(string entityType, bool fallback) + private IEnumerable GetFilteredContributors(string entityType, bool fallback) { - var contributors = Enumerable.Reverse(Contributors.Value); - - if (entityType != null) - { - contributors = contributors.SkipWhile(c => c.EntityType != entityType); - } + var contributors = Enumerable + .Reverse(Contributors.Value) + .SkipWhile(c => c.EntityType != entityType); if (!fallback) { diff --git a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpIdentityApplicationTestModule.cs b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpIdentityApplicationTestModule.cs index 71c49212cf..871aeab2f5 100644 --- a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpIdentityApplicationTestModule.cs +++ b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpIdentityApplicationTestModule.cs @@ -4,12 +4,16 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Autofac; using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; +using Volo.Abp.Session; using Volo.Abp.Settings.EntityFrameworkCore; using Volo.Abp.Uow; namespace Volo.Abp.Settings { - [DependsOn(typeof(AbpSettingsEntityFrameworkCoreModule), typeof(AbpAutofacModule))] + [DependsOn( + typeof(AbpSettingsEntityFrameworkCoreModule), + typeof(AbpSessionModule), + typeof(AbpAutofacModule))] public class AbpSettingsTestModule : AbpModule { public override void ConfigureServices(IServiceCollection services) diff --git a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpIdentityTestDataBuilder.cs b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpIdentityTestDataBuilder.cs index 707eb4c7d0..a1e5850c23 100644 --- a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpIdentityTestDataBuilder.cs +++ b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpIdentityTestDataBuilder.cs @@ -1,10 +1,15 @@ -using Volo.Abp.DependencyInjection; +using System; +using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; +using Volo.Abp.Session; namespace Volo.Abp.Settings { public class AbpIdentityTestDataBuilder : ITransientDependency { + public static Guid User1Id = Guid.NewGuid(); + public static Guid User2Id = Guid.NewGuid(); + private readonly ISettingRepository _settingRepository; private readonly IGuidGenerator _guidGenerator; @@ -17,6 +22,10 @@ namespace Volo.Abp.Settings public void Build() { _settingRepository.InsertAsync(new Setting(_guidGenerator.Create(), "MySetting1", "42")); + + _settingRepository.InsertAsync(new Setting(_guidGenerator.Create(), "MySetting2", "default-store-value")); + _settingRepository.InsertAsync(new Setting(_guidGenerator.Create(), "MySetting2", "user1-store-value", UserSettingContributor.DefaultEntityType, User1Id.ToString())); + _settingRepository.InsertAsync(new Setting(_guidGenerator.Create(), "MySetting2", "user2-store-value", UserSettingContributor.DefaultEntityType, User2Id.ToString())); } } } \ No newline at end of file diff --git a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs index 383a2f801d..1196910994 100644 --- a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs +++ b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs @@ -29,10 +29,9 @@ namespace Volo.Abp.Settings } [Fact] - public async Task Should_Get_From_Store_Without_Entity_Props() + public async Task Should_Get_Base_Store_Value() { - var value = await _settingManager.GetOrNullAsync("MySetting1"); - value.ShouldBe("42"); + (await _settingManager.GetOrNullAsync("MySetting1")).ShouldBe("42"); } } } diff --git a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_User_Based_Tests.cs b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_User_Based_Tests.cs new file mode 100644 index 0000000000..dd421b3243 --- /dev/null +++ b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_User_Based_Tests.cs @@ -0,0 +1,57 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute; +using Shouldly; +using Volo.Abp.Session; +using Xunit; + +namespace Volo.Abp.Settings +{ + public class SettingManager_User_Based_Tests: AbpSettingsTestBase + { + private Guid _currentUserId; + private readonly ISettingManager _settingManager; + + public SettingManager_User_Based_Tests() + { + _settingManager = GetRequiredService(); + } + + protected override void AfterAddApplication(IServiceCollection services) + { + ICurrentUser currentUser = Substitute.For(); + currentUser.Id.Returns(ci => _currentUserId); + services.AddSingleton(currentUser); + } + + [Fact] + public async Task Should_Get_From_Store_For_Given_User() + { + (await _settingManager.GetOrNullForUserAsync("MySetting2", AbpIdentityTestDataBuilder.User1Id)).ShouldBe("user1-store-value"); + (await _settingManager.GetOrNullForUserAsync("MySetting2", AbpIdentityTestDataBuilder.User2Id)).ShouldBe("user2-store-value"); + } + + [Fact] + public async Task Should_Get_From_Store_For_Current_User() + { + _currentUserId = AbpIdentityTestDataBuilder.User1Id; + (await _settingManager.GetOrNullAsync("MySetting2")).ShouldBe("user1-store-value"); + + _currentUserId = AbpIdentityTestDataBuilder.User2Id; + (await _settingManager.GetOrNullAsync("MySetting2")).ShouldBe("user2-store-value"); + } + + [Fact] + public async Task Should_Fallback_To_Default_Store_Value_When_No_Value_For_Given_User() + { + (await _settingManager.GetOrNullForUserAsync("MySetting2", Guid.NewGuid())).ShouldBe("default-store-value"); + } + + [Fact] + public async Task Should_Not_Fallback_To_Default_Store_Value_When_No_Value_For_Given_User_But_Specified_Fallback_As_False() + { + (await _settingManager.GetOrNullForUserAsync("MySetting2", Guid.NewGuid(), fallback: false)).ShouldBeNull(); + } + } +} \ No newline at end of file diff --git a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingProvider.cs b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingProvider.cs index ea06231514..eaa29cd7da 100644 --- a/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingProvider.cs +++ b/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingProvider.cs @@ -1,12 +1,11 @@ -using System; - -namespace Volo.Abp.Settings +namespace Volo.Abp.Settings { public class TestSettingProvider : SettingProvider { public override void Define(ISettingDefinitionContext context) { context.Add(new SettingDefinition("MySetting1")); + context.Add(new SettingDefinition("MySetting2")); context.Add(new SettingDefinition("SettingNotSetInStore", defaultValue: "default-value")); } }