Files
LehrerApp/LehrerApp.Desktop.Tests/StudentImportDialogViewModelTests.cs

117 lines
4.1 KiB
C#

using LehrerApp.Core.Importing;
using LehrerApp.Core.Models;
using LehrerApp.Core.Services;
using LehrerApp.Desktop.ViewModels.Students;
using Xunit;
namespace LehrerApp.Desktop.Tests;
public sealed class StudentImportDialogViewModelTests
{
[Fact]
public async Task Vorschau_ZeigtZusammenfassungUndImportiertNeueSchueler()
{
var stored = new List<Student>();
var service = Service(stored,
[
new ImportedStudent
{
FirstName = "Max",
LastName = "Beispiel",
Gender = Gender.M,
},
]);
var preview = await service.AnalyzeAsync(File());
var vm = new StudentImportDialogViewModel(service, preview, "students.csv");
Assert.Contains("1 erkannt", vm.Summary);
Assert.Equal(1, vm.NewStudents);
Assert.True(vm.IsReadyWithoutConflicts);
Assert.True(await vm.TryApplyAsync());
Assert.Equal(1, vm.Result?.CreatedStudents);
Assert.Single(stored);
}
[Fact]
public async Task Konflikt_VerwendetDieSichereStandardoptionUeberspringen()
{
var stored = new List<Student>
{
new() { FirstName = "Max", LastName = "Beispiel" },
};
var service = Service(stored,
[
new ImportedStudent { FirstName = "Max", LastName = "Beispiel" },
]);
var preview = await service.AnalyzeAsync(File());
var vm = new StudentImportDialogViewModel(service, preview, "students.csv");
var conflict = Assert.Single(vm.Conflicts);
Assert.Equal("skip", conflict.SelectedOption.Id);
Assert.Equal("skip", Assert.Single(vm.BuildDecisions()).SelectedOptionId);
Assert.True(await vm.TryApplyAsync());
Assert.Equal(1, vm.Result?.SkippedStudents);
Assert.Single(stored);
}
[Fact]
public async Task UebernehmenFuerAlle_WaehltBeiJedemEindeutigenKonfliktDenVorhandenenSchueler()
{
var stored = new List<Student>
{
new() { FirstName = "Max", LastName = "Beispiel" },
new() { FirstName = "Erika", LastName = "Muster" },
};
var service = Service(stored,
[
new ImportedStudent { FirstName = "Max", LastName = "Beispiel" },
new ImportedStudent { FirstName = "Erika", LastName = "Muster" },
]);
var preview = await service.AnalyzeAsync(File());
var vm = new StudentImportDialogViewModel(service, preview, "students.csv");
Assert.True(vm.CanUseExistingForAll);
Assert.All(vm.Conflicts, conflict => Assert.Equal("skip", conflict.SelectedOption.Id));
vm.UseExistingForAll();
Assert.All(vm.Conflicts,
conflict => Assert.StartsWith("existing:", conflict.SelectedOption.Id));
Assert.True(await vm.TryApplyAsync());
Assert.Equal(2, vm.Result?.MatchedExistingStudents);
Assert.Equal(0, vm.Result?.SkippedStudents);
Assert.Equal(2, stored.Count);
}
private static StudentImportService Service(
List<Student> stored,
IReadOnlyList<ImportedStudent> imported) => new(
[new FakeImportHandler(imported)],
new FakeStudents(stored),
new FakeGroups([]),
new FakeMemberships([]),
new SchoolYearService());
private static ImportFile File() => new("students.csv", "test"u8.ToArray());
private sealed class FakeImportHandler(IReadOnlyList<ImportedStudent> imported)
: IImportHandler<ImportedStudent>
{
public ImportFormatId FormatId { get; } = new("test.students");
public string DisplayName => "Testformat";
public IReadOnlyCollection<string> SupportedExtensions { get; } = [".csv"];
public ValueTask<ImportDetection> DetectAsync(
ImportFile file,
CancellationToken cancellationToken = default) =>
ValueTask.FromResult(ImportDetection.Match(100));
public ValueTask<ImportParseResult<ImportedStudent>> ParseAsync(
ImportFile file,
CancellationToken cancellationToken = default) =>
ValueTask.FromResult(new ImportParseResult<ImportedStudent>(imported));
}
}