Files
EmailBill/WebApi.Test/Service/ClassificationIconPromptProviderTest.cs
SunCheng a88556c784 fix
2026-02-15 10:10:28 +08:00

468 lines
14 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 Microsoft.Extensions.Options;
using Service.AI;
using Service.AppSettingModel;
namespace WebApi.Test.Service;
/// <summary>
/// ClassificationIconPromptProvider 单元测试
/// </summary>
public class ClassificationIconPromptProviderTest : BaseTest
{
private readonly ClassificationIconPromptProvider _provider;
private readonly ILogger<ClassificationIconPromptProvider> _logger;
private readonly IOptions<IconPromptSettings> _config;
public ClassificationIconPromptProviderTest()
{
_logger = Substitute.For<ILogger<ClassificationIconPromptProvider>>();
_config = Options.Create(new IconPromptSettings
{
EnableNewPrompt = true,
GrayScaleRatio = 1.0,
StyleStrength = 0.7,
ColorScheme = "single-color"
});
_provider = new ClassificationIconPromptProvider(_logger, _config);
}
#region GetPrompt Tests
[Fact]
public void GetPrompt_支出分类_应包含正确的上下文信息()
{
// Arrange
const string categoryName = "餐饮";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain(categoryName);
prompt.Should().Contain("支出");
prompt.Should().Contain("分类名称");
prompt.Should().Contain("分类类型");
}
[Fact]
public void GetPrompt_收入分类_应包含正确的上下文信息()
{
// Arrange
const string categoryName = "工资";
const TransactionType categoryType = TransactionType.Income;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain(categoryName);
prompt.Should().Contain("收入");
prompt.Should().Contain("分类名称");
prompt.Should().Contain("分类类型");
}
[Fact]
public void GetPrompt_不计入收支分类_应包含正确的上下文信息()
{
// Arrange
const string categoryName = "转账";
const TransactionType categoryType = TransactionType.None;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain(categoryName);
prompt.Should().Contain("不计入收支");
}
[Fact]
public void GetPrompt_应包含设计要求()
{
// Arrange
const string categoryName = "交通";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain("24x24");
prompt.Should().Contain("viewBox=\"0 0 24 24\"");
prompt.Should().Contain("扁平化、单色、极致简约");
prompt.Should().Contain("避免渐变和阴影");
prompt.Should().Contain("保持线条简洁");
prompt.Should().Contain("高对比度");
}
[Fact]
public void GetPrompt_应包含SVG格式要求()
{
// Arrange
const string categoryName = "购物";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain("JSON 数组格式");
prompt.Should().Contain("5 个完整的 SVG 字符串");
}
[Fact]
public void GetPrompt_应包含返回格式说明()
{
// Arrange
const string categoryName = "娱乐";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain("[\"<svg>...</svg>\", \"<svg>...</svg>\", \"<svg>...</svg>\", \"<svg>...</svg>\", \"<svg>...</svg>\"]");
}
[Fact]
public void GetPrompt_多次调用_应生成相同的提示词结构()
{
// Arrange
const string categoryName = "餐饮";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt1 = _provider.GetPrompt(categoryName, categoryType);
var prompt2 = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt1.Should().Be(prompt2);
}
[Fact]
public void GetPrompt_不同分类_应生成不同的提示词()
{
// Arrange
const string categoryName1 = "餐饮";
const string categoryName2 = "交通";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt1 = _provider.GetPrompt(categoryName1, categoryType);
var prompt2 = _provider.GetPrompt(categoryName2, categoryType);
// Assert
prompt1.Should().NotBe(prompt2);
prompt1.Should().Contain(categoryName1);
prompt2.Should().Contain(categoryName2);
}
#endregion
#region GetSingleIconPrompt Tests
[Fact]
public void GetSingleIconPrompt_支出分类_应包含正确的上下文信息()
{
// Arrange
const string categoryName = "餐饮";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetSingleIconPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain(categoryName);
prompt.Should().Contain("支出");
prompt.Should().Contain("分类名称");
prompt.Should().Contain("分类类型");
}
[Fact]
public void GetSingleIconPrompt_应包含单个图标要求()
{
// Arrange
const string categoryName = "交通";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetSingleIconPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain("生成 1 个");
prompt.Should().Contain("24x24");
prompt.Should().Contain("viewBox=\"0 0 24 24\"");
prompt.Should().Contain("扁平化、单色、极致简约");
}
[Fact]
public void GetSingleIconPrompt_应包含返回格式说明()
{
// Arrange
const string categoryName = "购物";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetSingleIconPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain("JSON 数组格式");
prompt.Should().Contain("1 个完整的 SVG 字符串");
prompt.Should().Contain("[\"<svg>...</svg>\"]");
}
[Fact]
public void GetSingleIconPrompt_应与GetPrompt生成不同的提示词()
{
// Arrange
const string categoryName = "餐饮";
const TransactionType categoryType = TransactionType.Expense;
// Act
var singlePrompt = _provider.GetSingleIconPrompt(categoryName, categoryType);
var multiPrompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
singlePrompt.Should().NotBe(multiPrompt);
singlePrompt.Should().Contain("生成 1 个");
multiPrompt.Should().Contain("生成 5 个");
}
#endregion
#region PromptTemplateEngine Tests (3.1)
[Fact]
public void PromptTemplateEngine_ReplacePlaceholders_应正确替换单个占位符()
{
// Arrange
var template = "分类名称:{{category_name}},类型:{{category_type}}";
var placeholders = new Dictionary<string, string>
{
["category_name"] = "餐饮",
["category_type"] = "支出"
};
// Act
var result = PromptTemplateEngine.ReplacePlaceholders(template, placeholders);
// Assert
result.Should().Be("分类名称:餐饮,类型:支出");
}
[Fact]
public void PromptTemplateEngine_ReplacePlaceholders_应正确替换多个占位符()
{
// Arrange
var template = "颜色方案:{{color_scheme}},简约度:{{style_strength}}";
var placeholders = new Dictionary<string, string>
{
["color_scheme"] = "single-color",
["style_strength"] = "0.8 - 高度简约"
};
// Act
var result = PromptTemplateEngine.ReplacePlaceholders(template, placeholders);
// Assert
result.Should().Be("颜色方案single-color简约度0.8 - 高度简约");
}
[Fact]
public void PromptTemplateEngine_ReplacePlaceholders_空模板应返回原字符串()
{
// Arrange
var template = string.Empty;
var placeholders = new Dictionary<string, string>();
// Act
var result = PromptTemplateEngine.ReplacePlaceholders(template, placeholders);
// Assert
result.Should().Be(string.Empty);
}
[Fact]
public void PromptTemplateEngine_ReplacePlaceholders_空占位符字典应返回原字符串()
{
// Arrange
var template = "测试模板字符串";
var placeholders = new Dictionary<string, string>();
// Act
var result = PromptTemplateEngine.ReplacePlaceholders(template, placeholders);
// Assert
result.Should().Be("测试模板字符串");
}
#endregion
#region (3.2)
[Fact]
public void GetPrompt_新版提示词_应包含简约风格要求()
{
// Arrange
const string categoryName = "餐饮";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain("扁平化、单色、极致简约");
prompt.Should().Contain("避免渐变和阴影");
prompt.Should().Contain("保持线条简洁");
prompt.Should().Contain("高对比度");
}
[Fact]
public void GetPrompt_新版提示词_应包含颜色方案占位符替换()
{
// Arrange
const string categoryName = "交通";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain("颜色方案single-color");
}
[Fact]
public void GetPrompt_新版提示词_应包含风格强度描述()
{
// Arrange
const string categoryName = "娱乐";
const TransactionType categoryType = TransactionType.Expense;
// Act
var prompt = _provider.GetPrompt(categoryName, categoryType);
// Assert
prompt.Should().Contain("简约度0.7");
prompt.Should().Contain("高度简约(去除所有装饰)");
}
#endregion
#region (3.3)
[Fact]
public void IconPromptSettings_初始化_应包含默认抽象分类配置()
{
// Arrange & Act
var config = new IconPromptSettings();
// Assert
config.AbstractCategories.Should().ContainKey("其他");
config.AbstractCategories.Should().ContainKey("通用");
config.AbstractCategories.Should().ContainKey("未知");
config.AbstractCategories["其他"].GeometryShape.Should().Be("circle");
config.AbstractCategories["其他"].ColorCode.Should().Be("#9E9E9E");
}
[Fact]
public void IconPromptSettings_抽象分类配置_可以自定义()
{
// Arrange
var config = new IconPromptSettings();
// Act
config.AbstractCategories["自定义分类"] = new AbstractCategoryConfig
{
GeometryShape = "hexagon",
ColorCode = "#FF5722"
};
// Assert
config.AbstractCategories["自定义分类"].GeometryShape.Should().Be("hexagon");
config.AbstractCategories["自定义分类"].ColorCode.Should().Be("#FF5722");
}
#endregion
#region (3.4)
[Fact]
public void PromptTemplateEngine_ReplaceForIconGeneration_风格强度09_应显示极度简约()
{
// Arrange
var template = "简约度:{{style_strength}}";
// Act
var result = PromptTemplateEngine.ReplaceForIconGeneration(
template,
"餐饮",
"支出",
"single-color",
0.95);
// Assert
result.Should().Contain("0.9");
result.Should().Contain("极度简约(仅保留最核心元素)");
}
[Fact]
public void PromptTemplateEngine_ReplaceForIconGeneration_风格强度07_应显示高度简约()
{
// Arrange
var template = "简约度:{{style_strength}}";
// Act
var result = PromptTemplateEngine.ReplaceForIconGeneration(
template,
"交通",
"支出",
"single-color",
0.7);
// Assert
result.Should().Contain("0.7");
result.Should().Contain("高度简约(去除所有装饰)");
}
[Fact]
public void PromptTemplateEngine_ReplaceForIconGeneration_风格强度05_应显示简约()
{
// Arrange
var template = "简约度:{{style_strength}}";
// Act
var result = PromptTemplateEngine.ReplaceForIconGeneration(
template,
"购物",
"支出",
"single-color",
0.5);
// Assert
result.Should().Contain("0.5");
result.Should().Contain("简约(保留必要细节)");
}
[Fact]
public void PromptTemplateEngine_ReplaceForIconGeneration_风格强度03_应显示适中()
{
// Arrange
var template = "简约度:{{style_strength}}";
// Act
var result = PromptTemplateEngine.ReplaceForIconGeneration(
template,
"娱乐",
"支出",
"single-color",
0.3);
// Assert
result.Should().Contain("0.3");
result.Should().Contain("适中");
}
#endregion
}