105 lines
4.0 KiB
TypeScript
105 lines
4.0 KiB
TypeScript
import { describe, it } from 'node:test';
|
|||
|
|
import assert from 'node:assert/strict';
|
||
|
|
import {
|
||
|
|
analyzeCopilot,
|
||
|
|
followUpMessage,
|
||
|
|
scoreDisc,
|
||
|
|
type DiscAnswers,
|
||
|
|
} from '../../../packages/shared/src/behavior';
|
||
|
|
|
||
|
|
function all(type: DiscAnswers[string]): DiscAnswers {
|
||
|
|
return { '1': type, '2': type, '3': type, '4': type, '5': type, '6': type, '7': type, '8': type };
|
||
|
|
}
|
||
|
|
|
||
|
|
describe('امتیاز DISC', () => {
|
||
|
|
it('گزینه D فقط امتیاز D را زیاد میکند', () => {
|
||
|
|
const result = scoreDisc(all('D'));
|
||
|
|
assert.equal(result.scores.D, 8);
|
||
|
|
assert.equal(result.scores.I, 0);
|
||
|
|
assert.equal(result.scores.S, 0);
|
||
|
|
assert.equal(result.scores.C, 0);
|
||
|
|
assert.equal(result.label, 'D');
|
||
|
|
assert.equal(result.percents.D, 100);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('هر چهار تیپ را جدا جمع میکند', () => {
|
||
|
|
const result = scoreDisc({ '1': 'D', '2': 'I', '3': 'S', '4': 'C', '5': 'D', '6': 'I' });
|
||
|
|
assert.deepEqual(result.scores, { D: 2, I: 2, S: 1, C: 1 });
|
||
|
|
assert.equal(result.validCount, 6);
|
||
|
|
assert.equal(result.label, 'D/I');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('در تساوی نتیجه ترکیبی میدهد', () => {
|
||
|
|
const result = scoreDisc({ '1': 'S', '2': 'C', '3': 'S', '4': 'C' });
|
||
|
|
assert.equal(result.reliable, true);
|
||
|
|
assert.equal(result.label, 'S/C');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('با کمتر از چهار پاسخ نتیجه قابل اتکا نمیدهد', () => {
|
||
|
|
const result = scoreDisc({ '1': 'D', '2': 'D', '3': 'D' });
|
||
|
|
assert.equal(result.reliable, false);
|
||
|
|
assert.equal(result.label, 'اطلاعات ناکافی برای نتیجه قابل اتکا');
|
||
|
|
assert.deepEqual(result.primaryTypes, []);
|
||
|
|
});
|
||
|
|
});
|
||
|
|
|
||
|
|
describe('دستیار فروش', () => {
|
||
|
|
it('برای نیاز ندارم سؤال کشف نیاز میدهد و قیمت نمیسازد', () => {
|
||
|
|
const analysis = analyzeCopilot({
|
||
|
|
topic: 'objection',
|
||
|
|
goal: 'discover_need',
|
||
|
|
customerStatement: 'فعلاً نیازی ندارم؛ همین روش فعلی برای من جواب میدهد.',
|
||
|
|
facts: { customerName: 'مهدی', stageName: 'سرنخ جدید' },
|
||
|
|
});
|
||
|
|
assert.equal(analysis.objection_category, 'no_need');
|
||
|
|
assert.match(analysis.recommended_question, /روش فعلی/);
|
||
|
|
assert.doesNotMatch(analysis.suggested_response, /\d{3,}/);
|
||
|
|
assert.equal(analysis.disc_context, null);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('DISC تازه را راهنما میکند نه تشخیص قطعی', () => {
|
||
|
|
const analysis = analyzeCopilot({
|
||
|
|
topic: 'pricing',
|
||
|
|
goal: 'follow_price',
|
||
|
|
customerStatement: 'قیمتتان بالاست.',
|
||
|
|
facts: {
|
||
|
|
customerName: 'مهدی',
|
||
|
|
priceOffered: null,
|
||
|
|
disc: {
|
||
|
|
label: 'D',
|
||
|
|
primaryTypes: ['D'],
|
||
|
|
reliable: true,
|
||
|
|
assessedAt: new Date().toISOString(),
|
||
|
|
},
|
||
|
|
},
|
||
|
|
});
|
||
|
|
assert.equal(analysis.disc_context?.used, true);
|
||
|
|
assert.match(analysis.suggested_response, /کوتاه میگویم/);
|
||
|
|
assert.match(analysis.confidence_note, /قطعی/);
|
||
|
|
assert.match(analysis.suggested_response, /عدد یا تخفیف جدیدی پیشنهاد نمیشود/);
|
||
|
|
});
|
||
|
|
|
||
|
|
it('حرف کوتاه را قطعی تحلیل نمیکند', () => {
|
||
|
|
const analysis = analyzeCopilot({
|
||
|
|
topic: 'intro',
|
||
|
|
goal: 'discover_need',
|
||
|
|
customerStatement: 'نه',
|
||
|
|
facts: {},
|
||
|
|
});
|
||
|
|
assert.equal(analysis.needs_more_input, true);
|
||
|
|
assert.equal(analysis.suggested_response, '');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('متن پیگیری قیمت را از خودش نمیسازد', () => {
|
||
|
|
const analysis = analyzeCopilot({
|
||
|
|
topic: 'pricing',
|
||
|
|
goal: 'follow_price',
|
||
|
|
customerStatement: 'باید فکر کنم.',
|
||
|
|
facts: { customerName: 'سارا', productName: 'منتکت' },
|
||
|
|
});
|
||
|
|
const text = followUpMessage('price_followup', { customerName: 'سارا', productName: 'منتکت' }, analysis);
|
||
|
|
assert.match(text, /منتکت/);
|
||
|
|
assert.match(text, /عدد قیمت را اینجا تکرار نمیکنم/);
|
||
|
|
});
|
||
|
|
});
|