using System; using System.Collections.Generic; using System.IO; using System.Text; using CounterDrone.Core; using CounterDrone.Core.Models; using CounterDrone.Core.Services; using CounterDrone.Core.Simulation; using SQLite; using Xunit; namespace CounterDrone.Core.Tests { public class ReportServiceTests : IDisposable { private readonly string _testDir; private readonly IReportService _service; private readonly SQLiteConnection _db; public ReportServiceTests() { _testDir = Path.Combine(Path.GetTempPath(), $"cd_rep_{Guid.NewGuid():N}"); var paths = new TestPathProvider(_testDir); var dbm = new DatabaseManager(paths); _db = dbm.OpenMainDb(); _service = new ReportService(_db, paths); } public void Dispose() { _db?.Close(); if (Directory.Exists(_testDir)) Directory.Delete(_testDir, true); } private ScenarioConfig CreateTestConfig() { return new ScenarioConfig { Info = new Scenario { Name = "Test", ScenarioNumber = "SIM-001" }, Drones = new List { TestData.CreateScenarioDrone("w1", 1) }, Units = new List(), Cloud = new CloudDispersal(), }; } [Fact] public void Generate_And_Get_ReturnsReport() { var report = _service.Generate("scenario1", CreateTestConfig(), new List(), "Destroyed", 45f); Assert.NotNull(report); Assert.NotEmpty(report.Id); Assert.Equal("Test", report.ScenarioName); Assert.Contains("仿真评估报告", report.Content); Assert.NotNull(report.ReportDataJson); var fetched = _service.GetReport(report.Id); Assert.NotNull(fetched); } [Fact] public void Delete_RemovesReport() { var report = _service.Generate("scenario1", CreateTestConfig(), new List(), "Destroyed", 10f); _service.DeleteReport(report.Id); Assert.Null(_service.GetReport(report.Id)); } [Fact] public void SearchReports_Keyword() { var cfg = CreateTestConfig(); cfg.Info.Name = "城市防御"; _service.Generate("t1", cfg, new List(), "Destroyed", 10f); cfg.Info.Name = "平原拦截"; cfg.Info.ScenarioNumber = "SIM-B"; _service.Generate("t2", cfg, new List(), "Destroyed", 20f); var result = _service.SearchReports("城市", null, null, 1, 10); Assert.Equal(1, result.TotalCount); } [Fact] public void ExportReport_Md_ReturnsMarkdownBytes() { var report = _service.Generate("scenario1", CreateTestConfig(), new List(), "Destroyed", 45f); var md = _service.ExportReport(report.Id, "md"); var text = Encoding.UTF8.GetString(md); Assert.Contains("仿真评估报告", text); } [Fact] public void ExportReport_Pdf_ReturnsValidPdf() { var report = _service.Generate("scenario1", CreateTestConfig(), new List(), "Destroyed", 45f); var pdf = _service.ExportReport(report.Id, "pdf"); Assert.NotEmpty(pdf); // PDF 文件以 "%PDF" 开头 Assert.Equal(0x25, pdf[0]); // % Assert.Equal(0x50, pdf[1]); // P Assert.Equal(0x44, pdf[2]); // D Assert.Equal(0x46, pdf[3]); // F } [Fact] public void ExportReport_Pdf_MissingReportData_Throws() { var report = new SimulationReport { ScenarioId = "s1", ScenarioName = "Old", Content = "# Old Report", ReportDataJson = null, }; _db.Insert(report); Assert.Throws(() => _service.ExportReport(report.Id, "pdf")); } [Fact] public void ExportReport_UnsupportedFormat_Throws() { var report = _service.Generate("scenario1", CreateTestConfig(), new List(), "Destroyed", 45f); Assert.Throws(() => _service.ExportReport(report.Id, "docx")); } [Fact] public void ExportToFile_Pdf_CreatesPdfFile() { var report = _service.Generate("scenario1", CreateTestConfig(), new List(), "Destroyed", 45f); var path = _service.ExportToFile(report.Id, _testDir, "pdf"); Assert.True(File.Exists(path)); Assert.EndsWith(".pdf", path); } [Fact] public void ExportToFile_Md_CreatesMdFile() { var report = _service.Generate("scenario1", CreateTestConfig(), new List(), "Destroyed", 45f); var path = _service.ExportToFile(report.Id, _testDir, "md"); Assert.True(File.Exists(path)); Assert.EndsWith(".md", path); var content = File.ReadAllText(path); Assert.Contains("仿真评估报告", content); } [Fact] public void Generate_AutoExportsMdToReportsDir() { var report = _service.Generate("scenario1", CreateTestConfig(), new List(), "Destroyed", 45f); var reportsDir = Path.Combine(_testDir, "reports"); Assert.True(Directory.Exists(reportsDir)); var mdFiles = Directory.GetFiles(reportsDir, "*.md"); Assert.True(mdFiles.Length > 0, "仿真后应自动生成 MD 文件到 reports 目录"); } } }