JobData/tests/ingest/test_configs_boss.py
win 6c8eb00a50 feat(06): quality & frontend (QUAL-02, QUAL-06)
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)
2026-03-21 22:56:24 +08:00

110 lines
3.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
Boss直聘 ingest config 解析函数单元测试 — QUAL-02
覆盖 _extract_job_id / _extract_company_name / _build_boss_push
"""
from app.services.ingest.configs.boss import (
_extract_job_id,
_extract_company_name,
_build_boss_push,
)
# ─── _extract_job_id ─────────────────────────────────
def test_extract_job_id_from_jobBaseInfoVO():
data = {"jobBaseInfoVO": {"jobId": "ABCD123"}}
assert _extract_job_id(data) == "ABCD123"
def test_extract_job_id_converts_int():
data = {"jobBaseInfoVO": {"jobId": 999}}
assert _extract_job_id(data) == "999"
def test_extract_job_id_missing_inner():
"""jobBaseInfoVO 存在但无 jobId → None"""
data = {"jobBaseInfoVO": {}}
assert _extract_job_id(data) is None
def test_extract_job_id_missing_outer():
"""缺 jobBaseInfoVO → None"""
data = {}
assert _extract_job_id(data) is None
# ─── _extract_company_name ────────────────────────────
def test_extract_company_name_from_name():
data = {"name": "字节跳动"}
assert _extract_company_name(data) == "字节跳动"
def test_extract_company_name_from_companyFullInfoVO():
data = {"companyFullInfoVO": {"name": "腾讯科技"}}
assert _extract_company_name(data) == "腾讯科技"
def test_extract_company_name_missing():
data = {}
assert _extract_company_name(data) is None
# ─── _build_boss_push ─────────────────────────────────
def test_build_boss_push_full():
data = {
"bossBaseInfoVO": {"brandName": "字节"},
"jobBaseInfoVO": {
"positionName": "算法工程师",
"jobDesc": "负责推荐算法",
"degreeName": "本科",
"requiredSkills": ["Python", "TensorFlow"],
"salaryWelfareInfo": ["五险一金"],
"experienceName": "3-5年",
"lowSalary": 25,
"highSalary": 40,
"locationName": "北京",
"locationDesc": "朝阳区",
"encryptJobId": "ENC_JOB_001",
},
"brandComInfoVO": {
"brandName": "字节跳动",
"encryptBrandId": "ENC_BRAND_001",
"scaleName": "10000人以上",
"industryName": "互联网",
"introduce": "全球领先的科技公司",
},
}
result = _build_boss_push(data)
assert result is not None
assert result["source_type"] == "Boss直聘"
assert result["title"] == "算法工程师"
assert "ENC_JOB_001" in result["url"]
assert result["company_id"] == "ENC_BRAND_001"
assert result["company_name"] == "字节跳动"
assert "25" in result["salary"] and "40" in result["salary"]
def test_build_boss_push_partial():
"""缺字段不 raise返回合理降级值"""
data = {}
result = _build_boss_push(data)
assert result is not None
assert result["source_type"] == "Boss直聘"
# safe_get 在缺字段时返回 None 或 '',两种均可接受
assert result["title"] in (None, "")
def test_build_boss_push_skill_join():
"""多技能列表通过 safe_join 拼接"""
data = {
"jobBaseInfoVO": {"requiredSkills": ["Go", "Rust"]},
"bossBaseInfoVO": {},
"brandComInfoVO": {},
}
result = _build_boss_push(data)
assert "Go" in result["skill"]
assert "Rust" in result["skill"]