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
}