diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs index 18e57f0f23..3d025d1463 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs @@ -16,10 +16,15 @@ namespace Volo.CmsKit.Admin.Pages public class PageAdminAppService : CmsKitAdminAppServiceBase, IPageAdminAppService { protected IPageRepository PageRepository { get; } - - public PageAdminAppService(IPageRepository pageRepository) + + protected PageManager PageManager { get; } + + public PageAdminAppService( + IPageRepository pageRepository, + PageManager pageManager) { PageRepository = pageRepository; + PageManager = pageManager; } public virtual async Task GetAsync(Guid id) @@ -48,11 +53,7 @@ namespace Volo.CmsKit.Admin.Pages [Authorize(CmsKitAdminPermissions.Pages.Create)] public virtual async Task CreateAsync(CreatePageInputDto input) { - /* TODO: This should be in a domain service, like PageManager.CreateAsync(...) - Otherwise, we can't ensure the slug check is applied. - The same pattern is already done for BlogManager */ - await CheckPageSlugAsync(input.Slug); - var page = new Page(GuidGenerator.Create(), input.Title, input.Slug, input.Content, CurrentTenant.Id); + var page = await PageManager.CreateAsync(input.Title, input.Slug, input.Content); await PageRepository.InsertAsync(page); @@ -64,12 +65,7 @@ namespace Volo.CmsKit.Admin.Pages { var page = await PageRepository.GetAsync(id); - if (page.Slug != input.Slug) - { - /* TODO: This should be in a domain service, like PageManager.SetSlugAsync(page, input.Slug) */ - await CheckPageSlugAsync(input.Slug); - page.SetSlug(input.Slug); - } + await PageManager.SetSlugAsync(page, input.Slug); page.SetTitle(input.Title); page.SetContent(input.Content); @@ -84,13 +80,5 @@ namespace Volo.CmsKit.Admin.Pages { await PageRepository.DeleteAsync(id); } - - protected virtual async Task CheckPageSlugAsync(string slug) - { - if (await PageRepository.ExistsAsync(slug)) - { - throw new PageSlugAlreadyExistsException(slug); - } - } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs index dd759ebd08..409d504952 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs @@ -20,7 +20,7 @@ namespace Volo.CmsKit.Pages { } - public Page(Guid id, [NotNull] string title, [NotNull] string slug, string content = null, Guid? tenantId = null) : base(id) + internal Page(Guid id, [NotNull] string title, [NotNull] string slug, string content = null, Guid? tenantId = null) : base(id) { TenantId = tenantId; @@ -34,7 +34,7 @@ namespace Volo.CmsKit.Pages Title = Check.NotNullOrEmpty(title, nameof(title), PageConsts.MaxTitleLength); } - public virtual void SetSlug(string slug) + internal virtual void SetSlug(string slug) { Slug = Check.NotNullOrEmpty(slug, nameof(slug), PageConsts.MaxSlugLength); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageManager.cs new file mode 100644 index 0000000000..c150e69e52 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageManager.cs @@ -0,0 +1,56 @@ +using JetBrains.Annotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Domain.Services; + +namespace Volo.CmsKit.Pages +{ + public class PageManager : DomainService + { + protected IPageRepository PageRepository { get; } + + public PageManager(IPageRepository pageRepository) + { + PageRepository = pageRepository; + } + + public virtual async Task CreateAsync( + [NotNull] string title, + [NotNull] string slug, + [CanBeNull] string content = null) + { + Check.NotNullOrEmpty(title, nameof(title)); + Check.NotNullOrEmpty(slug, nameof(slug)); + + await CheckPageSlugAsync(slug); + + return new Page( + GuidGenerator.Create(), + title, + slug, + content, + CurrentTenant.Id); + } + + public virtual async Task SetSlugAsync(Page page, string newSlug) + { + if (page.Slug != newSlug) + { + await CheckPageSlugAsync(newSlug); + page.SetSlug(newSlug); + } + } + + protected virtual async Task CheckPageSlugAsync(string slug) + { + if (await PageRepository.ExistsAsync(slug)) + { + throw new PageSlugAlreadyExistsException(slug); + } + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs new file mode 100644 index 0000000000..10dc874399 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs @@ -0,0 +1,70 @@ +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Volo.CmsKit.Pages +{ + public class PageManager_Test : CmsKitDomainTestBase + { + private readonly PageManager pageManager; + private readonly CmsKitTestData testData; + private readonly IPageRepository pageRepository; + + public PageManager_Test() + { + pageManager = GetRequiredService(); + testData = GetRequiredService(); + pageRepository = GetRequiredService(); + } + + public async Task CreateAsync_ShouldWorkProperly_WithNonExistingSlug() + { + var title = "My awesome page"; + var slug = "my-awesome-page"; + var content = "

My Awesome Page

This is my awesome page content!

"; + + var page = await pageManager.CreateAsync(title, slug, content); + + page.ShouldNotBeNull(); + page.Title.ShouldBe(title); + page.Slug.ShouldBe(slug); + page.Content.ShouldBe(content); + } + + public async Task CreateAsync_ShouldThrowException_WithExistingSlug() + { + var title = "My awesome page"; + var slug = testData.Page_1_Slug; + var content = "

My Awesome Page

This is my awesome page content!

"; + + var exception = await Should.ThrowAsync(async () => + await pageManager.CreateAsync(title, slug, content)); + + exception.ShouldNotBeNull(); + } + + public async Task SetSlugAsync_ShouldWorkProperly_WithNonExistingSlug() + { + var newSlug = "freshly-generated-new-slug"; + var page = await pageRepository.GetAsync(testData.Page_1_Id); + + await pageManager.SetSlugAsync(page, newSlug); + + page.Slug.ShouldBe(newSlug); + } + + public async Task SetSlugAsync_ShouldThrowException_WithExistingSlug() + { + var newSlug = testData.Page_2_Slug; + var page = await pageRepository.GetAsync(testData.Page_1_Id); + + var exception = await Should.ThrowAsync(async () => + await pageManager.SetSlugAsync(page, newSlug)); + + exception.ShouldNotBeNull(); + } + } +}