Merge pull request #5016 from abpframework/issue/4959

CMS Kit Code revisions/improvements
pull/5022/head
Halil İbrahim Kalkan 5 years ago committed by GitHub
commit 170f055d0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -34,6 +34,7 @@ using Volo.Abp.TenantManagement.Web;
using Volo.Abp.Threading;
using Volo.Abp.VirtualFileSystem;
using Volo.CmsKit.Admin.Web;
using Volo.CmsKit.Public.Web;
namespace Volo.CmsKit
{

@ -0,0 +1,32 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Volo.CmsKit.Migrations
{
public partial class Reaction_Comment_Multitenancy : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "CmsUserReactions",
nullable: true);
migrationBuilder.AddColumn<Guid>(
name: "TenantId",
table: "CmsComments",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "TenantId",
table: "CmsUserReactions");
migrationBuilder.DropColumn(
name: "TenantId",
table: "CmsComments");
}
}
}

@ -939,6 +939,10 @@ namespace Volo.CmsKit.Migrations
b.Property<Guid?>("RepliedCommentId")
.HasColumnType("uniqueidentifier");
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.Property<string>("Text")
.IsRequired()
.HasColumnType("nvarchar(512)")
@ -982,6 +986,10 @@ namespace Volo.CmsKit.Migrations
.HasColumnType("nvarchar(32)")
.HasMaxLength(32);
b.Property<Guid?>("TenantId")
.HasColumnName("TenantId")
.HasColumnType("uniqueidentifier");
b.HasKey("Id");
b.HasIndex("EntityType", "EntityId");

@ -2,8 +2,8 @@
@using Localization.Resources.AbpUi
@using Microsoft.Extensions.Localization
@using Volo.CmsKit.Pages
@using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting
@using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.ReactionSelection
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection
@model IndexModel
@inject IStringLocalizer<AbpUiResource> Localizer
<h1>CMS Kit DEMO</h1>

@ -2,7 +2,8 @@
@using Localization.Resources.AbpUi
@using Microsoft.Extensions.Localization
@using Volo.CmsKit.Pages
@using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting
@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection
@model PublicModel
@inject IStringLocalizer<AbpUiResource> Localizer
<h1>CMS Kit DEMO - Public</h1>
@ -18,7 +19,9 @@
</footer>
</abp-blockquote>
</abp-card-body>
@await Component.InvokeAsync(typeof(CommentingViewComponent), new { entityType = "publicQuote", entityId = "1", loginUrl="Account/Login?ReturnUrl=%2Fpublic" })
@await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new { entityType = "publicQuote", entityId = "1" })
<hr />
@await Component.InvokeAsync(typeof(CommentingViewComponent), new { entityType = "publicQuote", entityId = "1", loginUrl = "Account/Login?ReturnUrl=%2Fpublic" })
</abp-card>
<abp-card class="mb-3">

@ -2,7 +2,7 @@
using Volo.Abp.Localization;
using Volo.CmsKit.Localization;
namespace Volo.CmsKit.Permissions
namespace Volo.CmsKit.Admin.Permissions
{
public class CmsKitAdminPermissionDefinitionProvider : PermissionDefinitionProvider
{

@ -1,4 +1,4 @@
namespace Volo.CmsKit
namespace Volo.CmsKit.Admin
{
public abstract class CmsKitAdminAppService : CmsKitAppService
{

@ -1,9 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Application;
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace Volo.CmsKit
namespace Volo.CmsKit.Admin
{
[DependsOn(
typeof(CmsKitAdminApplicationContractsModule),

@ -2,7 +2,7 @@
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
namespace Volo.CmsKit
namespace Volo.CmsKit.Admin
{
[DependsOn(
typeof(CmsKitAdminApplicationContractsModule),

@ -1,7 +1,7 @@
using Volo.Abp.AspNetCore.Mvc;
using Volo.CmsKit.Localization;
namespace Volo.CmsKit
namespace Volo.CmsKit.Admin
{
public abstract class CmsKitAdminController : AbpController
{

@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace Volo.CmsKit
namespace Volo.CmsKit.Admin
{
[DependsOn(
typeof(CmsKitAdminApplicationContractsModule),

@ -1,4 +1,6 @@
using Volo.Abp.Modularity;
using Volo.CmsKit.Admin;
using Volo.CmsKit.Public;
namespace Volo.CmsKit
{

@ -1,4 +1,6 @@
using Volo.Abp.Modularity;
using Volo.CmsKit.Admin;
using Volo.CmsKit.Public;
namespace Volo.CmsKit
{

@ -3,11 +3,14 @@ using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace Volo.CmsKit.Comments
{
public class Comment: Entity<Guid>, IAggregateRoot<Guid>, IHasCreationTime, IMustHaveCreator
public class Comment: Entity<Guid>, IAggregateRoot<Guid>, IHasCreationTime, IMustHaveCreator, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual string EntityType { get; protected set; }
public virtual string EntityId { get; protected set; }
@ -31,13 +34,15 @@ namespace Volo.CmsKit.Comments
[NotNull] string entityId,
[NotNull] string text,
Guid? repliedCommentId,
Guid creatorId)
Guid creatorId,
Guid? tenantId = null)
: base(id)
{
EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType), CommentConsts.EntityTypeLength);
EntityId = Check.NotNullOrWhiteSpace(entityId, nameof(entityId), CommentConsts.EntityIdLength);
RepliedCommentId = repliedCommentId;
CreatorId = creatorId;
TenantId = tenantId;
SetText(text);
}

@ -4,6 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.MultiTenancy;
namespace Volo.CmsKit.Reactions
{
@ -72,7 +73,8 @@ namespace Volo.CmsKit.Reactions
entityType,
entityId,
reactionName,
creatorId
creatorId,
CurrentTenant.Id
)
);
}

@ -3,11 +3,14 @@ using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace Volo.CmsKit.Reactions
{
public class UserReaction : Entity<Guid>, IAggregateRoot<Guid>, IHasCreationTime, IMustHaveCreator
public class UserReaction : Entity<Guid>, IAggregateRoot<Guid>, IHasCreationTime, IMustHaveCreator, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
public virtual string EntityType { get; protected set; }
public virtual string EntityId { get; protected set; }
@ -28,13 +31,15 @@ namespace Volo.CmsKit.Reactions
[NotNull] string entityType,
[NotNull] string entityId,
[NotNull] string reactionName,
Guid creatorId)
Guid creatorId,
Guid? tenantId = null)
: base(id)
{
EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType));
EntityId = Check.NotNullOrWhiteSpace(entityId, nameof(entityId));
ReactionName = Check.NotNullOrWhiteSpace(reactionName, nameof(reactionName));
CreatorId = creatorId;
TenantId = tenantId;
}
}
}

@ -1,4 +1,6 @@
using Volo.Abp.Modularity;
using Volo.CmsKit.Admin;
using Volo.CmsKit.Public;
namespace Volo.CmsKit
{

@ -1,4 +1,6 @@
using Volo.Abp.Modularity;
using Volo.CmsKit.Admin;
using Volo.CmsKit.Public;
namespace Volo.CmsKit
{

@ -11,6 +11,7 @@
<ItemGroup>
<ProjectReference Include="..\..\..\..\framework\src\Volo.Abp.MongoDB\Volo.Abp.MongoDB.csproj" />
<ProjectReference Include="..\Volo.CmsKit.Domain\Volo.CmsKit.Domain.csproj" />
<ProjectReference Include="..\..\..\..\modules\users\src\Volo.Abp.Users.MongoDB\Volo.Abp.Users.MongoDB.csproj" />
</ItemGroup>
</Project>

@ -1,14 +1,20 @@
using Volo.Abp.Data;
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
using Volo.CmsKit.Comments;
using Volo.CmsKit.Reactions;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.MongoDB
{
[ConnectionStringName(CmsKitDbProperties.ConnectionStringName)]
public class CmsKitMongoDbContext : AbpMongoDbContext, ICmsKitMongoDbContext
{
/* Add mongo collections here. Example:
* public IMongoCollection<Question> Questions => Collection<Question>();
*/
public IMongoCollection<Comment> Comments => Collection<Comment>();
public IMongoCollection<UserReaction> UserReactions => Collection<UserReaction>();
public IMongoCollection<CmsUser> CmsUsers => Collection<CmsUser>();
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{
@ -17,4 +23,4 @@ namespace Volo.CmsKit.MongoDB
modelBuilder.ConfigureCmsKit();
}
}
}
}

@ -1,11 +1,19 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
using Volo.Abp.MongoDB;
using Volo.Abp.Users.MongoDB;
using Volo.CmsKit.Comments;
using Volo.CmsKit.MongoDB.Comments;
using Volo.CmsKit.MongoDB.Reactions;
using Volo.CmsKit.MongoDB.Users;
using Volo.CmsKit.Reactions;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.MongoDB
{
[DependsOn(
typeof(CmsKitDomainModule),
typeof(AbpUsersMongoDbModule),
typeof(AbpMongoDbModule)
)]
public class CmsKitMongoDbModule : AbpModule
@ -14,6 +22,9 @@ namespace Volo.CmsKit.MongoDB
{
context.Services.AddMongoDbContext<CmsKitMongoDbContext>(options =>
{
options.AddRepository<UserReaction, MongoUserReactionRepository>();
options.AddRepository<Comment, MongoCommentRepository>();
options.AddRepository<CmsUser, MongoCmsUserRepository>();
/* Add custom repositories here. Example:
* options.AddRepository<Question, MongoQuestionRepository>();
*/

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Driver.Linq;
using MongoDB.Driver;
using Volo.Abp;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
using Volo.CmsKit.Comments;
namespace Volo.CmsKit.MongoDB.Comments
{
public class MongoCommentRepository : MongoDbRepository<ICmsKitMongoDbContext, Comment, Guid>, ICommentRepository
{
public MongoCommentRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<List<CommentWithAuthor>> GetListWithAuthorsAsync(
string entityType,
string entityId)
{
Check.NotNullOrWhiteSpace(entityType, nameof(entityType));
Check.NotNullOrWhiteSpace(entityId, nameof(entityId));
var authorsQuery = from comment in GetMongoQueryable()
join user in DbContext.CmsUsers on comment.CreatorId equals user.Id
where entityType == comment.EntityType && entityId == comment.EntityId
orderby comment.CreationTime
select user;
var authors = await authorsQuery.ToListAsync();
var comments = await GetMongoQueryable()
.Where(c => c.EntityId == entityId && c.EntityType == entityType)
.OrderBy(c => c.CreationTime).ToListAsync();
return comments
.Select(
comment =>
new CommentWithAuthor
{
Comment = comment,
Author = authors.FirstOrDefault(a => a.Id == comment.CreatorId)
}).ToList();
}
public override async Task DeleteAsync(Guid id, bool autoSave = false, CancellationToken cancellationToken = default)
{
var replies = await GetMongoQueryable()
.Where(x => x.RepliedCommentId == id)
.ToListAsync(GetCancellationToken(cancellationToken));
foreach (var reply in replies)
{
//TODO: Discuss if it is better to mark it as deleted and show in the ui as "This is deleted" instead of deleting it and replies completely
await base.DeleteAsync(reply.Id, autoSave, GetCancellationToken(cancellationToken));
}
await base.DeleteAsync(id, autoSave, GetCancellationToken(cancellationToken));
}
}
}

@ -1,13 +1,19 @@
using Volo.Abp.Data;
using MongoDB.Driver;
using Volo.Abp.Data;
using Volo.Abp.MongoDB;
using Volo.CmsKit.Comments;
using Volo.CmsKit.Reactions;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.MongoDB
{
[ConnectionStringName(CmsKitDbProperties.ConnectionStringName)]
public interface ICmsKitMongoDbContext : IAbpMongoDbContext
{
/* Define mongo collections here. Example:
* IMongoCollection<Question> Questions { get; }
*/
IMongoCollection<UserReaction> UserReactions { get; }
IMongoCollection<Comment> Comments { get; }
IMongoCollection<CmsUser> CmsUsers { get; }
}
}

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
using Volo.CmsKit.Reactions;
namespace Volo.CmsKit.MongoDB.Reactions
{
public class MongoUserReactionRepository : MongoDbRepository<ICmsKitMongoDbContext, UserReaction, Guid>, IUserReactionRepository
{
public MongoUserReactionRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider) : base(dbContextProvider)
{
}
public async Task<UserReaction> FindAsync(
Guid userId,
string entityType,
string entityId,
string reactionName)
{
Check.NotNullOrWhiteSpace(entityType, nameof(entityType));
Check.NotNullOrWhiteSpace(entityId, nameof(entityId));
Check.NotNullOrWhiteSpace(reactionName, nameof(reactionName));
return await GetMongoQueryable()
.Where(x =>
x.CreatorId == userId &&
x.EntityType == entityType &&
x.EntityId == entityId &&
x.ReactionName == reactionName)
.FirstOrDefaultAsync();
}
public async Task<List<UserReaction>> GetListForUserAsync(
Guid userId,
string entityType,
string entityId)
{
Check.NotNullOrWhiteSpace(entityType, nameof(entityType));
Check.NotNullOrWhiteSpace(entityId, nameof(entityId));
return await GetMongoQueryable()
.Where(x =>
x.CreatorId == userId &&
x.EntityType == entityType &&
x.EntityId == entityId)
.ToListAsync();
}
public async Task<List<ReactionSummaryQueryResultItem>> GetSummariesAsync(
string entityType,
string entityId)
{
Check.NotNullOrWhiteSpace(entityType, nameof(entityType));
Check.NotNullOrWhiteSpace(entityId, nameof(entityId));
return await GetMongoQueryable()
.Where(x =>
x.EntityType == entityType &&
x.EntityId == entityId)
.GroupBy(x => x.ReactionName)
.Select(g => new ReactionSummaryQueryResultItem
{
ReactionName = g.Key,
Count = g.Count()
})
.ToListAsync();
}
}
}

@ -0,0 +1,15 @@
using Volo.Abp.MongoDB;
using Volo.Abp.Users.MongoDB;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.MongoDB.Users
{
public class MongoCmsUserRepository : MongoUserRepositoryBase<ICmsKitMongoDbContext, CmsUser>, ICmsUserRepository
{
public MongoCmsUserRepository(IMongoDbContextProvider<ICmsKitMongoDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
}
}

@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
namespace Volo.CmsKit.Comments
namespace Volo.CmsKit.Public.Comments
{
public class CommentWithDetailsDto
{

@ -1,8 +1,9 @@
using System;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
using Volo.CmsKit.Comments;
namespace Volo.CmsKit.Comments
namespace Volo.CmsKit.Public.Comments
{
public class CreateCommentInput
{

@ -1,11 +1,9 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Volo.CmsKit.Comments
namespace Volo.CmsKit.Public.Comments
{
public interface ICommentPublicAppService : IApplicationService
{

@ -1,8 +1,8 @@
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Validation;
using Volo.CmsKit.Comments;
namespace Volo.CmsKit.Comments
namespace Volo.CmsKit.Public.Comments
{
public class UpdateCommentInput
{

@ -2,7 +2,7 @@
using Volo.Abp.Localization;
using Volo.CmsKit.Localization;
namespace Volo.CmsKit.Permissions
namespace Volo.CmsKit.Public.Permissions
{
public class CmsKitPublicPermissionDefinitionProvider : PermissionDefinitionProvider
{

@ -2,7 +2,7 @@
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Volo.CmsKit.Reactions
namespace Volo.CmsKit.Public.Reactions
{
public interface IReactionPublicAppService : IApplicationService
{

@ -1,4 +1,4 @@
namespace Volo.CmsKit
namespace Volo.CmsKit.Public
{
public abstract class CmsKitPublicAppService : CmsKitAppService
{

@ -2,7 +2,7 @@
using Volo.Abp.AutoMapper;
using Volo.Abp.Modularity;
namespace Volo.CmsKit
namespace Volo.CmsKit.Public
{
[DependsOn(
typeof(CmsKitCommonApplicationModule),

@ -8,10 +8,12 @@ using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Users;
using Volo.CmsKit.Comments;
using Volo.CmsKit.Users;
namespace Volo.CmsKit.Comments
namespace Volo.CmsKit.Public.Comments
{
public class CommentPublicAppService : ApplicationService, ICommentPublicAppService
{
@ -29,7 +31,7 @@ namespace Volo.CmsKit.Comments
CmsUserLookupService = cmsUserLookupService;
}
public async Task<ListResultDto<CommentWithDetailsDto>> GetAllForEntityAsync(string entityType, string entityId)
public virtual async Task<ListResultDto<CommentWithDetailsDto>> GetAllForEntityAsync(string entityType, string entityId)
{
CheckAuthorizationAsync(entityType);
@ -41,7 +43,7 @@ namespace Volo.CmsKit.Comments
}
[Authorize]
public async Task<CommentDto> CreateAsync(CreateCommentInput input)
public virtual async Task<CommentDto> CreateAsync(CreateCommentInput input)
{
var user = await CmsUserLookupService.FindByIdAsync(CurrentUser.GetId());
@ -56,14 +58,15 @@ namespace Volo.CmsKit.Comments
input.EntityId,
input.Text,
input.RepliedCommentId,
user.Id
user.Id,
CurrentTenant.Id
));
return ObjectMapper.Map<Comment, CommentDto>(comment);
}
[Authorize]
public async Task<CommentDto> UpdateAsync(Guid id, UpdateCommentInput input)
public virtual async Task<CommentDto> UpdateAsync(Guid id, UpdateCommentInput input)
{
var comment = await CommentRepository.GetAsync(id);
@ -80,7 +83,7 @@ namespace Volo.CmsKit.Comments
}
[Authorize]
public async Task DeleteAsync(Guid id)
public virtual async Task DeleteAsync(Guid id)
{
var comment = await CommentRepository.GetAsync(id);

@ -1,9 +1,10 @@
using AutoMapper;
using Volo.Abp.AutoMapper;
using Volo.CmsKit.Comments;
using Volo.CmsKit.Public.Comments;
using Volo.CmsKit.Users;
namespace Volo.CmsKit
namespace Volo.CmsKit.Public
{
public class PublicApplicationAutoMapperProfile : Profile
{

@ -1,10 +1,12 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Users;
using Volo.CmsKit.Reactions;
namespace Volo.CmsKit.Reactions
namespace Volo.CmsKit.Public.Reactions
{
//TODO: Authorization
public class ReactionPublicAppService : CmsKitPublicAppService, IReactionPublicAppService
@ -29,12 +31,13 @@ namespace Volo.CmsKit.Reactions
{
var summaries = await ReactionManager.GetSummariesAsync(entityType, entityId);
var userReactions = (await UserReactionRepository
var userReactions = CurrentUser.IsAuthenticated ?
(await UserReactionRepository
.GetListForUserAsync(
CurrentUser.GetId(),
entityType,
entityId
)).ToDictionary(x => x.ReactionName, x => x);
)).ToDictionary(x => x.ReactionName, x => x) : null;
var reactionWithSelectionDtos = new List<ReactionWithSelectionDto>();
@ -45,7 +48,7 @@ namespace Volo.CmsKit.Reactions
{
Reaction = ConvertToReactionDto(summary.Reaction),
Count = summary.Count,
IsSelectedByCurrentUser = userReactions.ContainsKey(summary.Reaction.Name)
IsSelectedByCurrentUser = userReactions?.ContainsKey(summary.Reaction.Name) ?? false
}
);
}
@ -53,6 +56,7 @@ namespace Volo.CmsKit.Reactions
return new ListResultDto<ReactionWithSelectionDto>(reactionWithSelectionDtos);
}
[Authorize]
public virtual async Task CreateAsync(CreateReactionDto input)
{
await ReactionManager.CreateAsync(
@ -63,6 +67,7 @@ namespace Volo.CmsKit.Reactions
);
}
[Authorize]
public virtual async Task DeleteAsync(DeleteReactionDto input)
{
await ReactionManager.DeleteAsync(

@ -1,7 +1,8 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Http.Client;
using Volo.Abp.Modularity;
namespace Volo.CmsKit
namespace Volo.CmsKit.Public
{
[DependsOn(
typeof(CmsKitPublicApplicationContractsModule),

@ -1,6 +1,6 @@
using Volo.CmsKit.Controllers;
namespace Volo.CmsKit
namespace Volo.CmsKit.Public
{
public abstract class CmsKitPublicControllerBase : CmsKitControllerBase
{

@ -1,7 +1,7 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace Volo.CmsKit
namespace Volo.CmsKit.Public
{
[DependsOn(
typeof(CmsKitPublicApplicationContractsModule),

@ -1,11 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Comments
namespace Volo.CmsKit.Public.Comments
{
[RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)]
[Area("cms-kit")]

@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
namespace Volo.CmsKit.Reactions
namespace Volo.CmsKit.Public.Reactions
{
[RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)]
[Area("cms-kit")]

@ -1,6 +1,6 @@
using AutoMapper;
namespace Volo.CmsKit.Web
namespace Volo.CmsKit.Public.Web
{
public class CmsKitPublicWebAutoMapperProfile : Profile
{

@ -6,9 +6,10 @@ using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation;
using Volo.Abp.VirtualFileSystem;
using Volo.CmsKit.Localization;
using Volo.CmsKit.Web.Menus;
using Volo.CmsKit.Public.Web.Menus;
using Volo.CmsKit.Web;
namespace Volo.CmsKit.Web
namespace Volo.CmsKit.Public.Web
{
[DependsOn(
typeof(CmsKitPublicHttpApiModule),

@ -1,9 +1,9 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting;
using Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.ReactionSelection;
using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting;
using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection;
namespace Volo.CmsKit.Web.Controllers
namespace Volo.CmsKit.Public.Web.Controllers
{
//TODO: Consider to move to an area, but also consider to not have the same prefix with API Controllers which can be problem in case of a tiered architecture
public class CmsKitPublicWidgetsController : CmsKitPublicControllerBase

@ -1,7 +1,7 @@
using System.Threading.Tasks;
using Volo.Abp.UI.Navigation;
namespace Volo.CmsKit.Web.Menus
namespace Volo.CmsKit.Public.Web.Menus
{
public class CmsKitPublicMenuContributor : IMenuContributor
{

@ -1,4 +1,4 @@
namespace Volo.CmsKit.Web.Menus
namespace Volo.CmsKit.Public.Web.Menus
{
public class CmsKitPublicMenus
{

@ -1,9 +1,7 @@
using System.Collections.Generic;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap;
using Volo.Abp.Modularity;
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting
{
public class CommentingScriptBundleContributor : BundleContributor
{

@ -1,7 +1,7 @@
using System.Collections.Generic;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting
{
public class CommentingStyleBundleContributor : BundleContributor
{

@ -4,9 +4,9 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Widgets;
using Volo.CmsKit.Comments;
using Volo.CmsKit.Public.Comments;
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting
{
[ViewComponent(Name = "CmsCommenting")]
[Widget(

@ -3,9 +3,10 @@
@using Volo.Abp.Users
@using Volo.CmsKit.Comments
@using Volo.CmsKit.Localization
@using Volo.CmsKit.Public.Comments
@inject ICurrentUser CurrentUser
@inject IHtmlLocalizer<CmsKitResource> L
@model Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.Commenting.CommentingViewComponent.CommentingViewModel
@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting.CommentingViewComponent.CommentingViewModel
@{
Func<dynamic, IHtmlContent> GetCommentTitle(CmsUserDto author, DateTime creationTime) =>

@ -87,7 +87,7 @@
abp.message.confirm(l("MessageDeletionConfirmationMessage"), function (ok) {
if (ok){
volo.cmsKit.comments.commentPublic.delete($link.data('id')
volo.cmsKit.public.comments.commentPublic.delete($link.data('id')
).then(function () {
widgetManager.refresh($widget);
});
@ -103,7 +103,7 @@
$form.submit(function (e) {
e.preventDefault();
var formAsObject = $form.serializeFormToObject();
volo.cmsKit.comments.commentPublic.update(
volo.cmsKit.public.comments.commentPublic.update(
formAsObject.id,
{
text: formAsObject.commentText
@ -121,8 +121,7 @@
$form.submit(function (e) {
e.preventDefault();
var formAsObject = $form.serializeFormToObject();
console.log(formAsObject);
volo.cmsKit.comments.commentPublic.create(
volo.cmsKit.public.comments.commentPublic.create(
$.extend(getFilters(), {
repliedCommentId: formAsObject.repliedCommentId,
text: formAsObject.commentText

@ -1,17 +1,23 @@
@model Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.ReactionSelection.ReactionSelectionViewComponent.ReactionSelectionViewModel
@inject ICurrentUser CurrentUser
@using Volo.Abp.Users
@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection.ReactionSelectionViewComponent.ReactionSelectionViewModel
<span class="cms-reaction-area" data-entity-type="@Model.EntityType" data-entity-id="@Model.EntityId">
<a class="cms-reaction-select-icon" tabindex="0"><i class="fa fa-smile-o"></i></a>
<div class="cms-reaction-selection-popover-content" style="display: none">
@foreach (var reaction in Model.Reactions)
{
<span class="mr-1 cms-reaction-icon @(reaction.IsSelectedByCurrentUser ? "cms-reaction-icon-selected" : "")" data-reaction-name="@reaction.Name">
<img src="@reaction.Icon" width="18" height="18"/>
</span>
}
</div>
@if (CurrentUser.IsAuthenticated)
{
<a class="cms-reaction-select-icon" tabindex="0"><i class="fa fa-smile-o"></i></a>
<div class="cms-reaction-selection-popover-content" style="display: none">
@foreach (var reaction in Model.Reactions)
{
<span class="mr-1 cms-reaction-icon @(reaction.IsSelectedByCurrentUser ? "cms-reaction-icon-selected" : "")" data-reaction-name="@reaction.Name">
<img src="@reaction.Icon" width="18" height="18"/>
</span>
}
</div>
}
@foreach (var reaction in Model.Reactions.Where(r => r.Count > 0))
{
<span class="mr-1 cms-reaction-icon @(reaction.IsSelectedByCurrentUser ? "cms-reaction-icon-selected" : "")" data-reaction-name="@reaction.Name">
<span class="mr-1 cms-reaction-icon @(reaction.IsSelectedByCurrentUser ? "cms-reaction-icon-selected" : "")" data-reaction-name="@reaction.Name" data-click-action="@(CurrentUser.IsAuthenticated ? "true" : "false")">
<img src="@reaction.Icon" width="18" height="18"/>
@(reaction.Count)
</span>

@ -1,9 +1,7 @@
using System.Collections.Generic;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.Bootstrap;
using Volo.Abp.Modularity;
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.ReactionSelection
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection
{
public class ReactionSelectionScriptBundleContributor : BundleContributor
{

@ -1,7 +1,7 @@
using System.Collections.Generic;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.ReactionSelection
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection
{
public class ReactionSelectionStyleBundleContributor : BundleContributor
{

@ -5,9 +5,10 @@ using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.AspNetCore.Mvc.UI.Widgets;
using Volo.CmsKit.Reactions;
using Volo.CmsKit.Public.Reactions;
using Volo.CmsKit.Web;
namespace Volo.CmsKit.Web.Pages.CmsKit.Shared.Components.ReactionSelection
namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection
{
[ViewComponent(Name = "CmsReactionSelection")]
[Widget(

@ -26,11 +26,15 @@
function registerClickOfReactionIcons($container) {
$container.find('.cms-reaction-icon').each(function () {
var $icon = $(this);
var reactionName = $icon.attr('data-reaction-name');
if ($icon.attr('data-click-action') === 'false'){
return;
}
$icon.click(function () {
var methodName = $icon.hasClass('cms-reaction-icon-selected') ? 'delete' : 'create';
volo.cmsKit.reactions.reactionPublic[methodName](
volo.cmsKit.public.reactions.reactionPublic[methodName](
$.extend(getFilters(), {
reactionName: $icon.attr('data-reaction-name')
reactionName: reactionName
})
).then(function () {
$selectIcon.popover('hide');

@ -1,7 +1,7 @@
using Volo.Abp.AspNetCore.Mvc.UI.RazorPages;
using Volo.CmsKit.Localization;
namespace Volo.CmsKit.Web.Pages
namespace Volo.CmsKit.Public.Web.Pages
{
/* Inherit your PageModel classes from this class.
*/

@ -8,7 +8,7 @@
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
<IsPackable>true</IsPackable>
<OutputType>Library</OutputType>
<RootNamespace>Volo.CmsKit.Web</RootNamespace>
<RootNamespace>Volo.CmsKit.Public.Web</RootNamespace>
<GenerateEmbeddedFilesManifest>true</GenerateEmbeddedFilesManifest>
</PropertyGroup>

@ -1,5 +1,6 @@
using Volo.Abp.Modularity;
using Volo.CmsKit.Admin.Web;
using Volo.CmsKit.Public.Web;
namespace Volo.CmsKit.Web
{

@ -1,10 +1,27 @@
namespace Volo.CmsKit
using System;
using Volo.CmsKit.EntityFrameworkCore;
namespace Volo.CmsKit
{
/* Inherit from this class for your application layer tests.
* See SampleAppService_Tests for example.
*/
public abstract class CmsKitApplicationTestBase : CmsKitTestBase<CmsKitApplicationTestModule>
{
protected virtual void UsingDbContext(Action<ICmsKitDbContext> action)
{
using (var dbContext = GetRequiredService<ICmsKitDbContext>())
{
action.Invoke(dbContext);
}
}
protected virtual T UsingDbContext<T>(Func<ICmsKitDbContext, T> action)
{
using (var dbContext = GetRequiredService<ICmsKitDbContext>())
{
return action.Invoke(dbContext);
}
}
}
}
}

@ -0,0 +1,101 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Shouldly;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Users;
using Volo.CmsKit.Public.Comments;
using Xunit;
namespace Volo.CmsKit.Comments
{
public class CommentPublicAppService_Tests : CmsKitApplicationTestBase
{
private readonly ICommentPublicAppService _commentAppService;
private ICurrentUser _currentUser;
private readonly CmsKitTestData _cmsKitTestData;
public CommentPublicAppService_Tests()
{
_commentAppService = GetRequiredService<ICommentPublicAppService>();
_cmsKitTestData = GetRequiredService<CmsKitTestData>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
_currentUser = Substitute.For<ICurrentUser>();
services.AddSingleton(_currentUser);
}
[Fact]
public async Task GetAllForEntityAsync()
{
var list = await _commentAppService.GetAllForEntityAsync(_cmsKitTestData.EntityType1, _cmsKitTestData.EntityId1);
list.Items.Count.ShouldBe(2);
list.Items.First().Replies.Count.ShouldBe(2);
}
[Fact]
public async Task CreateAsync()
{
_currentUser.Id.Returns(_cmsKitTestData.User2Id);
var newComment = await _commentAppService.CreateAsync(new CreateCommentInput
{
EntityId = _cmsKitTestData.EntityId1,
EntityType = _cmsKitTestData.EntityType1,
RepliedCommentId = null,
Text = "newComment"
});
UsingDbContext(context =>
{
var comments = context.Comments.Where(x =>
x.EntityId == _cmsKitTestData.EntityId1 && x.EntityType == _cmsKitTestData.EntityType1).ToList();
comments
.Any(c=>c.Id == newComment.Id && c.CreatorId == newComment.CreatorId && c.Text == "newComment")
.ShouldBeTrue();
});
}
[Fact]
public async Task UpdateAsync()
{
_currentUser.Id.Returns(_cmsKitTestData.User1Id);
await _commentAppService.UpdateAsync(_cmsKitTestData.CommentWithChildId, new UpdateCommentInput
{
Text = "I'm Updated"
});
UsingDbContext(context =>
{
var comment = context.Comments.Single(x =>
x.Id == _cmsKitTestData.CommentWithChildId);
comment.Text.ShouldBe("I'm Updated");
});
}
[Fact]
public async Task DeleteAsync()
{
_currentUser.Id.Returns(_cmsKitTestData.User1Id);
await _commentAppService.DeleteAsync(_cmsKitTestData.CommentWithChildId);
UsingDbContext(context =>
{
var comment = context.Comments.FirstOrDefault(x =>
x.Id == _cmsKitTestData.CommentWithChildId);
comment.ShouldBeNull();
});
}
}
}

@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Shouldly;
using Volo.Abp.Users;
using Volo.CmsKit.Public.Reactions;
using Xunit;
namespace Volo.CmsKit.Reactions
{
public class ReactionPublicAppService_Tests : CmsKitApplicationTestBase
{
private readonly CmsKitTestData _cmsKitTestData;
private readonly ReactionPublicAppService _reactionPublicAppService;
private ICurrentUser _currentUser;
public ReactionPublicAppService_Tests()
{
_cmsKitTestData = GetRequiredService<CmsKitTestData>();
_reactionPublicAppService = GetRequiredService<ReactionPublicAppService>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
_currentUser = Substitute.For<ICurrentUser>();
services.AddSingleton(_currentUser);
}
[Fact]
public async Task GetForSelectionAsync()
{
_currentUser.Id.Returns(_cmsKitTestData.User1Id);
var reactions = await _reactionPublicAppService.GetForSelectionAsync(
_cmsKitTestData.EntityType2,
_cmsKitTestData.EntityId1
);
reactions.Items.
First(r=>r.Reaction.Name == StandardReactions.Rocket).IsSelectedByCurrentUser.ShouldBeTrue();
reactions.Items.
First(r=>r.Reaction.Name == StandardReactions.Rocket).Count.ShouldBe(1);
reactions.Items.
Where(r=>r.Reaction.Name != StandardReactions.Rocket).All(r=>!r.IsSelectedByCurrentUser)
.ShouldBeTrue();
reactions.Items.
Where(r=>r.Reaction.Name != StandardReactions.Rocket).All(r=> r.Count == 0)
.ShouldBeTrue();
}
[Fact]
public async Task CreateAsync()
{
_currentUser.Id.Returns(_cmsKitTestData.User1Id);
await _reactionPublicAppService.CreateAsync(new CreateReactionDto
{
EntityType = _cmsKitTestData.EntityType2,
EntityId = _cmsKitTestData.EntityId2,
ReactionName = StandardReactions.Hooray
});
UsingDbContext(context =>
{
var reaction = context.UserReactions.FirstOrDefault(x =>
x.CreatorId == _cmsKitTestData.User1Id &&
x.ReactionName == StandardReactions.Hooray &&
x.EntityId == _cmsKitTestData.EntityId2 &&
x.EntityType == _cmsKitTestData.EntityType2);
reaction.ShouldNotBeNull();
});
}
[Fact]
public async Task DeleteAsync()
{
_currentUser.Id.Returns(_cmsKitTestData.User1Id);
await _reactionPublicAppService.DeleteAsync(new DeleteReactionDto
{
EntityType = _cmsKitTestData.EntityType1,
EntityId = _cmsKitTestData.EntityId1,
ReactionName = StandardReactions.Confused
});
UsingDbContext(context =>
{
var reaction = context.UserReactions.FirstOrDefault(x =>
x.CreatorId == _cmsKitTestData.User1Id &&
x.ReactionName == StandardReactions.Confused &&
x.EntityId == _cmsKitTestData.EntityId1 &&
x.EntityType == _cmsKitTestData.EntityType1);
reaction.ShouldBeNull();
});
}
}
}

@ -1,10 +1,27 @@
namespace Volo.CmsKit
using System;
using Volo.CmsKit.EntityFrameworkCore;
namespace Volo.CmsKit
{
/* Inherit from this class for your domain layer tests.
* See SampleManager_Tests for example.
*/
public abstract class CmsKitDomainTestBase : CmsKitTestBase<CmsKitDomainTestModule>
{
protected virtual void UsingDbContext(Action<ICmsKitDbContext> action)
{
using (var dbContext = GetRequiredService<ICmsKitDbContext>())
{
action.Invoke(dbContext);
}
}
protected virtual T UsingDbContext<T>(Func<ICmsKitDbContext, T> action)
{
using (var dbContext = GetRequiredService<ICmsKitDbContext>())
{
return action.Invoke(dbContext);
}
}
}
}

@ -0,0 +1,82 @@
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Xunit;
namespace Volo.CmsKit.Reactions
{
public class ReactionManager_Tests : CmsKitDomainTestBase
{
private readonly CmsKitTestData _cmsKitTestData;
private readonly ReactionManager _reactionManager;
public ReactionManager_Tests()
{
_cmsKitTestData = GetRequiredService<CmsKitTestData>();
_reactionManager = GetRequiredService<ReactionManager>();
}
[Fact]
public async Task GetReactionsAsync()
{
var reactions = await _reactionManager.GetReactionsAsync();
reactions.Count.ShouldBe(8);
var reactionsByEntityType = await _reactionManager.GetReactionsAsync(_cmsKitTestData.EntityType1);
reactionsByEntityType.Count.ShouldBe(8);
}
[Fact]
public async Task GetSummariesAsync()
{
var summary = await _reactionManager.GetSummariesAsync(
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1
);
summary.Single(s=>s.Reaction.Name == StandardReactions.ThumbsUp).Count.ShouldBe(2);
summary.Single(s=>s.Reaction.Name == StandardReactions.Confused).Count.ShouldBe(1);
summary.Single(s=>s.Reaction.Name == StandardReactions.Rocket).Count.ShouldBe(0);
}
[Fact]
public async Task CreateAsync()
{
var reaction = await _reactionManager.CreateAsync(
_cmsKitTestData.User2Id,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId2,
StandardReactions.Eyes
);
reaction.CreatorId.ShouldBe(_cmsKitTestData.User2Id);
reaction.EntityType.ShouldBe(_cmsKitTestData.EntityType1);
reaction.EntityId.ShouldBe(_cmsKitTestData.EntityId2);
reaction.ReactionName.ShouldBe(StandardReactions.Eyes);
}
[Fact]
public async Task DeleteAsync()
{
await _reactionManager.DeleteAsync(
_cmsKitTestData.User1Id,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
StandardReactions.Confused
);
UsingDbContext(context =>
{
var reaction = context.UserReactions.FirstOrDefault(x =>
x.CreatorId == _cmsKitTestData.User1Id &&
x.ReactionName == StandardReactions.Confused &&
x.EntityId == _cmsKitTestData.EntityId1 &&
x.EntityType == _cmsKitTestData.EntityType1);
reaction.ShouldBeNull();
});
}
}
}

@ -1,21 +0,0 @@
using System.Threading.Tasks;
using Xunit;
namespace Volo.CmsKit.Samples
{
public class SampleManager_Tests : CmsKitDomainTestBase
{
//private readonly SampleManager _sampleManager;
public SampleManager_Tests()
{
//_sampleManager = GetRequiredService<SampleManager>();
}
[Fact]
public async Task Method1Async()
{
}
}
}

@ -0,0 +1,9 @@
using Volo.CmsKit.Comments;
namespace Volo.CmsKit.EntityFrameworkCore.Comments
{
public class CommentRepository_Tests : CommentRepository_Tests<CmsKitEntityFrameworkCoreTestModule>
{
}
}

@ -0,0 +1,8 @@
using Volo.CmsKit.Reactions;
namespace Volo.CmsKit.EntityFrameworkCore.Reactions
{
public class UserReactionRepository_Tests : UserReactionRepository_Tests<CmsKitEntityFrameworkCoreTestModule>
{
}
}

@ -1,12 +0,0 @@
using Volo.CmsKit.Samples;
namespace Volo.CmsKit.EntityFrameworkCore.Samples
{
public class SampleRepository_Tests : SampleRepository_Tests<CmsKitEntityFrameworkCoreTestModule>
{
/* Don't write custom repository tests here, instead write to
* the base class.
* One exception can be some specific tests related to EF core.
*/
}
}

@ -0,0 +1,9 @@
using Volo.CmsKit.Comments;
namespace Volo.CmsKit.MongoDB.Comments
{
public class CommentRepository_Tests : CommentRepository_Tests<CmsKitMongoDbTestModule>
{
}
}

@ -0,0 +1,8 @@
using Volo.CmsKit.Reactions;
namespace Volo.CmsKit.MongoDB.Reactions
{
public class UserReactionRepository_Tests : UserReactionRepository_Tests<CmsKitMongoDbTestModule>
{
}
}

@ -1,14 +0,0 @@
using Volo.CmsKit.Samples;
using Xunit;
namespace Volo.CmsKit.MongoDB.Samples
{
[Collection(MongoTestCollection.Name)]
public class SampleRepository_Tests : SampleRepository_Tests<CmsKitMongoDbTestModule>
{
/* Don't write custom repository tests here, instead write to
* the base class.
* One exception can be some specific tests related to MongoDB.
*/
}
}

@ -2,26 +2,134 @@
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Users;
using Volo.CmsKit.Comments;
using Volo.CmsKit.Reactions;
using Volo.CmsKit.Users;
namespace Volo.CmsKit
{
public class CmsKitDataSeedContributor : IDataSeedContributor, ITransientDependency
{
private readonly IGuidGenerator _guidGenerator;
private readonly ICmsUserRepository _cmsUserRepository;
private readonly CmsKitTestData _cmsKitTestData;
private readonly ICommentRepository _commentRepository;
private readonly ReactionManager _reactionManager;
public CmsKitDataSeedContributor(
IGuidGenerator guidGenerator)
IGuidGenerator guidGenerator,
ICmsUserRepository cmsUserRepository,
CmsKitTestData cmsKitTestData,
ICommentRepository commentRepository,
ReactionManager reactionManager)
{
_guidGenerator = guidGenerator;
_cmsUserRepository = cmsUserRepository;
_cmsKitTestData = cmsKitTestData;
_commentRepository = commentRepository;
_reactionManager = reactionManager;
}
public Task SeedAsync(DataSeedContext context)
public async Task SeedAsync(DataSeedContext context)
{
await SeedUsersAsync();
await SeedCommentsAsync();
await SeedReactionsAsync();
}
private async Task SeedUsersAsync()
{
await _cmsUserRepository.InsertAsync(new CmsUser(new UserData(_cmsKitTestData.User1Id, "user1", "user1@volo.com",
"user", "1")));
await _cmsUserRepository.InsertAsync(new CmsUser(new UserData(_cmsKitTestData.User2Id, "user2", "user2@volo.com",
"user", "2")));
}
private async Task SeedCommentsAsync()
{
var comment1 = await _commentRepository.InsertAsync(new Comment(_cmsKitTestData.CommentWithChildId,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
"comment",
null,
_cmsKitTestData.User1Id
));
await _commentRepository.InsertAsync(new Comment(_guidGenerator.Create(),
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
"reply",
comment1.Id,
_cmsKitTestData.User2Id
));
await _commentRepository.InsertAsync(new Comment(_guidGenerator.Create(),
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
"reply",
comment1.Id,
_cmsKitTestData.User1Id
));
await _commentRepository.InsertAsync(new Comment(_guidGenerator.Create(),
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
"comment",
null,
_cmsKitTestData.User2Id
));
await _commentRepository.InsertAsync(new Comment(_guidGenerator.Create(),
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId2,
"comment",
null,
_cmsKitTestData.User2Id
));
await _commentRepository.InsertAsync(new Comment(_guidGenerator.Create(),
_cmsKitTestData.EntityType2,
_cmsKitTestData.EntityId1,
"comment",
null,
_cmsKitTestData.User2Id
));
}
private async Task SeedReactionsAsync()
{
/* Instead of returning the Task.CompletedTask, you can insert your test data
* at this point!
*/
await _reactionManager.CreateAsync(
_cmsKitTestData.User1Id,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
StandardReactions.Confused);
await _reactionManager.CreateAsync(
_cmsKitTestData.User1Id,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
StandardReactions.ThumbsUp);
await _reactionManager.CreateAsync(
_cmsKitTestData.User1Id,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId2,
StandardReactions.Heart);
await _reactionManager.CreateAsync(
_cmsKitTestData.User1Id,
_cmsKitTestData.EntityType2,
_cmsKitTestData.EntityId1,
StandardReactions.Rocket);
return Task.CompletedTask;
await _reactionManager.CreateAsync(
_cmsKitTestData.User2Id,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
StandardReactions.ThumbsUp);
}
}
}
}

@ -0,0 +1,22 @@
using System;
using Volo.Abp.DependencyInjection;
namespace Volo.CmsKit
{
public class CmsKitTestData : ISingletonDependency
{
public Guid User1Id { get; } = Guid.NewGuid();
public Guid User2Id { get; } = Guid.NewGuid();
public Guid CommentWithChildId { get; } = Guid.NewGuid();
public string EntityType1 { get; } = "EntityName1";
public string EntityType2 { get; } = "EntityName2";
public string EntityId1 { get; } = "1";
public string EntityId2 { get; } = "2";
}
}

@ -0,0 +1,44 @@
using System.Linq;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Modularity;
using Xunit;
namespace Volo.CmsKit.Comments
{
public abstract class CommentRepository_Tests<TStartupModule> : CmsKitTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
private readonly CmsKitTestData _cmsKitTestData;
private readonly ICommentRepository _commentRepository;
public CommentRepository_Tests()
{
_cmsKitTestData = GetRequiredService<CmsKitTestData>();
_commentRepository = GetRequiredService<ICommentRepository>();
}
[Fact]
public async Task GetListWithAuthorsAsync()
{
var list = await _commentRepository.GetListWithAuthorsAsync(_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1);
list.Count.ShouldBe(4);
list.Any(x=>x.Comment == null).ShouldBeFalse();
list.Any(x=>x.Author == null).ShouldBeFalse();
}
[Fact]
public async Task DeleteAsync()
{
await _commentRepository.DeleteAsync(_cmsKitTestData.CommentWithChildId);
var list = await _commentRepository.GetListAsync();
list.Any(x=>
x.Id == _cmsKitTestData.CommentWithChildId || x.RepliedCommentId == _cmsKitTestData.CommentWithChildId)
.ShouldBeFalse();
}
}
}

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Modularity;
using Volo.CmsKit.Comments;
using Xunit;
namespace Volo.CmsKit.Reactions
{
public abstract class UserReactionRepository_Tests<TStartupModule> : CmsKitTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
private readonly CmsKitTestData _cmsKitTestData;
private readonly IUserReactionRepository __userReactionRepository;
public UserReactionRepository_Tests()
{
_cmsKitTestData = GetRequiredService<CmsKitTestData>();
__userReactionRepository = GetRequiredService<IUserReactionRepository>();
}
[Fact]
public async Task FindAsync()
{
var reaction = await __userReactionRepository.FindAsync(
_cmsKitTestData.User1Id,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1,
StandardReactions.Confused
);
reaction.ShouldNotBeNull();
reaction.CreatorId.ShouldBe(_cmsKitTestData.User1Id);
reaction.EntityId.ShouldBe(_cmsKitTestData.EntityId1);
reaction.EntityType.ShouldBe(_cmsKitTestData.EntityType1);
reaction.ReactionName.ShouldBe(StandardReactions.Confused);
}
[Fact]
public async Task GetListForUserAsync()
{
var reactions = await __userReactionRepository.GetListForUserAsync(
_cmsKitTestData.User1Id,
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1
);
reactions.Count.ShouldBe(2);
reactions.Count(x=>x.ReactionName == StandardReactions.Confused).ShouldBe(1);
reactions.Count(x=>x.ReactionName == StandardReactions.ThumbsUp).ShouldBe(1);
}
[Fact]
public async Task GetSummariesAsync()
{
var summaries = await __userReactionRepository.GetSummariesAsync(
_cmsKitTestData.EntityType1,
_cmsKitTestData.EntityId1
);
summaries.Count.ShouldBe(2);
summaries.First(x => x.ReactionName == StandardReactions.Confused).Count.ShouldBe(1);
summaries.First(x => x.ReactionName == StandardReactions.ThumbsUp).Count.ShouldBe(2);
}
}
}

@ -1,27 +0,0 @@
using System.Threading.Tasks;
using Volo.Abp.Modularity;
using Xunit;
namespace Volo.CmsKit.Samples
{
/* Write your custom repository tests like that, in this project, as abstract classes.
* Then inherit these abstract classes from EF Core & MongoDB test projects.
* In this way, both database providers are tests with the same set tests.
*/
public abstract class SampleRepository_Tests<TStartupModule> : CmsKitTestBase<TStartupModule>
where TStartupModule : IAbpModule
{
//private readonly ISampleRepository _sampleRepository;
protected SampleRepository_Tests()
{
//_sampleRepository = GetRequiredService<ISampleRepository>();
}
[Fact]
public async Task Method1Async()
{
}
}
}
Loading…
Cancel
Save