mirror of https://github.com/abpframework/abp.git
84 changed files with 1323 additions and 418 deletions
@ -0,0 +1,16 @@ |
|||
namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice |
|||
{ |
|||
public class MicroserviceServiceProTemplate : MicroserviceServiceTemplateBase |
|||
{ |
|||
/// <summary>
|
|||
/// "microservice-service-pro".
|
|||
/// </summary>
|
|||
public const string TemplateName = "microservice-service-pro"; |
|||
|
|||
public MicroserviceServiceProTemplate() |
|||
: base(TemplateName) |
|||
{ |
|||
DocumentUrl = null; // todo: set this
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Cli.ProjectBuilding.Building; |
|||
using Volo.Abp.Cli.ProjectBuilding.Building.Steps; |
|||
|
|||
namespace Volo.Abp.Cli.ProjectBuilding.Templates.Microservice |
|||
{ |
|||
public abstract class MicroserviceServiceTemplateBase : TemplateInfo |
|||
{ |
|||
protected MicroserviceServiceTemplateBase([NotNull] string name) |
|||
: base(name) |
|||
{ |
|||
} |
|||
|
|||
public static bool IsMicroserviceServiceTemplate(string templateName) |
|||
{ |
|||
return templateName == MicroserviceServiceProTemplate.TemplateName; |
|||
} |
|||
|
|||
public static string CalculateTargetFolder(string mainSolutionFolder, string serviceName) |
|||
{ |
|||
serviceName = serviceName.ToCamelCase().RemovePostFix("Service"); |
|||
|
|||
return Path.Combine(mainSolutionFolder, "microservices", serviceName); |
|||
} |
|||
|
|||
public override IEnumerable<ProjectBuildPipelineStep> GetCustomSteps(ProjectBuildContext context) |
|||
{ |
|||
var steps = new List<ProjectBuildPipelineStep>(); |
|||
|
|||
DeleteUnrelatedUiProject(context, steps); |
|||
RandomizeStringEncryption(context, steps); |
|||
|
|||
return steps; |
|||
} |
|||
|
|||
private static void DeleteUnrelatedUiProject(ProjectBuildContext context, List<ProjectBuildPipelineStep> steps) |
|||
{ |
|||
switch (context.BuildArgs.UiFramework) |
|||
{ |
|||
case UiFramework.Blazor: |
|||
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.MicroserviceName.Web")); |
|||
break; |
|||
case UiFramework.Mvc: |
|||
case UiFramework.NotSpecified: |
|||
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.MicroserviceName.Blazor")); |
|||
break; |
|||
default: |
|||
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.MicroserviceName.Blazor")); |
|||
steps.Add(new RemoveProjectFromSolutionStep("MyCompanyName.MyProjectName.MicroserviceName.Web")); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
private static void RandomizeStringEncryption(ProjectBuildContext context, List<ProjectBuildPipelineStep> steps) |
|||
{ |
|||
steps.Add(new RandomizeStringEncryptionStep()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false"/> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,24 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
<Import Project="..\..\..\configureawait.props"/> |
|||
<Import Project="..\..\..\common.props"/> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>netstandard2.0</TargetFramework> |
|||
<AssemblyName>Volo.Abp.Sms.Aliyun</AssemblyName> |
|||
<PackageId>Volo.Abp.Sms.Aliyun</PackageId> |
|||
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback> |
|||
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute> |
|||
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute> |
|||
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute> |
|||
<RootNamespace/> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\Volo.Abp.Sms\Volo.Abp.Sms.csproj"/> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="AlibabaCloud.SDK.Dysmsapi20170525" Version="1.0.2"/> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,11 @@ |
|||
namespace Volo.Abp.Sms.Aliyun |
|||
{ |
|||
public class AbpAliyunSmsOptions |
|||
{ |
|||
public string AccessKeySecret { get; set; } |
|||
|
|||
public string AccessKeyId { get; set; } |
|||
|
|||
public string EndPoint { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Sms.Aliyun |
|||
{ |
|||
[DependsOn(typeof(AbpSmsModule))] |
|||
public class AbpSmsAliyunModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
Configure<AbpAliyunSmsOptions>(configuration.GetSection("AbpAliyunSms")); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,43 @@ |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Options; |
|||
using Volo.Abp.DependencyInjection; |
|||
using AliyunClient = AlibabaCloud.SDK.Dysmsapi20170525.Client; |
|||
using AliyunConfig = AlibabaCloud.OpenApiClient.Models.Config; |
|||
using AliyunSendSmsRequest = AlibabaCloud.SDK.Dysmsapi20170525.Models.SendSmsRequest; |
|||
|
|||
namespace Volo.Abp.Sms.Aliyun |
|||
{ |
|||
public class AliyunSmsSender : ISmsSender, ITransientDependency |
|||
{ |
|||
protected AbpAliyunSmsOptions Options { get; } |
|||
|
|||
public AliyunSmsSender(IOptionsSnapshot<AbpAliyunSmsOptions> options) |
|||
{ |
|||
Options = options.Value; |
|||
} |
|||
|
|||
public async Task SendAsync(SmsMessage smsMessage) |
|||
{ |
|||
var client = CreateClient(); |
|||
|
|||
await client.SendSmsAsync(new AliyunSendSmsRequest |
|||
{ |
|||
PhoneNumbers = smsMessage.PhoneNumber, |
|||
SignName = smsMessage.Properties.GetOrDefault("SignName") as string, |
|||
TemplateCode = smsMessage.Properties.GetOrDefault("TemplateCode") as string, |
|||
TemplateParam = smsMessage.Text |
|||
}); |
|||
} |
|||
|
|||
protected virtual AliyunClient CreateClient() |
|||
{ |
|||
return new(new AliyunConfig |
|||
{ |
|||
AccessKeyId = Options.AccessKeyId, |
|||
AccessKeySecret = Options.AccessKeySecret, |
|||
Endpoint = Options.EndPoint |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\common.test.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net5.0</TargetFramework> |
|||
<RootNamespace /> |
|||
<UserSecretsId>9f0d2c00-80c1-435b-bfab-2c39c8249091</UserSecretsId> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" /> |
|||
<ProjectReference Include="..\..\src\Volo.Abp.Sms.Aliyun\Volo.Abp.Sms.Aliyun.csproj" /> |
|||
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> |
|||
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="$(MicrosoftPackageVersion)" /> |
|||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<None Remove="appsettings.json" /> |
|||
<Content Include="appsettings.json"> |
|||
<CopyToOutputDirectory>Always</CopyToOutputDirectory> |
|||
</Content> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,12 @@ |
|||
using Volo.Abp.Testing; |
|||
|
|||
namespace Volo.Abp.Sms.Aliyun |
|||
{ |
|||
public class AbpSmsAliyunTestBase : AbpIntegratedTest<AbpSmsAliyunTestsModule> |
|||
{ |
|||
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) |
|||
{ |
|||
options.UseAutofac(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
using Microsoft.Extensions.DependencyInjection; |
|||
using Volo.Abp.Modularity; |
|||
|
|||
namespace Volo.Abp.Sms.Aliyun |
|||
{ |
|||
[DependsOn(typeof(AbpSmsAliyunModule))] |
|||
public class AbpSmsAliyunTestsModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
var configuration = context.Services.GetConfiguration(); |
|||
|
|||
Configure<AbpAliyunSmsOptions>( |
|||
configuration.GetSection("AbpAliyunSms") |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,37 @@ |
|||
using System.Threading.Tasks; |
|||
using Microsoft.Extensions.Configuration; |
|||
using Xunit; |
|||
|
|||
namespace Volo.Abp.Sms.Aliyun |
|||
{ |
|||
public class AliyunSmsSender_Tests : AbpSmsAliyunTestBase |
|||
{ |
|||
private readonly ISmsSender _smsSender; |
|||
private readonly IConfiguration _configuration; |
|||
|
|||
public AliyunSmsSender_Tests() |
|||
{ |
|||
_configuration = GetRequiredService<IConfiguration>(); |
|||
_smsSender = GetRequiredService<ISmsSender>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task SendSms_Test() |
|||
{ |
|||
var config = _configuration.GetSection("AbpAliyunSms"); |
|||
|
|||
// Please fill in the real parameters in the appsettings.json file.
|
|||
if (config["AccessKeyId"] == "<Enter your AccessKeyId from Aliyun>") |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
var msg = new SmsMessage(config["TargetPhoneNumber"], |
|||
config["TemplateParam"]); |
|||
msg.Properties.Add("SignName", config["SignName"]); |
|||
msg.Properties.Add("TemplateCode", config["TemplateCode"]); |
|||
|
|||
await _smsSender.SendAsync(msg); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
{ |
|||
"AbpAliyunSms": { |
|||
"AccessKeySecret": "<Enter your AccessKeySecret from Aliyun>", |
|||
"AccessKeyId": "<Enter your AccessKeyId from Aliyun>", |
|||
"EndPoint": "<Enter your EndPoint from Aliyun>", |
|||
"TargetPhoneNumber": "<Enter the target phone number to receive the SMS>", |
|||
"SignName": "<Enter the SignName from Aliyun>", |
|||
"TemplateCode": "<Enter the TemplateCode you need to send>", |
|||
"TemplateParam": "<Enter the template parameters>" |
|||
} |
|||
} |
|||
@ -1,20 +1,13 @@ |
|||
using System; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Validation; |
|||
using Volo.CmsKit.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Admin.Blogs |
|||
{ |
|||
[Serializable] |
|||
public class BlogDto : EntityDto<Guid> |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
|
|||
[Required] |
|||
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxSlugLength))] |
|||
public string Slug { get; set; } |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,17 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
using Volo.CmsKit.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Admin.Blogs |
|||
{ |
|||
public class CreateBlogDto |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
|
|||
[Required] |
|||
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxSlugLength))] |
|||
public string Slug { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
using Volo.CmsKit.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Admin.Blogs |
|||
{ |
|||
public class UpdateBlogDto |
|||
{ |
|||
[Required] |
|||
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] |
|||
public string Name { get; set; } |
|||
|
|||
[Required] |
|||
[DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxSlugLength))] |
|||
public string Slug { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using System.Threading.Tasks; |
|||
using JetBrains.Annotations; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace Volo.CmsKit.Blogs |
|||
{ |
|||
public class BlogManager : DomainService |
|||
{ |
|||
protected IBlogRepository BlogRepository { get; } |
|||
|
|||
public BlogManager(IBlogRepository blogRepository) |
|||
{ |
|||
BlogRepository = blogRepository; |
|||
} |
|||
|
|||
public virtual async Task<Blog> CreateAsync([NotNull] string name, [NotNull] string slug) |
|||
{ |
|||
await CheckSlugAsync(slug); |
|||
|
|||
return new Blog(GuidGenerator.Create(), name, slug, CurrentTenant.Id); |
|||
} |
|||
|
|||
public virtual async Task<Blog> UpdateAsync([NotNull] Blog blog, [NotNull] string name, [NotNull] string slug) |
|||
{ |
|||
if (slug != blog.Slug) |
|||
{ |
|||
await CheckSlugAsync(slug); |
|||
} |
|||
|
|||
blog.SetName(name); |
|||
blog.SetSlug(slug); |
|||
|
|||
return blog; |
|||
} |
|||
|
|||
protected virtual async Task CheckSlugAsync([NotNull] string slug) |
|||
{ |
|||
if (await BlogRepository.SlugExistsAsync(slug)) |
|||
{ |
|||
throw new BlogSlugAlreadyExistException(slug); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
using System.Runtime.Serialization; |
|||
using Volo.Abp; |
|||
|
|||
namespace Volo.CmsKit.Blogs |
|||
{ |
|||
[Serializable] |
|||
public class BlogSlugAlreadyExistException : BusinessException |
|||
{ |
|||
public BlogSlugAlreadyExistException(string slug) |
|||
{ |
|||
Code = CmsKitErrorCodes.Blogs.SlugAlreadyExists; |
|||
|
|||
WithData(nameof(Blog.Slug), slug); |
|||
} |
|||
|
|||
public BlogSlugAlreadyExistException( |
|||
SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) |
|||
{ |
|||
} |
|||
} |
|||
} |
|||
@ -1,24 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public interface IEntityTagManager |
|||
{ |
|||
Task<EntityTag> AddTagToEntityAsync( |
|||
[NotNull] Guid tagId, |
|||
[NotNull] string entityType, |
|||
[NotNull] string entityId, |
|||
[CanBeNull] Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task RemoveTagFromEntityAsync( |
|||
[NotNull] Guid tagId, |
|||
[NotNull] string entityType, |
|||
[NotNull] string entityId, |
|||
[CanBeNull] Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
} |
|||
@ -1,33 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Services; |
|||
using Volo.CmsKit.Tags; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public interface ITagManager : IDomainService |
|||
{ |
|||
Task<Tag> InsertAsync( |
|||
Guid id, |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<Tag> UpdateAsync( |
|||
Guid id, |
|||
[NotNull] string name, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<Tag> GetOrAddAsync( |
|||
[NotNull] string entityType, |
|||
[NotNull] string name, |
|||
Guid? tenantId = null, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<List<TagEntityTypeDefiniton>> GetTagDefinitionsAsync(CancellationToken cancellationToken = default); |
|||
} |
|||
} |
|||
@ -1,11 +0,0 @@ |
|||
using JetBrains.Annotations; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Localization; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class TagEntityTypeDefinitionDictionary : List<TagEntityTypeDefiniton> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
using System.Collections.Generic; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public class TagEntityTypeDefinitions : List<TagEntityTypeDefiniton> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.CmsKit.Admin.Blogs; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.Blogs |
|||
{ |
|||
public class BlogAdminAppService_Tests : CmsKitApplicationTestBase |
|||
{ |
|||
protected IBlogAdminAppService BlogAdminAppService { get; } |
|||
protected CmsKitTestData CmsKitTestData { get; } |
|||
protected IBlogRepository BlogRepository { get; } |
|||
|
|||
public BlogAdminAppService_Tests() |
|||
{ |
|||
BlogAdminAppService = GetRequiredService<IBlogAdminAppService>(); |
|||
CmsKitTestData = GetRequiredService<CmsKitTestData>(); |
|||
BlogRepository = GetRequiredService<IBlogRepository>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetAsync() |
|||
{ |
|||
var blog = await BlogAdminAppService.GetAsync(CmsKitTestData.Blog_Id); |
|||
|
|||
blog.Slug.ShouldBe(CmsKitTestData.BlogSlug); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetListAsync() |
|||
{ |
|||
var blogs = await BlogAdminAppService.GetListAsync(new BlogGetListInput()); |
|||
|
|||
blogs.TotalCount.ShouldBeGreaterThan(0); |
|||
blogs.Items.Any(x => x.Slug == CmsKitTestData.BlogSlug).ShouldBeTrue(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task CreateAsync_ShouldWork() |
|||
{ |
|||
var blog = await BlogAdminAppService.CreateAsync(new CreateBlogDto |
|||
{ |
|||
Name = "News", |
|||
Slug = "latest-news" |
|||
}); |
|||
|
|||
blog.ShouldNotBeNull(); |
|||
blog.Name.ShouldBe("News"); |
|||
blog.Slug.ShouldBe("latest-news"); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task CreateAsync_ShouldThrow_WithExistSlug() |
|||
{ |
|||
await Should.ThrowAsync<BlogSlugAlreadyExistException>( |
|||
async () => |
|||
await BlogAdminAppService.CreateAsync(new CreateBlogDto |
|||
{ |
|||
Name = "News", |
|||
Slug = CmsKitTestData.BlogSlug |
|||
})); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task UpdateAsync_ShouldWork() |
|||
{ |
|||
var blog = await BlogAdminAppService.UpdateAsync(CmsKitTestData.Blog_Id, new UpdateBlogDto |
|||
{ |
|||
Name = "New Name", |
|||
Slug = "new-slug" |
|||
}); |
|||
|
|||
var updatedBlog = await BlogAdminAppService.GetAsync(CmsKitTestData.Blog_Id); |
|||
|
|||
updatedBlog.Name.ShouldBe("New Name"); |
|||
updatedBlog.Slug.ShouldBe("new-slug"); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task DeleteAsync_ShouldWork() |
|||
{ |
|||
await BlogAdminAppService.DeleteAsync(CmsKitTestData.Blog_Id); |
|||
|
|||
await Should.ThrowAsync<EntityNotFoundException>( |
|||
async () => |
|||
await BlogAdminAppService.GetAsync(CmsKitTestData.Blog_Id) |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.Blogs |
|||
{ |
|||
public class BlogManager_Test : CmsKitDomainTestBase |
|||
{ |
|||
protected IBlogRepository BlogRepository { get; } |
|||
protected BlogManager BlogManager { get; } |
|||
protected CmsKitTestData TestData { get; } |
|||
|
|||
public BlogManager_Test() |
|||
{ |
|||
BlogRepository = GetRequiredService<IBlogRepository>(); |
|||
BlogManager = GetRequiredService<BlogManager>(); |
|||
TestData = GetRequiredService<CmsKitTestData>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task BlogCreate_ShouldThrowException_WithExistSlug() |
|||
{ |
|||
await Should.ThrowAsync<BlogSlugAlreadyExistException>( |
|||
async () => |
|||
await BlogManager.CreateAsync("test-name", TestData.BlogSlug) |
|||
); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task BlogCreate_ShouldWorkProperly() |
|||
{ |
|||
var blog = await BlogManager.CreateAsync("test-name", "test-slug"); |
|||
|
|||
blog.ShouldNotBeNull(); |
|||
blog.Id.ShouldNotBe(Guid.Empty); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task BlogUpdate_ShouldWork() |
|||
{ |
|||
var blog = await BlogRepository.GetAsync(TestData.Blog_Id); |
|||
|
|||
await BlogManager.UpdateAsync(blog, "New name", "new-slug"); |
|||
|
|||
blog.Name.ShouldBe("New name"); |
|||
blog.Slug.ShouldBe("new-slug"); |
|||
} |
|||
} |
|||
} |
|||
@ -1,35 +0,0 @@ |
|||
using System; |
|||
using Microsoft.AspNetCore.Identity; |
|||
|
|||
namespace Volo.Abp.Identity |
|||
{ |
|||
public static class PasswordOptionsExtensions |
|||
{ |
|||
public static IDisposable ClearRequirements(this PasswordOptions options) |
|||
{ |
|||
var oldRequireDigit = options.RequireDigit; |
|||
var oldRequiredLength = options.RequiredLength; |
|||
var oldRequireLowercase = options.RequireLowercase; |
|||
var oldRequireUppercase = options.RequireUppercase; |
|||
var oldRequiredUniqueChars = options.RequiredUniqueChars; |
|||
var oldRequireNonAlphanumeric = options.RequireNonAlphanumeric; |
|||
|
|||
options.RequireDigit = false; |
|||
options.RequiredLength = 1; |
|||
options.RequireLowercase = false; |
|||
options.RequireUppercase = false; |
|||
options.RequiredUniqueChars = 1; |
|||
options.RequireNonAlphanumeric = false; |
|||
|
|||
return new DisposeAction(() => |
|||
{ |
|||
options.RequireDigit = oldRequireDigit; |
|||
options.RequiredLength = oldRequiredLength; |
|||
options.RequireLowercase = oldRequireLowercase; |
|||
options.RequireUppercase = oldRequireUppercase; |
|||
options.RequiredUniqueChars = oldRequiredUniqueChars; |
|||
options.RequireNonAlphanumeric = oldRequireNonAlphanumeric; |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue