112 lines
5.0 KiB
C#
112 lines
5.0 KiB
C#
using System.Net;
|
|
using System.Text;
|
|
using LehrerApp.Core.Models;
|
|
using LehrerApp.Desktop.Services;
|
|
using LehrerApp.Desktop.ViewModels.Planning;
|
|
using Xunit;
|
|
|
|
namespace LehrerApp.Desktop.Tests;
|
|
|
|
public sealed class WebUntisTimetableImportTests
|
|
{
|
|
[Fact]
|
|
public async Task Load_IsReadOnly_AndSaveUpdatesOnlyLessonIdsByDefault()
|
|
{
|
|
await using var fixture = new Fixture();
|
|
await fixture.Vm.LoadCommand.ExecuteAsync(null);
|
|
Assert.Null(fixture.Group.WebUntisLessonId);
|
|
Assert.Null(fixture.Settings.TeacherUntisId);
|
|
Assert.Single(fixture.Slots.GetAll());
|
|
Assert.Equal(38926, Assert.Single(fixture.Vm.Rows).LessonId);
|
|
fixture.Vm.SaveCommand.Execute(null);
|
|
Assert.True(fixture.Vm.Saved);
|
|
Assert.Equal(38926, fixture.Group.WebUntisLessonId);
|
|
Assert.Equal(DayOfWeek.Friday, Assert.Single(fixture.Slots.GetAll()).Weekday);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(false, 2)]
|
|
[InlineData(true, 1)]
|
|
public async Task TimetableUpdates_OnlyRemoveOldSlotsWhenExplicitlySelected(bool replace, int expected)
|
|
{
|
|
await using var fixture = new Fixture();
|
|
await fixture.Vm.LoadCommand.ExecuteAsync(null);
|
|
fixture.Vm.UpdateLessonIds = false;
|
|
fixture.Vm.UpdateTimetable = true;
|
|
fixture.Vm.ReplaceTimetable = replace;
|
|
fixture.Vm.SaveCommand.Execute(null);
|
|
Assert.True(fixture.Vm.Saved);
|
|
Assert.Null(fixture.Group.WebUntisLessonId);
|
|
Assert.Equal(expected, fixture.Slots.GetAll().Count);
|
|
Assert.Contains(fixture.Slots.GetAll(), slot => slot.Weekday == DayOfWeek.Monday);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ConflictingLessonIds_BlockAllChanges_UntilExcluded()
|
|
{
|
|
await using var fixture = new Fixture();
|
|
await fixture.Vm.LoadCommand.ExecuteAsync(null);
|
|
fixture.Vm.Rows.Add(new WebUntisTimetableRow
|
|
{
|
|
Weekday = DayOfWeek.Tuesday, PeriodNumber = 1, TimeLabel = "07:50", UntisLabel = "7a",
|
|
SuggestedGroupName = "7a", LessonId = 999, SelectedGroup = fixture.Vm.Rows[0].SelectedGroup,
|
|
});
|
|
fixture.Vm.UpdateTimetable = true;
|
|
fixture.Vm.SaveCommand.Execute(null);
|
|
Assert.False(fixture.Vm.Saved);
|
|
Assert.Null(fixture.Group.WebUntisLessonId);
|
|
Assert.Single(fixture.Slots.GetAll());
|
|
Assert.Contains("Mehrere Unterrichtsnummern", fixture.Vm.Status);
|
|
fixture.Vm.Rows[1].ApplyLessonId = false;
|
|
fixture.Vm.SaveCommand.Execute(null);
|
|
Assert.True(fixture.Vm.Saved);
|
|
Assert.Equal(38926, fixture.Group.WebUntisLessonId);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SaveWithoutLoadedWeek_DoesNotClearTimetable()
|
|
{
|
|
await using var fixture = new Fixture();
|
|
fixture.Vm.UpdateTimetable = fixture.Vm.ReplaceTimetable = true;
|
|
fixture.Vm.SaveCommand.Execute(null);
|
|
Assert.False(fixture.Vm.Saved);
|
|
Assert.Single(fixture.Slots.GetAll());
|
|
}
|
|
|
|
private sealed class Fixture : IAsyncDisposable
|
|
{
|
|
public LearningGroup Group { get; } = new() { Name = "7a" };
|
|
public FakeTimetableSlots Slots { get; } = new();
|
|
public WebUntisSettingsService Settings { get; } = TestSupport.BuildWebUntisSettingsService();
|
|
private readonly WebUntisIntegrationService _service;
|
|
public WebUntisTimetableImportViewModel Vm { get; }
|
|
public Fixture()
|
|
{
|
|
Settings.SetApiCredentials(new("school", "example.webuntis.com", "teacher", "password"));
|
|
_service = new(new HttpClient(new Handler()), Settings);
|
|
Slots.Add(new() { Weekday = DayOfWeek.Friday, PeriodNumber = 4, GroupId = Group.Id });
|
|
Vm = new(_service, Settings, Slots, new FakeGroups([Group]))
|
|
{
|
|
SelectedTeacher = new(89, "Teacher", null, null, null, true, []),
|
|
WeekDate = new DateTimeOffset(2026, 10, 5, 0, 0, 0, TimeSpan.Zero),
|
|
};
|
|
}
|
|
public ValueTask DisposeAsync() => _service.DisposeAsync();
|
|
}
|
|
|
|
private sealed class Handler : HttpMessageHandler
|
|
{
|
|
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken token)
|
|
{
|
|
var body = request.Content is null ? "" : await request.Content.ReadAsStringAsync(token);
|
|
var json = request.RequestUri!.AbsolutePath.Contains("weekly/data")
|
|
? """{"data":{"result":{"data":{"elementPeriods":{"89":[{"id":2013854,"lessonId":38926},{"id":2013854,"lessonId":38926}]}}}}}"""
|
|
: body.Contains("authenticate") ? """{"result":{"sessionId":"s"}}"""
|
|
: body.Contains("getTimetable") ? """{"result":[{"id":2013854,"date":20261005,"startTime":750,"endTime":835,"kl":[{"id":4,"name":"7a"}],"te":[],"su":[],"ro":[]}]}"""
|
|
: body.Contains("getTimegridUnits") ? """{"result":[{"day":1,"timeUnits":[{"name":"1","startTime":750,"endTime":835}]}]}"""
|
|
: """{"result":{}}""";
|
|
return new(HttpStatusCode.OK) { Content = new StringContent(json, Encoding.UTF8, "application/json") };
|
|
}
|
|
}
|
|
}
|