mirror of https://github.com/abpframework/abp.git
56 changed files with 1166 additions and 51 deletions
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
|
|||
namespace Volo.CmsKit.Admin.Tags |
|||
{ |
|||
public class EntityTagSetDto |
|||
{ |
|||
public string EntityId { get; set; } |
|||
public string EntityType { get; set; } |
|||
public List<string> Tags { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.GlobalFeatures; |
|||
using Volo.CmsKit.GlobalFeatures; |
|||
using Volo.CmsKit.Permissions; |
|||
|
|||
namespace Volo.CmsKit.Admin.Tags |
|||
{ |
|||
[RequiresGlobalFeature(typeof(TagsFeature))] |
|||
[RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("cms-kit")] |
|||
[Route("api/cms-kit-admin/entity-tags")] |
|||
public class EntityTagAdminController : CmsKitAdminController, IEntityTagAdminAppService |
|||
{ |
|||
protected IEntityTagAdminAppService EntityTagAdminAppService { get; } |
|||
|
|||
public EntityTagAdminController(IEntityTagAdminAppService entityTagAdminAppService) |
|||
{ |
|||
EntityTagAdminAppService = entityTagAdminAppService; |
|||
} |
|||
|
|||
[HttpPost] |
|||
public Task AddTagToEntityAsync(EntityTagCreateDto input) |
|||
{ |
|||
return EntityTagAdminAppService.AddTagToEntityAsync(input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
public Task RemoveTagFromEntityAsync(EntityTagRemoveDto input) |
|||
{ |
|||
return EntityTagAdminAppService.RemoveTagFromEntityAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
public Task SetEntityTagsAsync(EntityTagSetDto input) |
|||
{ |
|||
return EntityTagAdminAppService.SetEntityTagsAsync(input); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,20 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace Volo.CmsKit.Users |
|||
{ |
|||
public class CmsUserDto : EntityDto<Guid> |
|||
{ |
|||
public virtual Guid? TenantId { get; protected set; } |
|||
|
|||
public virtual string UserName { get; protected set; } |
|||
|
|||
public virtual string Name { get; set; } |
|||
|
|||
public virtual string Surname { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.CmsKit.Users; |
|||
|
|||
namespace Volo.CmsKit.Public.Blogs |
|||
{ |
|||
public class BlogPostPublicDto : AuditedEntityWithUserDto<Guid, CmsUserDto> |
|||
{ |
|||
public Guid BlogId { get; set; } |
|||
|
|||
public string Title { get; set; } |
|||
|
|||
public string UrlSlug { get; set; } |
|||
|
|||
public string ShortDescription { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Content; |
|||
|
|||
namespace Volo.CmsKit.Public.Blogs |
|||
{ |
|||
public interface IBlogPostPublicAppService |
|||
{ |
|||
Task<PagedResultDto<BlogPostPublicDto>> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input); |
|||
|
|||
Task<BlogPostPublicDto> GetAsync(string blogUrlSlug, string blogPostUrlSlug); |
|||
|
|||
Task<RemoteStreamContent> GetCoverImageAsync(Guid id); |
|||
} |
|||
} |
|||
@ -0,0 +1,54 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.BlobStoring; |
|||
using Volo.Abp.Content; |
|||
using Volo.CmsKit.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Public.Blogs |
|||
{ |
|||
public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPublicAppService |
|||
{ |
|||
protected IBlogRepository BlogRepository { get; } |
|||
|
|||
protected IBlobContainer<BlogPostCoverImageContainer> BlobContainer { get; } |
|||
|
|||
protected IBlogPostRepository BlogPostRepository { get; } |
|||
|
|||
public BlogPostPublicAppService( |
|||
IBlogRepository blogRepository, |
|||
IBlogPostRepository blogPostRepository) |
|||
{ |
|||
BlogRepository = blogRepository; |
|||
BlogPostRepository = blogPostRepository; |
|||
} |
|||
|
|||
public async Task<BlogPostPublicDto> GetAsync(string blogUrlSlug, string blogPostUrlSlug) |
|||
{ |
|||
var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); |
|||
|
|||
var blogPost = await BlogPostRepository.GetByUrlSlugAsync(blog.Id, blogPostUrlSlug); |
|||
|
|||
return ObjectMapper.Map<BlogPost, BlogPostPublicDto>(blogPost); |
|||
} |
|||
|
|||
public async Task<PagedResultDto<BlogPostPublicDto>> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input) |
|||
{ |
|||
var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); |
|||
|
|||
var blogPosts = await BlogPostRepository.GetPagedListAsync(blog.Id, input.SkipCount, input.MaxResultCount, input.Sorting); |
|||
|
|||
return new PagedResultDto<BlogPostPublicDto>( |
|||
await BlogPostRepository.GetCountAsync(blog.Id), |
|||
ObjectMapper.Map<List<BlogPost>, List<BlogPostPublicDto>>(blogPosts)); |
|||
} |
|||
|
|||
public async Task<RemoteStreamContent> GetCoverImageAsync(Guid id) |
|||
{ |
|||
var stream = await BlobContainer.GetAsync(id.ToString()); |
|||
|
|||
return new RemoteStreamContent(stream); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,53 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Content; |
|||
using Volo.Abp.GlobalFeatures; |
|||
using Volo.CmsKit.GlobalFeatures; |
|||
using Volo.CmsKit.Public.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Public.Blogs |
|||
{ |
|||
[RequiresGlobalFeature(typeof(BlogsFeature))] |
|||
[RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] |
|||
[Area("cms-kit")] |
|||
[Route("api/cms-kit-public/blog-posts")] |
|||
public class BlogPostPublicController : CmsKitPublicControllerBase, IBlogPostPublicAppService |
|||
{ |
|||
protected IBlogPostPublicAppService BlogPostPublicAppService { get; } |
|||
|
|||
public BlogPostPublicController(IBlogPostPublicAppService blogPostPublicAppService) |
|||
{ |
|||
BlogPostPublicAppService = blogPostPublicAppService; |
|||
} |
|||
|
|||
[HttpGet] |
|||
public Task<BlogPostPublicDto> GetAsync(string blogUrlSlug, string blogPostUrlSlug) |
|||
{ |
|||
return BlogPostPublicAppService.GetAsync(blogUrlSlug, blogPostUrlSlug); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}/cover-image")] |
|||
public Task<RemoteStreamContent> GetCoverImageAsync(Guid id) |
|||
{ |
|||
Response.Headers.Add("Content-Disposition", $"inline;filename=\"{id}\""); |
|||
Response.Headers.Add("Accept-Ranges", "bytes"); |
|||
Response.Headers.Add("Cache-Control", "max-age=120"); |
|||
Response.ContentType = "image"; |
|||
|
|||
return BlogPostPublicAppService.GetCoverImageAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public Task<PagedResultDto<BlogPostPublicDto>> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input) |
|||
{ |
|||
return BlogPostPublicAppService.GetListAsync(blogUrlSlug, input); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
@page "/blogs/{blogUrlSlug}/{blogPostUrlSlug}" |
|||
|
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost |
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment |
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs |
|||
@using Volo.CmsKit.Public.Web.Pages |
|||
@using Volo.Abp.GlobalFeatures |
|||
@using Volo.CmsKit.GlobalFeatures |
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection |
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating |
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Tags |
|||
|
|||
@inherits CmsKitPublicPageBase |
|||
|
|||
@model BlogPostModel |
|||
|
|||
@{ |
|||
PageLayout.Content.Title = Model.BlogPost.Title; |
|||
} |
|||
|
|||
@await Component.InvokeAsync(typeof(DefaultBlogPostViewComponent), new |
|||
{ |
|||
Model.BlogUrlSlug, |
|||
Model.BlogPostUrlSlug |
|||
}) |
|||
|
|||
@if (GlobalFeatureManager.Instance.IsEnabled<TagsFeature>()) |
|||
{ |
|||
@await Component.InvokeAsync(typeof(TagViewComponent), new |
|||
{ |
|||
entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, |
|||
entityId = Model.BlogPost.Id.ToString() |
|||
}) |
|||
} |
|||
|
|||
@if (GlobalFeatureManager.Instance.IsEnabled<ReactionsFeature>()) |
|||
{ |
|||
@await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new |
|||
{ |
|||
entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, |
|||
entityId = Model.BlogPost.Id.ToString() |
|||
}) |
|||
} |
|||
|
|||
@if (GlobalFeatureManager.Instance.IsEnabled<RatingsFeature>()) |
|||
{ |
|||
@await Component.InvokeAsync(typeof(RatingViewComponent), new |
|||
{ |
|||
entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, |
|||
entityId = Model.BlogPost.Id.ToString() |
|||
}) |
|||
} |
|||
|
|||
<hr /> |
|||
|
|||
@if (GlobalFeatureManager.Instance.IsEnabled<CommentsFeature>()) |
|||
{ |
|||
@await Component.InvokeAsync(typeof(DefaultBlogPostCommentViewComponent), new |
|||
{ |
|||
entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, |
|||
entityId = Model.BlogPost.Id.ToString() |
|||
}) |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.CmsKit.Public.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs |
|||
{ |
|||
public class BlogPostModel : CmsKitPublicPageModelBase |
|||
{ |
|||
[BindProperty(SupportsGet = true)] |
|||
public string BlogUrlSlug { get; set; } |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public string BlogPostUrlSlug { get; set; } |
|||
|
|||
public BlogPostPublicDto BlogPost { get; private set; } |
|||
|
|||
protected IBlogPostPublicAppService BlogPostPublicAppService { get; } |
|||
|
|||
public BlogPostModel(IBlogPostPublicAppService blogPostPublicAppService) |
|||
{ |
|||
BlogPostPublicAppService = blogPostPublicAppService; |
|||
} |
|||
|
|||
public async Task OnGetAsync() |
|||
{ |
|||
BlogPost = await BlogPostPublicAppService.GetAsync(BlogUrlSlug, BlogPostUrlSlug); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,47 @@ |
|||
@page "/blogs/{blogUrlSlug}" |
|||
|
|||
@using Volo.CmsKit.Public.Web.Pages |
|||
|
|||
@inherits CmsKitPublicPageBase |
|||
|
|||
@model Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs.IndexModel |
|||
|
|||
<abp-row id="blogs-container"> |
|||
@foreach (var blog in Model.Blogs.Items) |
|||
{ |
|||
<abp-column size="_12" class="m-3"> |
|||
<abp-card> |
|||
<abp-card-header> |
|||
<abp-card-title> |
|||
@blog.Title |
|||
</abp-card-title> |
|||
<abp-card-subtitle> |
|||
@@@blog.Creator?.UserName |
|||
</abp-card-subtitle> |
|||
</abp-card-header> |
|||
<abp-card-body> |
|||
<img src="/api/cms-kit-public/blog-posts/@blog.Id/cover-image" class="card-img-top" onerror="this.src='https://dummyimage.com/300x200/a3a3a3/fff.png'"/> |
|||
<abp-card-text> |
|||
@blog.ShortDescription |
|||
</abp-card-text> |
|||
<abp-card-text> |
|||
<a href="/blogs/@Model.BlogUrlSlug/@blog.UrlSlug"> |
|||
<abp-button text="@L["Read"]" |
|||
button-type="Outline_Primary" /> |
|||
</a> |
|||
</abp-card-text> |
|||
</abp-card-body> |
|||
<abp-card-footer> |
|||
<abp-card-text> |
|||
@blog.CreationTime |
|||
</abp-card-text> |
|||
</abp-card-footer> |
|||
</abp-card> |
|||
</abp-column> |
|||
|
|||
} |
|||
</abp-row> |
|||
<abp-row> |
|||
<abp-paginator model="Model.PagerModel" /> |
|||
</abp-row> |
|||
|
|||
@ -0,0 +1,45 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination; |
|||
using Volo.CmsKit.Public.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs |
|||
{ |
|||
public class IndexModel : CmsKitPublicPageModelBase |
|||
{ |
|||
public const int PageSize = 12; |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public string BlogUrlSlug { get; set; } |
|||
|
|||
[BindProperty(SupportsGet = true)] |
|||
public int CurrentPage { get; set; } = 1; |
|||
|
|||
public PagedResultDto<BlogPostPublicDto> Blogs { get; private set; } |
|||
|
|||
public PagerModel PagerModel => new PagerModel(Blogs.TotalCount, Blogs.Items.Count, CurrentPage, PageSize, Request.Path.ToString()); |
|||
|
|||
protected IBlogPostPublicAppService BlogPostPublicAppService { get; } |
|||
|
|||
public IndexModel(IBlogPostPublicAppService blogPostPublicAppService) |
|||
{ |
|||
BlogPostPublicAppService = blogPostPublicAppService; |
|||
} |
|||
|
|||
public async Task OnGetAsync() |
|||
{ |
|||
Blogs = await BlogPostPublicAppService.GetListAsync( |
|||
BlogUrlSlug, |
|||
new PagedAndSortedResultRequestDto |
|||
{ |
|||
SkipCount = PageSize * (CurrentPage - 1), |
|||
MaxResultCount = PageSize |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
@model Volo.CmsKit.Public.Blogs.BlogPostPublicDto |
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents |
|||
@using Volo.Abp.AspNetCore.Mvc.UI.Layout |
|||
@using Volo.CmsKit.Localization |
|||
@using Microsoft.Extensions.Localization |
|||
|
|||
@inject IStringLocalizer<CmsKitResource> L |
|||
|
|||
|
|||
<abp-card> |
|||
<abp-card-header> |
|||
<abp-card-title>@Model.Title</abp-card-title> |
|||
<abp-card-subtitle>@@@Model.Creator?.UserName</abp-card-subtitle> |
|||
</abp-card-header> |
|||
|
|||
<abp-card-body> |
|||
<img src="/api/cms-kit-public/blog-posts/@Model.Id/cover-image" class="card-img-top" onerror="this.src='https://dummyimage.com/300x200/a3a3a3/fff.png'" /> |
|||
@await Component.InvokeAsync(typeof(ContentViewComponent), new |
|||
{ |
|||
entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, |
|||
entityId = Model.Id.ToString() |
|||
}) |
|||
</abp-card-body> |
|||
<abp-card-footer> |
|||
<abp-card-subtitle>@Model.CreationTime</abp-card-subtitle> |
|||
@if (Model.LastModificationTime != null) |
|||
{ |
|||
<abp-card-text><i>@L["LastModification"].Value : @Model.LastModificationTime</i></abp-card-text> |
|||
} |
|||
</abp-card-footer> |
|||
</abp-card> |
|||
|
|||
|
|||
@ -0,0 +1,29 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.CmsKit.Public.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost |
|||
{ |
|||
[ViewComponent(Name = "CmsDefaultBlogPost")] |
|||
public class DefaultBlogPostViewComponent : AbpViewComponent |
|||
{ |
|||
protected IBlogPostPublicAppService BlogPostPublicAppService { get; } |
|||
|
|||
public DefaultBlogPostViewComponent(IBlogPostPublicAppService blogPostPublicAppService) |
|||
{ |
|||
BlogPostPublicAppService = blogPostPublicAppService; |
|||
} |
|||
|
|||
public virtual async Task<IViewComponentResult> InvokeAsync(string blogUrlSlug, string blogPostUrlSlug) |
|||
{ |
|||
var blogPost = await BlogPostPublicAppService.GetAsync(blogUrlSlug, blogPostUrlSlug); |
|||
|
|||
return View("~/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml", blogPost); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting |
|||
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment |
|||
@using Volo.CmsKit.Localization |
|||
@using Microsoft.Extensions.Localization |
|||
|
|||
@inject IStringLocalizer<CmsKitResource> L |
|||
|
|||
@model DefaultBlogPostCommentViewComponent.DefaultBlogPostCommentViewModel |
|||
|
|||
|
|||
<abp-card> |
|||
<abp-card-header> |
|||
<abp-card-title>@L["Comments"]</abp-card-title> |
|||
</abp-card-header> |
|||
<abp-card-body> |
|||
@await Component.InvokeAsync(typeof(CommentingViewComponent), new |
|||
{ |
|||
entityType = Model.EntityType, |
|||
entityId = Model.EntityId |
|||
}) |
|||
</abp-card-body> |
|||
</abp-card> |
|||
@ -0,0 +1,39 @@ |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.CmsKit.Public.Blogs; |
|||
|
|||
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment |
|||
{ |
|||
[ViewComponent(Name = "CmsDefaultBlogPostComment")] |
|||
public class DefaultBlogPostCommentViewComponent : AbpViewComponent |
|||
{ |
|||
protected IBlogPostPublicAppService BlogPostPublicAppService; |
|||
|
|||
public DefaultBlogPostCommentViewComponent(IBlogPostPublicAppService blogPostPublicAppService) |
|||
{ |
|||
BlogPostPublicAppService = blogPostPublicAppService; |
|||
} |
|||
|
|||
public virtual async Task<IViewComponentResult> InvokeAsync(string entityType, string entityId) |
|||
{ |
|||
return View( |
|||
"~/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/Default.cshtml", |
|||
new DefaultBlogPostCommentViewModel |
|||
{ |
|||
EntityType = entityType, |
|||
EntityId = entityId |
|||
}); |
|||
} |
|||
|
|||
public class DefaultBlogPostCommentViewModel |
|||
{ |
|||
public string EntityType { get; set; } |
|||
public string EntityId { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using Microsoft.AspNetCore.Mvc.Razor.Internal; |
|||
using Microsoft.Extensions.Localization; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Layout; |
|||
using Volo.CmsKit.Localization; |
|||
|
|||
namespace Volo.CmsKit.Public.Web.Pages |
|||
{ |
|||
public class CmsKitPublicPageBase : Microsoft.AspNetCore.Mvc.RazorPages.Page |
|||
{ |
|||
[RazorInject] |
|||
public IStringLocalizer<CmsKitResource> L { get; set; } |
|||
|
|||
[RazorInject] |
|||
public IPageLayout PageLayout { get; set; } |
|||
|
|||
public override Task ExecuteAsync() |
|||
{ |
|||
return Task.CompletedTask; // Will be overriden by razor pages. (.cshtml)
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
{ |
|||
"iisSettings": { |
|||
"windowsAuthentication": false, |
|||
"anonymousAuthentication": true, |
|||
"iisExpress": { |
|||
"applicationUrl": "http://localhost:60873/", |
|||
"sslPort": 44300 |
|||
} |
|||
}, |
|||
"profiles": { |
|||
"IIS Express": { |
|||
"commandName": "IISExpress", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
} |
|||
}, |
|||
"Volo.CmsKit.Public.Web": { |
|||
"commandName": "Project", |
|||
"launchBrowser": true, |
|||
"environmentVariables": { |
|||
"ASPNETCORE_ENVIRONMENT": "Development" |
|||
}, |
|||
"applicationUrl": "https://localhost:5001;http://localhost:5000" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.CmsKit.Blogs; |
|||
using Volo.CmsKit.Pages; |
|||
|
|||
namespace Volo.CmsKit.EntityFrameworkCore.Blogs |
|||
{ |
|||
public class BlogPostRepository_Test : BlogPostRepository_Test<CmsKitEntityFrameworkCoreTestModule> |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.CmsKit.Blogs; |
|||
|
|||
namespace Volo.CmsKit.EntityFrameworkCore.Blogs |
|||
{ |
|||
public class BlogRepository_Test : BlogRepository_Test<CmsKitEntityFrameworkCoreTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.CmsKit.Tags; |
|||
|
|||
namespace Volo.CmsKit.EntityFrameworkCore.Tags |
|||
{ |
|||
public class EntityTagRepository_Test : EntityTagRepository_Test<CmsKitEntityFrameworkCoreTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.CmsKit.Blogs; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Blogs |
|||
{ |
|||
[Collection(MongoTestCollection.Name)] |
|||
public class BlogPostRepository_Test : BlogPostRepository_Test<CmsKitMongoDbTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.CmsKit.Blogs; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Blogs |
|||
{ |
|||
[Collection(MongoTestCollection.Name)] |
|||
public class BlogRepository_Test : BlogRepository_Test<CmsKitMongoDbTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.CmsKit.Tags; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.MongoDB.Tags |
|||
{ |
|||
[Collection(MongoTestCollection.Name)] |
|||
public class EntityTagRepository_Test : EntityTagRepository_Test<CmsKitMongoDbTestModule> |
|||
{ |
|||
|
|||
} |
|||
} |
|||
@ -0,0 +1,125 @@ |
|||
using Shouldly; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Modularity; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.Blogs |
|||
{ |
|||
public abstract class BlogPostRepository_Test<TStartupModule> : CmsKitTestBase<TStartupModule> |
|||
where TStartupModule : IAbpModule |
|||
{ |
|||
private readonly CmsKitTestData testData; |
|||
private readonly IBlogPostRepository blogPostRepository; |
|||
|
|||
public BlogPostRepository_Test() |
|||
{ |
|||
testData = GetRequiredService<CmsKitTestData>(); |
|||
blogPostRepository = GetRequiredService<IBlogPostRepository>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task SlugExistsAsync_ShouldReturnTrue_WithExistingUrlSlug() |
|||
{ |
|||
var result = await blogPostRepository.SlugExistsAsync(testData.Blog_Id, testData.BlogPost_1_UrlSlug); |
|||
|
|||
result.ShouldBeTrue(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task SlugExistsAsync_ShouldReturnFalse_WithNonExistingUrlSlug() |
|||
{ |
|||
var nonExistingSlug = "any-other-url-slug"; |
|||
|
|||
var result = await blogPostRepository.SlugExistsAsync(testData.Blog_Id, nonExistingSlug); |
|||
|
|||
result.ShouldBeFalse(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task SlugExistsAsync_ShouldReturnFalse_WithNonExistingBlogId() |
|||
{ |
|||
var nonExistingBlogId = Guid.NewGuid(); |
|||
|
|||
var result = await blogPostRepository.SlugExistsAsync(nonExistingBlogId, testData.BlogPost_1_UrlSlug); |
|||
|
|||
result.ShouldBeFalse(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithCorrectParameters() |
|||
{ |
|||
var blogPost = await blogPostRepository.GetByUrlSlugAsync(testData.Blog_Id, testData.BlogPost_1_UrlSlug); |
|||
|
|||
blogPost.ShouldNotBeNull(); |
|||
blogPost.Id.ShouldBe(testData.BlogPost_1_Id); |
|||
blogPost.UrlSlug.ShouldBe(testData.BlogPost_1_UrlSlug); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogPostUrlSlug() |
|||
{ |
|||
var nonExistingSlugUrl = "absolutely-non-existing-url"; |
|||
var exception = await Should.ThrowAsync<EntityNotFoundException>( |
|||
async () => await blogPostRepository.GetByUrlSlugAsync(testData.Blog_Id, nonExistingSlugUrl)); |
|||
|
|||
exception.ShouldNotBeNull(); |
|||
exception.EntityType.ShouldBe(typeof(BlogPost)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogId() |
|||
{ |
|||
var nonExistingBlogId = Guid.NewGuid(); |
|||
var exception = await Should.ThrowAsync<EntityNotFoundException>( |
|||
async () => await blogPostRepository.GetByUrlSlugAsync(nonExistingBlogId, testData.BlogPost_1_UrlSlug)); |
|||
|
|||
exception.ShouldNotBeNull(); |
|||
exception.EntityType.ShouldBe(typeof(BlogPost)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetPagedListAsync_ShouldWorkProperly_WithBlogId_WhileGetting10_WithoutSorting() |
|||
{ |
|||
var result = await blogPostRepository.GetPagedListAsync(testData.Blog_Id, 0, 10, default); |
|||
|
|||
result.ShouldNotBeNull(); |
|||
result.ShouldNotBeEmpty(); |
|||
result.Count.ShouldBe(2); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetPagedListAsync_ShouldWorkProperly_WithBlogId_WhileGetting1_WithoutSorting() |
|||
{ |
|||
var result = await blogPostRepository.GetPagedListAsync(testData.Blog_Id, default, 1, default); |
|||
|
|||
result.ShouldNotBeNull(); |
|||
result.ShouldNotBeEmpty(); |
|||
result.Count.ShouldBe(1); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetPagedListAsync_ShouldWorkProperly_WithBlogId_WhileGetting1InPage2_WithoutSorting() |
|||
{ |
|||
var result = await blogPostRepository.GetPagedListAsync(testData.Blog_Id, 1, 1, default); |
|||
|
|||
result.ShouldNotBeNull(); |
|||
result.ShouldNotBeEmpty(); |
|||
result.Count.ShouldBe(1); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetPagedListAsync_ShouldWorkProperly_WithBlogId_WhileGetting10_WithSortingByTitle() |
|||
{ |
|||
var result = await blogPostRepository.GetPagedListAsync(testData.Blog_Id, default, 10, nameof(BlogPost.Title)); |
|||
|
|||
result.ShouldNotBeNull(); |
|||
result.ShouldNotBeEmpty(); |
|||
result.Count.ShouldBe(2); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
using Shouldly; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Entities; |
|||
using Volo.Abp.Modularity; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.Blogs |
|||
{ |
|||
public abstract class BlogRepository_Test<TStartupModule> : CmsKitTestBase<TStartupModule> |
|||
where TStartupModule : IAbpModule |
|||
{ |
|||
private readonly CmsKitTestData testData; |
|||
private readonly IBlogRepository blogRepository; |
|||
|
|||
public BlogRepository_Test() |
|||
{ |
|||
this.testData = GetRequiredService<CmsKitTestData>(); |
|||
this.blogRepository = GetRequiredService<IBlogRepository>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithExistingSlug() |
|||
{ |
|||
var blog = await blogRepository.GetByUrlSlugAsync(testData.BlogUrlSlug); |
|||
|
|||
blog.ShouldNotBeNull(); |
|||
blog.UrlSlug.ShouldBe(testData.BlogUrlSlug); |
|||
blog.Id.ShouldBe(testData.Blog_Id); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingSlug() |
|||
{ |
|||
var nonExistingSlug = "some-blog-slug-that-doesnt-exist"; |
|||
|
|||
var exception = await Should.ThrowAsync<EntityNotFoundException>( |
|||
async () => await blogRepository.GetByUrlSlugAsync(nonExistingSlug)); |
|||
|
|||
exception.ShouldNotBeNull(); |
|||
exception.EntityType.ShouldBe(typeof(Blog)); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ExistsAsync_ShouldReturnTrue_WithExistingId() |
|||
{ |
|||
var result = await blogRepository.ExistsAsync(testData.Blog_Id); |
|||
|
|||
result.ShouldBeTrue(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task ExistsAsync_ShouldReturnFalse_WithExistingId() |
|||
{ |
|||
var nonExistingId = Guid.NewGuid(); |
|||
|
|||
var result = await blogRepository.ExistsAsync(nonExistingId); |
|||
|
|||
result.ShouldBeFalse(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
using Shouldly; |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Modularity; |
|||
using Xunit; |
|||
|
|||
namespace Volo.CmsKit.Tags |
|||
{ |
|||
public abstract class EntityTagRepository_Test<TStartupModule> : CmsKitTestBase<TStartupModule> |
|||
where TStartupModule : IAbpModule |
|||
{ |
|||
private CmsKitTestData _cmsKitTestData; |
|||
private IEntityTagRepository _entityTagRepository; |
|||
private ITagRepository _tagRepository; |
|||
|
|||
public EntityTagRepository_Test() |
|||
{ |
|||
_cmsKitTestData = GetRequiredService<CmsKitTestData>(); |
|||
_entityTagRepository = GetRequiredService<IEntityTagRepository>(); |
|||
_tagRepository = GetRequiredService<ITagRepository>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task DeleteManyAsync_ShouldWorkProperly_WithExistingIds() |
|||
{ |
|||
var relatedTags = await _tagRepository.GetAllRelatedTagsAsync(_cmsKitTestData.Content_1_EntityType, _cmsKitTestData.Content_1_EntityId); |
|||
|
|||
await _entityTagRepository.DeleteManyAsync(relatedTags.Select(s => s.Id).ToArray()); |
|||
|
|||
relatedTags = await _tagRepository.GetAllRelatedTagsAsync(_cmsKitTestData.Content_1_EntityType, _cmsKitTestData.Content_1_EntityId); |
|||
|
|||
relatedTags.ShouldBeEmpty(); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue