using AutoMapper; using IM_API.Dtos.User; using IM_API.Exceptions; using IM_API.Interface.Services; using IM_API.Models; using IM_API.Services; using IM_API.Tools; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Moq; using StackExchange.Redis; using System; using System.Threading.Tasks; using Xunit; public class UserServiceTests { private ImContext CreateDbContext() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(Guid.NewGuid().ToString()) .Options; return new ImContext(options); } private IMapper CreateMapper() { var config = new MapperConfiguration(cfg => { cfg.CreateMap(); cfg.CreateMap(); }); return config.CreateMapper(); } private UserService CreateService(ImContext context) { var loggerMock = new Mock>(); var mapper = CreateMapper(); var mockCache = new Mock(); var res = new Mock(); return new UserService(context, loggerMock.Object, mapper , mockCache.Object, res.Object); } // ========== GetUserInfoAsync ========== [Fact] public async Task GetUserInfoAsync_ShouldReturnUser_WhenExists() { var context = CreateDbContext(); context.Users.Add(new User { Id = 1, Username = "Tom", Password = "123456" }); await context.SaveChangesAsync(); var service = CreateService(context); var result = await service.GetUserInfoAsync(1); Assert.NotNull(result); Assert.Equal("Tom", result.Username); } [Fact] public async Task GetUserInfoAsync_ShouldThrow_WhenNotFound() { var service = CreateService(CreateDbContext()); await Assert.ThrowsAsync(() => service.GetUserInfoAsync(999) ); } // ========== GetUserInfoByUsernameAsync ========== [Fact] public async Task GetUserInfoByUsernameAsync_ShouldReturn_WhenExists() { var context = CreateDbContext(); context.Users.Add(new User { Id = 2, Username = "Jerry", Password = "aaa" }); await context.SaveChangesAsync(); var service = CreateService(context); var result = await service.GetUserInfoByUsernameAsync("Jerry"); Assert.NotNull(result); Assert.Equal(2, result.Id); } [Fact] public async Task GetUserInfoByUsernameAsync_ShouldThrow_WhenNotFound() { var service = CreateService(CreateDbContext()); await Assert.ThrowsAsync(() => service.GetUserInfoByUsernameAsync("Nobody") ); } // ========== ResetPasswordAsync ========== [Fact] public async Task ResetPasswordAsync_ShouldReset_WhenCorrectPassword() { var context = CreateDbContext(); context.Users.Add(new User { Id = 3, Username = "test", Password = "old" }); await context.SaveChangesAsync(); var service = CreateService(context); var result = await service.ResetPasswordAsync(3, "old", "new"); Assert.True(result); Assert.Equal("new", context.Users.Find(3).Password); } [Fact] public async Task ResetPasswordAsync_ShouldThrow_WhenWrongPassword() { var context = CreateDbContext(); context.Users.Add(new User { Id = 4, Username = "test", Password = "oldPwd" }); await context.SaveChangesAsync(); var service = CreateService(context); await Assert.ThrowsAsync(() => service.ResetPasswordAsync(4, "wrong", "new") ); } [Fact] public async Task ResetPasswordAsync_ShouldThrow_WhenUserNotFound() { var service = CreateService(CreateDbContext()); await Assert.ThrowsAsync(() => service.ResetPasswordAsync(123, "anything", "new") ); } // ========== UpdateOlineStatusAsync ========== [Fact] public async Task UpdateOlineStatusAsync_ShouldUpdateStatus() { var context = CreateDbContext(); context.Users.Add(new User { Id = 5, Username = "test", Password = "p", OnlineStatusEnum = UserOnlineStatus.Offline }); await context.SaveChangesAsync(); var service = CreateService(context); var result = await service.UpdateOlineStatusAsync(5, UserOnlineStatus.Online); Assert.True(result); Assert.Equal(UserOnlineStatus.Online, context.Users.Find(5).OnlineStatusEnum); } [Fact] public async Task UpdateOlineStatusAsync_ShouldThrow_WhenUserNotFound() { var service = CreateService(CreateDbContext()); await Assert.ThrowsAsync(() => service.UpdateOlineStatusAsync(999, UserOnlineStatus.Online) ); } // ========== UpdateUserAsync ========== [Fact] public async Task UpdateUserAsync_ShouldUpdateUserFields() { var context = CreateDbContext(); context.Users.Add(new User { Id = 6, Username = "test", Password = "p", NickName = "OldName" }); await context.SaveChangesAsync(); var service = CreateService(context); var dto = new UpdateUserDto { NickName = "NewName" }; var result = await service.UpdateUserAsync(6, dto); Assert.NotNull(result); Assert.Equal("NewName", context.Users.Find(6).NickName); } [Fact] public async Task UpdateUserAsync_ShouldThrow_WhenNotFound() { var service = CreateService(CreateDbContext()); await Assert.ThrowsAsync(() => service.UpdateUserAsync(123, new UpdateUserDto { NickName = "Test" }) ); } }