committed by
GitHub
22 changed files with 796 additions and 4 deletions
@ -0,0 +1,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net9.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<IsPackable>false</IsPackable> |
|||
<Configurations>Debug;Release;PostgreSQL</Configurations> |
|||
<Platforms>AnyCPU</Platforms> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\framework\cloud-tencent\LINGYUN.Abp.BlobStoring.Tencent\LINGYUN.Abp.BlobStoring.Tencent.csproj" /> |
|||
<ProjectReference Include="..\LINGYUN.Abp.BlobStoring.Tests\LINGYUN.Abp.BlobStoring.Tests.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,8 @@ |
|||
using LINGYUN.Abp.Tests; |
|||
|
|||
namespace LINGYUN.Abp.BlobStoring.Tencent; |
|||
|
|||
public class AbpBlobStoringTencentTestBase : AbpTestsBase<AbpBlobStoringTencentTestModule> |
|||
{ |
|||
|
|||
} |
|||
@ -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<FakeFeatureOptions>(options => |
|||
{ |
|||
options.Map(TencentCloudFeatures.BlobStoring.MaximumStreamSize, (feature) => (int.MaxValue - 1024).ToString()); |
|||
}); |
|||
|
|||
Configure<AbpBlobStoringOptions>(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<IStringEncryptionService>(); |
|||
|
|||
_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)); |
|||
} |
|||
} |
|||
} |
|||
@ -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<IBlobNamingNormalizer>(); |
|||
} |
|||
|
|||
[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--"); |
|||
} |
|||
|
|||
} |
|||
@ -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<AbpBlobStoringTencentTestModule> |
|||
{ |
|||
public TencentBlobContainer_Tests() |
|||
{ |
|||
|
|||
|
|||
} |
|||
} |
|||
@ -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<ITencentBlobNameCalculator>(); |
|||
_currentTenant = GetRequiredService<ICurrentTenant>(); |
|||
} |
|||
|
|||
[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 |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net9.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<IsPackable>false</IsPackable> |
|||
<Configurations>Debug;Release;PostgreSQL</Configurations> |
|||
<Platforms>AnyCPU</Platforms> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" /> |
|||
<PackageReference Include="Volo.Abp.BlobStoring" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -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<IBlobContainerConfigurationProvider>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Property_Set_And_Get_Options_For_Different_Containers() |
|||
{ |
|||
var testContainer1Config = _configurationProvider.Get<TestContainer1>(); |
|||
testContainer1Config.ProviderType.ShouldBe(typeof(FakeBlobProvider1)); |
|||
testContainer1Config.GetConfigurationOrDefault<string>("TestConfig1").ShouldBe("TestValue1"); |
|||
testContainer1Config.GetConfigurationOrDefault<string>("TestConfigDefault").ShouldBe("TestValueDefault"); |
|||
|
|||
var testContainer2Config = _configurationProvider.Get<TestContainer2>(); |
|||
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<TestContainer3>(); |
|||
config.ProviderType.ShouldBe(typeof(FakeBlobProvider1)); |
|||
config.GetConfigurationOrNull("TestConfigDefault").ShouldBe("TestValueDefault"); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp; |
|||
using Volo.Abp.Testing; |
|||
|
|||
namespace LINGYUN.Abp.BlobStoring; |
|||
|
|||
public abstract class AbpBlobStoringTestBase : AbpIntegratedTest<AbpBlobStoringTestModule> |
|||
{ |
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
} |
|||
@ -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<IBlobProvider>(Substitute.For<FakeBlobProvider1>()); |
|||
context.Services.AddSingleton<IBlobProvider>(Substitute.For<FakeBlobProvider2>()); |
|||
|
|||
Configure<AbpBlobStoringOptions>(options => |
|||
{ |
|||
options.Containers |
|||
.ConfigureDefault(container => |
|||
{ |
|||
container.SetConfiguration("TestConfigDefault", "TestValueDefault"); |
|||
container.ProviderType = typeof(FakeBlobProvider1); |
|||
}) |
|||
.Configure<TestContainer1>(container => |
|||
{ |
|||
container.SetConfiguration("TestConfig1", "TestValue1"); |
|||
container.ProviderType = typeof(FakeBlobProvider1); |
|||
}) |
|||
.Configure<TestContainer2>(container => |
|||
{ |
|||
container.SetConfiguration("TestConfig2", "TestValue2"); |
|||
container.ProviderType = typeof(FakeBlobProvider2); |
|||
}); |
|||
}); |
|||
} |
|||
} |
|||
@ -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<IBlobContainerFactory>(); |
|||
_fakeProviders = GetRequiredService<FakeProviders>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Create_Containers_With_Configured_Providers() |
|||
{ |
|||
// TestContainer1 with FakeBlobProvider1
|
|||
|
|||
await _fakeProviders.Provider1 |
|||
.DidNotReceiveWithAnyArgs() |
|||
.ExistsAsync(default); |
|||
|
|||
await _factory |
|||
.Create<TestContainer1>() |
|||
.ExistsAsync("TestBlob1"); |
|||
|
|||
await _fakeProviders.Provider1 |
|||
.Received(1) |
|||
.ExistsAsync(Arg.Is<BlobProviderExistsArgs>(args => |
|||
args.ContainerName == BlobContainerNameAttribute.GetContainerName<TestContainer1>() && |
|||
args.BlobName == "TestBlob1" |
|||
) |
|||
); |
|||
|
|||
// TestContainer2 with FakeBlobProvider2
|
|||
|
|||
await _fakeProviders.Provider2 |
|||
.DidNotReceiveWithAnyArgs() |
|||
.ExistsAsync(default); |
|||
|
|||
await _factory |
|||
.Create<TestContainer2>() |
|||
.ExistsAsync("TestBlob2"); |
|||
|
|||
await _fakeProviders.Provider2 |
|||
.Received(1) |
|||
.ExistsAsync(Arg.Is<BlobProviderExistsArgs>(args => |
|||
args.ContainerName == BlobContainerNameAttribute.GetContainerName<TestContainer2>() && |
|||
args.BlobName == "TestBlob2" |
|||
) |
|||
); |
|||
|
|||
// TestContainer3 with FakeBlobProvider1 (default provider)
|
|||
|
|||
_fakeProviders.Provider1.ClearReceivedCalls(); |
|||
|
|||
await _factory |
|||
.Create<TestContainer3>() |
|||
.ExistsAsync("TestBlob3"); |
|||
|
|||
await _fakeProviders.Provider1 |
|||
.Received(1) |
|||
.ExistsAsync(Arg.Is<BlobProviderExistsArgs>(t => |
|||
t.ContainerName == BlobContainerNameAttribute.GetContainerName<TestContainer3>() && |
|||
t.BlobName == "TestBlob3" |
|||
) |
|||
); |
|||
} |
|||
} |
|||
@ -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<TestContainer2>() |
|||
.ShouldBe("Test2"); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Get_Full_Class_Name_If_Not_Specified() |
|||
{ |
|||
BlobContainerNameAttribute |
|||
.GetContainerName<TestContainer1>() |
|||
.ShouldBe(typeof(TestContainer1).FullName); |
|||
} |
|||
} |
|||
@ -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<IBlobContainer>() |
|||
.ShouldBeOfType<BlobContainer<DefaultContainer>>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Inject_Specified_Container_For_Generic_Interface() |
|||
{ |
|||
GetRequiredService<IBlobContainer<DefaultContainer>>() |
|||
.ShouldBeOfType<BlobContainer<DefaultContainer>>(); |
|||
|
|||
GetRequiredService<IBlobContainer<TestContainer1>>() |
|||
.ShouldBeOfType<BlobContainer<TestContainer1>>(); |
|||
|
|||
GetRequiredService<IBlobContainer<TestContainer2>>() |
|||
.ShouldBeOfType<BlobContainer<TestContainer2>>(); |
|||
|
|||
GetRequiredService<IBlobContainer<TestContainer3>>() |
|||
.ShouldBeOfType<BlobContainer<TestContainer3>>(); |
|||
} |
|||
} |
|||
@ -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<TStartupModule> : AbpIntegratedTest<TStartupModule> |
|||
where TStartupModule : IAbpModule |
|||
{ |
|||
protected IBlobContainer<TestContainer1> Container { get; } |
|||
|
|||
protected ICurrentTenant CurrentTenant { get; } |
|||
|
|||
protected BlobContainer_Tests() |
|||
{ |
|||
Container = GetRequiredService<IBlobContainer<TestContainer1>>(); |
|||
CurrentTenant = GetRequiredService<ICurrentTenant>(); |
|||
} |
|||
|
|||
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<AbpException>(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<BlobAlreadyExistsException>(() => |
|||
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(); |
|||
} |
|||
} |
|||
@ -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<IBlobProviderSelector>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Select_Default_Provider_If_Not_Configured() |
|||
{ |
|||
_selector.Get<TestContainer3>().ShouldBeAssignableTo<FakeBlobProvider1>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Should_Select_Configured_Provider() |
|||
{ |
|||
_selector.Get<TestContainer1>().ShouldBeAssignableTo<FakeBlobProvider1>(); |
|||
_selector.Get<TestContainer2>().ShouldBeAssignableTo<FakeBlobProvider2>(); |
|||
} |
|||
} |
|||
@ -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<bool> DeleteAsync(BlobProviderDeleteArgs args) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
|
|||
public virtual Task<bool> ExistsAsync(BlobProviderExistsArgs args) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
|
|||
public virtual Task<Stream> GetAsync(BlobProviderGetArgs args) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
|
|||
public virtual Task<Stream> GetOrNullAsync(BlobProviderGetArgs args) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
} |
|||
@ -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<bool> DeleteAsync(BlobProviderDeleteArgs args) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
|
|||
public virtual Task<bool> ExistsAsync(BlobProviderExistsArgs args) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
|
|||
public virtual Task<Stream> GetAsync(BlobProviderGetArgs args) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
|
|||
public virtual Task<Stream> GetOrNullAsync(BlobProviderGetArgs args) |
|||
{ |
|||
throw new System.NotImplementedException(); |
|||
} |
|||
} |
|||
@ -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<IBlobProvider> providers) |
|||
{ |
|||
Provider1 = providers.OfType<FakeBlobProvider1>().Single(); |
|||
Provider2 = providers.OfType<FakeBlobProvider2>().Single(); |
|||
} |
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Abp.BlobStoring.TestObjects; |
|||
|
|||
public class TestContainer1 |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,9 @@ |
|||
using Volo.Abp.BlobStoring; |
|||
|
|||
namespace LINGYUN.Abp.BlobStoring.TestObjects; |
|||
|
|||
[BlobContainerName("Test2")] |
|||
public class TestContainer2 |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,6 @@ |
|||
namespace LINGYUN.Abp.BlobStoring.TestObjects; |
|||
|
|||
public class TestContainer3 |
|||
{ |
|||
|
|||
} |
|||
Loading…
Reference in new issue