Files
santifer--career-ops/reply-matcher.test.mjs
T
wehub-resource-sync d083df1fdb
CodeQL Analysis / Analyze (javascript-typescript) (push) Failing after 2s
Web CI / web typecheck + build (push) Failing after 1s
Release Please / release-please (push) Failing after 1s
CodeQL Analysis / Analyze (go) (push) Failing after 16s
chore: import upstream snapshot with attribution
2026-07-13 12:02:43 +08:00

215 lines
7.2 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
extractDomain,
checkCompanyMatch,
checkRoleMatch,
matchCandidates,
classifyReply
} from './reply-matcher.mjs';
test('extractDomain', () => {
assert.equal(extractDomain('notice@fundeliver.com'), 'fundeliver.com');
assert.equal(extractDomain('Jane Doe <jane.doe@lever.co>'), 'lever.co');
assert.equal(extractDomain('invalid-email'), null);
});
test('checkCompanyMatch', () => {
// English matches
assert.ok(checkCompanyMatch('Interview with Acme Corp', 'Acme Corp'));
assert.ok(checkCompanyMatch('Interview with acme corp', 'Acme Corp'));
assert.ok(checkCompanyMatch('Interview with AcmeCorp', 'Acme Corp'));
// Chinese matches
assert.ok(checkCompanyMatch('恭喜简历通过,杭州赢云贸易有限公司邀您面试', '杭州赢云贸易有限公司'));
// Partial Chinese (omitting '有限公司')
assert.ok(checkCompanyMatch('恭喜简历通过,杭州赢云贸易邀您面试', '杭州赢云贸易有限公司'));
// Fails
assert.equal(checkCompanyMatch('Interview with Random', 'Acme Corp'), false);
});
test('checkRoleMatch', () => {
assert.ok(checkRoleMatch('Update for Software Engineer role', 'Software Engineer'));
// Chinese role matches
assert.ok(checkRoleMatch('邀请您参加PY01_python开发工程师的面试', 'python开发工程师'));
assert.ok(checkRoleMatch('邀请您参加python开发工程师的面试', 'PY01_python开发工程师'));
});
test('matchCandidates - high confidence with company + role', () => {
const apps = [
{ num: 1, company: 'Acme Corp', role: 'Software Engineer', notes: '' },
{ num: 2, company: '杭州赢云贸易有限公司', role: 'PY01_python开发工程师', notes: '' }
];
const candidates = [
{
message_id: 'msg1',
from: 'notice@acmecorp.com',
subject: 'Interview for Software Engineer at Acme Corp',
body_snippet: 'We would like to invite you...',
signal: 'interview_invite'
},
{
message_id: 'msg2',
from: 'Notice@fundeliver.com',
subject: '恭喜简历通过,杭州赢云贸易有限公司邀您面试',
body_snippet: '邀请您参加PY01_python开发工程师的面试... AI微信小程序面试',
signal: 'interview_invite'
}
];
const results = matchCandidates(candidates, apps, []);
assert.equal(results.length, 2);
assert.equal(results[0].application_num, 1);
assert.equal(results[0].confidence, 'high');
assert.ok(results[0].signals.includes('company-name'));
assert.ok(results[0].signals.includes('role-title'));
assert.equal(results[1].application_num, 2);
assert.equal(results[1].confidence, 'high');
assert.equal(results[1].company_hint, '杭州赢云贸易有限公司');
});
test('matchCandidates - medium confidence domain match', () => {
const apps = [
{ num: 3, company: 'Tech Startup', role: 'Data Scientist', notes: 'recruiter@techstartup.io' }
];
const candidates = [
{
message_id: 'msg3',
from: 'jane@techstartup.io',
subject: 'Application Update',
body_snippet: 'Thank you for applying to our open position.',
signal: 'update'
}
];
const results = matchCandidates(candidates, apps, []);
assert.equal(results[0].application_num, 3);
assert.equal(results[0].confidence, 'medium');
assert.ok(results[0].signals.includes('sender-domain'));
});
test('matchCandidates - ambiguous matches', () => {
const apps = [
{ num: 4, company: 'BigBank', role: 'Backend Dev', notes: '' },
{ num: 5, company: 'BigBank', role: 'Frontend Dev', notes: '' }
];
const candidates = [
{
message_id: 'msg4',
from: 'recruiting@bigbank.com',
subject: 'Interview with BigBank',
body_snippet: 'We want to proceed with your application.',
signal: 'interview_invite'
}
];
const results = matchCandidates(candidates, apps, []);
assert.equal(results[0].application_num, null);
assert.equal(results[0].confidence, 'low');
assert.ok(results[0].signals.includes('ambiguous-match'));
});
test('matchCandidates - no match', () => {
const apps = [
{ num: 6, company: 'SmallCo', role: 'Dev', notes: '' }
];
const candidates = [
{
message_id: 'msg5',
from: 'spam@spam.com',
subject: 'Buy our product',
body_snippet: '...',
signal: null
}
];
const results = matchCandidates(candidates, apps, []);
assert.equal(results[0].application_num, null);
assert.equal(results[0].confidence, 'low');
assert.ok(results[0].signals.includes('no-match'));
});
test('classifyReply - high confidence interview fixtures', () => {
const fixtures = [
'恭喜简历通过,杭州赢云贸易有限公司邀您面试',
'我司首轮面试是AI微信小程序面试',
'面试形式:AI微信小程序面试',
'面试时长:约15~30分钟',
'Interview invitation: Senior Frontend Developer'
];
for (const text of fixtures) {
const res = classifyReply({ subject: text, body_snippet: '' });
assert.equal(res.type, 'Interview');
assert.equal(res.suggestedTrackerUpdate, 'Interview');
assert.ok(res.evidence.length > 0);
}
});
test('classifyReply - noise / job lead fixtures', () => {
const fixtures = [
'邀请投递测试工程师岗位',
'现在沟通,抢面试先机',
'近期热招职位',
'立即投递',
'Zhaopin job alert'
];
for (const text of fixtures) {
const res = classifyReply({ subject: text, body_snippet: '' });
assert.equal(res.type, 'Noise');
assert.equal(res.suggestedTrackerUpdate, 'none');
assert.ok(res.evidence.length > 0);
}
});
test('classifyReply - needs review / process activity', () => {
const fixtures = [
'邀请您在面试/入职之前更新或补充最新的应聘信息'
];
for (const text of fixtures) {
const res = classifyReply({ subject: text, body_snippet: '' });
// This is classified as Unknown (needs review / process activity)
assert.equal(res.type, 'Unknown');
assert.equal(res.suggestedTrackerUpdate, 'Needs Review');
}
});
test('classifyReply - rejection fixtures', () => {
const fixtures = [
'很遗憾',
'暂不匹配',
'不合适',
'未能进入下一轮',
'Unfortunately we decided not to proceed'
];
for (const text of fixtures) {
const res = classifyReply({ subject: text, body_snippet: '' });
assert.equal(res.type, 'Rejected');
assert.equal(res.suggestedTrackerUpdate, 'Rejected');
assert.ok(res.evidence.length > 0);
}
});
test('classifyReply - offer fixtures', () => {
const res = classifyReply({ subject: 'Offer of Employment', body_snippet: 'We are pleased to offer you...' });
assert.equal(res.type, 'Offer');
assert.equal(res.suggestedTrackerUpdate, 'Offer');
});
test('classifyReply - need action vs scheduling', () => {
const actionRes = classifyReply({ subject: 'Please complete assessment test', body_snippet: '' });
assert.equal(actionRes.type, 'Need Action');
assert.equal(actionRes.suggestedTrackerUpdate, 'Responded');
const scheduleRes = classifyReply({ subject: 'Please pick a time to schedule our interview', body_snippet: '' });
assert.equal(scheduleRes.type, 'Need Action');
assert.equal(scheduleRes.suggestedTrackerUpdate, 'Interview');
});