using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using MiAssessment.Admin.Business.Data; using MiAssessment.Admin.Business.Entities; using MiAssessment.Admin.Business.Models; using MiAssessment.Admin.Business.Models.BusinessPage; using MiAssessment.Admin.Business.Models.Common; using MiAssessment.Admin.Business.Services; using Moq; using Xunit; namespace MiAssessment.Tests.Admin; /// /// 业务介绍页服务单元测试 /// 验证业务介绍页服务的边界条件和错误处理 /// public class BusinessPageServiceTests { private readonly Mock> _mockLogger = new(); #region 测试页面不存在返回错误 (Requirements 7.4, 8.3) /// /// 测试 GetPageByIdAsync 当页面 ID 不存在时返回 null /// **Validates: Requirements 7.4** /// [Fact] public async Task GetPageByIdAsync_WhenPageNotExists_ReturnsNull() { // Arrange using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var nonExistentId = 99999L; // Act var result = await service.GetPageByIdAsync(nonExistentId); // Assert Assert.Null(result); } /// /// 测试 UpdatePageAsync 当页面 ID 不存在时抛出 BusinessException /// **Validates: Requirements 7.4** /// [Fact] public async Task UpdatePageAsync_WhenPageNotExists_ThrowsBusinessException() { // Arrange using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var request = new UpdateBusinessPageRequest { Id = 99999L, Title = "测试标题", ImageUrl = "https://example.com/image.jpg", HasActionButton = false, Sort = 0, Status = 1 }; // Act & Assert var exception = await Assert.ThrowsAsync( () => service.UpdatePageAsync(request)); Assert.Equal(ErrorCodes.BusinessPageNotFound, exception.Code); Assert.Equal("业务介绍页不存在", exception.Message); } /// /// 测试 DeletePageAsync 当页面 ID 不存在时抛出 BusinessException /// **Validates: Requirements 8.3** /// [Fact] public async Task DeletePageAsync_WhenPageNotExists_ThrowsBusinessException() { // Arrange using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var nonExistentId = 99999L; // Act & Assert var exception = await Assert.ThrowsAsync( () => service.DeletePageAsync(nonExistentId)); Assert.Equal(ErrorCodes.BusinessPageNotFound, exception.Code); Assert.Equal("业务介绍页不存在", exception.Message); } /// /// 测试 UpdatePageStatusAsync 当页面 ID 不存在时抛出 BusinessException /// **Validates: Requirements 8.3** /// [Fact] public async Task UpdatePageStatusAsync_WhenPageNotExists_ThrowsBusinessException() { // Arrange using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var nonExistentId = 99999L; // Act & Assert var exception = await Assert.ThrowsAsync( () => service.UpdatePageStatusAsync(nonExistentId, 1)); Assert.Equal(ErrorCodes.BusinessPageNotFound, exception.Code); Assert.Equal("业务介绍页不存在", exception.Message); } /// /// 测试 UpdatePageSortAsync 当页面 ID 不存在时抛出 BusinessException /// **Validates: Requirements 8.3** /// [Fact] public async Task UpdatePageSortAsync_WhenPageNotExists_ThrowsBusinessException() { // Arrange using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var nonExistentId = 99999L; // Act & Assert var exception = await Assert.ThrowsAsync( () => service.UpdatePageSortAsync(nonExistentId, 100)); Assert.Equal(ErrorCodes.BusinessPageNotFound, exception.Code); Assert.Equal("业务介绍页不存在", exception.Message); } #endregion #region 测试软删除后不出现在列表中 (Requirements 8.1) /// /// 测试 GetPageListAsync 软删除后页面不出现在列表中 /// **Validates: Requirements 8.1** /// [Fact] public async Task GetPageListAsync_AfterSoftDelete_PageNotInList() { // Arrange using var dbContext = CreateDbContext(); // 创建一个业务介绍页 var page = await CreateTestBusinessPage(dbContext, 1); var pageId = page.Id; var service = new BusinessPageService(dbContext, _mockLogger.Object); // 验证页面在列表中 var listBeforeDelete = await service.GetPageListAsync(new BusinessPageQueryRequest { Page = 1, PageSize = 10 }); Assert.Single(listBeforeDelete.List); Assert.Equal(pageId, listBeforeDelete.List[0].Id); // Act - 执行软删除 await service.DeletePageAsync(pageId); // Assert - 验证页面不在列表中 var listAfterDelete = await service.GetPageListAsync(new BusinessPageQueryRequest { Page = 1, PageSize = 10 }); Assert.Empty(listAfterDelete.List); } /// /// 测试 GetPageByIdAsync 软删除后页面返回 null /// **Validates: Requirements 8.1** /// [Fact] public async Task GetPageByIdAsync_AfterSoftDelete_ReturnsNull() { // Arrange using var dbContext = CreateDbContext(); // 创建一个业务介绍页 var page = await CreateTestBusinessPage(dbContext, 1); var pageId = page.Id; var service = new BusinessPageService(dbContext, _mockLogger.Object); // 验证页面存在 var pageBeforeDelete = await service.GetPageByIdAsync(pageId); Assert.NotNull(pageBeforeDelete); // Act - 执行软删除 await service.DeletePageAsync(pageId); // Assert - 验证页面返回 null var pageAfterDelete = await service.GetPageByIdAsync(pageId); Assert.Null(pageAfterDelete); } /// /// 测试 UpdatePageAsync 软删除后更新页面抛出 BusinessException /// **Validates: Requirements 8.1, 7.4** /// [Fact] public async Task UpdatePageAsync_AfterSoftDelete_ThrowsBusinessException() { // Arrange using var dbContext = CreateDbContext(); // 创建一个业务介绍页 var page = await CreateTestBusinessPage(dbContext, 1); var pageId = page.Id; var service = new BusinessPageService(dbContext, _mockLogger.Object); // 执行软删除 await service.DeletePageAsync(pageId); // Act & Assert - 尝试更新已软删除的页面 var request = new UpdateBusinessPageRequest { Id = pageId, Title = "更新后的标题", ImageUrl = "https://example.com/new-image.jpg", HasActionButton = false, Sort = 0, Status = 1 }; var exception = await Assert.ThrowsAsync( () => service.UpdatePageAsync(request)); Assert.Equal(ErrorCodes.BusinessPageNotFound, exception.Code); Assert.Equal("业务介绍页不存在", exception.Message); } /// /// 测试 DeletePageAsync 软删除后再次删除抛出 BusinessException /// **Validates: Requirements 8.1, 8.3** /// [Fact] public async Task DeletePageAsync_AfterSoftDelete_ThrowsBusinessException() { // Arrange using var dbContext = CreateDbContext(); // 创建一个业务介绍页 var page = await CreateTestBusinessPage(dbContext, 1); var pageId = page.Id; var service = new BusinessPageService(dbContext, _mockLogger.Object); // 执行软删除 await service.DeletePageAsync(pageId); // Act & Assert - 尝试再次删除已软删除的页面 var exception = await Assert.ThrowsAsync( () => service.DeletePageAsync(pageId)); Assert.Equal(ErrorCodes.BusinessPageNotFound, exception.Code); Assert.Equal("业务介绍页不存在", exception.Message); } /// /// 测试 UpdatePageStatusAsync 软删除后更新状态抛出 BusinessException /// **Validates: Requirements 8.1, 8.3** /// [Fact] public async Task UpdatePageStatusAsync_AfterSoftDelete_ThrowsBusinessException() { // Arrange using var dbContext = CreateDbContext(); // 创建一个业务介绍页 var page = await CreateTestBusinessPage(dbContext, 1); var pageId = page.Id; var service = new BusinessPageService(dbContext, _mockLogger.Object); // 执行软删除 await service.DeletePageAsync(pageId); // Act & Assert - 尝试更新已软删除页面的状态 var exception = await Assert.ThrowsAsync( () => service.UpdatePageStatusAsync(pageId, 0)); Assert.Equal(ErrorCodes.BusinessPageNotFound, exception.Code); Assert.Equal("业务介绍页不存在", exception.Message); } /// /// 测试 UpdatePageSortAsync 软删除后更新排序抛出 BusinessException /// **Validates: Requirements 8.1, 8.3** /// [Fact] public async Task UpdatePageSortAsync_AfterSoftDelete_ThrowsBusinessException() { // Arrange using var dbContext = CreateDbContext(); // 创建一个业务介绍页 var page = await CreateTestBusinessPage(dbContext, 1); var pageId = page.Id; var service = new BusinessPageService(dbContext, _mockLogger.Object); // 执行软删除 await service.DeletePageAsync(pageId); // Act & Assert - 尝试更新已软删除页面的排序 var exception = await Assert.ThrowsAsync( () => service.UpdatePageSortAsync(pageId, 100)); Assert.Equal(ErrorCodes.BusinessPageNotFound, exception.Code); Assert.Equal("业务介绍页不存在", exception.Message); } #endregion #region 辅助方法 /// /// 创建内存数据库上下文 /// private AdminBusinessDbContext CreateDbContext() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) .Options; return new AdminBusinessDbContext(options); } /// /// 创建测试业务介绍页 /// private async Task CreateTestBusinessPage(AdminBusinessDbContext dbContext, int seed) { var now = DateTime.Now; var page = new BusinessPage { Title = $"测试业务介绍页_{seed}", ImageUrl = $"https://example.com/image_{seed}.jpg", HasActionButton = false, ActionButtonText = null, ActionButtonLink = null, Sort = seed, Status = 1, CreateTime = now, UpdateTime = now, IsDeleted = false }; dbContext.BusinessPages.Add(page); await dbContext.SaveChangesAsync(); return page; } #endregion }