using FsCheck; using FsCheck.Xunit; 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 BusinessPageServicePropertyTests { private readonly Mock> _mockLogger = new(); #region Property 10: 业务介绍页验证规则 /// /// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则 /// *For any* CreateBusinessPageRequest or UpdateBusinessPageRequest, if Title is empty or ImageUrl is empty, /// the service must reject the request. Additionally, if HasActionButton is true and ActionButtonText /// or ActionButtonLink is empty, the service must reject the request. /// **Validates: Requirements 5.1, 5.2, 7.1, 7.2** /// [Property(MaxTest = 100)] public bool BusinessPageValidationRejectsInvalid_EmptyTitleRejected(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个 Title 为空的请求 var request = new CreateBusinessPageRequest { Title = string.Empty, // 空标题 ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = 0, Status = 1 }; // Act & Assert: 服务应该拒绝空标题的请求 try { service.CreatePageAsync(request).GetAwaiter().GetResult(); return false; // 如果没有抛出异常,测试失败 } catch (BusinessException ex) { return ex.Code == ErrorCodes.ParamError; } } /// /// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则 /// 验证空 ImageUrl 被拒绝 /// **Validates: Requirements 5.1, 5.2, 7.1, 7.2** /// [Property(MaxTest = 100)] public bool BusinessPageValidationRejectsInvalid_EmptyImageUrlRejected(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个 ImageUrl 为空的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = string.Empty, // 空图片URL HasActionButton = false, Sort = 0, Status = 1 }; // Act & Assert: 服务应该拒绝空图片URL的请求 try { service.CreatePageAsync(request).GetAwaiter().GetResult(); return false; // 如果没有抛出异常,测试失败 } catch (BusinessException ex) { return ex.Code == ErrorCodes.ParamError; } } /// /// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则 /// 验证当 HasActionButton 为 true 时,空 ActionButtonText 被拒绝 /// **Validates: Requirements 5.1, 5.2, 7.1, 7.2** /// [Property(MaxTest = 100)] public bool BusinessPageValidationRejectsInvalid_EmptyActionButtonTextRejected(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个 HasActionButton 为 true 但 ActionButtonText 为空的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = true, // 启用操作按钮 ActionButtonText = string.Empty, // 空按钮文字 ActionButtonLink = "https://example.com/link", Sort = 0, Status = 1 }; // Act & Assert: 服务应该拒绝空按钮文字的请求 try { service.CreatePageAsync(request).GetAwaiter().GetResult(); return false; // 如果没有抛出异常,测试失败 } catch (BusinessException ex) { return ex.Code == ErrorCodes.ParamError; } } /// /// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则 /// 验证当 HasActionButton 为 true 时,空 ActionButtonLink 被拒绝 /// **Validates: Requirements 5.1, 5.2, 7.1, 7.2** /// [Property(MaxTest = 100)] public bool BusinessPageValidationRejectsInvalid_EmptyActionButtonLinkRejected(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个 HasActionButton 为 true 但 ActionButtonLink 为空的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = true, // 启用操作按钮 ActionButtonText = "点击查看", ActionButtonLink = string.Empty, // 空按钮链接 Sort = 0, Status = 1 }; // Act & Assert: 服务应该拒绝空按钮链接的请求 try { service.CreatePageAsync(request).GetAwaiter().GetResult(); return false; // 如果没有抛出异常,测试失败 } catch (BusinessException ex) { return ex.Code == ErrorCodes.ParamError; } } /// /// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则 /// 验证更新请求中空 Title 被拒绝 /// **Validates: Requirements 5.1, 5.2, 7.1, 7.2** /// [Property(MaxTest = 100)] public bool BusinessPageValidationRejectsInvalid_UpdateEmptyTitleRejected(PositiveInt seed) { // Arrange: 创建数据库上下文并添加一个业务介绍页 using var dbContext = CreateDbContext(); var existingPage = CreateTestBusinessPage(dbContext, seed.Get); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个 Title 为空的更新请求 var request = new UpdateBusinessPageRequest { Id = existingPage.Id, Title = string.Empty, // 空标题 ImageUrl = existingPage.ImageUrl, HasActionButton = false, Sort = 0, Status = 1 }; // Act & Assert: 服务应该拒绝空标题的更新请求 try { service.UpdatePageAsync(request).GetAwaiter().GetResult(); return false; // 如果没有抛出异常,测试失败 } catch (BusinessException ex) { return ex.Code == ErrorCodes.ParamError; } } /// /// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则 /// 验证更新请求中当 HasActionButton 为 true 时,空 ActionButtonText 被拒绝 /// **Validates: Requirements 5.1, 5.2, 7.1, 7.2** /// [Property(MaxTest = 100)] public bool BusinessPageValidationRejectsInvalid_UpdateEmptyActionButtonTextRejected(PositiveInt seed) { // Arrange: 创建数据库上下文并添加一个业务介绍页 using var dbContext = CreateDbContext(); var existingPage = CreateTestBusinessPage(dbContext, seed.Get); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个 HasActionButton 为 true 但 ActionButtonText 为空的更新请求 var request = new UpdateBusinessPageRequest { Id = existingPage.Id, Title = existingPage.Title, ImageUrl = existingPage.ImageUrl, HasActionButton = true, // 启用操作按钮 ActionButtonText = string.Empty, // 空按钮文字 ActionButtonLink = "https://example.com/link", Sort = 0, Status = 1 }; // Act & Assert: 服务应该拒绝空按钮文字的更新请求 try { service.UpdatePageAsync(request).GetAwaiter().GetResult(); return false; // 如果没有抛出异常,测试失败 } catch (BusinessException ex) { return ex.Code == ErrorCodes.ParamError; } } /// /// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则 /// 验证有效请求被接受(当 HasActionButton 为 false 时,ActionButtonText 和 ActionButtonLink 可以为空) /// **Validates: Requirements 5.1, 5.2, 7.1, 7.2** /// [Property(MaxTest = 100)] public bool BusinessPageValidationRejectsInvalid_ValidRequestWithoutActionButtonAccepted(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个有效的请求(HasActionButton 为 false) var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, // 不启用操作按钮 ActionButtonText = null, // 可以为空 ActionButtonLink = null, // 可以为空 Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页 try { var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); return pageId > 0; // 成功创建 } catch { return false; // 不应该抛出异常 } } /// /// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则 /// 验证有效请求被接受(当 HasActionButton 为 true 且 ActionButtonText 和 ActionButtonLink 都有值时) /// **Validates: Requirements 5.1, 5.2, 7.1, 7.2** /// [Property(MaxTest = 100)] public bool BusinessPageValidationRejectsInvalid_ValidRequestWithActionButtonAccepted(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个有效的请求(HasActionButton 为 true,且按钮文字和链接都有值) var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = true, // 启用操作按钮 ActionButtonText = "点击查看", ActionButtonLink = "https://example.com/link", Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页 try { var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); return pageId > 0; // 成功创建 } catch { return false; // 不应该抛出异常 } } #endregion #region Property 11: 业务介绍页创建默认值 /// /// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值 /// *For any* valid CreateBusinessPageRequest, the created entity must have CreateTime and UpdateTime /// set to approximately the current time, Status set to the request value (default 1), /// and IsDeleted set to false. /// **Validates: Requirements 5.3, 5.4** /// [Property(MaxTest = 100)] public bool BusinessPageCreationDefaults_CreateTimeSetCorrectly(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var beforeCreate = DateTime.Now.AddSeconds(-1); // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var afterCreate = DateTime.Now.AddSeconds(1); // 从数据库获取创建的实体 var entity = dbContext.BusinessPages.Find(pageId); // Assert: CreateTime 应该在创建前后的时间范围内 return entity != null && entity.CreateTime >= beforeCreate && entity.CreateTime <= afterCreate; } /// /// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值 /// 验证 UpdateTime 设置正确 /// **Validates: Requirements 5.3, 5.4** /// [Property(MaxTest = 100)] public bool BusinessPageCreationDefaults_UpdateTimeSetCorrectly(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var beforeCreate = DateTime.Now.AddSeconds(-1); // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var afterCreate = DateTime.Now.AddSeconds(1); // 从数据库获取创建的实体 var entity = dbContext.BusinessPages.Find(pageId); // Assert: UpdateTime 应该在创建前后的时间范围内 return entity != null && entity.UpdateTime >= beforeCreate && entity.UpdateTime <= afterCreate; } /// /// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值 /// 验证 Status 设置为请求值 /// **Validates: Requirements 5.3, 5.4** /// [Property(MaxTest = 100)] public bool BusinessPageCreationDefaults_StatusSetToRequestValue(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 随机选择状态值 0 或 1 var requestStatus = seed.Get % 2; // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = seed.Get % 100, Status = requestStatus }; // Act: 创建业务介绍页 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); // 从数据库获取创建的实体 var entity = dbContext.BusinessPages.Find(pageId); // Assert: Status 应该等于请求中的值 return entity != null && entity.Status == requestStatus; } /// /// /// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值 /// 验证 IsDeleted 设置为 false /// **Validates: Requirements 5.3, 5.4** /// [Property(MaxTest = 100)] public bool BusinessPageCreationDefaults_IsDeletedSetToFalse(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); // 从数据库获取创建的实体 var entity = dbContext.BusinessPages.Find(pageId); // Assert: IsDeleted 应该为 false return entity != null && entity.IsDeleted == false; } /// /// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值 /// 验证默认 Status 为 1(启用) /// **Validates: Requirements 5.3, 5.4** /// [Property(MaxTest = 100)] public bool BusinessPageCreationDefaults_DefaultStatusIsEnabled(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个使用默认 Status 的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = seed.Get % 100 // Status 使用默认值 1 }; // Act: 创建业务介绍页 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); // 从数据库获取创建的实体 var entity = dbContext.BusinessPages.Find(pageId); // Assert: 默认 Status 应该为 1(启用) return entity != null && entity.Status == 1; } /// /// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值 /// 验证 CreateTime 和 UpdateTime 相等(新创建时) /// **Validates: Requirements 5.3, 5.4** /// [Property(MaxTest = 100)] public bool BusinessPageCreationDefaults_CreateTimeEqualsUpdateTime(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); // 从数据库获取创建的实体 var entity = dbContext.BusinessPages.Find(pageId); // Assert: CreateTime 和 UpdateTime 应该相等 return entity != null && entity.CreateTime == entity.UpdateTime; } #endregion #region Property 15: 业务介绍页 CRUD 往返一致性 /// /// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性 /// *For any* valid CreateBusinessPageRequest, creating a page and then reading it back via GetPageByIdAsync /// must return an entity with matching Title, ImageUrl, HasActionButton, ActionButtonText, /// ActionButtonLink, and Sort values. /// **Validates: Requirements 5.1, 6.3, 7.1** /// [Property(MaxTest = 100)] public bool BusinessPageCrudRoundTrip_TitleMatches(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var expectedTitle = $"测试标题_{seed.Get}_{Guid.NewGuid():N}"; // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = expectedTitle, ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页并读取回来 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var readBack = service.GetPageByIdAsync(pageId).GetAwaiter().GetResult(); // Assert: Title 应该匹配 return readBack != null && readBack.Title == expectedTitle; } /// /// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性 /// 验证 ImageUrl 匹配 /// **Validates: Requirements 5.1, 6.3, 7.1** /// [Property(MaxTest = 100)] public bool BusinessPageCrudRoundTrip_ImageUrlMatches(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var expectedImageUrl = $"https://example.com/image_{seed.Get}_{Guid.NewGuid():N}.jpg"; // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = expectedImageUrl, HasActionButton = false, Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页并读取回来 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var readBack = service.GetPageByIdAsync(pageId).GetAwaiter().GetResult(); // Assert: ImageUrl 应该匹配 return readBack != null && readBack.ImageUrl == expectedImageUrl; } /// /// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性 /// 验证 HasActionButton 匹配 /// **Validates: Requirements 5.1, 6.3, 7.1** /// [Property(MaxTest = 100)] public bool BusinessPageCrudRoundTrip_HasActionButtonMatches(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var expectedHasActionButton = seed.Get % 2 == 0; // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = expectedHasActionButton, ActionButtonText = expectedHasActionButton ? "点击查看" : null, ActionButtonLink = expectedHasActionButton ? "https://example.com/link" : null, Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页并读取回来 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var readBack = service.GetPageByIdAsync(pageId).GetAwaiter().GetResult(); // Assert: HasActionButton 应该匹配 return readBack != null && readBack.HasActionButton == expectedHasActionButton; } /// /// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性 /// 验证 ActionButtonText 匹配 /// **Validates: Requirements 5.1, 6.3, 7.1** /// [Property(MaxTest = 100)] public bool BusinessPageCrudRoundTrip_ActionButtonTextMatches(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var expectedActionButtonText = $"按钮文字_{seed.Get}"; // 创建一个有效的请求(启用操作按钮) var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = true, ActionButtonText = expectedActionButtonText, ActionButtonLink = "https://example.com/link", Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页并读取回来 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var readBack = service.GetPageByIdAsync(pageId).GetAwaiter().GetResult(); // Assert: ActionButtonText 应该匹配 return readBack != null && readBack.ActionButtonText == expectedActionButtonText; } /// /// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性 /// 验证 ActionButtonLink 匹配 /// **Validates: Requirements 5.1, 6.3, 7.1** /// [Property(MaxTest = 100)] public bool BusinessPageCrudRoundTrip_ActionButtonLinkMatches(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var expectedActionButtonLink = $"https://example.com/link_{seed.Get}"; // 创建一个有效的请求(启用操作按钮) var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = true, ActionButtonText = "点击查看", ActionButtonLink = expectedActionButtonLink, Sort = seed.Get % 100, Status = 1 }; // Act: 创建业务介绍页并读取回来 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var readBack = service.GetPageByIdAsync(pageId).GetAwaiter().GetResult(); // Assert: ActionButtonLink 应该匹配 return readBack != null && readBack.ActionButtonLink == expectedActionButtonLink; } /// /// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性 /// 验证 Sort 匹配 /// **Validates: Requirements 5.1, 6.3, 7.1** /// [Property(MaxTest = 100)] public bool BusinessPageCrudRoundTrip_SortMatches(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var expectedSort = seed.Get % 1000; // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = $"测试标题_{seed.Get}", ImageUrl = $"https://example.com/image_{seed.Get}.jpg", HasActionButton = false, Sort = expectedSort, Status = 1 }; // Act: 创建业务介绍页并读取回来 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var readBack = service.GetPageByIdAsync(pageId).GetAwaiter().GetResult(); // Assert: Sort 应该匹配 return readBack != null && readBack.Sort == expectedSort; } /// /// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性 /// 验证所有字段同时匹配 /// **Validates: Requirements 5.1, 6.3, 7.1** /// [Property(MaxTest = 100)] public bool BusinessPageCrudRoundTrip_AllFieldsMatch(PositiveInt seed) { // Arrange: 创建数据库上下文 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); var hasActionButton = seed.Get % 2 == 0; var expectedTitle = $"测试标题_{seed.Get}_{Guid.NewGuid():N}"; var expectedImageUrl = $"https://example.com/image_{seed.Get}_{Guid.NewGuid():N}.jpg"; var expectedActionButtonText = hasActionButton ? $"按钮文字_{seed.Get}" : null; var expectedActionButtonLink = hasActionButton ? $"https://example.com/link_{seed.Get}" : null; var expectedSort = seed.Get % 1000; // 创建一个有效的请求 var request = new CreateBusinessPageRequest { Title = expectedTitle, ImageUrl = expectedImageUrl, HasActionButton = hasActionButton, ActionButtonText = expectedActionButtonText, ActionButtonLink = expectedActionButtonLink, Sort = expectedSort, Status = 1 }; // Act: 创建业务介绍页并读取回来 var pageId = service.CreatePageAsync(request).GetAwaiter().GetResult(); var readBack = service.GetPageByIdAsync(pageId).GetAwaiter().GetResult(); // Assert: 所有字段都应该匹配 return readBack != null && readBack.Title == expectedTitle && readBack.ImageUrl == expectedImageUrl && readBack.HasActionButton == hasActionButton && readBack.ActionButtonText == expectedActionButtonText && readBack.ActionButtonLink == expectedActionButtonLink && readBack.Sort == expectedSort; } /// /// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性 /// 验证更新后读取回来的数据一致 /// **Validates: Requirements 5.1, 6.3, 7.1** /// [Property(MaxTest = 100)] public bool BusinessPageCrudRoundTrip_UpdateAndReadBackMatches(PositiveInt seed) { // Arrange: 创建数据库上下文并创建初始页面 using var dbContext = CreateDbContext(); var service = new BusinessPageService(dbContext, _mockLogger.Object); // 创建初始页面 var createRequest = new CreateBusinessPageRequest { Title = $"初始标题_{seed.Get}", ImageUrl = $"https://example.com/initial_{seed.Get}.jpg", HasActionButton = false, Sort = 0, Status = 1 }; var pageId = service.CreatePageAsync(createRequest).GetAwaiter().GetResult(); // 更新页面 var hasActionButton = seed.Get % 2 == 0; var expectedTitle = $"更新标题_{seed.Get}_{Guid.NewGuid():N}"; var expectedImageUrl = $"https://example.com/updated_{seed.Get}_{Guid.NewGuid():N}.jpg"; var expectedActionButtonText = hasActionButton ? $"更新按钮_{seed.Get}" : null; var expectedActionButtonLink = hasActionButton ? $"https://example.com/updated_link_{seed.Get}" : null; var expectedSort = (seed.Get + 100) % 1000; var updateRequest = new UpdateBusinessPageRequest { Id = pageId, Title = expectedTitle, ImageUrl = expectedImageUrl, HasActionButton = hasActionButton, ActionButtonText = expectedActionButtonText, ActionButtonLink = expectedActionButtonLink, Sort = expectedSort, Status = 1 }; // Act: 更新并读取回来 service.UpdatePageAsync(updateRequest).GetAwaiter().GetResult(); var readBack = service.GetPageByIdAsync(pageId).GetAwaiter().GetResult(); // Assert: 更新后的所有字段都应该匹配 return readBack != null && readBack.Title == expectedTitle && readBack.ImageUrl == expectedImageUrl && readBack.HasActionButton == hasActionButton && readBack.ActionButtonText == expectedActionButtonText && readBack.ActionButtonLink == expectedActionButtonLink && readBack.Sort == expectedSort; } #endregion #region 辅助方法 /// /// 创建内存数据库上下文 /// private AdminBusinessDbContext CreateDbContext() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) .Options; return new AdminBusinessDbContext(options); } /// /// 创建测试业务介绍页 /// private BusinessPage CreateTestBusinessPage(AdminBusinessDbContext dbContext, int seed) { var page = new BusinessPage { Title = $"测试标题_{seed}", ImageUrl = $"https://example.com/image_{seed}.jpg", HasActionButton = false, ActionButtonText = null, ActionButtonLink = null, Sort = seed % 100, Status = 1, CreateTime = DateTime.Now, UpdateTime = DateTime.Now, IsDeleted = false }; dbContext.BusinessPages.Add(page); dbContext.SaveChanges(); return page; } #endregion }