using System.IO; using System.Text.Json; using AxCopilot.Services.Agent; using DocumentFormat.OpenXml.Packaging; using DocumentFormat.OpenXml.Wordprocessing; using FluentAssertions; using Xunit; namespace AxCopilot.Tests.Services; public class DocxSkillTemplateFeaturesTests { [Fact] public async Task ExecuteAsync_ShouldCreateDocx_WithTemplateCoverAndToc() { var workDir = Path.Combine(Path.GetTempPath(), "ax-docx-template-" + Guid.NewGuid().ToString("N")); Directory.CreateDirectory(workDir); try { var templatePath = Path.Combine(workDir, "template.docx"); using (var template = WordprocessingDocument.Create(templatePath, DocumentFormat.OpenXml.WordprocessingDocumentType.Document)) { var mainPart = template.AddMainDocumentPart(); mainPart.Document = new Document(new Body(new Paragraph(new Run(new Text("Template Root"))))); mainPart.Document.Save(); } var tool = new DocxSkill(); var context = new AgentContext { WorkFolder = workDir, Permission = "Auto", OperationMode = "external", }; var args = JsonDocument.Parse( """ { "path": "executive-brief.docx", "title": "Executive Brief", "template_path": "template.docx", "cover_subtitle": "Q2 Operating Review", "cover_meta": ["Prepared for Steering Committee", "Confidential"], "toc": true, "sections": [ { "heading": "Executive Summary", "body": "Summary line one.\nSummary line two.", "level": 1 }, { "heading": "Recommendation", "body": "Recommendation details.", "level": 1 } ] } """).RootElement; var result = await tool.ExecuteAsync(args, context, CancellationToken.None); result.Success.Should().BeTrue(); var outputPath = Path.Combine(workDir, "executive-brief.docx"); File.Exists(outputPath).Should().BeTrue(); using var doc = WordprocessingDocument.Open(outputPath, false); doc.MainDocumentPart!.Document.Body!.InnerText.Should().Contain("Q2 Operating Review"); doc.MainDocumentPart.Document.Body.InnerText.Should().Contain("Prepared for Steering Committee"); doc.MainDocumentPart.Document.Body.Descendants().Should().Contain(f => f.Text.Contains("TOC")); } finally { try { if (Directory.Exists(workDir)) Directory.Delete(workDir, true); } catch { } } } }