import { ActivityService, ActivityPayType, Activity, Participant } from '../src/core/activity/activity.service'; describe('ActivityService (TDD 测试套件: 活动项目与4位核销码)', () => { let activityService: ActivityService; beforeEach(() => { activityService = new ActivityService(); }); describe('1. 发起活动 (AA制与项目制)', () => { it('应成功创建AA制活动并正确初始化', () => { const activity = activityService.createActivity({ creatorId: 1001, title: '王者荣耀荣耀王者五排冲星车队', gameCategory: '王者荣耀', payType: ActivityPayType.AA_PAY, aaFeeCents: 3000, // 每人30元 maxParticipants: 4, // 限制4人,0表示不限制 }); expect(activity.id).toBeDefined(); expect(activity.payType).toBe(ActivityPayType.AA_PAY); expect(activity.aaFeeCents).toBe(3000); expect(activity.maxParticipants).toBe(4); expect(activity.currentParticipants).toBe(0); }); it('应成功创建项目制活动(不限制报名人数)', () => { const activity = activityService.createActivity({ creatorId: 1002, title: '水友粉丝狂欢内战赛', gameCategory: '英雄联盟', payType: ActivityPayType.PROJECT_PAY, totalFeeCents: 100000, // 发起人项目总包1000元 maxParticipants: 0, // 不限制报名人数 }); expect(activity.payType).toBe(ActivityPayType.PROJECT_PAY); expect(activity.totalFeeCents).toBe(100000); expect(activity.maxParticipants).toBe(0); }); }); describe('2. 报名与生成 4 位纯数字核销码', () => { let aaActivity: Activity; beforeEach(() => { aaActivity = activityService.createActivity({ creatorId: 1001, title: '和平精英四排吃鸡车队', gameCategory: '和平精英', payType: ActivityPayType.AA_PAY, aaFeeCents: 2500, maxParticipants: 3, }); }); it('报名成功后应生成合法的 4 位纯数字核销码 (1000-9999)', () => { const participant = activityService.joinActivity(aaActivity.id, { userId: 2001, payAmountCents: 2500, }); expect(participant.verifyCode).toMatch(/^\d{4}$/); const codeNum = parseInt(participant.verifyCode, 10); expect(codeNum).toBeGreaterThanOrEqual(1000); expect(codeNum).toBeLessThanOrEqual(9999); expect(participant.checkinStatus).toBe(false); }); it('单活动内多个参与者的 4 位核销码不可重复碰撞', () => { const p1 = activityService.joinActivity(aaActivity.id, { userId: 2001, payAmountCents: 2500 }); const p2 = activityService.joinActivity(aaActivity.id, { userId: 2002, payAmountCents: 2500 }); const p3 = activityService.joinActivity(aaActivity.id, { userId: 2003, payAmountCents: 2500 }); const codes = new Set([p1.verifyCode, p2.verifyCode, p3.verifyCode]); expect(codes.size).toBe(3); }); it('同一用户不可重复报名同一活动', () => { activityService.joinActivity(aaActivity.id, { userId: 2001, payAmountCents: 2500 }); expect(() => { activityService.joinActivity(aaActivity.id, { userId: 2001, payAmountCents: 2500 }); }).toThrow('用户已报名该活动'); }); it('超出人数限制时应阻止报名', () => { activityService.joinActivity(aaActivity.id, { userId: 2001, payAmountCents: 2500 }); activityService.joinActivity(aaActivity.id, { userId: 2002, payAmountCents: 2500 }); activityService.joinActivity(aaActivity.id, { userId: 2003, payAmountCents: 2500 }); expect(() => { activityService.joinActivity(aaActivity.id, { userId: 2004, payAmountCents: 2500 }); }).toThrow('活动报名人数已满'); }); }); describe('3. 4位核销码签到核销与防重控制', () => { let testActivity: Activity; let participant: Participant; beforeEach(() => { testActivity = activityService.createActivity({ creatorId: 1001, title: '双排上分活动', gameCategory: '王者荣耀', payType: ActivityPayType.AA_PAY, aaFeeCents: 2000, maxParticipants: 1, }); participant = activityService.joinActivity(testActivity.id, { userId: 3001, payAmountCents: 2000, }); }); it('发起人使用正确的 4 位核销码应核销成功', () => { const result = activityService.verifyCheckin({ activityId: testActivity.id, operatorId: 1001, // 发起人操作 verifyCode: participant.verifyCode, }); expect(result.success).toBe(true); expect(result.participant.checkinStatus).toBe(true); expect(result.participant.verifiedAt).toBeDefined(); }); it('同一 4 位核销码不可重复核销(防重签到)', () => { activityService.verifyCheckin({ activityId: testActivity.id, operatorId: 1001, verifyCode: participant.verifyCode, }); expect(() => { activityService.verifyCheckin({ activityId: testActivity.id, operatorId: 1001, verifyCode: participant.verifyCode, }); }).toThrow('该核销码已被核销,不可重复使用'); }); it('输入错误的 4 位核销码应报错拒绝', () => { expect(() => { activityService.verifyCheckin({ activityId: testActivity.id, operatorId: 1001, verifyCode: '0000', // 不存在的核销码 }); }).toThrow('无效或不存在的核销码'); }); it('非发起人或未授权人员核销应被拒绝', () => { expect(() => { activityService.verifyCheckin({ activityId: testActivity.id, operatorId: 9999, // 非法第三方操作者 verifyCode: participant.verifyCode, }); }).toThrow('无权核销该活动的核销码'); }); }); });