Plan 01 - QUAL-02: 三平台解析函数单元测试: - tests/ingest/test_configs_boss.py: 10 个测试 (_extract_job_id, _extract_company_name, _build_boss_push) - tests/ingest/test_configs_qcwy.py: 12 个测试 (_extract_job_id, _extract_update_dt, _extract_company_name, _build_qcwy_push) - tests/ingest/test_configs_zhilian.py: 12 个测试 (_extract_number, _extract_fpt, _extract_company_name, _build_zhilian_push) Plan 02 - QUAL-06: 爬虫入库统计 API + 前端监控区域: - job.py: GET /job/data/stats 端点(总量/今日/最近入库时间/近7天趋势) - web/src/api/index.js: getIngestStats() 方法 - monitoring.vue: 新增爬虫职位入库统计区域(三平台卡片 + 趋势表格) - job.py: Optional 导入修复 QUAL-07: 确认 monitor.vue 已有完整清洗队列功能,无需改动 Full regression: 146 passed (112 existing + 34 new)
111 lines
3.4 KiB
Python
111 lines
3.4 KiB
Python
"""
|
||
前程无忧 (51Job) ingest config 解析函数单元测试 — QUAL-02
|
||
覆盖 _extract_job_id / _extract_update_dt / _extract_company_name / _build_qcwy_push
|
||
"""
|
||
|
||
from app.services.ingest.configs.qcwy import (
|
||
_extract_job_id,
|
||
_extract_update_dt,
|
||
_extract_company_name,
|
||
_build_qcwy_push,
|
||
)
|
||
|
||
|
||
# ─── _extract_job_id ─────────────────────────────────
|
||
|
||
def test_qcwy_extract_job_id_normal():
|
||
data = {"jobId": "5001234567"}
|
||
assert _extract_job_id(data) == "5001234567"
|
||
|
||
|
||
def test_qcwy_extract_job_id_int():
|
||
data = {"jobId": 5001234567}
|
||
assert _extract_job_id(data) == "5001234567"
|
||
|
||
|
||
def test_qcwy_extract_job_id_missing():
|
||
data = {}
|
||
assert _extract_job_id(data) is None
|
||
|
||
|
||
# ─── _extract_update_dt ──────────────────────────────
|
||
|
||
def test_qcwy_extract_update_dt_normal():
|
||
data = {"updateDateTime": "2026-03-01 12:00:00"}
|
||
assert _extract_update_dt(data) == "2026-03-01 12:00:00"
|
||
|
||
|
||
def test_qcwy_extract_update_dt_missing():
|
||
data = {}
|
||
assert _extract_update_dt(data) is None
|
||
|
||
|
||
# ─── _extract_company_name ────────────────────────────
|
||
|
||
def test_qcwy_extract_company_name_from_companyName():
|
||
data = {"companyName": "阿里巴巴"}
|
||
assert _extract_company_name(data) == "阿里巴巴"
|
||
|
||
|
||
def test_qcwy_extract_company_name_from_company_name_fallback():
|
||
data = {"company_name": "阿里巴巴网络"}
|
||
assert _extract_company_name(data) == "阿里巴巴网络"
|
||
|
||
|
||
def test_qcwy_extract_company_name_missing():
|
||
data = {}
|
||
assert _extract_company_name(data) is None
|
||
|
||
|
||
# ─── _build_qcwy_push ─────────────────────────────────
|
||
|
||
def test_qcwy_build_push_welfare_list():
|
||
"""welfare 为对象列表 → 提取 chineseTitle"""
|
||
data = {
|
||
"jobWelfareCodeDataList": [
|
||
{"chineseTitle": "五险一金", "code": "A1"},
|
||
{"chineseTitle": "年终奖", "code": "A2"},
|
||
],
|
||
"jobName": "Java 开发工程师",
|
||
"companyName": "阿里巴巴",
|
||
"jobSalaryMax": 25000,
|
||
"jobSalaryMin": 18000,
|
||
"jobHref": "https://example.com/job/12345.html",
|
||
"coId": "co123",
|
||
}
|
||
result = _build_qcwy_push(data)
|
||
assert result is not None
|
||
assert result["source_type"] == "前程无忧"
|
||
assert "五险一金" in result["welfare"]
|
||
assert "年终奖" in result["welfare"]
|
||
assert result["title"] == "Java 开发工程师"
|
||
|
||
|
||
def test_qcwy_build_push_welfare_string():
|
||
"""welfare 为字符串 → 清理括号后返回"""
|
||
data = {
|
||
"jobWelfareCodeDataList": "[五险一金,年终奖]",
|
||
"jobName": "产品经理",
|
||
"companyName": "腾讯",
|
||
}
|
||
result = _build_qcwy_push(data)
|
||
assert result is not None
|
||
assert "五险一金" in result["welfare"]
|
||
|
||
|
||
def test_qcwy_build_push_partial():
|
||
"""缺字段不 raise,source_type 正确"""
|
||
data = {}
|
||
result = _build_qcwy_push(data)
|
||
assert result is not None
|
||
assert result["source_type"] == "前程无忧"
|
||
assert result["title"] is None or result["title"] == ""
|
||
|
||
|
||
def test_qcwy_build_push_salary_format():
|
||
"""薪资字段格式化"""
|
||
data = {"jobSalaryMax": 30000, "jobSalaryMin": 20000}
|
||
result = _build_qcwy_push(data)
|
||
assert "30000" in result["salary"]
|
||
assert "20000" in result["salary"]
|