- PdfSharpCore 1.3.64 引入(纯托管,Unity IL2CPP 兼容,+9 DLL) - ReportData 结构化模型 + MarkdownRenderer + StandardPdfTemplate - IReportService.ExportReport(id, format) 按需导出 PDF/MD - 仿真后自动生成 MD 到 reports 目录,PDF 按需调用 - CJK 字体嵌入(SimHei),IPathProvider + GetFontPath - ReportGenerator 重构为构建 ReportData,去掉 emoji - check_unity_build.ps1 修复 -quit 参数缺失导致超时 - 对接文档 V2.0:坐标系/3D 可视化/完整枚举/Manager 签名/模型字段 - 262 测试全部通过
158 lines
5.7 KiB
C#
158 lines
5.7 KiB
C#
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<ScenarioDrone> { TestData.CreateScenarioDrone("w1", 1) },
|
|
Units = new List<ScenarioUnit>(),
|
|
Cloud = new CloudDispersal(),
|
|
};
|
|
}
|
|
|
|
[Fact]
|
|
public void Generate_And_Get_ReturnsReport()
|
|
{
|
|
var report = _service.Generate("scenario1", CreateTestConfig(), new List<SimEvent>(), "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<SimEvent>(), "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<SimEvent>(), "Destroyed", 10f);
|
|
cfg.Info.Name = "平原拦截";
|
|
cfg.Info.ScenarioNumber = "SIM-B";
|
|
_service.Generate("t2", cfg, new List<SimEvent>(), "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<SimEvent>(), "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<SimEvent>(), "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<InvalidOperationException>(() => _service.ExportReport(report.Id, "pdf"));
|
|
}
|
|
|
|
[Fact]
|
|
public void ExportReport_UnsupportedFormat_Throws()
|
|
{
|
|
var report = _service.Generate("scenario1", CreateTestConfig(), new List<SimEvent>(), "Destroyed", 45f);
|
|
Assert.Throws<ArgumentException>(() => _service.ExportReport(report.Id, "docx"));
|
|
}
|
|
|
|
[Fact]
|
|
public void ExportToFile_Pdf_CreatesPdfFile()
|
|
{
|
|
var report = _service.Generate("scenario1", CreateTestConfig(), new List<SimEvent>(), "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<SimEvent>(), "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<SimEvent>(), "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 目录");
|
|
}
|
|
}
|
|
}
|