import { CrmLeadService } from '../../../src/modules/crm/service/lead'; import { CrmRadarService } from '../../../src/modules/crm/service/radar'; import { CardInfoEntity } from '../../../src/modules/card/entity/info'; import { CrmLeadEntity } from '../../../src/modules/crm/entity/lead'; import { CrmTrackEntity } from '../../../src/modules/crm/entity/track'; describe('多租户安全闭环: 公开留资与雷达足迹自动绑定名片所属租户', () => { let leadService: CrmLeadService; let radarService: CrmRadarService; const mockCard: Partial = { id: 101, tenantId: 88, userId: 12, name: '测试名片', }; let mockCardRepo: any; let mockLeadRepo: any; let mockTrackRepo: any; beforeEach(() => { mockCardRepo = { findOne: jest.fn().mockImplementation(async ({ where }: any) => { if (where?.id === 101) { return { ...mockCard }; } return null; }), }; mockLeadRepo = { save: jest.fn().mockImplementation(async (item: any) => { return { id: 1, ...item }; }), }; mockTrackRepo = { save: jest.fn().mockImplementation(async (item: any) => { return { id: 1, ...item }; }), }; leadService = new CrmLeadService(); leadService.crmLeadEntity = mockLeadRepo; leadService.cardInfoEntity = mockCardRepo; radarService = new CrmRadarService(); radarService.crmTrackEntity = mockTrackRepo; radarService.cardInfoEntity = mockCardRepo; }); describe('1. CrmLeadService.submitLead 租户自动继承', () => { it('公开留资未显式传入 tenantId 时,必须根据 cardId 自动追溯绑定归属名片的 tenantId 和 userId', async () => { const lead = await leadService.submitLead({ cardId: 101, name: '国际采购商', phone: '+971-50-9876543', company: 'Dubai Trading LLC', }); expect(mockCardRepo.findOne).toHaveBeenCalledWith({ where: { id: 101 } }); expect(lead.tenantId).toBe(88); expect(lead.userId).toBe(12); }); it('若显式指定了有效 tenantId,则应保持显式值', async () => { const lead = await leadService.submitLead({ cardId: 101, tenantId: 999, name: '国际采购商', phone: '+971-50-9876543', } as any); expect(lead.tenantId).toBe(999); }); }); describe('2. CrmRadarService.recordTrack 租户自动继承', () => { it('公开雷达足迹未传入 tenantId 时,必须根据 cardId 自动补齐名片所属 tenantId', async () => { const track = await radarService.recordTrack({ cardId: 101, ip: '8.8.8.8', touchType: 'nfc', }); expect(mockCardRepo.findOne).toHaveBeenCalledWith({ where: { id: 101 } }); expect(track.tenantId).toBe(88); }); }); });