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)
110 lines
3.3 KiB
Python
110 lines
3.3 KiB
Python
"""
|
||
智联招聘 ingest config 解析函数单元测试 — QUAL-02
|
||
覆盖 _extract_number / _extract_fpt / _extract_company_name / _build_zhilian_push
|
||
"""
|
||
|
||
from app.services.ingest.configs.zhilian import (
|
||
_extract_number,
|
||
_extract_fpt,
|
||
_extract_company_name,
|
||
_build_zhilian_push,
|
||
)
|
||
|
||
|
||
# ─── _extract_number ─────────────────────────────────
|
||
|
||
def test_zhilian_extract_number_normal():
|
||
data = {"number": "ZL98765"}
|
||
assert _extract_number(data) == "ZL98765"
|
||
|
||
|
||
def test_zhilian_extract_number_int():
|
||
data = {"number": 98765}
|
||
assert _extract_number(data) == "98765"
|
||
|
||
|
||
def test_zhilian_extract_number_missing():
|
||
data = {}
|
||
assert _extract_number(data) is None
|
||
|
||
|
||
# ─── _extract_fpt ────────────────────────────────────
|
||
|
||
def test_zhilian_extract_fpt_normal():
|
||
data = {"firstPublishTime": "2026-03-15 09:00:00"}
|
||
assert _extract_fpt(data) == "2026-03-15 09:00:00"
|
||
|
||
|
||
def test_zhilian_extract_fpt_missing():
|
||
data = {}
|
||
assert _extract_fpt(data) is None
|
||
|
||
|
||
# ─── _extract_company_name ────────────────────────────
|
||
|
||
def test_zhilian_extract_company_name_from_companyName():
|
||
data = {"companyName": "华为技术"}
|
||
assert _extract_company_name(data) == "华为技术"
|
||
|
||
|
||
def test_zhilian_extract_company_name_from_name_fallback():
|
||
data = {"name": "华为有限公司"}
|
||
assert _extract_company_name(data) == "华为有限公司"
|
||
|
||
|
||
def test_zhilian_extract_company_name_missing():
|
||
data = {}
|
||
assert _extract_company_name(data) is None
|
||
|
||
|
||
# ─── _build_zhilian_push ─────────────────────────────
|
||
|
||
def test_zhilian_build_push_skill_labels():
|
||
"""skillLabel 为对象列表 → 提取 value"""
|
||
data = {
|
||
"skillLabel": [
|
||
{"value": "Python"},
|
||
{"value": "深度学习"},
|
||
],
|
||
"companyName": "百度",
|
||
"name": "算法工程师",
|
||
"salary60": "25k-40k",
|
||
"workCity": "北京",
|
||
"cityDistrict": "海淀区",
|
||
"companyId": 1001,
|
||
"positionURL": "https://zhaopin.com/jobs/ABC123.htm",
|
||
}
|
||
result = _build_zhilian_push(data)
|
||
assert result is not None
|
||
assert result["source_type"] == "智联招聘"
|
||
assert "Python" in result["skill"]
|
||
assert "深度学习" in result["skill"]
|
||
assert result["title"] == "算法工程师"
|
||
assert result["company_name"] == "百度"
|
||
assert result["salary"] == "25k-40k"
|
||
|
||
|
||
def test_zhilian_build_push_empty_skill_labels():
|
||
"""skillLabel 为空列表 → skill 为空字符串"""
|
||
data = {"skillLabel": []}
|
||
result = _build_zhilian_push(data)
|
||
assert result is not None
|
||
assert result["skill"] == ""
|
||
|
||
|
||
def test_zhilian_build_push_partial():
|
||
"""缺字段不 raise,source_type 正确"""
|
||
data = {}
|
||
result = _build_zhilian_push(data)
|
||
assert result is not None
|
||
assert result["source_type"] == "智联招聘"
|
||
# safe_get 在缺字段时返回 None 或 '',两种均可接受
|
||
assert result["title"] in (None, "")
|
||
|
||
|
||
def test_zhilian_build_push_recruiter_number_str():
|
||
"""招募人数字段转字符串"""
|
||
data = {"recruitNumber": 5}
|
||
result = _build_zhilian_push(data)
|
||
assert result["number"] == "5"
|