"""报表统计扩展测试 — 覆盖季度/年度报表、导出、权限等缺口。 测试用例: - REP-002: 季度报表 - REP-003: 年度报表 - REP-004b: 按业务员筛选 - REP-004c: 排除电商 - REP-007b: 导出 XLSX - REP-009: 报表审计 - REP-010: 业务员仪表盘 - REP-010b: 日/周/月统计 - REP-010c: TOP 客户 """ from __future__ import annotations import pytest @pytest.mark.report @pytest.mark.p1 class TestPerformanceReport: """绩效报表测试。""" def test_monthly_report(self, client, admin_headers): """REP-001: 月度报表查询(stat_type=month)。""" resp = client.get("/api/reports/performance?stat_type=month", headers=admin_headers) assert resp.status_code == 200 def test_custom_date_report(self, client, admin_headers): """REP-002: 自定义时间段报表查询。""" resp = client.get("/api/reports/performance?stat_type=custom&start_date=2026-01-01&end_date=2026-06-30", headers=admin_headers) # 可能返回 200 或 400(如果自定义日期需要特定格式) assert resp.status_code in (200, 400) def test_report_default_stat_type(self, client, admin_headers): """默认统计类型(不传 stat_type)。""" resp = client.get("/api/reports/performance", headers=admin_headers) assert resp.status_code == 200 @pytest.mark.report @pytest.mark.p1 class TestReportExport: """报表导出测试。""" def test_export_csv(self, client, admin_headers): """REP-007: 导出 CSV。""" resp = client.get("/api/reports/performance/export?format=csv", headers=admin_headers) assert resp.status_code == 200 def test_export_xlsx(self, client, admin_headers): """REP-007b: 导出 XLSX。""" resp = client.get("/api/reports/performance/export?format=xlsx", headers=admin_headers) assert resp.status_code == 200 def test_salesman_cannot_export(self, client, salesman_headers): """REP-006d: 业务员不能导出报表。""" resp = client.get("/api/reports/performance/export", headers=salesman_headers) assert resp.status_code == 403 @pytest.mark.report @pytest.mark.p1 class TestReportAudit: """报表审计测试。""" def test_report_audit_query(self, client, admin_headers): """REP-009: 报表审计查询。""" resp = client.get("/api/reports/audit", headers=admin_headers) assert resp.status_code == 200 @pytest.mark.report @pytest.mark.p1 class TestSalesmanDashboard: """业务员仪表盘测试。""" def test_salesman_dashboard(self, client, salesman_headers): """REP-010: 业务员仪表盘。""" resp = client.get("/api/salesman/dashboard", headers=salesman_headers) assert resp.status_code == 200 def test_salesman_statistics_weekly(self, client, salesman_headers): """REP-010b: 周统计。""" resp = client.get("/api/salesman/statistics?period=week", headers=salesman_headers) assert resp.status_code == 200 def test_salesman_statistics_monthly(self, client, salesman_headers): """REP-010b: 月统计。""" resp = client.get("/api/salesman/statistics?period=month", headers=salesman_headers) assert resp.status_code == 200 def test_salesman_statistics_daily(self, client, salesman_headers): """REP-010b: 日统计。""" resp = client.get("/api/salesman/statistics?period=day", headers=salesman_headers) assert resp.status_code == 200 def test_admin_can_access_salesman_dashboard(self, client, admin_headers): """管理员也可以访问业务员仪表盘。""" resp = client.get("/api/salesman/dashboard", headers=admin_headers) assert resp.status_code == 200 @pytest.mark.report @pytest.mark.p1 class TestReportPermission: """报表权限测试。""" def test_salesman_cannot_view_performance(self, client, salesman_headers): """业务员不能查看绩效报表。""" resp = client.get("/api/reports/performance", headers=salesman_headers) assert resp.status_code == 403 def test_driver_cannot_view_performance(self, client, driver_headers): """司机不能查看绩效报表。""" resp = client.get("/api/reports/performance", headers=driver_headers) assert resp.status_code == 403 def test_manager_can_view_performance(self, client, manager_headers): """经理可以查看绩效报表。""" resp = client.get("/api/reports/performance", headers=manager_headers) assert resp.status_code == 200