補 PPT 報表覆蓋矩陣
All checks were successful
CD Pipeline / deploy (push) Successful in 1m4s

This commit is contained in:
OoO
2026-05-19 01:09:58 +08:00
parent f6d34628f6
commit 4a6f6a2007
6 changed files with 376 additions and 17 deletions

View File

@@ -287,6 +287,101 @@ def test_ppt_audit_history_shows_recent_preview_workbench(client, monkeypatch, t
assert '1</strong> 份 PDF 快取' in html
def test_ppt_audit_history_coverage_matrix_joins_db_preview_qa(client, monkeypatch, tmp_path):
"""定義簡報覆蓋區要同列呈現 DB、預覽、QA 與交付狀態。"""
import zipfile
from datetime import datetime
from unittest.mock import MagicMock
from routes import admin_observability_routes as mod
from services import ppt_auto_generation_service as svc
reports_dir = tmp_path / 'reports'
reports_dir.mkdir()
pptx = reports_dir / 'ocbot_daily_20260517.pptx'
with zipfile.ZipFile(pptx, 'w') as zf:
zf.writestr('[Content_Types].xml', '<Types></Types>')
monkeypatch.setenv('REPORTS_DIR', str(reports_dir))
monkeypatch.setenv('PPT_PREVIEW_CACHE_DIR', str(tmp_path / 'preview-cache'))
coverage_items = [{
'key': 'daily',
'label': '每日日報',
'target_label': '2026/05/17',
'ready': True,
'status': 'ready',
'status_label': '目標已產生',
'status_hint': '檔案參數與本期定義相符。',
'sources': ['database', 'filesystem'],
'latest_generated_at': '2026-05-17 20:31',
'latest_file_path': str(pptx),
'latest_file_name': pptx.name,
}]
monkeypatch.setattr(svc, 'get_defined_report_coverage', lambda **_kw: {
'enabled': True,
'items': coverage_items,
'missing_report_types': [],
'missing_count': 0,
'ready_count': 1,
'total': 1,
'last_run': None,
'can_auto_start': False,
'cadences': svc.get_schedule_cadence_status(coverage_items),
'cadence_summary': '每日 20:30',
})
monkeypatch.setattr(svc, 'get_generation_run_history', lambda **_kw: [{
'schedule_kind': 'daily',
'schedule_label': '每日',
'report_type': 'daily',
'report_label': '每日日報',
'target_label': '2026/05/17',
'status': 'ready',
'status_label': '已產生',
'file_name': pptx.name,
'file_size_kb': 1024,
'error_msg': '',
'started_at': '2026-05-17 20:30',
'finished_at': '2026-05-17 20:31',
}])
class FakeSession:
def execute(self, statement, _params=None):
sql = str(statement)
result = MagicMock()
if 'FROM ppt_reports' in sql:
result.fetchall.return_value = []
elif 'SELECT audited_at, pptx_filename' in sql:
result.fetchall.return_value = [
(datetime(2026, 5, 17, 22, 5), pptx.name, 'passed', 0, 0.95, 900, '', [])
]
elif 'COALESCE(AVG(confidence)' in sql:
result.fetchone.return_value = (1, 1, 0, 0, 0, 0.95, 0)
elif 'GROUP BY pptx_filename' in sql:
result.fetchall.return_value = []
else:
result.fetchall.return_value = []
result.fetchone.return_value = (0,)
return result
def close(self):
return None
monkeypatch.setattr(mod, 'get_session', lambda: FakeSession())
r = client.get('/observability/ppt_audit_history?month=2026-05')
html = r.get_data(as_text=True)
assert r.status_code == 200
assert '報表覆蓋矩陣' in html
assert 'DB / 預覽 / 視覺 QA / 交付' in html
assert 'DB 已寫入' in html
assert '可預覽' in html
assert 'QA 通過' in html
assert '可交付' in html
assert 'data-ppt-open-preview' in html
assert 'ocbot_daily_20260517.pptx' in html
def test_ppt_audit_file_view_renders_online_preview(client, monkeypatch, tmp_path):
"""PPTX view 入口應回站內預覽頁,而不是把 PPTX 直接丟給瀏覽器。"""
import zipfile