2026-02-14 12:58:26 +08:00
|
|
|
|
namespace WebApi.Test.Repository;
|
2026-01-28 17:00:58 +08:00
|
|
|
|
|
|
|
|
|
|
public class BudgetRepositoryTest : TransactionTestBase
|
|
|
|
|
|
{
|
|
|
|
|
|
private readonly IBudgetRepository _repository;
|
|
|
|
|
|
private readonly ITransactionRecordRepository _transactionRepository;
|
|
|
|
|
|
|
|
|
|
|
|
public BudgetRepositoryTest()
|
|
|
|
|
|
{
|
|
|
|
|
|
_repository = new BudgetRepository(FreeSql);
|
|
|
|
|
|
_transactionRepository = new TransactionRecordRepository(FreeSql);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
|
public async Task GetCurrentAmountAsync_计算预算金额_Test()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Arrange
|
|
|
|
|
|
// 插入一些交易记录
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateExpense(100, classify: "餐饮")); // A
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateExpense(200, classify: "交通")); // B
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateExpense(50, classify: "餐饮")); // C
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateIncome(1000)); // 收入,不应计入支出预算
|
|
|
|
|
|
|
|
|
|
|
|
var budget = new BudgetRecord
|
|
|
|
|
|
{
|
|
|
|
|
|
Limit = 2000,
|
|
|
|
|
|
Category = BudgetCategory.Expense,
|
|
|
|
|
|
SelectedCategories = "餐饮,购物", // Only 餐饮 matches
|
|
|
|
|
|
Name = "日常开销"
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var startDate = DateTime.Now.AddDays(-1);
|
|
|
|
|
|
var endDate = DateTime.Now.AddDays(1);
|
|
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
|
var amount = await _repository.GetCurrentAmountAsync(budget, startDate, endDate);
|
|
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
|
// Should sum A+C = -150. But wait, transaction amounts for expense are negative in CreateExpense?
|
|
|
|
|
|
// Let's check CreateExpense: return CreateTestRecord(-amount, ...);
|
|
|
|
|
|
// So actual stored values are -100, -200, -50.
|
|
|
|
|
|
// SumAsync sums them up. Result should be -150.
|
|
|
|
|
|
amount.Should().Be(-150);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
|
public async Task UpdateBudgetCategoryNameAsync_更新分类名称_Test()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Arrange
|
|
|
|
|
|
await _repository.AddAsync(new BudgetRecord { Name = "B1", SelectedCategories = "餐饮,交通", Category = BudgetCategory.Expense });
|
|
|
|
|
|
await _repository.AddAsync(new BudgetRecord { Name = "B2", SelectedCategories = "餐饮", Category = BudgetCategory.Expense });
|
|
|
|
|
|
await _repository.AddAsync(new BudgetRecord { Name = "B3", SelectedCategories = "住宿", Category = BudgetCategory.Expense });
|
|
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
|
// 将 "餐饮" 更新为 "美食"
|
|
|
|
|
|
await _repository.UpdateBudgetCategoryNameAsync("餐饮", "美食", TransactionType.Expense);
|
|
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
|
var all = await _repository.GetAllAsync();
|
|
|
|
|
|
var b1_updated = all.First(b => b.Name == "B1");
|
|
|
|
|
|
b1_updated.SelectedCategories.Should().Contain("美食");
|
|
|
|
|
|
b1_updated.SelectedCategories.Should().NotContain("餐饮");
|
2026-01-30 10:41:19 +08:00
|
|
|
|
|
2026-01-28 17:00:58 +08:00
|
|
|
|
var b2_updated = all.First(b => b.Name == "B2");
|
|
|
|
|
|
b2_updated.SelectedCategories.Should().Be("美食");
|
|
|
|
|
|
}
|
2026-02-14 12:58:26 +08:00
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
|
public async Task GetCurrentAmountAsync_收入预算家庭年终奖金_Test()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Arrange
|
|
|
|
|
|
// 创建收入交易记录,分类为"家庭年终奖金"
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateIncome(50000, classify: "家庭年终奖金", reason: "年终奖"));
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateIncome(30000, classify: "家庭年终奖金", reason: "绩效奖"));
|
|
|
|
|
|
|
|
|
|
|
|
// 创建其他收入交易,不应计入该预算
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateIncome(20000, classify: "工资", reason: "月工资"));
|
|
|
|
|
|
|
|
|
|
|
|
// 创建收入预算,包含"家庭年终奖金"分类
|
|
|
|
|
|
var budget = new BudgetRecord
|
|
|
|
|
|
{
|
|
|
|
|
|
Limit = 100000,
|
|
|
|
|
|
Category = BudgetCategory.Income,
|
|
|
|
|
|
SelectedCategories = "家庭年终奖金",
|
|
|
|
|
|
Name = "家庭年终奖金"
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var startDate = DateTime.Now.AddDays(-1);
|
|
|
|
|
|
var endDate = DateTime.Now.AddDays(1);
|
|
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
|
var amount = await _repository.GetCurrentAmountAsync(budget, startDate, endDate);
|
|
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
|
// 应该汇总两条"家庭年终奖金"交易:50000 + 30000 = 80000
|
|
|
|
|
|
amount.Should().Be(80000);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
[Fact]
|
|
|
|
|
|
public async Task GetCurrentAmountAsync_收入预算多个分类_Test()
|
|
|
|
|
|
{
|
|
|
|
|
|
// Arrange
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateIncome(50000, classify: "家庭年终奖金"));
|
|
|
|
|
|
await _transactionRepository.AddAsync(CreateIncome(20000, classify: "工资"));
|
|
|
|
|
|
|
|
|
|
|
|
// 创建收入预算,包含多个分类
|
|
|
|
|
|
var budget = new BudgetRecord
|
|
|
|
|
|
{
|
|
|
|
|
|
Limit = 80000,
|
|
|
|
|
|
Category = BudgetCategory.Income,
|
|
|
|
|
|
SelectedCategories = "家庭年终奖金,工资",
|
|
|
|
|
|
Name = "年收入"
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var startDate = DateTime.Now.AddDays(-1);
|
|
|
|
|
|
var endDate = DateTime.Now.AddDays(1);
|
|
|
|
|
|
|
|
|
|
|
|
// Act
|
|
|
|
|
|
var amount = await _repository.GetCurrentAmountAsync(budget, startDate, endDate);
|
|
|
|
|
|
|
|
|
|
|
|
// Assert
|
|
|
|
|
|
// 应该汇总两个分类的交易:50000 + 20000 = 70000
|
|
|
|
|
|
amount.Should().Be(70000);
|
|
|
|
|
|
}
|
2026-01-28 17:00:58 +08:00
|
|
|
|
}
|