1
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 23s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 1s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s

This commit is contained in:
SunCheng
2026-02-19 22:44:26 +08:00
parent 6922dff5a9
commit 2cf19a45e5
14 changed files with 583 additions and 55 deletions

View File

@@ -546,4 +546,62 @@ public class BudgetStatsTest : BaseTest
// 年度使用率7350 / 47000 * 100 = 15.64%
result.Year.Rate.Should().BeApproximately(7350m / 47000m * 100, 0.01m);
}
[Fact]
public async Task GetCategoryStats_年度收入_不应包含支出预算_Test()
{
// Arrange: 模拟实际数据库中的情况
// 2026年1月当前日期为2026-02-19
var referenceDate = new DateTime(2026, 1, 15);
var currentNow = new DateTime(2026, 2, 19);
_dateTimeProvider.Now.Returns(currentNow);
var budgets = new List<BudgetRecord>
{
// Type=1 表示月度预算Category=0 表示支出(这些不应该被计入收入统计)
new() { Id = 1, Name = "工作餐预算", Limit = 700, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "G工作餐", StartDate = new DateTime(2026, 1, 6) },
new() { Id = 2, Name = "副业投资", Limit = 2000, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "Z钻石福袋", StartDate = new DateTime(2026, 1, 7) },
new() { Id = 3, Name = "通勤支出", Limit = 240, Category = BudgetCategory.Expense, Type = BudgetPeriodType.Month, SelectedCategories = "D地铁通勤", StartDate = new DateTime(2026, 1, 7) },
// Category=1 表示收入(只有这些应该被计入收入统计)
new() { Id = 4, Name = "工资-SYE", Limit = 6100, Category = BudgetCategory.Income, Type = BudgetPeriodType.Month, IsMandatoryExpense = true, SelectedCategories = "G工资SYE", StartDate = new DateTime(2026, 1, 7) },
new() { Id = 5, Name = "副业收入", Limit = 6000, Category = BudgetCategory.Income, Type = BudgetPeriodType.Month, SelectedCategories = "", StartDate = new DateTime(2026, 1, 7) },
new() { Id = 6, Name = "公积金收入", Limit = 5540, Category = BudgetCategory.Income, Type = BudgetPeriodType.Month, IsMandatoryExpense = true, SelectedCategories = "G公积金", StartDate = new DateTime(2026, 1, 7) },
new() { Id = 7, Name = "工资-SC", Limit = 17500, Category = BudgetCategory.Income, Type = BudgetPeriodType.Month, IsMandatoryExpense = true, SelectedCategories = "G工资SC", StartDate = new DateTime(2026, 1, 16) }
};
_budgetRepository.GetAllAsync().Returns(budgets);
// 模拟实际收入金额
_budgetRepository.GetCurrentAmountAsync(Arg.Any<BudgetRecord>(), Arg.Any<DateTime>(), Arg.Any<DateTime>())
.Returns(args =>
{
var budget = (BudgetRecord)args[0];
// 假设当前月2月没有收入记录
return 0m;
});
_transactionStatisticsService.GetFilteredTrendStatisticsAsync(Arg.Any<DateTime>(), Arg.Any<DateTime>(), Arg.Any<TransactionType>(), Arg.Any<List<string>>(), Arg.Any<bool>())
.Returns(new Dictionary<DateTime, decimal>());
_budgetArchiveRepository.GetArchiveAsync(Arg.Any<int>(), Arg.Any<int>())
.Returns((BudgetArchive?)null);
// Act
var result = await _service.GetCategoryStatsAsync(BudgetCategory.Income, referenceDate);
// Assert
// 年度已收应该是1月的4个收入预算
// 1月归档工资-SYE(6100) + 副业收入(6000) + 公积金收入(5540) + 工资-SC(17500) = 35140
// 2月当前0假设没有实际收入
// 3-12月未来0
// 总计应该约等于 35140 (取决于硬性收入的调整逻辑)
// 重点year.limit 应该只包含收入预算,不应该包含支出预算
// 正确的年度limit应该是(6100 + 6000 + 5540 + 17500) * (1 + 11) = 35140 * 12 = 421680
// 或者更准确地说1月归档(35140) + 2月当前月(35140) + 未来10个月(35140 * 10) = 35140 * 12
result.Year.Limit.Should().BeGreaterThan(35000 * 11); // 至少应该是35140的11倍以上
result.Year.Limit.Should().BeLessThan(36000 * 12); // 不应该超过36000的12倍
}
}