diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln
index 7cae777e00..9916c2a8e8 100644
--- a/framework/Volo.Abp.sln
+++ b/framework/Volo.Abp.sln
@@ -216,6 +216,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Localization.Abstr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Security.Tests", "test\Volo.Abp.Security.Tests\Volo.Abp.Security.Tests.csproj", "{7CE07034-7E02-4C78-B981-F1039412CA5E}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Settings.Tests", "test\Volo.Abp.Settings.Tests\Volo.Abp.Settings.Tests.csproj", "{5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -610,6 +612,10 @@ Global
{7CE07034-7E02-4C78-B981-F1039412CA5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CE07034-7E02-4C78-B981-F1039412CA5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CE07034-7E02-4C78-B981-F1039412CA5E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -714,6 +720,7 @@ Global
{882E82F1-1A57-4BB9-B126-4CBF700C8F0C} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{20513A4E-FAC7-4106-8976-5D79A3BDFED1} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
{7CE07034-7E02-4C78-B981-F1039412CA5E} = {447C8A77-E5F0-4538-8687-7383196D04EA}
+ {5F3A2D1E-EA89-40A7-8D2F-FB4EB2092403} = {447C8A77-E5F0-4538-8687-7383196D04EA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj b/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj
new file mode 100644
index 0000000000..7b4eda07c9
--- /dev/null
+++ b/framework/test/Volo.Abp.Settings.Tests/Volo.Abp.Settings.Tests.csproj
@@ -0,0 +1,21 @@
+
+
+
+ netcoreapp2.1
+ latest
+ Volo.Abp.Settings.Tests
+ Volo.Abp.Settings.Tests
+ true
+ false
+ false
+ false
+
+
+
+
+
+
+
+
+
+
diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpSettingsTestModule.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpSettingsTestModule.cs
new file mode 100644
index 0000000000..dc4ab057a0
--- /dev/null
+++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/AbpSettingsTestModule.cs
@@ -0,0 +1,20 @@
+using Volo.Abp.Modularity;
+
+namespace Volo.Abp.Settings
+{
+ [DependsOn(
+ typeof(AbpSettingsModule),
+ typeof(AbpTestBaseModule)
+ )]
+ public class AbpSettingsTestModule : AbpModule
+ {
+ public override void ConfigureServices(ServiceConfigurationContext context)
+ {
+ Configure(options =>
+ {
+ options.ValueProviders.Add();
+ options.DefinitionProviders.Add();
+ });
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs
new file mode 100644
index 0000000000..be039451f2
--- /dev/null
+++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/SettingManager_Tests.cs
@@ -0,0 +1,49 @@
+using System.Threading.Tasks;
+using Shouldly;
+using Xunit;
+
+namespace Volo.Abp.Settings
+{
+ public class SettingManager_Tests : AbpIntegratedTest
+ {
+ private readonly ISettingManager _settingManager;
+
+ public SettingManager_Tests()
+ {
+ _settingManager = GetRequiredService();
+ }
+
+ [Fact]
+ public async Task Should_Get_Null_If_No_Value_Provided_And_No_Default_Value()
+ {
+ (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingWithoutDefaultValue))
+ .ShouldBeNull();
+ }
+
+ [Fact]
+ public async Task Should_Get_Default_Value_If_No_Value_Provided_And_There_Is_A_Default_Value()
+ {
+ (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingWithDefaultValue))
+ .ShouldBe("default-value");
+ }
+
+ [Fact]
+ public async Task Should_Set_And_Get_Encrypted_Values()
+ {
+ (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingEncrypted))
+ .ShouldBeNull();
+
+ await _settingManager.SetAsync(
+ TestSettingNames.TestSettingEncrypted,
+ "abc",
+ TestSettingValueProvider.ProviderName,
+ null
+ );
+
+ (await _settingManager.GetOrNullAsync(TestSettingNames.TestSettingEncrypted))
+ .ShouldBe("abc");
+ }
+
+ //TODO: Needs more tests with more advanced scenarios.
+ }
+}
diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingDefinitionProvider.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingDefinitionProvider.cs
new file mode 100644
index 0000000000..1cbe860963
--- /dev/null
+++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingDefinitionProvider.cs
@@ -0,0 +1,14 @@
+namespace Volo.Abp.Settings
+{
+ public class TestSettingDefinitionProvider : SettingDefinitionProvider
+ {
+ public override void Define(ISettingDefinitionContext context)
+ {
+ context.Add(
+ new SettingDefinition(TestSettingNames.TestSettingWithoutDefaultValue),
+ new SettingDefinition(TestSettingNames.TestSettingWithDefaultValue, "default-value"),
+ new SettingDefinition(TestSettingNames.TestSettingEncrypted, isEncrypted: true)
+ );
+ }
+ }
+}
diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingNames.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingNames.cs
new file mode 100644
index 0000000000..b10267e69d
--- /dev/null
+++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingNames.cs
@@ -0,0 +1,9 @@
+namespace Volo.Abp.Settings
+{
+ public static class TestSettingNames
+ {
+ public const string TestSettingWithoutDefaultValue = "TestSettingWithoutDefaultValue";
+ public const string TestSettingWithDefaultValue = "TestSettingWithDefaultValue";
+ public const string TestSettingEncrypted = "TestSettingEncrypted";
+ }
+}
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs
new file mode 100644
index 0000000000..e8f5cbc559
--- /dev/null
+++ b/framework/test/Volo.Abp.Settings.Tests/Volo/Abp/Settings/TestSettingValueProvider.cs
@@ -0,0 +1,37 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.Settings
+{
+ public class TestSettingValueProvider : ISettingValueProvider, ITransientDependency
+ {
+ public const string ProviderName = "Test";
+
+ private readonly Dictionary _values;
+
+ public string Name => ProviderName;
+
+ public TestSettingValueProvider()
+ {
+ _values = new Dictionary();
+ }
+
+ public Task GetOrNullAsync(SettingDefinition setting, string providerKey)
+ {
+ return Task.FromResult(_values.GetOrDefault(setting.Name));
+ }
+
+ public Task SetAsync(SettingDefinition setting, string value, string providerKey)
+ {
+ _values[setting.Name] = value;
+ return Task.CompletedTask;
+ }
+
+ public Task ClearAsync(SettingDefinition setting, string providerKey)
+ {
+ _values.Remove(setting.Name);
+ return Task.CompletedTask;
+ }
+ }
+}