from __future__ import annotations import json import tempfile import unittest from datetime import datetime, timezone from pathlib import Path from daily_report.db import Database from daily_report.report_service import ReportService def make_database(employees: list[dict]) -> Database: temp_dir = Path(tempfile.mkdtemp(prefix="daily-report-")) seed_path = temp_dir / "employees.json" seed_path.write_text(json.dumps(employees), encoding="utf-8") return Database(temp_dir / "test.sqlite", seed_path) class ReportServiceTest(unittest.TestCase): def test_creates_schema_and_loads_active_employees(self) -> None: db = make_database( [ {"feishu_user_id": "u_1", "name": "Lin", "department": "Design", "manager": "Mo", "active": True}, {"feishu_user_id": "u_2", "name": "Chen", "department": "Sales", "manager": "Mo", "active": False}, ] ) try: employees = db.list_active_employees() self.assertEqual(len(employees), 1) self.assertEqual(employees[0]["name"], "Lin") finally: db.close() def test_validates_required_report_fields(self) -> None: db = make_database([{"feishu_user_id": "u_1", "name": "Lin", "active": True}]) service = ReportService(db) try: with self.assertRaisesRegex(ValueError, "today_done is required"): service.upsert_report( { "feishu_user_id": "u_1", "report_date": "2026-05-07", "today_done": "", "tomorrow_plan": "完善管理页", } ) finally: db.close() def test_upserts_one_report_per_employee_and_date(self) -> None: db = make_database([{"feishu_user_id": "u_1", "name": "Lin", "department": "Design", "active": True}]) service = ReportService(db, clock=lambda: datetime(2026, 5, 7, 10, tzinfo=timezone.utc)) try: service.upsert_report( { "feishu_user_id": "u_1", "report_date": "2026-05-07", "report_status": "risk", "today_done": "1. 完成原型初稿", "tomorrow_plan": "1. 和主管评审", } ) service.upsert_report( { "feishu_user_id": "u_1", "report_date": "2026-05-07", "report_status": "need_help", "today_done": "1. 完成原型初稿\n2. 调整文案", "tomorrow_plan": "1. 和主管评审", "blockers": "需要确认 logo", "help_needed": "确认视觉方向", } ) result = service.list_reports_for_date("2026-05-07") self.assertEqual(len(result["reports"]), 1) self.assertEqual(result["reports"][0]["report_status"], "need_help") self.assertEqual(result["reports"][0]["today_done"], "1. 完成原型初稿\n2. 调整文案") self.assertEqual(result["reports"][0]["blockers"], "需要确认 logo") self.assertEqual(len(result["missing"]), 0) finally: db.close() def test_returns_missing_active_employees_csv_and_previous_reference(self) -> None: db = make_database( [ {"feishu_user_id": "u_1", "name": "Lin", "department": "Design", "active": True}, {"feishu_user_id": "u_2", "name": "Chen", "department": "Sales", "active": True}, ] ) service = ReportService(db, clock=lambda: datetime(2026, 5, 7, 10, tzinfo=timezone.utc)) try: service.upsert_report( { "feishu_user_id": "u_1", "report_date": "2026-05-06", "today_done": "1. 完成上线检查清单", "tomorrow_plan": "1. 准备发布", } ) service.upsert_report( { "feishu_user_id": "u_1", "report_date": "2026-05-07", "today_done": "1. 准备发布", "tomorrow_plan": "1. 复盘问题", } ) result = service.list_reports_for_date("2026-05-07") self.assertEqual(result["submittedCount"], 1) self.assertEqual(result["missing"][0]["name"], "Chen") csv_text = service.export_reports_csv("2026-05-07") self.assertIn("employee_name,report_date,today_done,tomorrow_plan,blockers,help_needed,report_status,submitted_at", csv_text) self.assertIn("Lin,2026-05-07,1. 准备发布,1. 复盘问题,,,normal,", csv_text) reference = service.previous_report_reference("u_1", "2026-05-07") self.assertEqual(reference["report"]["report_date"], "2026-05-06") self.assertEqual(reference["report"]["tomorrow_plan"], "1. 准备发布") finally: db.close() if __name__ == "__main__": unittest.main()