This commit is contained in:
@@ -174,6 +174,81 @@ def test_ppt_audit_history_200(client):
|
||||
assert r.status_code == 200
|
||||
|
||||
|
||||
def test_ppt_audit_history_shows_ppt_schedule_and_db_runs(client, monkeypatch):
|
||||
"""PPT 產線頁必須呈現六種固定週期與 DB 寫入紀錄。"""
|
||||
from services import ppt_auto_generation_service as svc
|
||||
|
||||
cadences = svc.get_schedule_cadence_status([
|
||||
{'key': key, 'ready': True}
|
||||
for key in svc.DEFINED_REPORT_TYPES
|
||||
])
|
||||
monkeypatch.setattr(svc, 'get_defined_report_coverage', lambda **_kw: {
|
||||
'enabled': True,
|
||||
'items': [],
|
||||
'missing_report_types': [],
|
||||
'missing_count': 0,
|
||||
'ready_count': len(svc.DEFINED_REPORT_TYPES),
|
||||
'total': len(svc.DEFINED_REPORT_TYPES),
|
||||
'last_run': None,
|
||||
'cadences': cadences,
|
||||
'cadence_summary': '、'.join(c['schedule_text'] for c in cadences),
|
||||
})
|
||||
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': 'ocbot_daily_20260517.pptx',
|
||||
'file_size_kb': 1024,
|
||||
'error_msg': '',
|
||||
'started_at': '2026-05-17 20:30',
|
||||
'finished_at': '2026-05-17 20:31',
|
||||
}])
|
||||
|
||||
r = client.get('/observability/ppt_audit_history')
|
||||
html = r.data.decode('utf-8')
|
||||
|
||||
for text in ['每日 20:30', '每週一 20:40', '每月 1 日 20:50', '每季首日 21:00', '每半年首日 21:10', '每年 1/1 21:20']:
|
||||
assert text in html
|
||||
assert 'ppt_generation_runs' in html
|
||||
assert '每日日報' in html
|
||||
|
||||
|
||||
def test_ppt_audit_file_view_renders_online_preview(client, monkeypatch, tmp_path):
|
||||
"""PPTX view 入口應回站內預覽頁,而不是把 PPTX 直接丟給瀏覽器。"""
|
||||
import zipfile
|
||||
from services import ppt_preview_service as preview_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.setattr(
|
||||
preview_svc,
|
||||
'build_ppt_preview',
|
||||
lambda *_args, **_kwargs: preview_svc.PPTPreviewResult(
|
||||
ok=True,
|
||||
pdf_path=str(reports_dir / 'preview.pdf'),
|
||||
cache_hit=True,
|
||||
converter='/usr/bin/libreoffice',
|
||||
),
|
||||
)
|
||||
|
||||
r = client.get('/observability/ppt_audit_file/ocbot_daily_20260517.pptx')
|
||||
html = r.data.decode('utf-8')
|
||||
|
||||
assert r.status_code == 200
|
||||
assert 'PPT 線上預覽' in html
|
||||
assert 'action=pdf' in html
|
||||
assert '下載 PPTX' in html
|
||||
|
||||
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
# /observability/host_health
|
||||
# ──────────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -124,6 +124,30 @@ def test_due_schedule_kinds_include_periodic_boundaries():
|
||||
]
|
||||
|
||||
|
||||
def test_schedule_cadence_status_exposes_all_periodic_contracts():
|
||||
from services.ppt_auto_generation_service import get_schedule_cadence_status
|
||||
|
||||
cadences = get_schedule_cadence_status([
|
||||
{"key": "daily", "ready": True},
|
||||
{"key": "weekly", "ready": False},
|
||||
{"key": "market_intel", "ready": True},
|
||||
])
|
||||
by_key = {cadence["key"]: cadence for cadence in cadences}
|
||||
|
||||
assert [cadence["schedule_text"] for cadence in cadences] == [
|
||||
"每日 20:30",
|
||||
"每週一 20:40",
|
||||
"每月 1 日 20:50",
|
||||
"每季首日 21:00",
|
||||
"每半年首日 21:10",
|
||||
"每年 1/1 21:20",
|
||||
]
|
||||
assert by_key["weekly"]["report_types"] == ["weekly", "market_intel"]
|
||||
assert by_key["weekly"]["ready_count"] == 1
|
||||
assert by_key["weekly"]["missing_report_types"] == ["weekly"]
|
||||
assert "TTM 滾動 12 月" in by_key["monthly"]["report_labels"]
|
||||
|
||||
|
||||
def test_scheduled_generation_uses_profile_without_generating(monkeypatch):
|
||||
from services import ppt_auto_generation_service as svc
|
||||
|
||||
@@ -144,3 +168,16 @@ def test_scheduled_generation_uses_profile_without_generating(monkeypatch):
|
||||
"schedule_kind": "weekly",
|
||||
"force": True,
|
||||
}]
|
||||
|
||||
|
||||
def test_ppt_preview_reports_missing_converter(monkeypatch, tmp_path):
|
||||
from services import ppt_preview_service as svc
|
||||
|
||||
pptx = tmp_path / "demo.pptx"
|
||||
pptx.write_bytes(b"fake pptx")
|
||||
monkeypatch.setattr(svc.shutil, "which", lambda _name: None)
|
||||
|
||||
result = svc.build_ppt_preview(pptx, cache_dir=tmp_path / "cache")
|
||||
|
||||
assert result.ok is False
|
||||
assert "LibreOffice" in (result.error or "")
|
||||
|
||||
Reference in New Issue
Block a user