fix
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 4m27s
Docker Build & Deploy / Deploy to Production (push) Successful in 7s
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-11 13:00:01 +08:00
parent ca3e929770
commit 51172e8c5a
88 changed files with 10076 additions and 142 deletions

View File

@@ -9,15 +9,13 @@ public class BudgetApplicationTest : BaseApplicationTest
{
private readonly IBudgetService _budgetService;
private readonly IBudgetRepository _budgetRepository;
private readonly ILogger<BudgetApplication> _logger;
private readonly BudgetApplication _application;
public BudgetApplicationTest()
{
_budgetService = Substitute.For<IBudgetService>();
_budgetRepository = Substitute.For<IBudgetRepository>();
_logger = CreateMockLogger<BudgetApplication>();
_application = new BudgetApplication(_budgetService, _budgetRepository, _logger);
_application = new BudgetApplication(_budgetService, _budgetRepository);
}
#region GetListAsync Tests

View File

@@ -12,7 +12,6 @@ public class EmailMessageApplicationTest : BaseApplicationTest
private readonly ITransactionRecordRepository _transactionRepository;
private readonly IEmailHandleService _emailHandleService;
private readonly IEmailSyncService _emailSyncService;
private readonly ILogger<EmailMessageApplication> _logger;
private readonly EmailMessageApplication _application;
public EmailMessageApplicationTest()
@@ -21,13 +20,11 @@ public class EmailMessageApplicationTest : BaseApplicationTest
_transactionRepository = Substitute.For<ITransactionRecordRepository>();
_emailHandleService = Substitute.For<IEmailHandleService>();
_emailSyncService = Substitute.For<IEmailSyncService>();
_logger = CreateMockLogger<EmailMessageApplication>();
_application = new EmailMessageApplication(
_emailRepository,
_transactionRepository,
_emailHandleService,
_emailSyncService,
_logger);
_emailSyncService);
}
#region GetListAsync Tests

View File

@@ -10,17 +10,15 @@ public class JobApplicationTest : BaseApplicationTest
{
private readonly ISchedulerFactory _schedulerFactory;
private readonly IScheduler _scheduler;
private readonly ILogger<JobApplication> _logger;
private readonly JobApplication _application;
public JobApplicationTest()
{
_schedulerFactory = Substitute.For<ISchedulerFactory>();
_scheduler = Substitute.For<IScheduler>();
_logger = CreateMockLogger<JobApplication>();
_schedulerFactory.GetScheduler().Returns(_scheduler);
_application = new JobApplication(_schedulerFactory, _logger);
_application = new JobApplication(_schedulerFactory);
}
#region GetJobsAsync Tests

View File

@@ -8,14 +8,12 @@ namespace WebApi.Test.Application;
public class MessageRecordApplicationTest : BaseApplicationTest
{
private readonly IMessageService _messageService;
private readonly ILogger<MessageRecordApplication> _logger;
private readonly MessageRecordApplication _application;
public MessageRecordApplicationTest()
{
_messageService = Substitute.For<IMessageService>();
_logger = CreateMockLogger<MessageRecordApplication>();
_application = new MessageRecordApplication(_messageService, _logger);
_application = new MessageRecordApplication(_messageService);
}
[Fact]

View File

@@ -8,14 +8,12 @@ namespace WebApi.Test.Application;
public class NotificationApplicationTest : BaseApplicationTest
{
private readonly INotificationService _notificationService;
private readonly ILogger<NotificationApplication> _logger;
private readonly NotificationApplication _application;
public NotificationApplicationTest()
{
_notificationService = Substitute.For<INotificationService>();
_logger = CreateMockLogger<NotificationApplication>();
_application = new NotificationApplication(_notificationService, _logger);
_application = new NotificationApplication(_notificationService);
}
#region GetVapidPublicKeyAsync Tests

View File

@@ -10,15 +10,13 @@ public class TransactionApplicationTest : BaseApplicationTest
{
private readonly ITransactionRecordRepository _transactionRepository;
private readonly ISmartHandleService _smartHandleService;
private readonly ILogger<TransactionApplication> _logger;
private readonly TransactionApplication _application;
public TransactionApplicationTest()
{
_transactionRepository = Substitute.For<ITransactionRecordRepository>();
_smartHandleService = Substitute.For<ISmartHandleService>();
_logger = CreateMockLogger<TransactionApplication>();
_application = new TransactionApplication(_transactionRepository, _smartHandleService, _logger);
_application = new TransactionApplication(_transactionRepository, _smartHandleService);
}
#region GetByIdAsync Tests

View File

@@ -12,7 +12,6 @@ public class TransactionCategoryApplicationTest : BaseApplicationTest
private readonly ITransactionRecordRepository _transactionRepository;
private readonly IBudgetRepository _budgetRepository;
private readonly ISmartHandleService _smartHandleService;
private readonly ILogger<TransactionCategoryApplication> _logger;
private readonly TransactionCategoryApplication _application;
public TransactionCategoryApplicationTest()
@@ -21,13 +20,11 @@ public class TransactionCategoryApplicationTest : BaseApplicationTest
_transactionRepository = Substitute.For<ITransactionRecordRepository>();
_budgetRepository = Substitute.For<IBudgetRepository>();
_smartHandleService = Substitute.For<ISmartHandleService>();
_logger = CreateMockLogger<TransactionCategoryApplication>();
_application = new TransactionCategoryApplication(
_categoryRepository,
_transactionRepository,
_budgetRepository,
_smartHandleService,
_logger);
_smartHandleService);
}
#region GetListAsync Tests

View File

@@ -10,15 +10,13 @@ public class TransactionPeriodicApplicationTest : BaseApplicationTest
{
private readonly ITransactionPeriodicRepository _periodicRepository;
private readonly ITransactionPeriodicService _periodicService;
private readonly ILogger<TransactionPeriodicApplication> _logger;
private readonly TransactionPeriodicApplication _application;
public TransactionPeriodicApplicationTest()
{
_periodicRepository = Substitute.For<ITransactionPeriodicRepository>();
_periodicService = Substitute.For<ITransactionPeriodicService>();
_logger = CreateMockLogger<TransactionPeriodicApplication>();
_application = new TransactionPeriodicApplication(_periodicRepository, _periodicService, _logger);
_application = new TransactionPeriodicApplication(_periodicRepository, _periodicService);
}
#region GetListAsync Tests

View File

@@ -10,15 +10,13 @@ public class TransactionStatisticsApplicationTest : BaseApplicationTest
{
private readonly ITransactionStatisticsService _statisticsService;
private readonly IConfigService _configService;
private readonly ILogger<TransactionStatisticsApplication> _logger;
private readonly TransactionStatisticsApplication _application;
public TransactionStatisticsApplicationTest()
{
_statisticsService = Substitute.For<ITransactionStatisticsService>();
_configService = Substitute.For<IConfigService>();
_logger = CreateMockLogger<TransactionStatisticsApplication>();
_application = new TransactionStatisticsApplication(_statisticsService, _configService, _logger);
_application = new TransactionStatisticsApplication(_statisticsService, _configService);
}
#region GetBalanceStatisticsAsync Tests

View File

@@ -499,4 +499,81 @@ public class BudgetSavingsTest : BaseTest
// 预计存款 = 116400 - 30000 - 2049.18 - 300 + 2000 = 86050.82
result.Limit.Should().BeApproximately(86050.82m, 0.1m);
}
[Fact]
public async Task GetSavings_年度_包含一月份归档存款_Test()
{
// Arrange
var year = 2026;
// 当前是2月11号
_dateTimeProvider.Now.Returns(new DateTime(year, 2, 11));
var budgets = new List<BudgetRecord>
{
// 月度预算
new() { Id = 1, Name = "工资", Type = BudgetPeriodType.Month, Limit = 11000, Category = BudgetCategory.Income, SelectedCategories = "工资" },
new() { Id = 2, Name = "房租", Type = BudgetPeriodType.Month, Limit = 3000, Category = BudgetCategory.Expense, SelectedCategories = "房租" }
};
// 当前月2月的交易数据
var currentTransactions = new Dictionary<(string, TransactionType), decimal>
{
{ ("工资", TransactionType.Income), 11000m },
{ ("房租", TransactionType.Expense), 3000m },
{ ("转账到公共", TransactionType.Expense), 5000m } // 2月份实际存款5000元
};
// 一月份的归档数据
var archives = new List<BudgetArchive>
{
new()
{
Year = year, Month = 1,
Content =
[
new BudgetArchiveContent
{
Id = 1,
Name = "工资",
Type = BudgetPeriodType.Month,
Limit = 11000,
Actual = 11000,
Category = BudgetCategory.Income
},
new BudgetArchiveContent
{
Id = 2,
Name = "房租",
Type = BudgetPeriodType.Month,
Limit = 3000,
Actual = 3000,
Category = BudgetCategory.Expense
},
new BudgetArchiveContent
{
Id = -2,
Name = "月度存款计划",
Type = BudgetPeriodType.Month,
Limit = 6287.34m,
Actual = 9600.0m, // ✅ 一月份实际存款9600元
Category = BudgetCategory.Savings
}
]
}
};
_budgetRepository.GetAllAsync().Returns(budgets);
_transactionStatisticsService.GetAmountGroupByClassifyAsync(Arg.Any<DateTime>(), Arg.Any<DateTime>())
.Returns(currentTransactions);
_budgetArchiveRepository.GetArchivesByYearAsync(year).Returns(archives);
_configService.GetConfigByKeyAsync<string>("SavingsCategories").Returns(Task.FromResult<string?>("转账到公共"));
// Act
var result = await _service.GetSavingsDtoAsync(BudgetPeriodType.Year, new DateTime(year, 1, 1));
// Assert
result.Should().NotBeNull();
// 年度已存款 = 一月份归档存款9600 + 二月份当前存款5000 = 14600
result.Current.Should().Be(14600m);
}
}