341 lines
10 KiB
C#
341 lines
10 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using AutoMapper;
|
|
using Entities.Contracts;
|
|
using Entities.DTO;
|
|
using Microsoft.AspNetCore.Identity;
|
|
using Moq;
|
|
using SharedDATA.Api;
|
|
using TechHelper.Features;
|
|
using TechHelper.Services.Beta;
|
|
using Xunit;
|
|
|
|
namespace TechHelper.Server.Tests
|
|
{
|
|
public class UserServicesTests
|
|
{
|
|
private readonly Mock<IUnitOfWork> _unitOfWorkMock;
|
|
private readonly Mock<IClassService> _classServiceMock;
|
|
private readonly Mock<UserManager<User>> _userManagerMock;
|
|
private readonly Mock<IMapper> _mapperMock;
|
|
private readonly Mock<IEmailSender> _emailSenderMock;
|
|
private readonly UserServices _userServices;
|
|
|
|
public UserServicesTests()
|
|
{
|
|
_unitOfWorkMock = new Mock<IUnitOfWork>();
|
|
_classServiceMock = new Mock<IClassService>();
|
|
_userManagerMock = new Mock<UserManager<User>>(
|
|
Mock.Of<IUserStore<User>>(),
|
|
null, null, null, null, null, null, null, null);
|
|
_mapperMock = new Mock<IMapper>();
|
|
_emailSenderMock = new Mock<IEmailSender>();
|
|
|
|
_userServices = new UserServices(
|
|
_unitOfWorkMock.Object,
|
|
_classServiceMock.Object,
|
|
_userManagerMock.Object,
|
|
_mapperMock.Object,
|
|
_emailSenderMock.Object);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RegisterNewUserAsync_WhenEmailAlreadyExists_ReturnsErrorMessage()
|
|
{
|
|
// Arrange
|
|
var registrationDto = new UserForRegistrationDto
|
|
{
|
|
Email = "user@example.com",
|
|
Password = "wx1998WX!",
|
|
ConfirmPassword = "wx1998WX!",
|
|
DisplayName = "Test User",
|
|
Roles = UserRoles.Student
|
|
};
|
|
|
|
var existingUser = new User { Email = "user@example.com" };
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync(existingUser);
|
|
|
|
// Act
|
|
var result = await _userServices.RegisterNewUserAsync(registrationDto);
|
|
|
|
// Assert
|
|
Assert.False(result.Status);
|
|
Assert.Contains("此电子邮件地址已被注册", result.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RegisterNewUserAsync_WhenUserCreationFails_ReturnsErrorWithErrors()
|
|
{
|
|
// Arrange
|
|
var registrationDto = new UserForRegistrationDto
|
|
{
|
|
Email = "test@example.com",
|
|
Password = "Password123!",
|
|
ConfirmPassword = "Password123!",
|
|
DisplayName = "Test User",
|
|
Roles = UserRoles.Student
|
|
};
|
|
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync((User)null!);
|
|
|
|
var user = new User();
|
|
_mapperMock.Setup(x => x.Map<User>(registrationDto))
|
|
.Returns(user);
|
|
|
|
_userManagerMock.Setup(x => x.CreateAsync(user, registrationDto.Password))
|
|
.ReturnsAsync(IdentityResult.Failed(new IdentityError { Description = "Password too weak" }));
|
|
|
|
// Act
|
|
var result = await _userServices.RegisterNewUserAsync(registrationDto);
|
|
|
|
// Assert
|
|
Assert.False(result.Status);
|
|
Assert.NotNull(result.Result);
|
|
Assert.IsType<List<string>>(result.Result);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RegisterNewUserAsync_WhenUserCreatedButNotFound_ReturnsErrorMessage()
|
|
{
|
|
// Arrange
|
|
var registrationDto = new UserForRegistrationDto
|
|
{
|
|
Email = "test@example.com",
|
|
Password = "Password123!",
|
|
ConfirmPassword = "Password123!",
|
|
DisplayName = "Test User",
|
|
Roles = UserRoles.Student
|
|
};
|
|
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync((User)null!);
|
|
|
|
var user = new User();
|
|
_mapperMock.Setup(x => x.Map<User>(registrationDto))
|
|
.Returns(user);
|
|
|
|
var identityResult = IdentityResult.Success;
|
|
_userManagerMock.Setup(x => x.CreateAsync(user, registrationDto.Password))
|
|
.ReturnsAsync(identityResult);
|
|
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(user.Email))
|
|
.ReturnsAsync((User)null!);
|
|
|
|
// Act
|
|
var result = await _userServices.RegisterNewUserAsync(registrationDto);
|
|
|
|
// Assert
|
|
Assert.False(result.Status);
|
|
Assert.Contains("注册失败,请联系管理员", result.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RegisterNewUserAsync_WhenRoleAssignmentFails_ReturnsError()
|
|
{
|
|
// Arrange
|
|
var registrationDto = new UserForRegistrationDto
|
|
{
|
|
Email = "test@example.com",
|
|
Password = "Password123!",
|
|
ConfirmPassword = "Password123!",
|
|
DisplayName = "Test User",
|
|
Roles = UserRoles.Student
|
|
};
|
|
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync((User)null!);
|
|
|
|
var user = new User();
|
|
_mapperMock.Setup(x => x.Map<User>(registrationDto))
|
|
.Returns(user);
|
|
|
|
var identityResult = IdentityResult.Success;
|
|
_userManagerMock.Setup(x => x.CreateAsync(user, registrationDto.Password))
|
|
.ReturnsAsync(identityResult);
|
|
|
|
var createdUser = new User { Id = Guid.NewGuid(), Email = registrationDto.Email };
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(user.Email))
|
|
.ReturnsAsync(createdUser);
|
|
|
|
_userManagerMock.Setup(x => x.AddToRoleAsync(createdUser, registrationDto.Roles.ToString()))
|
|
.ReturnsAsync(IdentityResult.Failed(new IdentityError { Description = "Role assignment failed" }));
|
|
|
|
// Act
|
|
var result = await _userServices.RegisterNewUserAsync(registrationDto);
|
|
|
|
// Assert
|
|
Assert.False(result.Status);
|
|
Assert.NotNull(result.Result);
|
|
Assert.IsType<List<string>>(result.Result);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RegisterNewUserAsync_WhenClassRegistrationFails_DeletesUserAndReturnsError()
|
|
{
|
|
// Arrange
|
|
var registrationDto = new UserForRegistrationDto
|
|
{
|
|
Email = "test@example.com",
|
|
Password = "Password123!",
|
|
ConfirmPassword = "Password123!",
|
|
DisplayName = "Test User",
|
|
Roles = UserRoles.Student,
|
|
RegisterUserToClassDto = new RegisterUserToClassDto
|
|
{
|
|
UserId = Guid.NewGuid(),
|
|
ClassId = Guid.NewGuid()
|
|
}
|
|
};
|
|
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync((User)null!);
|
|
|
|
var user = new User();
|
|
_mapperMock.Setup(x => x.Map<User>(registrationDto))
|
|
.Returns(user);
|
|
|
|
var identityResult = IdentityResult.Success;
|
|
_userManagerMock.Setup(x => x.CreateAsync(user, registrationDto.Password))
|
|
.ReturnsAsync(identityResult);
|
|
|
|
var createdUser = new User { Id = Guid.NewGuid(), Email = registrationDto.Email };
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(user.Email))
|
|
.ReturnsAsync(createdUser);
|
|
|
|
_userManagerMock.Setup(x => x.AddToRoleAsync(createdUser, registrationDto.Roles.ToString()))
|
|
.ReturnsAsync(IdentityResult.Success);
|
|
|
|
_classServiceMock.Setup(x => x.UserRegister(registrationDto.RegisterUserToClassDto))
|
|
.ReturnsAsync(new ApiResponse(false, "Class registration failed"));
|
|
|
|
// Act
|
|
var result = await _userServices.RegisterNewUserAsync(registrationDto);
|
|
|
|
// Assert
|
|
Assert.False(result.Status);
|
|
Assert.Contains("Class registration failed", result.Message);
|
|
|
|
// Verify that the user was deleted
|
|
_userManagerMock.Verify(x => x.DeleteAsync(createdUser), Times.Once);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RegisterNewUserAsync_WhenAllStepsSucceed_ReturnsSuccess()
|
|
{
|
|
// Arrange
|
|
var registrationDto = new UserForRegistrationDto
|
|
{
|
|
Email = "test@example.com",
|
|
Password = "Password123!",
|
|
ConfirmPassword = "Password123!",
|
|
DisplayName = "Test User",
|
|
Roles = UserRoles.Student,
|
|
RegisterUserToClassDto = new RegisterUserToClassDto
|
|
{
|
|
UserId = Guid.NewGuid(),
|
|
ClassId = Guid.NewGuid()
|
|
}
|
|
};
|
|
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync((User)null!);
|
|
|
|
var user = new User();
|
|
_mapperMock.Setup(x => x.Map<User>(registrationDto))
|
|
.Returns(user);
|
|
|
|
var identityResult = IdentityResult.Success;
|
|
_userManagerMock.Setup(x => x.CreateAsync(user, registrationDto.Password))
|
|
.ReturnsAsync(identityResult);
|
|
|
|
var createdUser = new User { Id = Guid.NewGuid(), Email = registrationDto.Email };
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(user.Email))
|
|
.ReturnsAsync(createdUser);
|
|
|
|
_userManagerMock.Setup(x => x.AddToRoleAsync(createdUser, registrationDto.Roles.ToString()))
|
|
.ReturnsAsync(IdentityResult.Success);
|
|
|
|
_classServiceMock.Setup(x => x.UserRegister(registrationDto.RegisterUserToClassDto))
|
|
.ReturnsAsync(new ApiResponse(true, "操作成功。"));
|
|
|
|
// Act
|
|
var result = await _userServices.RegisterNewUserAsync(registrationDto);
|
|
|
|
// Assert
|
|
Assert.True(result.Status);
|
|
Assert.Equal("操作成功。", result.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RegisterNewUserAsync_WhenExceptionOccurs_DeletesUserAndReturnsError()
|
|
{
|
|
// Arrange
|
|
var registrationDto = new UserForRegistrationDto
|
|
{
|
|
Email = "test@example.com",
|
|
Password = "Password123!",
|
|
ConfirmPassword = "Password123!",
|
|
DisplayName = "Test User",
|
|
Roles = UserRoles.Student
|
|
};
|
|
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync((User)null!);
|
|
|
|
var user = new User();
|
|
_mapperMock.Setup(x => x.Map<User>(registrationDto))
|
|
.Returns(user);
|
|
|
|
_userManagerMock.Setup(x => x.CreateAsync(user, registrationDto.Password))
|
|
.ThrowsAsync(new Exception("Database error"));
|
|
|
|
var createdUser = new User { Id = Guid.NewGuid(), Email = registrationDto.Email };
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync(createdUser);
|
|
|
|
// Act
|
|
var result = await _userServices.RegisterNewUserAsync(registrationDto);
|
|
|
|
// Assert
|
|
Assert.False(result.Status);
|
|
Assert.Contains("注册过程中发生错误", result.Message);
|
|
|
|
// Verify that the user was deleted
|
|
_userManagerMock.Verify(x => x.DeleteAsync(createdUser), Times.Once);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task RegisterNewUserAsync_SetsCorrectUserProperties()
|
|
{
|
|
// Arrange
|
|
var registrationDto = new UserForRegistrationDto
|
|
{
|
|
Email = "test@example.com",
|
|
Password = "Password123!",
|
|
ConfirmPassword = "Password123!",
|
|
DisplayName = "Test User",
|
|
Roles = UserRoles.Teacher
|
|
};
|
|
|
|
_userManagerMock.Setup(x => x.FindByEmailAsync(registrationDto.Email))
|
|
.ReturnsAsync((User)null!);
|
|
|
|
var mappedUser = new User();
|
|
_mapperMock.Setup(x => x.Map<User>(registrationDto))
|
|
.Returns(mappedUser);
|
|
|
|
// Act
|
|
await _userServices.RegisterNewUserAsync(registrationDto);
|
|
|
|
// Assert
|
|
Assert.Equal(registrationDto.Email, mappedUser.UserName);
|
|
Assert.Equal(registrationDto.DisplayName, mappedUser.DisplayName);
|
|
Assert.Equal(registrationDto.Roles, mappedUser.Role);
|
|
Assert.False(mappedUser.EmailConfirmed);
|
|
}
|
|
}
|
|
}
|