419 lines
12 KiB
C#
419 lines
12 KiB
C#
using HoneyBox.Admin.Business.Models.Finance;
|
|
using HoneyBox.Admin.Business.Services;
|
|
using HoneyBox.Model.Data;
|
|
using HoneyBox.Model.Entities;
|
|
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
using Moq;
|
|
using Xunit;
|
|
|
|
namespace HoneyBox.Tests.Services;
|
|
|
|
/// <summary>
|
|
/// FinanceService 单元测试
|
|
/// </summary>
|
|
public class FinanceServiceTests : IDisposable
|
|
{
|
|
private readonly HoneyBoxDbContext _dbContext;
|
|
private readonly FinanceService _service;
|
|
private readonly Mock<ILogger<FinanceService>> _mockLogger;
|
|
|
|
public FinanceServiceTests()
|
|
{
|
|
var options = new DbContextOptionsBuilder<HoneyBoxDbContext>()
|
|
.UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString())
|
|
.Options;
|
|
|
|
_dbContext = new HoneyBoxDbContext(options);
|
|
_mockLogger = new Mock<ILogger<FinanceService>>();
|
|
_service = new FinanceService(_dbContext, _mockLogger.Object);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_dbContext.Dispose();
|
|
}
|
|
|
|
#region 消费排行榜测试
|
|
|
|
[Fact]
|
|
public async Task GetConsumptionRanking_ShouldReturnUsersOrderedByConsumption()
|
|
{
|
|
// Arrange
|
|
SeedUsers(3);
|
|
SeedOrders();
|
|
|
|
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
|
|
|
|
// Act
|
|
var result = await _service.GetConsumptionRankingAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.True(result.List.Count > 0);
|
|
// 验证按消费金额降序排序
|
|
for (int i = 0; i < result.List.Count - 1; i++)
|
|
{
|
|
Assert.True(result.List[i].TotalConsumption >= result.List[i + 1].TotalConsumption);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetConsumptionRanking_ShouldIncludeUserInfo()
|
|
{
|
|
// Arrange
|
|
SeedUsers(1);
|
|
SeedOrders();
|
|
|
|
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
|
|
|
|
// Act
|
|
var result = await _service.GetConsumptionRankingAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
if (result.List.Count > 0)
|
|
{
|
|
var first = result.List[0];
|
|
Assert.NotNull(first.Uid);
|
|
Assert.NotNull(first.Nickname);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 余额明细测试
|
|
|
|
[Fact]
|
|
public async Task GetBalanceDetails_ShouldReturnPaginatedResults()
|
|
{
|
|
// Arrange
|
|
SeedUsers(1);
|
|
SeedProfitMoney(15);
|
|
|
|
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
|
|
|
|
// Act
|
|
var result = await _service.GetBalanceDetailsAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal(15, result.Total);
|
|
Assert.Equal(10, result.List.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetBalanceDetails_ShouldFilterByUserId()
|
|
{
|
|
// Arrange
|
|
SeedUsers(3);
|
|
SeedProfitMoneyForMultipleUsers();
|
|
|
|
var request = new FinanceQueryRequest { UserId = 1, Page = 1, PageSize = 20 };
|
|
|
|
// Act
|
|
var result = await _service.GetBalanceDetailsAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.All(result.List, item => Assert.Equal(1, item.UserId));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetBalanceDetails_ShouldFilterByDateRange()
|
|
{
|
|
// Arrange
|
|
SeedUsers(1);
|
|
SeedProfitMoneyWithDates();
|
|
|
|
var request = new FinanceQueryRequest
|
|
{
|
|
StartDate = DateTime.Today.AddDays(-3),
|
|
EndDate = DateTime.Today,
|
|
Page = 1,
|
|
PageSize = 20
|
|
};
|
|
|
|
// Act
|
|
var result = await _service.GetBalanceDetailsAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.All(result.List, item =>
|
|
{
|
|
Assert.True(item.CreatedAt >= request.StartDate.Value.Date);
|
|
Assert.True(item.CreatedAt < request.EndDate.Value.Date.AddDays(1));
|
|
});
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 积分明细测试
|
|
|
|
[Fact]
|
|
public async Task GetIntegralDetails_ShouldReturnPaginatedResults()
|
|
{
|
|
// Arrange
|
|
SeedUsers(1);
|
|
SeedProfitIntegral(10);
|
|
|
|
var request = new FinanceQueryRequest { Page = 1, PageSize = 5 };
|
|
|
|
// Act
|
|
var result = await _service.GetIntegralDetailsAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal(10, result.Total);
|
|
Assert.Equal(5, result.List.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetIntegralDetails_ShouldFilterByUserId()
|
|
{
|
|
// Arrange
|
|
SeedUsers(2);
|
|
SeedProfitIntegralForMultipleUsers();
|
|
|
|
var request = new FinanceQueryRequest { UserId = 2, Page = 1, PageSize = 20 };
|
|
|
|
// Act
|
|
var result = await _service.GetIntegralDetailsAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.All(result.List, item => Assert.Equal(2, item.UserId));
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 钻石明细测试
|
|
|
|
[Fact]
|
|
public async Task GetScoreDetails_ShouldReturnPaginatedResults()
|
|
{
|
|
// Arrange
|
|
SeedUsers(1);
|
|
SeedProfitScore(8);
|
|
|
|
var request = new FinanceQueryRequest { Page = 1, PageSize = 5 };
|
|
|
|
// Act
|
|
var result = await _service.GetScoreDetailsAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal(8, result.Total);
|
|
Assert.Equal(5, result.List.Count);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 充值记录测试
|
|
|
|
[Fact]
|
|
public async Task GetRechargeRecords_ShouldReturnPaginatedResults()
|
|
{
|
|
// Arrange
|
|
SeedUsers(1);
|
|
SeedProfitPay(12);
|
|
|
|
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
|
|
|
|
// Act
|
|
var result = await _service.GetRechargeRecordsAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Equal(12, result.Total);
|
|
Assert.Equal(10, result.List.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task GetRechargeRecords_ShouldIncludePayTypeName()
|
|
{
|
|
// Arrange
|
|
SeedUsers(1);
|
|
SeedProfitPay(1);
|
|
|
|
var request = new FinanceQueryRequest { Page = 1, PageSize = 10 };
|
|
|
|
// Act
|
|
var result = await _service.GetRechargeRecordsAsync(request);
|
|
|
|
// Assert
|
|
Assert.NotNull(result);
|
|
Assert.Single(result.List);
|
|
Assert.NotEmpty(result.List[0].PayTypeName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Helper Methods
|
|
|
|
private void SeedUsers(int count)
|
|
{
|
|
for (int i = 1; i <= count; i++)
|
|
{
|
|
_dbContext.Users.Add(new User
|
|
{
|
|
Id = i,
|
|
Uid = $"U{i:D3}",
|
|
Nickname = $"测试用户{i}",
|
|
Mobile = $"1380013800{i}",
|
|
OpenId = $"openid{i}",
|
|
HeadImg = $"http://test.com/head{i}.jpg",
|
|
CreatedAt = DateTime.Now,
|
|
UpdatedAt = DateTime.Now
|
|
});
|
|
}
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
private void SeedOrders()
|
|
{
|
|
var orders = new[]
|
|
{
|
|
new Order { UserId = 1, OrderNum = "ORD001", Price = 100, UseMoney = 0, UseIntegral = 0, UseScore = 0, Status = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, GoodsId = 1, GoodsTitle = "商品1", GoodsPrice = 100, OrderTotal = 100, OrderZheTotal = 100, Zhe = 1, Num = 1, PrizeNum = 1, Addtime = (int)DateTimeOffset.Now.ToUnixTimeSeconds() },
|
|
new Order { UserId = 1, OrderNum = "ORD002", Price = 200, UseMoney = 50, UseIntegral = 0, UseScore = 0, Status = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, GoodsId = 1, GoodsTitle = "商品1", GoodsPrice = 200, OrderTotal = 200, OrderZheTotal = 200, Zhe = 1, Num = 1, PrizeNum = 1, Addtime = (int)DateTimeOffset.Now.ToUnixTimeSeconds() },
|
|
new Order { UserId = 2, OrderNum = "ORD003", Price = 500, UseMoney = 0, UseIntegral = 100, UseScore = 0, Status = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, GoodsId = 1, GoodsTitle = "商品1", GoodsPrice = 500, OrderTotal = 500, OrderZheTotal = 500, Zhe = 1, Num = 1, PrizeNum = 1, Addtime = (int)DateTimeOffset.Now.ToUnixTimeSeconds() },
|
|
new Order { UserId = 3, OrderNum = "ORD004", Price = 50, UseMoney = 0, UseIntegral = 0, UseScore = 0, Status = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now, GoodsId = 1, GoodsTitle = "商品1", GoodsPrice = 50, OrderTotal = 50, OrderZheTotal = 50, Zhe = 1, Num = 1, PrizeNum = 1, Addtime = (int)DateTimeOffset.Now.ToUnixTimeSeconds() },
|
|
};
|
|
_dbContext.Orders.AddRange(orders);
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
private void SeedProfitMoney(int count)
|
|
{
|
|
for (int i = 1; i <= count; i++)
|
|
{
|
|
_dbContext.ProfitMoneys.Add(new ProfitMoney
|
|
{
|
|
UserId = 1,
|
|
ChangeMoney = 100 * i,
|
|
Money = 100 * i,
|
|
Type = 1,
|
|
Content = $"测试变动{i}",
|
|
ShareUid = 0,
|
|
CreatedAt = DateTime.Now
|
|
});
|
|
}
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
private void SeedProfitMoneyForMultipleUsers()
|
|
{
|
|
for (int userId = 1; userId <= 3; userId++)
|
|
{
|
|
for (int i = 1; i <= 5; i++)
|
|
{
|
|
_dbContext.ProfitMoneys.Add(new ProfitMoney
|
|
{
|
|
UserId = userId,
|
|
ChangeMoney = 100 * i,
|
|
Money = 100 * i,
|
|
Type = 1,
|
|
Content = $"用户{userId}变动{i}",
|
|
ShareUid = 0,
|
|
CreatedAt = DateTime.Now
|
|
});
|
|
}
|
|
}
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
private void SeedProfitMoneyWithDates()
|
|
{
|
|
for (int i = -10; i <= 0; i++)
|
|
{
|
|
_dbContext.ProfitMoneys.Add(new ProfitMoney
|
|
{
|
|
UserId = 1,
|
|
ChangeMoney = 100,
|
|
Money = 100,
|
|
Type = 1,
|
|
Content = $"日期测试{i}",
|
|
ShareUid = 0,
|
|
CreatedAt = DateTime.Today.AddDays(i)
|
|
});
|
|
}
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
private void SeedProfitIntegral(int count)
|
|
{
|
|
for (int i = 1; i <= count; i++)
|
|
{
|
|
_dbContext.ProfitIntegrals.Add(new ProfitIntegral
|
|
{
|
|
UserId = 1,
|
|
ChangeMoney = 50 * i,
|
|
Money = 50 * i,
|
|
Type = 1,
|
|
Content = $"积分变动{i}",
|
|
ShareUid = 0,
|
|
CreatedAt = DateTime.Now
|
|
});
|
|
}
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
private void SeedProfitIntegralForMultipleUsers()
|
|
{
|
|
for (int userId = 1; userId <= 2; userId++)
|
|
{
|
|
for (int i = 1; i <= 5; i++)
|
|
{
|
|
_dbContext.ProfitIntegrals.Add(new ProfitIntegral
|
|
{
|
|
UserId = userId,
|
|
ChangeMoney = 50 * i,
|
|
Money = 50 * i,
|
|
Type = 1,
|
|
Content = $"用户{userId}积分{i}",
|
|
ShareUid = 0,
|
|
CreatedAt = DateTime.Now
|
|
});
|
|
}
|
|
}
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
private void SeedProfitScore(int count)
|
|
{
|
|
for (int i = 1; i <= count; i++)
|
|
{
|
|
_dbContext.ProfitScores.Add(new ProfitScore
|
|
{
|
|
UserId = 1,
|
|
ChangeMoney = 10 * i,
|
|
Money = 10 * i,
|
|
Type = 1,
|
|
Content = $"钻石变动{i}",
|
|
ShareUid = 0,
|
|
CreatedAt = DateTime.Now
|
|
});
|
|
}
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
private void SeedProfitPay(int count)
|
|
{
|
|
for (int i = 1; i <= count; i++)
|
|
{
|
|
_dbContext.ProfitPays.Add(new ProfitPay
|
|
{
|
|
UserId = 1,
|
|
OrderNum = $"PAY{i:D5}",
|
|
ChangeMoney = 100 * i,
|
|
Content = $"充值{i}",
|
|
PayType = (byte)(i % 4),
|
|
CreatedAt = DateTime.Now
|
|
});
|
|
}
|
|
_dbContext.SaveChanges();
|
|
}
|
|
|
|
#endregion
|
|
}
|