mi-assessment/server/MiAssessment/tests/MiAssessment.Tests/Admin/BusinessPageServicePropertyTests.cs
2026-02-08 11:31:08 +08:00

873 lines
33 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
/// <summary>
/// 业务介绍页服务属性测试
/// 验证业务介绍页服务的正确性属性
/// </summary>
public class BusinessPageServicePropertyTests
{
private readonly Mock<ILogger<BusinessPageService>> _mockLogger = new();
#region Property 10:
/// <summary>
/// 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**
/// </summary>
[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;
}
}
/// <summary>
/// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则
/// 验证空 ImageUrl 被拒绝
/// **Validates: Requirements 5.1, 5.2, 7.1, 7.2**
/// </summary>
[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;
}
}
/// <summary>
/// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则
/// 验证当 HasActionButton 为 true 时,空 ActionButtonText 被拒绝
/// **Validates: Requirements 5.1, 5.2, 7.1, 7.2**
/// </summary>
[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;
}
}
/// <summary>
/// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则
/// 验证当 HasActionButton 为 true 时,空 ActionButtonLink 被拒绝
/// **Validates: Requirements 5.1, 5.2, 7.1, 7.2**
/// </summary>
[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;
}
}
/// <summary>
/// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则
/// 验证更新请求中空 Title 被拒绝
/// **Validates: Requirements 5.1, 5.2, 7.1, 7.2**
/// </summary>
[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;
}
}
/// <summary>
/// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则
/// 验证更新请求中当 HasActionButton 为 true 时,空 ActionButtonText 被拒绝
/// **Validates: Requirements 5.1, 5.2, 7.1, 7.2**
/// </summary>
[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;
}
}
/// <summary>
/// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则
/// 验证有效请求被接受(当 HasActionButton 为 false 时ActionButtonText 和 ActionButtonLink 可以为空)
/// **Validates: Requirements 5.1, 5.2, 7.1, 7.2**
/// </summary>
[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; // 不应该抛出异常
}
}
/// <summary>
/// Feature: admin-missing-modules, Property 10: 业务介绍页验证规则
/// 验证有效请求被接受(当 HasActionButton 为 true 且 ActionButtonText 和 ActionButtonLink 都有值时)
/// **Validates: Requirements 5.1, 5.2, 7.1, 7.2**
/// </summary>
[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:
/// <summary>
/// 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**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值
/// 验证 UpdateTime 设置正确
/// **Validates: Requirements 5.3, 5.4**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值
/// 验证 Status 设置为请求值
/// **Validates: Requirements 5.3, 5.4**
/// </summary>
[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;
}
///
/// <summary>
/// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值
/// 验证 IsDeleted 设置为 false
/// **Validates: Requirements 5.3, 5.4**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值
/// 验证默认 Status 为 1启用
/// **Validates: Requirements 5.3, 5.4**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 11: 业务介绍页创建默认值
/// 验证 CreateTime 和 UpdateTime 相等(新创建时)
/// **Validates: Requirements 5.3, 5.4**
/// </summary>
[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
/// <summary>
/// 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**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性
/// 验证 ImageUrl 匹配
/// **Validates: Requirements 5.1, 6.3, 7.1**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性
/// 验证 HasActionButton 匹配
/// **Validates: Requirements 5.1, 6.3, 7.1**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性
/// 验证 ActionButtonText 匹配
/// **Validates: Requirements 5.1, 6.3, 7.1**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性
/// 验证 ActionButtonLink 匹配
/// **Validates: Requirements 5.1, 6.3, 7.1**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性
/// 验证 Sort 匹配
/// **Validates: Requirements 5.1, 6.3, 7.1**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性
/// 验证所有字段同时匹配
/// **Validates: Requirements 5.1, 6.3, 7.1**
/// </summary>
[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;
}
/// <summary>
/// Feature: admin-missing-modules, Property 15: 业务介绍页 CRUD 往返一致性
/// 验证更新后读取回来的数据一致
/// **Validates: Requirements 5.1, 6.3, 7.1**
/// </summary>
[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
/// <summary>
/// 创建内存数据库上下文
/// </summary>
private AdminBusinessDbContext CreateDbContext()
{
var options = new DbContextOptionsBuilder<AdminBusinessDbContext>()
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
.Options;
return new AdminBusinessDbContext(options);
}
/// <summary>
/// 创建测试业务介绍页
/// </summary>
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
}