From 0653ebe7e91c6b1160665af85fdfeaf1bf2baeeb Mon Sep 17 00:00:00 2001 From: colin Date: Tue, 11 Nov 2025 11:07:29 +0800 Subject: [PATCH] tests: Add some unit tests --- ...NGYUN.Abp.BlobStoring.Tencent.Tests.csproj | 20 +++ .../Tencent/AbpBlobStoringTencentTestBase.cs | 8 + .../AbpBlobStoringTencentTestModule.cs | 97 ++++++++++++ ...ncentBlobNamingNormalizerProvider_Tests.cs | 48 ++++++ .../Tencent/TencentBlobContainer_Tests.cs | 12 ++ .../TencentBlobNameCalculator_Tests.cs | 55 +++++++ .../LINGYUN.Abp.BlobStoring.Tests.csproj | 20 +++ .../AbpBlobStoringOptions_Tests.cs | 39 +++++ .../Abp/BlobStoring/AbpBlobStoringTestBase.cs | 12 ++ .../BlobStoring/AbpBlobStoringTestModule.cs | 44 ++++++ .../BlobStoring/BlobContainerFactory_Tests.cs | 76 ++++++++++ .../BlobContainerNameAttribute_Tests.cs | 25 +++ .../BlobContainer_Injection_Tests.cs | 32 ++++ .../Abp/BlobStoring/BlobContainer_Tests.cs | 143 ++++++++++++++++++ .../BlobStoring/BlobProviderSelector_Tests.cs | 30 ++++ .../BlobStoring/Fakes/FakeBlobProvider1.cs | 33 ++++ .../BlobStoring/Fakes/FakeBlobProvider2.cs | 33 ++++ .../Abp/BlobStoring/Fakes/FakeProviders.cs | 19 +++ .../BlobStoring/TestObjects/TestContainer1.cs | 6 + .../BlobStoring/TestObjects/TestContainer2.cs | 9 ++ .../BlobStoring/TestObjects/TestContainer3.cs | 6 + .../Aliyun/AliyunSmsVerifyCodeSender_Tests.cs | 33 +++- 22 files changed, 796 insertions(+), 4 deletions(-) create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN.Abp.BlobStoring.Tencent.Tests.csproj create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/AbpBlobStoringTencentTestBase.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/AbpBlobStoringTencentTestModule.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/DefaultTencentBlobNamingNormalizerProvider_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobContainer_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobNameCalculator_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN.Abp.BlobStoring.Tests.csproj create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringOptions_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringTestBase.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringTestModule.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainerFactory_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainerNameAttribute_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainer_Injection_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainer_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobProviderSelector_Tests.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeBlobProvider1.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeBlobProvider2.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeProviders.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer1.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer2.cs create mode 100644 aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer3.cs diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN.Abp.BlobStoring.Tencent.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN.Abp.BlobStoring.Tencent.Tests.csproj new file mode 100644 index 000000000..fd33ade61 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN.Abp.BlobStoring.Tencent.Tests.csproj @@ -0,0 +1,20 @@ + + + + net9.0 + + false + Debug;Release;PostgreSQL + AnyCPU + + + + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/AbpBlobStoringTencentTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/AbpBlobStoringTencentTestBase.cs new file mode 100644 index 000000000..67fe9e7b4 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/AbpBlobStoringTencentTestBase.cs @@ -0,0 +1,8 @@ +using LINGYUN.Abp.Tests; + +namespace LINGYUN.Abp.BlobStoring.Tencent; + +public class AbpBlobStoringTencentTestBase : AbpTestsBase +{ + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/AbpBlobStoringTencentTestModule.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/AbpBlobStoringTencentTestModule.cs new file mode 100644 index 000000000..8a0b38295 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/AbpBlobStoringTencentTestModule.cs @@ -0,0 +1,97 @@ +using COSXML; +using COSXML.Auth; +using LINGYUN.Abp.Tencent.Features; +using LINGYUN.Abp.Tencent.Settings; +using LINGYUN.Abp.Tests; +using LINGYUN.Abp.Tests.Features; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System.Linq; +using Volo.Abp; +using Volo.Abp.Autofac; +using Volo.Abp.BlobStoring; +using Volo.Abp.Modularity; +using Volo.Abp.Security.Encryption; + +namespace LINGYUN.Abp.BlobStoring.Tencent; + +[DependsOn( + typeof(AbpBlobStoringModule), + typeof(AbpBlobStoringTencentCloudModule), + typeof(AbpTestsBaseModule), + typeof(AbpAutofacModule) + )] +public class AbpBlobStoringTencentTestModule : AbpModule +{ + private string _bucketName; + private string _secretId; + private string _secretKey; + private string _region; + private string _appId; + + private IConfiguration _configuration; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + _configuration = context.Services.GetConfiguration(); + + _appId = _configuration[TencentBlobProviderConfigurationNames.AppId]; + _region = _configuration[TencentBlobProviderConfigurationNames.Region]; + _bucketName = _configuration[TencentBlobProviderConfigurationNames.BucketName]; + + Configure(options => + { + options.Map(TencentCloudFeatures.BlobStoring.MaximumStreamSize, (feature) => (int.MaxValue - 1024).ToString()); + }); + + Configure(options => + { + options.Containers.ConfigureAll((containerName, containerConfiguration) => + { + containerConfiguration.UseTencentCloud(blob => + { + blob.AppId = _appId; + blob.Region = _region; + blob.BucketName = _bucketName; + blob.CreateBucketIfNotExists = true; + }); + }); + }); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + var encryptionService = context.ServiceProvider.GetRequiredService(); + + _secretId = encryptionService.Decrypt(_configuration["Settings:" + TencentCloudSettingNames.SecretId]); + _secretKey = encryptionService.Decrypt(_configuration["Settings:" + TencentCloudSettingNames.SecretKey]); + } + + public override void OnApplicationShutdown(ApplicationShutdownContext context) + { + var configBuilder = new CosXmlConfig.Builder(); + configBuilder + .IsHttps(true) + .SetAppid(_appId) + .SetRegion(_region) + .SetDebugLog(true); + + var cred = new DefaultQCloudCredentialProvider( + _secretId, + _secretKey, + 60); + + var ossClient = new CosXmlServer(configBuilder.Build(), cred); + if (ossClient.DoesBucketExist(new COSXML.Model.Bucket.DoesBucketExistRequest(_bucketName))) + { + var bucket = ossClient.GetBucket(new COSXML.Model.Bucket.GetBucketRequest(_bucketName)); + if (bucket.listBucket.contentsList.Any()) + { + var request = new COSXML.Model.Object.DeleteMultiObjectRequest(_bucketName); + request.SetObjectKeys(bucket.listBucket.contentsList.Select(x => x.key).ToList()); + ossClient.DeleteMultiObjects(request); + } + ossClient.DeleteBucket(new COSXML.Model.Bucket.DeleteBucketRequest(_bucketName)); + } + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/DefaultTencentBlobNamingNormalizerProvider_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/DefaultTencentBlobNamingNormalizerProvider_Tests.cs new file mode 100644 index 000000000..0e1fedf57 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/DefaultTencentBlobNamingNormalizerProvider_Tests.cs @@ -0,0 +1,48 @@ +using Shouldly; +using Volo.Abp.BlobStoring; +using Xunit; + +namespace LINGYUN.Abp.BlobStoring.Tencent; + +public class DefaultTencentBlobNamingNormalizerProvider_Tests : AbpBlobStoringTencentTestBase +{ + private readonly IBlobNamingNormalizer _blobNamingNormalizer; + + public DefaultTencentBlobNamingNormalizerProvider_Tests() + { + _blobNamingNormalizer = GetRequiredService(); + } + + [Fact] + public void NormalizeContainerName_Lowercase() + { + var filename = "ThisIsMyContainerName"; + filename = _blobNamingNormalizer.NormalizeContainerName(filename); + filename.ShouldBe("thisismycontainername"); + } + + [Fact] + public void NormalizeContainerName_Only_Letters_Numbers_Dash() + { + var filename = ",./this-i,./s-my-c,./ont,./ai+*/.=!@#$n^&*er-name.+/"; + filename = _blobNamingNormalizer.NormalizeContainerName(filename); + filename.ShouldBe("this-is-my-container-name"); + } + + [Fact] + public void NormalizeContainerName_Max_Length() + { + var filename = "abpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabpabp"; + filename = _blobNamingNormalizer.NormalizeContainerName(filename); + filename.Length.ShouldBeLessThanOrEqualTo(63); + } + + [Fact] + public void NormalizeContainerName_Max_Length_Dash() + { + var filename = "-this-is-my-container-name-abpabpabpabpabpabpabpabp-a-b-p-a--b-p-"; + filename = _blobNamingNormalizer.NormalizeContainerName(filename); + filename.ShouldBe("this-is-my-container-name-abpabpabpabpabpabpabpabp-a-b-p-a--"); + } + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobContainer_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobContainer_Tests.cs new file mode 100644 index 000000000..bf1e9b332 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobContainer_Tests.cs @@ -0,0 +1,12 @@ +namespace LINGYUN.Abp.BlobStoring.Tencent; + + +//Please set the correct connection string in secrets.json and continue the test. +public class TencentBlobContainer_Tests : BlobContainer_Tests +{ + public TencentBlobContainer_Tests() + { + + + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobNameCalculator_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobNameCalculator_Tests.cs new file mode 100644 index 000000000..8dc65e2db --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tencent.Tests/LINGYUN/Abp/BlobStoring/Tencent/TencentBlobNameCalculator_Tests.cs @@ -0,0 +1,55 @@ +using Shouldly; +using System; +using Volo.Abp.BlobStoring; +using Volo.Abp.MultiTenancy; +using Xunit; + +namespace LINGYUN.Abp.BlobStoring.Tencent; + +public class TencentBlobNameCalculator_Tests : AbpBlobStoringTencentTestBase +{ + private readonly ITencentBlobNameCalculator _calculator; + private readonly ICurrentTenant _currentTenant; + + private const string AliyunSeparator = "/"; + + public TencentBlobNameCalculator_Tests() + { + _calculator = GetRequiredService(); + _currentTenant = GetRequiredService(); + } + + [Fact] + public void Default_Settings() + { + _calculator.Calculate( + GetArgs("my-container", "my-blob") + ).ShouldBe($"host{AliyunSeparator}my-blob"); + } + + [Fact] + public void Default_Settings_With_TenantId() + { + var tenantId = Guid.NewGuid(); + + using (_currentTenant.Change(tenantId)) + { + _calculator.Calculate( + GetArgs("my-container", "my-blob") + ).ShouldBe($"tenants{AliyunSeparator}{tenantId:D}{AliyunSeparator}my-blob"); + } + } + + private static BlobProviderArgs GetArgs( + string containerName, + string blobName) + { + return new BlobProviderGetArgs( + containerName, + new BlobContainerConfiguration().UseTencentCloud(x => + { + }), + blobName + ); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN.Abp.BlobStoring.Tests.csproj b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN.Abp.BlobStoring.Tests.csproj new file mode 100644 index 000000000..79464a180 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN.Abp.BlobStoring.Tests.csproj @@ -0,0 +1,20 @@ + + + + net9.0 + + false + Debug;Release;PostgreSQL + AnyCPU + + + + + + + + + + + + diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringOptions_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringOptions_Tests.cs new file mode 100644 index 000000000..f8112fa02 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringOptions_Tests.cs @@ -0,0 +1,39 @@ +using LINGYUN.Abp.BlobStoring.Fakes; +using LINGYUN.Abp.BlobStoring.TestObjects; +using Shouldly; +using Volo.Abp.BlobStoring; +using Xunit; + +namespace LINGYUN.Abp.BlobStoring; + +public class AbpBlobStoringOptions_Tests : AbpBlobStoringTestBase +{ + private readonly IBlobContainerConfigurationProvider _configurationProvider; + + public AbpBlobStoringOptions_Tests() + { + _configurationProvider = GetRequiredService(); + } + + [Fact] + public void Should_Property_Set_And_Get_Options_For_Different_Containers() + { + var testContainer1Config = _configurationProvider.Get(); + testContainer1Config.ProviderType.ShouldBe(typeof(FakeBlobProvider1)); + testContainer1Config.GetConfigurationOrDefault("TestConfig1").ShouldBe("TestValue1"); + testContainer1Config.GetConfigurationOrDefault("TestConfigDefault").ShouldBe("TestValueDefault"); + + var testContainer2Config = _configurationProvider.Get(); + testContainer2Config.ProviderType.ShouldBe(typeof(FakeBlobProvider2)); + testContainer2Config.GetConfigurationOrNull("TestConfig2").ShouldBe("TestValue2"); + testContainer2Config.GetConfigurationOrNull("TestConfigDefault").ShouldBe("TestValueDefault"); + } + + [Fact] + public void Should_Fallback_To_Default_Configuration_If_Not_Specialized() + { + var config = _configurationProvider.Get(); + config.ProviderType.ShouldBe(typeof(FakeBlobProvider1)); + config.GetConfigurationOrNull("TestConfigDefault").ShouldBe("TestValueDefault"); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringTestBase.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringTestBase.cs new file mode 100644 index 000000000..1da6f37bc --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringTestBase.cs @@ -0,0 +1,12 @@ +using Volo.Abp; +using Volo.Abp.Testing; + +namespace LINGYUN.Abp.BlobStoring; + +public abstract class AbpBlobStoringTestBase : AbpIntegratedTest +{ + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringTestModule.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringTestModule.cs new file mode 100644 index 000000000..b40fd6dcf --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/AbpBlobStoringTestModule.cs @@ -0,0 +1,44 @@ +using LINGYUN.Abp.BlobStoring.Fakes; +using LINGYUN.Abp.BlobStoring.TestObjects; +using LINGYUN.Abp.Tests; +using Microsoft.Extensions.DependencyInjection; +using NSubstitute; +using Volo.Abp.Autofac; +using Volo.Abp.BlobStoring; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.BlobStoring; + +[DependsOn( + typeof(AbpBlobStoringModule), + typeof(AbpTestsBaseModule), + typeof(AbpAutofacModule) + )] +public class AbpBlobStoringTestModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddSingleton(Substitute.For()); + context.Services.AddSingleton(Substitute.For()); + + Configure(options => + { + options.Containers + .ConfigureDefault(container => + { + container.SetConfiguration("TestConfigDefault", "TestValueDefault"); + container.ProviderType = typeof(FakeBlobProvider1); + }) + .Configure(container => + { + container.SetConfiguration("TestConfig1", "TestValue1"); + container.ProviderType = typeof(FakeBlobProvider1); + }) + .Configure(container => + { + container.SetConfiguration("TestConfig2", "TestValue2"); + container.ProviderType = typeof(FakeBlobProvider2); + }); + }); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainerFactory_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainerFactory_Tests.cs new file mode 100644 index 000000000..758a36976 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainerFactory_Tests.cs @@ -0,0 +1,76 @@ +using LINGYUN.Abp.BlobStoring.Fakes; +using LINGYUN.Abp.BlobStoring.TestObjects; +using NSubstitute; +using System.Threading.Tasks; +using Volo.Abp.BlobStoring; +using Xunit; + +namespace LINGYUN.Abp.BlobStoring; + +public class BlobContainerFactory_Tests : AbpBlobStoringTestBase +{ + private readonly IBlobContainerFactory _factory; + private readonly FakeProviders _fakeProviders; + + public BlobContainerFactory_Tests() + { + _factory = GetRequiredService(); + _fakeProviders = GetRequiredService(); + } + + [Fact] + public async Task Should_Create_Containers_With_Configured_Providers() + { + // TestContainer1 with FakeBlobProvider1 + + await _fakeProviders.Provider1 + .DidNotReceiveWithAnyArgs() + .ExistsAsync(default); + + await _factory + .Create() + .ExistsAsync("TestBlob1"); + + await _fakeProviders.Provider1 + .Received(1) + .ExistsAsync(Arg.Is(args => + args.ContainerName == BlobContainerNameAttribute.GetContainerName() && + args.BlobName == "TestBlob1" + ) + ); + + // TestContainer2 with FakeBlobProvider2 + + await _fakeProviders.Provider2 + .DidNotReceiveWithAnyArgs() + .ExistsAsync(default); + + await _factory + .Create() + .ExistsAsync("TestBlob2"); + + await _fakeProviders.Provider2 + .Received(1) + .ExistsAsync(Arg.Is(args => + args.ContainerName == BlobContainerNameAttribute.GetContainerName() && + args.BlobName == "TestBlob2" + ) + ); + + // TestContainer3 with FakeBlobProvider1 (default provider) + + _fakeProviders.Provider1.ClearReceivedCalls(); + + await _factory + .Create() + .ExistsAsync("TestBlob3"); + + await _fakeProviders.Provider1 + .Received(1) + .ExistsAsync(Arg.Is(t => + t.ContainerName == BlobContainerNameAttribute.GetContainerName() && + t.BlobName == "TestBlob3" + ) + ); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainerNameAttribute_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainerNameAttribute_Tests.cs new file mode 100644 index 000000000..ad52c33d2 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainerNameAttribute_Tests.cs @@ -0,0 +1,25 @@ +using LINGYUN.Abp.BlobStoring.TestObjects; +using Shouldly; +using Volo.Abp.BlobStoring; +using Xunit; + +namespace LINGYUN.Abp.BlobStoring; + +public class BlobContainerNameAttribute_Tests +{ + [Fact] + public void Should_Get_Specified_Name() + { + BlobContainerNameAttribute + .GetContainerName() + .ShouldBe("Test2"); + } + + [Fact] + public void Should_Get_Full_Class_Name_If_Not_Specified() + { + BlobContainerNameAttribute + .GetContainerName() + .ShouldBe(typeof(TestContainer1).FullName); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainer_Injection_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainer_Injection_Tests.cs new file mode 100644 index 000000000..e5c5de339 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainer_Injection_Tests.cs @@ -0,0 +1,32 @@ +using LINGYUN.Abp.BlobStoring.TestObjects; +using Shouldly; +using Volo.Abp.BlobStoring; +using Xunit; + +namespace LINGYUN.Abp.BlobStoring; + +public class BlobContainer_Injection_Tests : AbpBlobStoringTestBase +{ + [Fact] + public void Should_Inject_DefaultContainer_For_Non_Generic_Interface() + { + GetRequiredService() + .ShouldBeOfType>(); + } + + [Fact] + public void Should_Inject_Specified_Container_For_Generic_Interface() + { + GetRequiredService>() + .ShouldBeOfType>(); + + GetRequiredService>() + .ShouldBeOfType>(); + + GetRequiredService>() + .ShouldBeOfType>(); + + GetRequiredService>() + .ShouldBeOfType>(); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainer_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainer_Tests.cs new file mode 100644 index 000000000..ef457569b --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobContainer_Tests.cs @@ -0,0 +1,143 @@ +using LINGYUN.Abp.BlobStoring.TestObjects; +using Shouldly; +using System; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.BlobStoring; +using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; +using Volo.Abp.Testing; +using Xunit; + +namespace LINGYUN.Abp.BlobStoring; + +public abstract class BlobContainer_Tests : AbpIntegratedTest + where TStartupModule : IAbpModule +{ + protected IBlobContainer Container { get; } + + protected ICurrentTenant CurrentTenant { get; } + + protected BlobContainer_Tests() + { + Container = GetRequiredService>(); + CurrentTenant = GetRequiredService(); + } + + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + + [Theory] + [InlineData("test-blob-1")] + [InlineData("test-blob-1.txt")] + [InlineData("test-folder/test-blob-1")] + public async Task Should_Save_And_Get_Blobs(string blobName) + { + var testContent = "test content".GetBytes(); + await Container.SaveAsync(blobName, testContent); + + var result = await Container.GetAllBytesAsync(blobName); + result.SequenceEqual(testContent).ShouldBeTrue(); + } + + [Fact] + public async Task Should_Save_And_Get_Blobs_In_Different_Tenant() + { + var blobName = "test-blob-1"; + var testContent = "test content".GetBytes(); + + using (CurrentTenant.Change(Guid.NewGuid())) + { + await Container.SaveAsync(blobName, testContent); + (await Container.GetAllBytesAsync(blobName)).SequenceEqual(testContent).ShouldBeTrue(); + } + + using (CurrentTenant.Change(Guid.NewGuid())) + { + await Container.SaveAsync(blobName, testContent); + (await Container.GetAllBytesAsync(blobName)).SequenceEqual(testContent).ShouldBeTrue(); + + using (CurrentTenant.Change(null)) + { + // Could not find the requested BLOB... + await Assert.ThrowsAsync(async () => + await Container.GetAllBytesAsync(blobName) + ); + } + } + + using (CurrentTenant.Change(null)) + { + await Container.SaveAsync(blobName, testContent); + (await Container.GetAllBytesAsync(blobName)).SequenceEqual(testContent).ShouldBeTrue(); + } + } + + [Fact] + public async Task Should_Overwrite_Pre_Saved_Blob_If_Requested() + { + var blobName = "test-blob-1"; + + var testContent = "test content".GetBytes(); + await Container.SaveAsync(blobName, testContent); + + var testContentOverwritten = "test content overwritten".GetBytes(); + await Container.SaveAsync(blobName, testContentOverwritten, true); + + var result = await Container.GetAllBytesAsync(blobName); + result.SequenceEqual(testContentOverwritten).ShouldBeTrue(); + } + + [Fact] + public async Task Should_Not_Allow_To_Overwrite_Pre_Saved_Blob_By_Default() + { + var blobName = "test-blob-1"; + + var testContent = "test content".GetBytes(); + await Container.SaveAsync(blobName, testContent); + + var testContentOverwritten = "test content overwritten".GetBytes(); + await Assert.ThrowsAsync(() => + Container.SaveAsync(blobName, testContentOverwritten) + ); + } + + [Theory] + [InlineData("test-blob-1")] + [InlineData("test-blob-1.txt")] + [InlineData("test-folder/test-blob-1")] + public async Task Should_Delete_Saved_Blobs(string blobName) + { + await Container.SaveAsync(blobName, "test content".GetBytes()); + (await Container.GetAllBytesAsync(blobName)).ShouldNotBeNull(); + + await Container.DeleteAsync(blobName); + (await Container.GetAllBytesOrNullAsync(blobName)).ShouldBeNull(); + } + + [Theory] + [InlineData("test-blob-1")] + [InlineData("test-blob-1.txt")] + [InlineData("test-folder/test-blob-1")] + public async Task Saved_Blobs_Should_Exists(string blobName) + { + await Container.SaveAsync(blobName, "test content".GetBytes()); + (await Container.ExistsAsync(blobName)).ShouldBeTrue(); + + await Container.DeleteAsync(blobName); + (await Container.ExistsAsync(blobName)).ShouldBeFalse(); + } + + [Theory] + [InlineData("test-blob-1")] + [InlineData("test-blob-1.txt")] + [InlineData("test-folder/test-blob-1")] + public async Task Unknown_Blobs_Should_Not_Exists(string blobName) + { + await Container.DeleteAsync(blobName); + (await Container.ExistsAsync(blobName)).ShouldBeFalse(); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobProviderSelector_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobProviderSelector_Tests.cs new file mode 100644 index 000000000..cbbb54fff --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/BlobProviderSelector_Tests.cs @@ -0,0 +1,30 @@ +using LINGYUN.Abp.BlobStoring.Fakes; +using LINGYUN.Abp.BlobStoring.TestObjects; +using Shouldly; +using Volo.Abp.BlobStoring; +using Xunit; + +namespace LINGYUN.Abp.BlobStoring; + +public class BlobProviderSelector_Tests : AbpBlobStoringTestBase +{ + private readonly IBlobProviderSelector _selector; + + public BlobProviderSelector_Tests() + { + _selector = GetRequiredService(); + } + + [Fact] + public void Should_Select_Default_Provider_If_Not_Configured() + { + _selector.Get().ShouldBeAssignableTo(); + } + + [Fact] + public void Should_Select_Configured_Provider() + { + _selector.Get().ShouldBeAssignableTo(); + _selector.Get().ShouldBeAssignableTo(); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeBlobProvider1.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeBlobProvider1.cs new file mode 100644 index 000000000..57850d959 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeBlobProvider1.cs @@ -0,0 +1,33 @@ +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.BlobStoring; + +namespace LINGYUN.Abp.BlobStoring.Fakes; + +public class FakeBlobProvider1 : IBlobProvider +{ + public virtual Task SaveAsync(BlobProviderSaveArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task DeleteAsync(BlobProviderDeleteArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task ExistsAsync(BlobProviderExistsArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetOrNullAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeBlobProvider2.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeBlobProvider2.cs new file mode 100644 index 000000000..93bf525b6 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeBlobProvider2.cs @@ -0,0 +1,33 @@ +using System.IO; +using System.Threading.Tasks; +using Volo.Abp.BlobStoring; + +namespace LINGYUN.Abp.BlobStoring.Fakes; + +public class FakeBlobProvider2 : IBlobProvider +{ + public virtual Task SaveAsync(BlobProviderSaveArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task DeleteAsync(BlobProviderDeleteArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task ExistsAsync(BlobProviderExistsArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } + + public virtual Task GetOrNullAsync(BlobProviderGetArgs args) + { + throw new System.NotImplementedException(); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeProviders.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeProviders.cs new file mode 100644 index 000000000..4a6864241 --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/Fakes/FakeProviders.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Linq; +using Volo.Abp.BlobStoring; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.BlobStoring.Fakes; + +public class FakeProviders : ISingletonDependency +{ + public FakeBlobProvider1 Provider1 { get; } + + public FakeBlobProvider2 Provider2 { get; } + + public FakeProviders(IEnumerable providers) + { + Provider1 = providers.OfType().Single(); + Provider2 = providers.OfType().Single(); + } +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer1.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer1.cs new file mode 100644 index 000000000..26cfbe94d --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer1.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.BlobStoring.TestObjects; + +public class TestContainer1 +{ + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer2.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer2.cs new file mode 100644 index 000000000..c937b90ba --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer2.cs @@ -0,0 +1,9 @@ +using Volo.Abp.BlobStoring; + +namespace LINGYUN.Abp.BlobStoring.TestObjects; + +[BlobContainerName("Test2")] +public class TestContainer2 +{ + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer3.cs b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer3.cs new file mode 100644 index 000000000..21368073b --- /dev/null +++ b/aspnet-core/tests/LINGYUN.Abp.BlobStoring.Tests/LINGYUN/Abp/BlobStoring/TestObjects/TestContainer3.cs @@ -0,0 +1,6 @@ +namespace LINGYUN.Abp.BlobStoring.TestObjects; + +public class TestContainer3 +{ + +} diff --git a/aspnet-core/tests/LINGYUN.Abp.Sms.Aliyun.Tests/LINGYUN/Abp/Sms/Aliyun/AliyunSmsVerifyCodeSender_Tests.cs b/aspnet-core/tests/LINGYUN.Abp.Sms.Aliyun.Tests/LINGYUN/Abp/Sms/Aliyun/AliyunSmsVerifyCodeSender_Tests.cs index 04e15c5d8..ea63851ed 100644 --- a/aspnet-core/tests/LINGYUN.Abp.Sms.Aliyun.Tests/LINGYUN/Abp/Sms/Aliyun/AliyunSmsVerifyCodeSender_Tests.cs +++ b/aspnet-core/tests/LINGYUN.Abp.Sms.Aliyun.Tests/LINGYUN/Abp/Sms/Aliyun/AliyunSmsVerifyCodeSender_Tests.cs @@ -1,16 +1,19 @@ using Microsoft.Extensions.Configuration; using System.Threading.Tasks; +using Volo.Abp.Sms; using Xunit; namespace LINGYUN.Abp.Sms.Aliyun; public class AliyunSmsVerifyCodeSender_Tests : AbpAliyunTestBase { - protected IAliyunSmsVerifyCodeSender SmsSender { get; } + protected IAliyunSmsVerifyCodeSender SmsVerifyCodeSender { get; } + protected ISmsSender SmsSender { get; } protected IConfiguration Configuration { get; } public AliyunSmsVerifyCodeSender_Tests() { - SmsSender = GetRequiredService(); + SmsSender = GetRequiredService(); + SmsVerifyCodeSender = GetRequiredService(); Configuration = GetRequiredService(); } @@ -21,17 +24,39 @@ public class AliyunSmsVerifyCodeSender_Tests : AbpAliyunTestBase /// [Theory] [InlineData("123456")] - public async Task Send_Test(string code) + public async Task Send_Sms_Verify_Code_Test(string code) { var signName = Configuration["Aliyun:Sms:Sender:SignName"]; var phone = Configuration["Aliyun:Sms:Sender:PhoneNumber"]; var template = Configuration["Aliyun:Sms:Sender:TemplateCode"]; - await SmsSender.SendAsync( + await SmsVerifyCodeSender.SendAsync( new SmsVerifyCodeMessage( phone, new SmsVerifyCodeMessageParam(code), signName, template)); } + + /// + /// 阿里云短信测试 + /// + /// + /// + [Theory] + [InlineData("123456")] + public async Task Send_Sms_Test(string code) + { + var signName = Configuration["Aliyun:Sms:Sender:SignName"]; + var phone = Configuration["Aliyun:Sms:Sender:PhoneNumber"]; + var template = Configuration["Aliyun:Sms:Sender:TemplateCode"]; + + var message = new SmsMessage(phone, "test"); + message.Properties.Add("SignName", signName); + message.Properties.Add("SmsVerifyCode", true); + message.Properties.Add("TemplateCode", template); + message.Properties.Add("code", code); + + await SmsSender.SendAsync(message); + } }