import { CardInfoService } from '../../../src/modules/card/service/info'; import { TeamQuotaService } from '../../../src/modules/team/service/quota'; import { CoolCommException } from '@cool-midway/core'; describe('商业化配额门禁: 新增名片配额校验与租户自动绑定', () => { let cardInfoService: CardInfoService; let mockQuotaService: any; let mockPortalService: any; let mockRepo: any; beforeEach(() => { mockRepo = { save: jest.fn().mockImplementation(async (item: any) => ({ id: 1, ...item })), }; mockPortalService = { clearPortalCache: jest.fn().mockResolvedValue(undefined), }; mockQuotaService = { assertQuotaAvailable: jest.fn().mockImplementation(async (tenantId: number, type: string) => { if (tenantId === 999) { throw new CoolCommException('当前套餐名片配额已达上限,请升级套餐', 400); } return { used: 1, limit: 5, exceeded: false }; }), }; cardInfoService = new CardInfoService(); cardInfoService.cardInfoEntity = mockRepo; cardInfoService.cardPortalService = mockPortalService; cardInfoService.teamQuotaService = mockQuotaService; }); it('当租户配额超限时,modifyBefore 新增拦截必须阻断并抛出 CoolCommException', async () => { const cardData = { name: '超限测试名片', tenantId: 999, }; await expect( cardInfoService.modifyBefore(cardData, 'add') ).rejects.toThrow(/配额/); expect(mockQuotaService.assertQuotaAvailable).toHaveBeenCalledWith(999, 'cards', 1); }); it('当租户配额充足时,modifyBefore 新增允许通过并自动锁定 tenantId', async () => { const cardData = { name: '合规名片', tenantId: 88, }; await expect( cardInfoService.modifyBefore(cardData, 'add') ).resolves.not.toThrow(); expect(mockQuotaService.assertQuotaAvailable).toHaveBeenCalledWith(88, 'cards', 1); }); });