Kapitel 7 abgeschlossen.

This commit is contained in:
2026-08-16 00:29:01 +02:00
parent da8d2bb1da
commit f9e398b225
47 changed files with 2636 additions and 107 deletions
@@ -0,0 +1,108 @@
using System.IO.Compression;
using LehrerApp.Core.Models;
using LehrerApp.Core.Services;
using LehrerApp.Desktop.ViewModels.Students;
using Xunit;
namespace LehrerApp.Desktop.Tests;
public sealed class CreateLetterDialogViewModelTests : IDisposable
{
private readonly string _directory = Path.Combine(Path.GetTempPath(), $"lehrerapp-letter-vm-tests-{Guid.NewGuid():N}");
public CreateLetterDialogViewModelTests() => Directory.CreateDirectory(_directory);
[Fact]
public void OhneVorlage_KannKeinenBriefErzeugen()
{
var student = StudentWithContact("Sehr geehrte Frau Muster,");
var vm = Build(student, new LetterTemplateService(_directory));
Assert.False(vm.CanGenerate);
Assert.Contains(vm.Issues, i => i.Message.Contains("Vorlage", StringComparison.OrdinalIgnoreCase));
}
[Fact]
public void VerwendeteBriefanredeFehlt_BlockiertErzeugung()
{
var service = ServiceWithTemplate("Letter.Salutation");
var vm = Build(StudentWithContact(null), service);
Assert.False(vm.CanGenerate);
Assert.Contains(vm.Issues, i => i.Message.Contains("Briefanrede"));
}
[Fact]
public void VollstaendigeDaten_ErzeugenEditierbareDocxKopie()
{
var service = ServiceWithTemplate("Letter.Salutation", "Student.FirstName", "CurrentDate");
var vm = Build(StudentWithContact("Sehr geehrte Frau Muster,"), service);
var output = Path.Combine(_directory, "Brief.docx");
var generated = vm.Generate(output);
Assert.True(generated);
Assert.True(File.Exists(output));
using var archive = ZipFile.OpenRead(output);
using var reader = new StreamReader(archive.GetEntry("word/document.xml")!.Open());
var xml = reader.ReadToEnd();
Assert.Contains("Sehr geehrte Frau Muster,", xml);
Assert.Contains("Lena", xml);
}
[Fact]
public void KontaktBearbeiten_SpeichertExpliziteBriefanrede()
{
var vm = new ContactEditDialogViewModel(new Contact { Name = "Frau Muster" });
vm.LetterSalutation = "Sehr geehrte Frau Muster,";
vm.SaveCommand.Execute(null);
Assert.Equal("Sehr geehrte Frau Muster,", vm.Result!.LetterSalutation);
}
private CreateLetterDialogViewModel Build(Student student, LetterTemplateService service) =>
new(student, service, new FakeMemberships([]), new FakeGroups([]));
private LetterTemplateService ServiceWithTemplate(params string[] tags)
{
var source = Path.Combine(_directory, $"{Guid.NewGuid():N}.docx");
using (var archive = ZipFile.Open(source, ZipArchiveMode.Create))
{
var entry = archive.CreateEntry("word/document.xml");
using var writer = new StreamWriter(entry.Open());
var controls = string.Join("", tags.Select(tag =>
$"<w:sdt><w:sdtPr><w:tag w:val=\"{tag}\"/></w:sdtPr><w:sdtContent>" +
"<w:p><w:r><w:t>Platzhalter</w:t></w:r></w:p></w:sdtContent></w:sdt>"));
writer.Write("<w:document xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">" +
$"<w:body>{controls}</w:body></w:document>");
}
var service = new LetterTemplateService(Path.Combine(_directory, $"service-{Guid.NewGuid():N}"));
service.Import(source, "Elternbrief");
return service;
}
private static Student StudentWithContact(string? salutation) => new()
{
FirstName = "Lena",
LastName = "Beispiel",
Contacts =
[
new Contact
{
Name = "Frau Muster",
Relation = "Mutter",
LetterSalutation = salutation,
Street = "Hauptstraße 1",
PostalCode = "12345",
City = "Musterstadt",
},
],
};
public void Dispose()
{
if (Directory.Exists(_directory)) Directory.Delete(_directory, recursive: true);
}
}