138 lines
5.5 KiB
JavaScript
138 lines
5.5 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import { readFile } from 'node:fs/promises';
|
|
import test, { after } from 'node:test';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { createServer } from 'vite';
|
|
|
|
const vite = await createServer({
|
|
root: fileURLToPath(new URL('..', import.meta.url)),
|
|
configFile: false,
|
|
optimizeDeps: { noDiscovery: true },
|
|
server: { middlewareMode: true, hmr: false },
|
|
appType: 'custom'
|
|
});
|
|
|
|
after(async () => {
|
|
await vite.close();
|
|
});
|
|
|
|
const candidateView = await vite.ssrLoadModule('/src/services/candidate-view.ts');
|
|
const { buildCandidateFlow, candidateRoutes, formatCandidateFileSize, materialStatusTone } = candidateView;
|
|
|
|
const record = (overrides = {}) => ({
|
|
time: '2026-07-10 10:00:00',
|
|
candidate: '候选人0001',
|
|
position: '生活顾问',
|
|
score: 86,
|
|
result: '建议进入下一轮',
|
|
summary: '沟通完整',
|
|
...overrides
|
|
});
|
|
|
|
const material = (overrides = {}) => ({
|
|
id: 1,
|
|
ossId: 2,
|
|
fileName: '简历.pdf',
|
|
materialType: '补充资料',
|
|
fileSize: 2048,
|
|
status: '待审核',
|
|
time: '2026-07-10 10:30:00',
|
|
...overrides
|
|
});
|
|
|
|
const pageSource = async (path) => readFile(new URL(path, import.meta.url), 'utf8');
|
|
|
|
test('候选流程从面试、补资料、审核到完成只依赖真实记录', () => {
|
|
assert.deepEqual(buildCandidateFlow([], []), {
|
|
stage: 'interview',
|
|
badge: '待面试',
|
|
title: '完成结构化面试',
|
|
desc: '按岗位题目完成回答,提交后生成正式面试记录。',
|
|
progress: 0,
|
|
progressText: '0/2',
|
|
notice: '待完成结构化面试',
|
|
cta: '开始面试',
|
|
route: candidateRoutes.interview
|
|
});
|
|
|
|
assert.equal(buildCandidateFlow([record()], []).stage, 'materials');
|
|
assert.equal(buildCandidateFlow([record()], []).route, candidateRoutes.materials);
|
|
assert.equal(buildCandidateFlow([record()], [material({ status: '已驳回' })]).badge, '资料被驳回');
|
|
assert.equal(buildCandidateFlow([record()], [material()]).stage, 'review');
|
|
assert.equal(buildCandidateFlow([record()], [material()]).route, candidateRoutes.progress);
|
|
assert.equal(buildCandidateFlow([record()], [material({ status: '已通过' })]).stage, 'complete');
|
|
assert.equal(buildCandidateFlow([record()], [material({ status: '已通过' })]).progress, 100);
|
|
});
|
|
|
|
test('资料展示格式保持三态且文件大小可读', () => {
|
|
assert.equal(materialStatusTone('已通过'), 'passed');
|
|
assert.equal(materialStatusTone('已驳回'), 'rejected');
|
|
assert.equal(materialStatusTone('待审核'), 'pending');
|
|
assert.equal(formatCandidateFileSize(0), '0KB');
|
|
assert.equal(formatCandidateFileSize(2048), '2KB');
|
|
assert.equal(formatCandidateFileSize(1572864), '1.5MB');
|
|
});
|
|
|
|
test('候选首页只做状态总览和独立页面分流', async () => {
|
|
const source = await pageSource('../src/pages/candidate/index/index.vue');
|
|
|
|
assert.match(source, /getCandidateInterviewRecords/);
|
|
assert.match(source, /getCandidateMaterials/);
|
|
Object.values(candidateRoutes).forEach((route) => assert.match(source, new RegExp(route.replaceAll('/', '\\/'))));
|
|
assert.doesNotMatch(source, /startCandidateInterview/);
|
|
assert.doesNotMatch(source, /uploadCandidateMaterial/);
|
|
assert.doesNotMatch(source, /searchKnowledge/);
|
|
assert.doesNotMatch(source, /interviewQuestions/);
|
|
});
|
|
|
|
test('面试、资料、进度和预习页各自只承载一类真实任务', async () => {
|
|
const [interview, materials, progress, study] = await Promise.all([
|
|
pageSource('../src/pages/candidate/interview/index.vue'),
|
|
pageSource('../src/pages/candidate/materials/index.vue'),
|
|
pageSource('../src/pages/candidate/progress/index.vue'),
|
|
pageSource('../src/pages/candidate/study/index.vue')
|
|
]);
|
|
|
|
assert.match(interview, /startCandidateInterview/);
|
|
assert.match(interview, /saveInterviewAnswer/);
|
|
assert.match(interview, /finishCandidateInterview/);
|
|
assert.doesNotMatch(interview, /uploadCandidateMaterial|searchKnowledge/);
|
|
|
|
assert.match(materials, /chooseCandidateFile/);
|
|
assert.match(materials, /uploadCandidateMaterial/);
|
|
assert.doesNotMatch(materials, /startCandidateInterview|searchKnowledge/);
|
|
|
|
assert.match(progress, /getCandidateInterviewRecords/);
|
|
assert.match(progress, /getCandidateMaterials/);
|
|
assert.doesNotMatch(progress, /startCandidateInterview|uploadCandidateMaterial|searchKnowledge/);
|
|
|
|
assert.match(study, /searchKnowledge/);
|
|
assert.doesNotMatch(study, /startCandidateInterview|uploadCandidateMaterial/);
|
|
});
|
|
|
|
test('五个候选页面登录都使用 redirectTo 并保留当前任务页', async () => {
|
|
const sources = await Promise.all([
|
|
pageSource('../src/pages/candidate/index/index.vue'),
|
|
pageSource('../src/pages/candidate/interview/index.vue'),
|
|
pageSource('../src/pages/candidate/materials/index.vue'),
|
|
pageSource('../src/pages/candidate/progress/index.vue'),
|
|
pageSource('../src/pages/candidate/study/index.vue')
|
|
]);
|
|
|
|
sources.forEach((source) => {
|
|
const goLogin = source.match(/const goLogin = \(\) => \{\n[\s\S]*?\n\};/)?.[0] || '';
|
|
assert.match(goLogin, /rememberLoginRedirect\(currentPath\)/);
|
|
assert.match(goLogin, /uni\.redirectTo\(\{ url: '\/pages\/auth\/login\/index' \}\)/);
|
|
assert.doesNotMatch(goLogin, /uni\.navigateTo\(/);
|
|
});
|
|
});
|
|
|
|
test('候选子路由已注册为真实页面', async () => {
|
|
const pages = await pageSource('../src/pages.json');
|
|
|
|
assert.match(pages, /pages\/candidate\/interview\/index/);
|
|
assert.match(pages, /pages\/candidate\/materials\/index/);
|
|
assert.match(pages, /pages\/candidate\/progress\/index/);
|
|
assert.match(pages, /pages\/candidate\/study\/index/);
|
|
});
|