mirror of https://github.com/abpframework/abp.git
committed by
GitHub
90 changed files with 2171 additions and 192 deletions
File diff suppressed because it is too large
@ -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"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,6 @@ |
|||||
using Volo.Abp.Modularity; |
using Volo.Abp.Modularity; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Admin |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(CmsKitCommonApplicationContractsModule) |
typeof(CmsKitCommonApplicationContractsModule) |
||||
@ -1,4 +1,4 @@ |
|||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Admin |
||||
{ |
{ |
||||
public class CmsKitAdminRemoteServiceConsts |
public class CmsKitAdminRemoteServiceConsts |
||||
{ |
{ |
||||
@ -1,6 +1,6 @@ |
|||||
using Volo.Abp.Reflection; |
using Volo.Abp.Reflection; |
||||
|
|
||||
namespace Volo.CmsKit.Permissions |
namespace Volo.CmsKit.Admin.Permissions |
||||
{ |
{ |
||||
public class CmsKitAdminPermissions |
public class CmsKitAdminPermissions |
||||
{ |
{ |
||||
@ -1,4 +1,4 @@ |
|||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Admin |
||||
{ |
{ |
||||
public abstract class CmsKitAdminAppService : CmsKitAppService |
public abstract class CmsKitAdminAppService : CmsKitAppService |
||||
{ |
{ |
||||
@ -1,6 +1,6 @@ |
|||||
using AutoMapper; |
using AutoMapper; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Admin |
||||
{ |
{ |
||||
public class CmsKitAdminApplicationAutoMapperProfile : Profile |
public class CmsKitAdminApplicationAutoMapperProfile : Profile |
||||
{ |
{ |
||||
@ -1,9 +1,8 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
using Microsoft.Extensions.DependencyInjection; |
||||
using Volo.Abp.Application; |
|
||||
using Volo.Abp.AutoMapper; |
using Volo.Abp.AutoMapper; |
||||
using Volo.Abp.Modularity; |
using Volo.Abp.Modularity; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Admin |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(CmsKitAdminApplicationContractsModule), |
typeof(CmsKitAdminApplicationContractsModule), |
||||
@ -1,7 +1,7 @@ |
|||||
using Volo.Abp.AspNetCore.Mvc; |
using Volo.Abp.AspNetCore.Mvc; |
||||
using Volo.CmsKit.Localization; |
using Volo.CmsKit.Localization; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Admin |
||||
{ |
{ |
||||
public abstract class CmsKitAdminController : AbpController |
public abstract class CmsKitAdminController : AbpController |
||||
{ |
{ |
||||
@ -1,7 +1,7 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
using Microsoft.Extensions.DependencyInjection; |
||||
using Volo.Abp.Modularity; |
using Volo.Abp.Modularity; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Admin |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(CmsKitAdminApplicationContractsModule), |
typeof(CmsKitAdminApplicationContractsModule), |
||||
@ -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.Abp.MongoDB; |
||||
|
using Volo.CmsKit.Comments; |
||||
|
using Volo.CmsKit.Reactions; |
||||
|
using Volo.CmsKit.Users; |
||||
|
|
||||
namespace Volo.CmsKit.MongoDB |
namespace Volo.CmsKit.MongoDB |
||||
{ |
{ |
||||
[ConnectionStringName(CmsKitDbProperties.ConnectionStringName)] |
[ConnectionStringName(CmsKitDbProperties.ConnectionStringName)] |
||||
public interface ICmsKitMongoDbContext : IAbpMongoDbContext |
public interface ICmsKitMongoDbContext : IAbpMongoDbContext |
||||
{ |
{ |
||||
/* Define mongo collections here. Example: |
IMongoCollection<UserReaction> UserReactions { get; } |
||||
* IMongoCollection<Question> Questions { 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,6 +1,6 @@ |
|||||
using Volo.Abp.Modularity; |
using Volo.Abp.Modularity; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Public |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(CmsKitCommonApplicationContractsModule) |
typeof(CmsKitCommonApplicationContractsModule) |
||||
@ -1,4 +1,4 @@ |
|||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Public |
||||
{ |
{ |
||||
public class CmsKitPublicRemoteServiceConsts |
public class CmsKitPublicRemoteServiceConsts |
||||
{ |
{ |
||||
@ -1,6 +1,6 @@ |
|||||
using System; |
using System; |
||||
|
|
||||
namespace Volo.CmsKit.Comments |
namespace Volo.CmsKit.Public.Comments |
||||
{ |
{ |
||||
public class CmsUserDto |
public class CmsUserDto |
||||
{ |
{ |
||||
@ -1,6 +1,6 @@ |
|||||
using System; |
using System; |
||||
|
|
||||
namespace Volo.CmsKit.Comments |
namespace Volo.CmsKit.Public.Comments |
||||
{ |
{ |
||||
public class CommentDto |
public class CommentDto |
||||
{ |
{ |
||||
@ -1,7 +1,7 @@ |
|||||
using System; |
using System; |
||||
using System.Collections.Generic; |
using System.Collections.Generic; |
||||
|
|
||||
namespace Volo.CmsKit.Comments |
namespace Volo.CmsKit.Public.Comments |
||||
{ |
{ |
||||
public class CommentWithDetailsDto |
public class CommentWithDetailsDto |
||||
{ |
{ |
||||
@ -1,8 +1,9 @@ |
|||||
using System; |
using System; |
||||
using System.ComponentModel.DataAnnotations; |
using System.ComponentModel.DataAnnotations; |
||||
using Volo.Abp.Validation; |
using Volo.Abp.Validation; |
||||
|
using Volo.CmsKit.Comments; |
||||
|
|
||||
namespace Volo.CmsKit.Comments |
namespace Volo.CmsKit.Public.Comments |
||||
{ |
{ |
||||
public class CreateCommentInput |
public class CreateCommentInput |
||||
{ |
{ |
||||
@ -1,11 +1,9 @@ |
|||||
using System; |
using System; |
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
using System.Threading.Tasks; |
||||
using JetBrains.Annotations; |
|
||||
using Volo.Abp.Application.Dtos; |
using Volo.Abp.Application.Dtos; |
||||
using Volo.Abp.Application.Services; |
using Volo.Abp.Application.Services; |
||||
|
|
||||
namespace Volo.CmsKit.Comments |
namespace Volo.CmsKit.Public.Comments |
||||
{ |
{ |
||||
public interface ICommentPublicAppService : IApplicationService |
public interface ICommentPublicAppService : IApplicationService |
||||
{ |
{ |
||||
@ -1,8 +1,8 @@ |
|||||
using System; |
using System.ComponentModel.DataAnnotations; |
||||
using System.ComponentModel.DataAnnotations; |
|
||||
using Volo.Abp.Validation; |
using Volo.Abp.Validation; |
||||
|
using Volo.CmsKit.Comments; |
||||
|
|
||||
namespace Volo.CmsKit.Comments |
namespace Volo.CmsKit.Public.Comments |
||||
{ |
{ |
||||
public class UpdateCommentInput |
public class UpdateCommentInput |
||||
{ |
{ |
||||
@ -1,6 +1,6 @@ |
|||||
using Volo.Abp.Reflection; |
using Volo.Abp.Reflection; |
||||
|
|
||||
namespace Volo.CmsKit.Permissions |
namespace Volo.CmsKit.Public.Permissions |
||||
{ |
{ |
||||
public class CmsKitPublicPermissions |
public class CmsKitPublicPermissions |
||||
{ |
{ |
||||
@ -1,4 +1,4 @@ |
|||||
namespace Volo.CmsKit.Reactions |
namespace Volo.CmsKit.Public.Reactions |
||||
{ |
{ |
||||
public class CreateReactionDto |
public class CreateReactionDto |
||||
{ |
{ |
||||
@ -1,4 +1,4 @@ |
|||||
namespace Volo.CmsKit.Reactions |
namespace Volo.CmsKit.Public.Reactions |
||||
{ |
{ |
||||
public class DeleteReactionDto |
public class DeleteReactionDto |
||||
{ |
{ |
||||
@ -1,6 +1,6 @@ |
|||||
using JetBrains.Annotations; |
using JetBrains.Annotations; |
||||
|
|
||||
namespace Volo.CmsKit.Reactions |
namespace Volo.CmsKit.Public.Reactions |
||||
{ |
{ |
||||
public class ReactionDto |
public class ReactionDto |
||||
{ |
{ |
||||
@ -1,4 +1,4 @@ |
|||||
namespace Volo.CmsKit.Reactions |
namespace Volo.CmsKit.Public.Reactions |
||||
{ |
{ |
||||
public class ReactionWithSelectionDto |
public class ReactionWithSelectionDto |
||||
{ |
{ |
||||
@ -1,4 +1,4 @@ |
|||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Public |
||||
{ |
{ |
||||
public abstract class CmsKitPublicAppService : CmsKitAppService |
public abstract class CmsKitPublicAppService : CmsKitAppService |
||||
{ |
{ |
||||
@ -1,9 +1,10 @@ |
|||||
using AutoMapper; |
using AutoMapper; |
||||
using Volo.Abp.AutoMapper; |
using Volo.Abp.AutoMapper; |
||||
using Volo.CmsKit.Comments; |
using Volo.CmsKit.Comments; |
||||
|
using Volo.CmsKit.Public.Comments; |
||||
using Volo.CmsKit.Users; |
using Volo.CmsKit.Users; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Public |
||||
{ |
{ |
||||
public class PublicApplicationAutoMapperProfile : Profile |
public class PublicApplicationAutoMapperProfile : Profile |
||||
{ |
{ |
||||
@ -1,7 +1,8 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Volo.Abp.Http.Client; |
||||
using Volo.Abp.Modularity; |
using Volo.Abp.Modularity; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Public |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(CmsKitPublicApplicationContractsModule), |
typeof(CmsKitPublicApplicationContractsModule), |
||||
@ -1,6 +1,6 @@ |
|||||
using Volo.CmsKit.Controllers; |
using Volo.CmsKit.Controllers; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Public |
||||
{ |
{ |
||||
public abstract class CmsKitPublicControllerBase : CmsKitControllerBase |
public abstract class CmsKitPublicControllerBase : CmsKitControllerBase |
||||
{ |
{ |
||||
@ -1,7 +1,7 @@ |
|||||
using Microsoft.Extensions.DependencyInjection; |
using Microsoft.Extensions.DependencyInjection; |
||||
using Volo.Abp.Modularity; |
using Volo.Abp.Modularity; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit.Public |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(CmsKitPublicApplicationContractsModule), |
typeof(CmsKitPublicApplicationContractsModule), |
||||
@ -1,11 +1,10 @@ |
|||||
using System; |
using System; |
||||
using System.Collections.Generic; |
|
||||
using System.Threading.Tasks; |
using System.Threading.Tasks; |
||||
using Microsoft.AspNetCore.Mvc; |
using Microsoft.AspNetCore.Mvc; |
||||
using Volo.Abp; |
using Volo.Abp; |
||||
using Volo.Abp.Application.Dtos; |
using Volo.Abp.Application.Dtos; |
||||
|
|
||||
namespace Volo.CmsKit.Comments |
namespace Volo.CmsKit.Public.Comments |
||||
{ |
{ |
||||
[RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] |
[RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] |
||||
[Area("cms-kit")] |
[Area("cms-kit")] |
||||
@ -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. |
/* Inherit from this class for your application layer tests. |
||||
* See SampleAppService_Tests for example. |
* See SampleAppService_Tests for example. |
||||
*/ |
*/ |
||||
public abstract class CmsKitApplicationTestBase : CmsKitTestBase<CmsKitApplicationTestModule> |
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. |
/* Inherit from this class for your domain layer tests. |
||||
* See SampleManager_Tests for example. |
* See SampleManager_Tests for example. |
||||
*/ |
*/ |
||||
public abstract class CmsKitDomainTestBase : CmsKitTestBase<CmsKitDomainTestModule> |
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. |
|
||||
*/ |
|
||||
} |
|
||||
} |
|
||||
@ -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…
Reference in new issue