chore: migrate remaining ECharts components to Chart.js
- Migrated 4 components from ECharts to Chart.js: * MonthlyExpenseCard.vue (折线图) * DailyTrendChart.vue (双系列折线图) * ExpenseCategoryCard.vue (环形图) * BudgetChartAnalysis.vue (仪表盘 + 多种图表) - Removed all ECharts imports and environment variable switches - Unified all charts to use BaseChart.vue component - Build verified: pnpm build success ✓ - No echarts imports remaining ✓ Refs: openspec/changes/migrate-remaining-echarts-to-chartjs
This commit is contained in:
181
WebApi.Test/Entity/TransactionCategoryTest.cs
Normal file
181
WebApi.Test/Entity/TransactionCategoryTest.cs
Normal file
@@ -0,0 +1,181 @@
|
||||
namespace WebApi.Test.Entity;
|
||||
|
||||
/// <summary>
|
||||
/// TransactionCategory 实体测试
|
||||
/// </summary>
|
||||
public class TransactionCategoryTest : BaseTest
|
||||
{
|
||||
[Fact]
|
||||
public void Icon字段_应该接受Iconify标识符格式()
|
||||
{
|
||||
// Arrange
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "餐饮",
|
||||
Type = TransactionType.Expense
|
||||
};
|
||||
|
||||
// Act
|
||||
category.Icon = "mdi:food";
|
||||
|
||||
// Assert
|
||||
category.Icon.Should().Be("mdi:food");
|
||||
category.Icon.Should().Contain(":");
|
||||
category.Icon.Length.Should().BeLessThanOrEqualTo(50);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Icon字段_应该允许为空()
|
||||
{
|
||||
// Arrange & Act
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "交通",
|
||||
Type = TransactionType.Expense,
|
||||
Icon = null
|
||||
};
|
||||
|
||||
// Assert
|
||||
category.Icon.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Icon字段_应该遵守长度限制50字符()
|
||||
{
|
||||
// Arrange
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "购物",
|
||||
Type = TransactionType.Expense
|
||||
};
|
||||
|
||||
var validIcon = "mdi:shopping-cart"; // 合法长度
|
||||
var tooLongIcon = new string('a', 51); // 超过50字符
|
||||
|
||||
// Act
|
||||
category.Icon = validIcon;
|
||||
|
||||
// Assert
|
||||
category.Icon.Should().Be(validIcon);
|
||||
category.Icon.Length.Should().BeLessThanOrEqualTo(50);
|
||||
|
||||
// 验证长度限制(实际数据库插入时会被截断或报错)
|
||||
tooLongIcon.Length.Should().BeGreaterThan(50);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IconKeywords字段_应该接受JSON数组格式()
|
||||
{
|
||||
// Arrange
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "餐饮",
|
||||
Type = TransactionType.Expense
|
||||
};
|
||||
|
||||
// Act
|
||||
category.IconKeywords = "[\"food\", \"restaurant\", \"dining\"]";
|
||||
|
||||
// Assert
|
||||
category.IconKeywords.Should().NotBeNullOrEmpty();
|
||||
category.IconKeywords.Should().StartWith("[");
|
||||
category.IconKeywords.Should().EndWith("]");
|
||||
category.IconKeywords.Should().Contain("food");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IconKeywords字段_应该允许为空()
|
||||
{
|
||||
// Arrange & Act
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "交通",
|
||||
Type = TransactionType.Expense,
|
||||
IconKeywords = null
|
||||
};
|
||||
|
||||
// Assert
|
||||
category.IconKeywords.Should().BeNull();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IconKeywords字段_应该遵守长度限制200字符()
|
||||
{
|
||||
// Arrange
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "旅游",
|
||||
Type = TransactionType.Expense
|
||||
};
|
||||
|
||||
var validKeywords = "[\"travel\", \"vacation\", \"tourism\", \"trip\"]"; // 合法长度
|
||||
var tooLongKeywords = "[" + string.Join(",", Enumerable.Repeat("\"keyword\"", 30)) + "]"; // 超过200字符
|
||||
|
||||
// Act
|
||||
category.IconKeywords = validKeywords;
|
||||
|
||||
// Assert
|
||||
category.IconKeywords.Should().Be(validKeywords);
|
||||
category.IconKeywords.Length.Should().BeLessThanOrEqualTo(200);
|
||||
|
||||
// 验证长度限制
|
||||
tooLongKeywords.Length.Should().BeGreaterThan(200);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TransactionCategory_应该继承自BaseEntity()
|
||||
{
|
||||
// Arrange & Act
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "测试分类",
|
||||
Type = TransactionType.Expense
|
||||
};
|
||||
|
||||
// Assert
|
||||
category.Should().BeAssignableTo<BaseEntity>();
|
||||
category.Id.Should().BeGreaterThan(0); // Snowflake ID
|
||||
category.CreateTime.Should().BeCloseTo(DateTime.Now, TimeSpan.FromSeconds(1));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TransactionCategory_应该包含必需字段()
|
||||
{
|
||||
// Arrange & Act
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "餐饮",
|
||||
Type = TransactionType.Expense,
|
||||
Icon = "mdi:food",
|
||||
IconKeywords = "[\"food\"]"
|
||||
};
|
||||
|
||||
// Assert
|
||||
category.Name.Should().NotBeNullOrEmpty();
|
||||
category.Type.Should().Be(TransactionType.Expense);
|
||||
category.Icon.Should().NotBeNullOrEmpty();
|
||||
category.IconKeywords.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("mdi:home")]
|
||||
[InlineData("fa:shopping-cart")]
|
||||
[InlineData("tabler:airplane")]
|
||||
[InlineData("fluent:food-24-regular")]
|
||||
public void Icon字段_应该支持多种图标集格式(string iconIdentifier)
|
||||
{
|
||||
// Arrange
|
||||
var category = new TransactionCategory
|
||||
{
|
||||
Name = "测试",
|
||||
Type = TransactionType.Expense
|
||||
};
|
||||
|
||||
// Act
|
||||
category.Icon = iconIdentifier;
|
||||
|
||||
// Assert
|
||||
category.Icon.Should().Be(iconIdentifier);
|
||||
category.Icon.Should().Contain(":");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user