mirror of https://github.com/abpframework/abp.git
27 changed files with 448 additions and 36 deletions
@ -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; } |
||||
|
} |
||||
|
} |
||||
@ -1,9 +1,11 @@ |
|||||
using System; |
using System; |
||||
|
using System.Threading.Tasks; |
||||
using Volo.Abp.Domain.Repositories; |
using Volo.Abp.Domain.Repositories; |
||||
|
|
||||
namespace Volo.CmsKit.Blogs |
namespace Volo.CmsKit.Blogs |
||||
{ |
{ |
||||
public interface IBlogRepository : IBasicRepository<Blog, Guid> |
public interface IBlogRepository : IBasicRepository<Blog, Guid> |
||||
{ |
{ |
||||
|
public Task<Blog> GetByUrlSlugAsync(string urlSlug); |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -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,13 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
|
||||
|
namespace Volo.CmsKit.Public.Blogs |
||||
|
{ |
||||
|
public interface IBlogPostPublicAppService |
||||
|
{ |
||||
|
Task<List<BlogPostPublicDto>> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input); |
||||
|
|
||||
|
Task<BlogPostPublicDto> GetAsync(string blogUrlSlug, string blogPostUrlSlug); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,41 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
using Volo.CmsKit.Blogs; |
||||
|
|
||||
|
namespace Volo.CmsKit.Public.Blogs |
||||
|
{ |
||||
|
public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPublicAppService |
||||
|
{ |
||||
|
protected IBlogRepository BlogRepository { 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<List<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 ObjectMapper.Map<List<BlogPost>, List<BlogPostPublicDto>>(blogPosts); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -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,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,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,47 @@ |
|||||
|
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)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue