using HoneyBox.Core.Services; using HoneyBox.Model.Data; using HoneyBox.Model.Entities; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.Extensions.Logging; using Moq; using Xunit; namespace HoneyBox.Tests.Integration; /// /// 任务服务集成测试 /// Requirements: 8.1-8.7 /// public class TaskServiceIntegrationTests { private HoneyBoxDbContext CreateInMemoryDbContext() { var options = new DbContextOptionsBuilder() .UseInMemoryDatabase(databaseName: Guid.NewGuid().ToString()) .ConfigureWarnings(w => w.Ignore(InMemoryEventId.TransactionIgnoredWarning)) .Options; return new HoneyBoxDbContext(options); } private TaskService CreateTaskService(HoneyBoxDbContext dbContext) { var mockLogger = new Mock>(); return new TaskService(dbContext, mockLogger.Object); } private User CreateTestUser(int id, int? ouQi = 100) { return new User { Id = id, OpenId = $"openid_{Guid.NewGuid():N}", Uid = $"uid_{Guid.NewGuid():N}", Nickname = "测试用户", HeadImg = "", OuQi = ouQi, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; } [Fact] public async Task GetTaskList_DailyTasks_ReturnsCorrectTasks() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; await dbContext.Tasks.AddRangeAsync(new List { new() { Title = "每日签到", Type = 1, Cate = 1, Number = 1, ZNumber = 10, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }, new() { Title = "每日抽赏", Type = 1, Cate = 2, Number = 3, ZNumber = 20, Sort = 2, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }, new() { Title = "每周任务", Type = 2, Cate = 1, Number = 5, ZNumber = 50, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now } }); await dbContext.SaveChangesAsync(); var result = await service.GetTaskListAsync(userId, 1); Assert.Equal(2, result.TaskList.Count); Assert.All(result.TaskList, t => Assert.Equal(1, t.Type)); } [Fact] public async Task GetTaskList_WeeklyTasks_ReturnsCorrectTasks() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; await dbContext.Tasks.AddRangeAsync(new List { new() { Title = "每日签到", Type = 1, Cate = 1, Number = 1, ZNumber = 10, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }, new() { Title = "每周邀请", Type = 2, Cate = 1, Number = 5, ZNumber = 50, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }, new() { Title = "每周抽赏", Type = 2, Cate = 2, Number = 10, ZNumber = 100, Sort = 2, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now } }); await dbContext.SaveChangesAsync(); var result = await service.GetTaskListAsync(userId, 2); Assert.Equal(2, result.TaskList.Count); Assert.All(result.TaskList, t => Assert.Equal(2, t.Type)); } [Fact] public async Task GetTaskList_InvitationTask_CalculatesProgressCorrectly() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; var task = new T_Task { Title = "邀请好友", Type = 1, Cate = 1, Number = 3, ZNumber = 30, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Tasks.AddAsync(task); // 创建被邀请用户 (今天注册) await dbContext.Users.AddRangeAsync(new List { new() { Pid = userId, OpenId = $"openid_{Guid.NewGuid():N}", Uid = $"uid_{Guid.NewGuid():N}", Nickname = "用户1", HeadImg = "", CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }, new() { Pid = userId, OpenId = $"openid_{Guid.NewGuid():N}", Uid = $"uid_{Guid.NewGuid():N}", Nickname = "用户2", HeadImg = "", CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now } }); await dbContext.SaveChangesAsync(); var result = await service.GetTaskListAsync(userId, 1); var inviteTask = result.TaskList.First(t => t.Cate == 1); Assert.Equal(2, inviteTask.YwcCount); Assert.Equal(0, inviteTask.IsComplete); Assert.Equal(67, inviteTask.Percentage); } [Fact] public async Task GetTaskList_LotteryTask_CalculatesProgressCorrectly() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; var task = new T_Task { Title = "每日抽赏", Type = 1, Cate = 2, Number = 3, ZNumber = 20, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Tasks.AddAsync(task); var todayTimestamp = (int)((DateTimeOffset)DateTime.Today).ToUnixTimeSeconds(); await dbContext.Orders.AddRangeAsync(new List { new() { UserId = userId, PayType = 1, Status = 1, Addtime = todayTimestamp, OrderNum = "ORD001", GoodsId = 1, GoodsTitle = "商品1", Price = 10, Num = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }, new() { UserId = userId, PayType = 2, Status = 1, Addtime = todayTimestamp, OrderNum = "ORD002", GoodsId = 1, GoodsTitle = "商品2", Price = 20, Num = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }, new() { UserId = userId, PayType = 1, Status = 1, Addtime = todayTimestamp, OrderNum = "ORD003", GoodsId = 1, GoodsTitle = "商品3", Price = 30, Num = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now } }); await dbContext.SaveChangesAsync(); var result = await service.GetTaskListAsync(userId, 1); var lotteryTask = result.TaskList.First(t => t.Cate == 2); Assert.Equal(3, lotteryTask.YwcCount); Assert.Equal(1, lotteryTask.IsComplete); Assert.Equal(100, lotteryTask.Percentage); } [Fact] public async Task GetTaskList_AlreadyClaimed_ShowsClaimedStatus() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; var task = new T_Task { Title = "每日签到", Type = 1, Cate = 1, Number = 1, ZNumber = 10, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Tasks.AddAsync(task); await dbContext.SaveChangesAsync(); var userTask = new UserTask { UserId = userId, TaskId = task.Id, Type = 1, Cate = 1, Number = 1, ZNumber = 10, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.UserTasks.AddAsync(userTask); await dbContext.SaveChangesAsync(); var result = await service.GetTaskListAsync(userId, 1); var claimedTask = result.TaskList.First(); Assert.Equal(2, claimedTask.IsComplete); } [Fact] public async Task ClaimTaskReward_Success_AddsOuQiReward() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; var user = CreateTestUser(userId, 100); await dbContext.Users.AddAsync(user); var task = new T_Task { Title = "邀请好友", Type = 1, Cate = 1, Number = 1, ZNumber = 50, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Tasks.AddAsync(task); // 创建被邀请用户 - 使用不同的Id避免冲突 var invitedUser = CreateTestUser(100, 0); invitedUser.Pid = userId; invitedUser.Nickname = "被邀请用户"; await dbContext.Users.AddAsync(invitedUser); await dbContext.SaveChangesAsync(); var result = await service.ClaimTaskRewardAsync(userId, task.Id); Assert.Equal(50, result.Reward); Assert.Equal(150, result.CurrentOuQi); var updatedUser = await dbContext.Users.FindAsync(userId); Assert.Equal(150, updatedUser!.OuQi); var profitOuQi = await dbContext.ProfitOuQis.FirstOrDefaultAsync(p => p.UserId == userId); Assert.NotNull(profitOuQi); Assert.Equal(50, profitOuQi.ChangeMoney); } [Fact] public async Task ClaimTaskReward_TaskNotComplete_ThrowsException() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; var task = new T_Task { Title = "邀请好友", Type = 1, Cate = 1, Number = 3, ZNumber = 50, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Tasks.AddAsync(task); // 只邀请了1人 var invitedUser = new User { Pid = userId, OpenId = $"openid_{Guid.NewGuid():N}", Uid = $"uid_{Guid.NewGuid():N}", Nickname = "被邀请用户", HeadImg = "", CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Users.AddAsync(invitedUser); await dbContext.SaveChangesAsync(); var ex = await Assert.ThrowsAsync(() => service.ClaimTaskRewardAsync(userId, task.Id)); Assert.Equal("任务未完成", ex.Message); } [Fact] public async Task ClaimTaskReward_AlreadyClaimed_ThrowsException() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; var user = CreateTestUser(userId, 100); await dbContext.Users.AddAsync(user); var task = new T_Task { Title = "邀请好友", Type = 1, Cate = 1, Number = 1, ZNumber = 50, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Tasks.AddAsync(task); // 创建被邀请用户 - 使用不同的Id避免冲突 var invitedUser = CreateTestUser(100, 0); invitedUser.Pid = userId; invitedUser.Nickname = "被邀请用户"; await dbContext.Users.AddAsync(invitedUser); var userTask = new UserTask { UserId = userId, TaskId = task.Id, Type = 1, Cate = 1, Number = 1, ZNumber = 50, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.UserTasks.AddAsync(userTask); await dbContext.SaveChangesAsync(); var ex = await Assert.ThrowsAsync(() => service.ClaimTaskRewardAsync(userId, task.Id)); Assert.Equal("你已经领取过了", ex.Message); } [Fact] public async Task ClaimTaskReward_TaskNotFound_ThrowsException() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; var ex = await Assert.ThrowsAsync(() => service.ClaimTaskRewardAsync(userId, 999)); Assert.Equal("任务不存在", ex.Message); } [Fact] public async Task GetTaskList_WeeklyTask_OnlyCountsCurrentWeek() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; var task = new T_Task { Title = "每周邀请", Type = 2, Cate = 1, Number = 3, ZNumber = 100, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Tasks.AddAsync(task); // 本周邀请的用户 var thisWeekUser = new User { Pid = userId, OpenId = $"openid_{Guid.NewGuid():N}", Uid = $"uid_{Guid.NewGuid():N}", Nickname = "本周用户", HeadImg = "", CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }; await dbContext.Users.AddAsync(thisWeekUser); // 上周邀请的用户 (不应计入) var lastWeekUser = new User { Pid = userId, OpenId = $"openid_{Guid.NewGuid():N}", Uid = $"uid_{Guid.NewGuid():N}", Nickname = "上周用户", HeadImg = "", CreatedAt = DateTime.Now.AddDays(-10), UpdatedAt = DateTime.Now.AddDays(-10) }; await dbContext.Users.AddAsync(lastWeekUser); await dbContext.SaveChangesAsync(); var result = await service.GetTaskListAsync(userId, 2); var weeklyTask = result.TaskList.First(); Assert.Equal(1, weeklyTask.YwcCount); } [Fact] public async Task GetTaskList_DeletedTasks_NotReturned() { var dbContext = CreateInMemoryDbContext(); var service = CreateTaskService(dbContext); var userId = 1; await dbContext.Tasks.AddRangeAsync(new List { new() { Title = "正常任务", Type = 1, Cate = 1, Number = 1, ZNumber = 10, Sort = 1, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now }, new() { Title = "已删除任务", Type = 1, Cate = 2, Number = 3, ZNumber = 20, Sort = 2, DeletedAt = DateTime.Now, CreatedAt = DateTime.Now, UpdatedAt = DateTime.Now } }); await dbContext.SaveChangesAsync(); var result = await service.GetTaskListAsync(userId, 1); Assert.Single(result.TaskList); Assert.Equal("正常任务", result.TaskList[0].Title); } }