From 0d889920890a74e0b3ab63a6cb64e35a183efcd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 20 Sep 2017 11:02:42 +0300 Subject: [PATCH] Added unit tests. --- .../Abp/Identity/IIdentityUserAppService.cs | 3 +- .../Identity/IdentityUserCreateOrUpdateDto.cs | 7 ++- .../Abp/Identity/IdentityUserRoleInfoDto.cs | 9 ++++ .../Abp/Identity/IdentityUserAppService.cs | 22 +++++--- .../Identity/EfCoreIdentityUserRepository.cs | 10 ++-- .../Volo/Abp/Identity/IdentityRole.cs | 1 + .../Volo/Abp/Identity/IdentityUser.cs | 10 ++-- .../Volo/Abp/Identity/IdentityUserManager.cs | 29 ++++++++--- .../Identity/AbpIdentityTestDataBuilder.cs | 18 ++++++- .../Identity/IdentityUserAppService_Tests.cs | 50 ++++++++++++++++++- 10 files changed, 128 insertions(+), 31 deletions(-) create mode 100644 src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserRoleInfoDto.cs diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs index e8ca91f82e..c2856673c2 100644 --- a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IIdentityUserAppService.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; @@ -6,6 +7,6 @@ namespace Volo.Abp.Identity { public interface IIdentityUserAppService : IAsyncCrudAppService { - + } } diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDto.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDto.cs index 864f4a91a5..ba61f3ec8f 100644 --- a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDto.cs +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserCreateOrUpdateDto.cs @@ -1,4 +1,6 @@ -namespace Volo.Abp.Identity +using JetBrains.Annotations; + +namespace Volo.Abp.Identity { public abstract class IdentityUserCreateOrUpdateDtoBase { @@ -11,5 +13,8 @@ public bool TwoFactorEnabled { get; set; } //TODO: Optional? public bool LockoutEnabled { get; set; } //TODO: Optional? + + [CanBeNull] + public string[] Roles { get; set; } } } \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserRoleInfoDto.cs b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserRoleInfoDto.cs new file mode 100644 index 0000000000..a5dbc9db3a --- /dev/null +++ b/src/Volo.Abp.Identity.Application.Contracts/Volo/Abp/Identity/IdentityUserRoleInfoDto.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Application.Dtos; + +namespace Volo.Abp.Identity +{ + public class IdentityUserRoleInfoDto : EntityDto + { + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs index 8c7ae97b38..d4af50528e 100644 --- a/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs +++ b/src/Volo.Abp.Identity.Application/Volo/Abp/Identity/IdentityUserAppService.cs @@ -28,19 +28,20 @@ namespace Volo.Abp.Identity public async Task> GetListAsync(PagedAndSortedResultRequestDto input) { - var userCount = (int) await _userRepository.GetCountAsync(); - var userDtos = ObjectMapper.Map, List>( - await _userRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount) - ); + var userCount = (int)await _userRepository.GetCountAsync(); + var users = await _userRepository.GetListAsync(input.Sorting, input.MaxResultCount, input.SkipCount); - return new PagedResultDto(userCount, userDtos); + return new PagedResultDto( + userCount, + ObjectMapper.Map, List>(users) + ); } public async Task CreateAsync(IdentityUserCreateDto input) { var user = new IdentityUser(GuidGenerator.Create(), input.UserName); - await UpdateUserProperties(input, user); + await UpdateUserByInput(user, input); await _userManager.AddPasswordAsync(user, input.Password); await _userManager.CreateAsync(user); await CurrentUnitOfWork.SaveChangesAsync(); @@ -53,7 +54,7 @@ namespace Volo.Abp.Identity var user = await _userManager.GetByIdAsync(id); await _userManager.SetUserNameAsync(user, input.UserName); - await UpdateUserProperties(input, user); + await UpdateUserByInput(user, input); await _userManager.UpdateAsync(user); await CurrentUnitOfWork.SaveChangesAsync(); @@ -66,12 +67,17 @@ namespace Volo.Abp.Identity await _userManager.DeleteAsync(user); } - private async Task UpdateUserProperties(IdentityUserCreateOrUpdateDtoBase input, IdentityUser user) + private async Task UpdateUserByInput(IdentityUser user, IdentityUserCreateOrUpdateDtoBase input) { await _userManager.SetEmailAsync(user, input.Email); await _userManager.SetPhoneNumberAsync(user, input.PhoneNumber); await _userManager.SetTwoFactorEnabledAsync(user, input.TwoFactorEnabled); await _userManager.SetLockoutEnabledAsync(user, input.LockoutEnabled); + + if (input.Roles != null) + { + await _userManager.SetRolesAsync(user, input.Roles); + } } } } diff --git a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs index 632a9028fb..477f8da6c7 100644 --- a/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs +++ b/src/Volo.Abp.Identity.EntityFrameworkCore/Volo/Abp/Identity/EfCoreIdentityUserRepository.cs @@ -14,7 +14,7 @@ namespace Volo.Abp.Identity { public class EfCoreIdentityUserRepository : EfCoreRepository, IIdentityUserRepository { - public EfCoreIdentityUserRepository(IDbContextProvider dbContextProvider) + public EfCoreIdentityUserRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) { } @@ -71,16 +71,16 @@ namespace Volo.Abp.Identity } var query = from userrole in DbContext.UserRoles - join user in DbContext.Users on userrole.UserId equals user.Id - where userrole.RoleId.Equals(role.Id) - select user; + join user in DbContext.Users on userrole.UserId equals user.Id + where userrole.RoleId.Equals(role.Id) + select user; return await query.ToListAsync(cancellationToken); } public async Task> GetListAsync(string sorting, int maxResultCount, int skipCount) { - return await this.OrderBy(sorting ?? "UserName").PageBy(skipCount, maxResultCount).ToListAsync(); + return await this.OrderBy(sorting ?? nameof(IdentityUser.UserName)).PageBy(skipCount, maxResultCount).ToListAsync(); } } } diff --git a/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityRole.cs b/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityRole.cs index 590598d48d..62eb54c46b 100644 --- a/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityRole.cs +++ b/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityRole.cs @@ -52,6 +52,7 @@ namespace Volo.Abp.Identity Id = id; Name = name; + NormalizedName = name.ToUpperInvariant(); ConcurrencyStamp = Guid.NewGuid().ToString(); Claims = new Collection(); diff --git a/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityUser.cs b/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityUser.cs index c1df7ba87e..2c50e5283d 100644 --- a/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityUser.cs +++ b/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityUser.cs @@ -101,8 +101,7 @@ namespace Volo.Abp.Identity /// /// Navigation property for the roles this user belongs to. /// - public virtual IReadOnlyList Roles => RolesCollection; - protected virtual List RolesCollection { get; set; } + public virtual ICollection Roles { get; protected set; } /// /// Navigation property for the claims this user possesses. @@ -130,9 +129,10 @@ namespace Volo.Abp.Identity Id = id; UserName = userName; + NormalizedUserName = userName.ToUpperInvariant(); ConcurrencyStamp = Guid.NewGuid().ToString(); - RolesCollection = new List(); + Roles = new Collection(); Claims = new Collection(); Logins = new Collection(); Tokens = new Collection(); @@ -147,7 +147,7 @@ namespace Volo.Abp.Identity return; } - RolesCollection.Add(new IdentityUserRole(guidGenerator.Create(), Id, roleId)); + Roles.Add(new IdentityUserRole(guidGenerator.Create(), Id, roleId)); } public void RemoveRole(Guid roleId) @@ -159,7 +159,7 @@ namespace Volo.Abp.Identity return; } - RolesCollection.RemoveAll(r => r.RoleId == roleId); + Roles.RemoveAll(r => r.RoleId == roleId); } public bool IsInRole(Guid roleId) diff --git a/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityUserManager.cs b/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityUserManager.cs index 6f6cbfc0d2..d94b104a79 100644 --- a/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityUserManager.cs +++ b/src/Volo.Abp.Identity/Volo/Abp/Identity/IdentityUserManager.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; +using JetBrains.Annotations; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; @@ -21,14 +23,14 @@ namespace Volo.Abp.Identity IServiceProvider services, ILogger logger) : base( - store, - optionsAccessor, - passwordHasher, - userValidators, - passwordValidators, - keyNormalizer, - errors, - services, + store, + optionsAccessor, + passwordHasher, + userValidators, + passwordValidators, + keyNormalizer, + errors, + services, logger) { @@ -44,5 +46,16 @@ namespace Volo.Abp.Identity return user; } + + public async Task SetRolesAsync([NotNull] IdentityUser user, [NotNull] string[] roleNames) + { + Check.NotNull(user, nameof(user)); + Check.NotNull(roleNames, nameof(roleNames)); + + var currentRoleNames = await GetRolesAsync(user); + + await RemoveFromRolesAsync(user, currentRoleNames.Except(roleNames)); + await AddToRolesAsync(user, roleNames.Except(currentRoleNames)); + } } } diff --git a/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/AbpIdentityTestDataBuilder.cs b/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/AbpIdentityTestDataBuilder.cs index 6cfbd655be..ebdc325b6d 100644 --- a/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/AbpIdentityTestDataBuilder.cs +++ b/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/AbpIdentityTestDataBuilder.cs @@ -7,16 +7,32 @@ namespace Volo.Abp.Identity { private readonly IGuidGenerator _guidGenerator; private readonly IIdentityUserRepository _userRepository; + private readonly IIdentityRoleRepository _roleRepository; public AbpIdentityTestDataBuilder( IGuidGenerator guidGenerator, - IIdentityUserRepository userRepository) + IIdentityUserRepository userRepository, + IIdentityRoleRepository roleRepository) { _guidGenerator = guidGenerator; _userRepository = userRepository; + _roleRepository = roleRepository; } public void Build() + { + AddRoles(); + AddUsers(); + } + + private void AddRoles() + { + _roleRepository.Insert(new IdentityRole(_guidGenerator.Create(), "admin")); + _roleRepository.Insert(new IdentityRole(_guidGenerator.Create(), "moderator")); + _roleRepository.Insert(new IdentityRole(_guidGenerator.Create(), "supporter")); + } + + private void AddUsers() { _userRepository.Insert(new IdentityUser(_guidGenerator.Create(), "john.nash")); } diff --git a/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs b/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs index 78f7109344..25aa11dbe7 100644 --- a/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs +++ b/test/Volo.Abp.Identity.Application.Tests/Volo/Abp/Identity/IdentityUserAppService_Tests.cs @@ -20,10 +20,35 @@ namespace Volo.Abp.Identity _userRepository = ServiceProvider.GetRequiredService>(); } + [Fact] + public async Task GetAsync() + { + //Arrange + + var johnNash = await GetUserAsync("john.nash"); + + //Act + + var result = await _identityUserAppService.GetAsync(johnNash.Id); + + //Assert + + result.Id.ShouldBe(johnNash.Id); + result.UserName.ShouldBe(johnNash.UserName); + result.Email.ShouldBe(johnNash.Email); + result.LockoutEnabled.ShouldBe(johnNash.LockoutEnabled); + result.PhoneNumber.ShouldBe(johnNash.PhoneNumber); + } + [Fact] public async Task GetListAsync() { + //Act + var result = await _identityUserAppService.GetListAsync(new PagedAndSortedResultRequestDto()); + + //Assert + result.TotalCount.ShouldBeGreaterThan(0); result.Items.Count.ShouldBeGreaterThan(0); } @@ -39,7 +64,8 @@ namespace Volo.Abp.Identity Email = CreateRandomEmail(), LockoutEnabled = true, PhoneNumber = CreateRandomPhoneNumber(), - Password = "123qwe" + Password = "123qwe", + Roles = new[] {"moderator"} }; //Act @@ -78,7 +104,6 @@ namespace Volo.Abp.Identity Email = CreateRandomEmail() }; - //Act var result = await _identityUserAppService.UpdateAsync(johnNash.Id, input); @@ -99,11 +124,32 @@ namespace Volo.Abp.Identity user.PhoneNumber.ShouldBe(input.PhoneNumber); } + [Fact] + public async Task DeleteAsync() + { + //Arrange + + var johnNash = await GetUserAsync("john.nash"); + + //Act + + await _identityUserAppService.DeleteAsync(johnNash.Id); + + //Assert + + (await FindUserAsync("john.nash")).ShouldBeNull(); + } + private async Task GetUserAsync(string userName) { return (await _userRepository.GetListAsync()).First(u => u.UserName == userName); } + private async Task FindUserAsync(string userName) + { + return (await _userRepository.GetListAsync()).FirstOrDefault(u => u.UserName == userName); + } + private static string CreateRandomEmail() { return Guid.NewGuid().ToString("N").Left(16) + "@abp.io";