127 lines
4.8 KiB
C#
127 lines
4.8 KiB
C#
using System.IO.Compression;
|
|
using System.Xml.Linq;
|
|
using LehrerApp.Core.Services;
|
|
using Xunit;
|
|
|
|
namespace LehrerApp.Tests;
|
|
|
|
public sealed class LetterTemplateServiceTests : IDisposable
|
|
{
|
|
private static readonly XNamespace W = "http://schemas.openxmlformats.org/wordprocessingml/2006/main";
|
|
private readonly string _directory = Path.Combine(Path.GetTempPath(), $"lehrerapp-letter-tests-{Guid.NewGuid():N}");
|
|
|
|
public LetterTemplateServiceTests() => Directory.CreateDirectory(_directory);
|
|
|
|
[Fact]
|
|
public void Validate_OhneInhaltssteuerelement_Warnt()
|
|
{
|
|
var path = CreateDocx("<w:p><w:r><w:t>Brief</w:t></w:r></w:p>");
|
|
|
|
var result = new LetterTemplateService(_directory).Validate(path);
|
|
|
|
Assert.Contains(result.Issues, i => i.Severity == TemplateIssueSeverity.Warning
|
|
&& i.Message.Contains("keine Inhaltssteuerelemente"));
|
|
}
|
|
|
|
[Fact]
|
|
public void Validate_UnbekannterTag_Warnt()
|
|
{
|
|
var path = CreateDocx(Control("Something.EntirelyUnknown"));
|
|
|
|
var result = new LetterTemplateService(_directory).Validate(path);
|
|
|
|
Assert.Contains(result.Issues, i => i.Tag == "Something.EntirelyUnknown"
|
|
&& i.Severity == TemplateIssueSeverity.Warning);
|
|
}
|
|
|
|
[Fact]
|
|
public void Validate_WahrscheinlicherTippfehler_WarntDeutlichMitVorschlag()
|
|
{
|
|
var path = CreateDocx(Control("Contact.Adress"));
|
|
|
|
var result = new LetterTemplateService(_directory).Validate(path);
|
|
|
|
var issue = Assert.Single(result.Issues);
|
|
Assert.Equal(TemplateIssueSeverity.StrongWarning, issue.Severity);
|
|
Assert.Equal("Contact.Address", issue.SuggestedTag);
|
|
Assert.Contains("Meinten Sie", issue.Message);
|
|
}
|
|
|
|
[Fact]
|
|
public void Validate_FindetTagsInKopfzeile()
|
|
{
|
|
var path = CreateDocx(Control("Student.FirstName"), Control("CurrentDate"));
|
|
|
|
var result = new LetterTemplateService(_directory).Validate(path);
|
|
|
|
Assert.Contains("Student.FirstName", result.Tags);
|
|
Assert.Contains("CurrentDate", result.Tags);
|
|
Assert.Empty(result.Issues);
|
|
}
|
|
|
|
[Fact]
|
|
public void Generate_BefuelltTextUndMehrzeiligeAdresse_OhneVorlageZuVeraendern()
|
|
{
|
|
var path = CreateDocx(Control("Student.FirstName") + Control("Contact.Address"));
|
|
var original = File.ReadAllBytes(path);
|
|
var output = Path.Combine(_directory, "filled.docx");
|
|
var service = new LetterTemplateService(_directory);
|
|
|
|
service.Generate(path, output, new Dictionary<string, string?>
|
|
{
|
|
["Student.FirstName"] = "Mara",
|
|
["Contact.Address"] = "Hauptstraße 1\n12345 Musterstadt",
|
|
});
|
|
|
|
Assert.Equal(original, File.ReadAllBytes(path));
|
|
using var archive = ZipFile.OpenRead(output);
|
|
var entry = archive.GetEntry("word/document.xml")!;
|
|
using var reader = new StreamReader(entry.Open());
|
|
var xml = XDocument.Parse(reader.ReadToEnd());
|
|
Assert.Contains("Mara", xml.Descendants(W + "t").Select(t => t.Value));
|
|
Assert.Single(xml.Descendants(W + "br"));
|
|
Assert.Contains("12345 Musterstadt", xml.Descendants(W + "t").Select(t => t.Value));
|
|
}
|
|
|
|
[Fact]
|
|
public void Import_KopiertVorlageUndLoeschenEntferntSie()
|
|
{
|
|
var path = CreateDocx(Control("CurrentDate"));
|
|
var service = new LetterTemplateService(Path.Combine(_directory, "appdata"));
|
|
|
|
var imported = service.Import(path, "Elternbrief");
|
|
|
|
Assert.Equal("Elternbrief", Assert.Single(service.GetTemplates()).Name);
|
|
Assert.True(File.Exists(service.GetTemplatePath(imported)));
|
|
service.Delete(imported.Id);
|
|
Assert.Empty(service.GetTemplates());
|
|
Assert.False(File.Exists(service.GetTemplatePath(imported)));
|
|
}
|
|
|
|
private string CreateDocx(string body, string? header = null)
|
|
{
|
|
var path = Path.Combine(_directory, $"{Guid.NewGuid():N}.docx");
|
|
using var archive = ZipFile.Open(path, ZipArchiveMode.Create);
|
|
AddXml(archive, "word/document.xml", body);
|
|
if (header is not null) AddXml(archive, "word/header1.xml", header);
|
|
return path;
|
|
}
|
|
|
|
private static void AddXml(ZipArchive archive, string name, string content)
|
|
{
|
|
var entry = archive.CreateEntry(name);
|
|
using var writer = new StreamWriter(entry.Open());
|
|
writer.Write($"<w:document xmlns:w=\"{W}\"><w:body>{content}</w:body></w:document>");
|
|
}
|
|
|
|
private static string Control(string tag) =>
|
|
$"<w:sdt><w:sdtPr><w:tag w:val=\"{tag}\"/></w:sdtPr><w:sdtContent>" +
|
|
"<w:p><w:r><w:rPr><w:b/></w:rPr><w:t>Platzhalter</w:t></w:r></w:p>" +
|
|
"</w:sdtContent></w:sdt>";
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Directory.Exists(_directory)) Directory.Delete(_directory, recursive: true);
|
|
}
|
|
}
|