86 行
2.6 KiB
TypeScript
86 行
2.6 KiB
TypeScript
import {
|
|
LeadStageAutomationService,
|
|
evaluateLeadStagePromotion,
|
|
LeadStage,
|
|
LeadBehaviorTrigger,
|
|
} from '../../../src/modules/crm/service/lead-automation';
|
|
|
|
describe('Point 58 (P1): 出海潜客线索行为自动化阶段推进引擎', () => {
|
|
let service: LeadStageAutomationService;
|
|
|
|
beforeEach(() => {
|
|
service = new LeadStageAutomationService();
|
|
});
|
|
|
|
describe('1. evaluateLeadStagePromotion (行为触发与阶段自动跃升)', () => {
|
|
it('新访客停留时长超过 120 秒且有 AI 咨询互动时,应自动从 new 推进为 contacted', () => {
|
|
const next = evaluateLeadStagePromotion('new', {
|
|
action: 'AI_CHAT_INTERACT',
|
|
staySeconds: 150,
|
|
radarScore: 65,
|
|
});
|
|
|
|
expect(next.promoted).toBe(true);
|
|
expect(next.targetStage).toBe('contacted');
|
|
expect(next.reason).toContain('AI');
|
|
});
|
|
|
|
it('访客提交留资或雷达意向分 >= 80 时,应自动推进为 qualified', () => {
|
|
const next = evaluateLeadStagePromotion('contacted', {
|
|
action: 'FORM_SUBMITTED',
|
|
radarScore: 85,
|
|
});
|
|
|
|
expect(next.promoted).toBe(true);
|
|
expect(next.targetStage).toBe('qualified');
|
|
});
|
|
|
|
it('成功预约跨国会议时,应直接跃升至 proposal 阶段', () => {
|
|
const next = evaluateLeadStagePromotion('qualified', {
|
|
action: 'MEETING_SCHEDULED',
|
|
});
|
|
|
|
expect(next.promoted).toBe(true);
|
|
expect(next.targetStage).toBe('proposal');
|
|
});
|
|
|
|
it('Stripe 订阅付款成功时,自动推进为 closed_won 成交', () => {
|
|
const next = evaluateLeadStagePromotion('proposal', {
|
|
action: 'PAYMENT_SUCCESS',
|
|
});
|
|
|
|
expect(next.promoted).toBe(true);
|
|
expect(next.targetStage).toBe('closed_won');
|
|
});
|
|
|
|
it('已有高阶段 (如 proposal) 不应因低频次事件发生逆向降级', () => {
|
|
const next = evaluateLeadStagePromotion('proposal', {
|
|
action: 'PAGE_VIEW',
|
|
staySeconds: 10,
|
|
});
|
|
|
|
expect(next.promoted).toBe(false);
|
|
expect(next.targetStage).toBe('proposal');
|
|
});
|
|
});
|
|
|
|
describe('2. LeadStageAutomationService 状态流转执行与日志审计', () => {
|
|
it('应自动执行线索推进并返回流转记录', async () => {
|
|
const mockLead = {
|
|
id: 701,
|
|
stage: 'new' as LeadStage,
|
|
name: 'Tariq',
|
|
};
|
|
|
|
const result = await service.processBehaviorEvent(mockLead, {
|
|
action: 'FORM_SUBMITTED',
|
|
radarScore: 90,
|
|
});
|
|
|
|
expect(result.previousStage).toBe('new');
|
|
expect(result.currentStage).toBe('qualified');
|
|
expect(result.historyLog.length).toBeGreaterThan(0);
|
|
});
|
|
});
|
|
});
|