PayrollManagementSystem/backend/tests/unit/test_dashboard_sync.py
liuwenxin 1461a8d113 feat(后端): 添加授权体系、系统监控与试用期计提
按 2026-11-02 需求补齐计划交付后端能力:
- 角色授权:权限目录化,接口统一准入校验,未登记默认拒绝;
  管理员判断改为按数据库角色重新判定,防止权限码持有者绕过
- 系统监控:单进程采集资源、请求与异常指标,分钟级聚合,
  阈值配置化;敏感配置增加 repr 保护,Redis 密码 URL 转义
- 试用期计提:按回款日判定并写入快照,年度结清与调整单联动;
  人员模型补试用期、离职日期与工资版本历史字段
- 计提模板:公式骨架受控,页面维护名称与参数绑定
- T+ 采集:自动化配置表与进度查询

内置角色禁停用保护对齐模块注释;核算规则版本提为常量并
补充批量核算失败堆栈日志。

影响范围:后端全部模块、数据库迁移 V22-V28
验证:uv run ruff check 通过;922 个单元测试全部通过;
集成测试因本机 MySQL 数据卷被其他容器锁定暂未运行
2026-11-03 11:20:55 +08:00

75 lines
2.9 KiB
Python

"""首页采集状态来自真实批次,关闭读取不抹掉历史成功记录。"""
from datetime import datetime
import pytest
from sqlalchemy import Column, DateTime, Integer, MetaData, String, Table, create_engine
from sqlalchemy.orm import Session
from app.core.config import Settings
from app.services import dashboard_service
@pytest.fixture
def sync_database(monkeypatch):
engine = create_engine("sqlite://")
metadata = MetaData()
# 只建 V14 已有列,证明读取状态不要求业务库先升级 V20。
table = Table(
"tplus_sync_batches", metadata,
Column("id", Integer, primary_key=True),
Column("sync_mode", String(16)),
Column("status", String(16)),
Column("finished_at", DateTime),
)
metadata.create_all(engine)
settings = Settings(_env_file=None, app_secret_key="x" * 32)
monkeypatch.setattr(dashboard_service, "get_settings", lambda: settings, raising=False)
with Session(engine) as session:
yield session, table, settings
engine.dispose()
def test_关闭采集仍显示历史成功且不将旧失败冒充当前失败(sync_database):
session, table, _ = sync_database
finished = datetime(2026, 10, 30, 16, 52, 3)
session.execute(table.insert(), [
{"id": 1, "sync_mode": "FULL", "status": "FAILED", "finished_at": finished},
{"id": 2, "sync_mode": "FULL", "status": "SUCCEEDED", "finished_at": finished},
{"id": 3, "sync_mode": "AUDIT", "status": "FAILED", "finished_at": finished},
])
result = dashboard_service._sync_status(session)
assert result["available"] is True
assert result["enabled"] is False and result["automation_enabled"] is False
assert result["latest_status"] == "SUCCEEDED"
assert result["last_success_at"] == finished
assert result["historical_failure_total"] == 1
@pytest.mark.parametrize("status", ["FAILED", "PARTIAL", "QUEUED", "RUNNING"])
def test_首页如实返回最近采集状态(sync_database, status):
session, table, settings = sync_database
settings.t_plus_enabled = True
session.execute(table.insert(), {"id": 1, "sync_mode": "FULL", "status": status})
result = dashboard_service._sync_status(session)
assert result["latest_status"] == status and result["enabled"] is True
assert result["last_success_at"] is None
def test_无记录不显示已采集(sync_database):
session, _, _ = sync_database
result = dashboard_service._sync_status(session)
assert result["available"] is True
assert result["latest_status"] is None and result["last_success_at"] is None
def test_未建同步表时明确返回不可查询():
engine = create_engine("sqlite://")
try:
with Session(engine) as session:
result = dashboard_service._sync_status(session)
assert result["available"] is False
assert result["last_success_at"] is None
finally:
engine.dispose()