using System.Net; using System.Net.Http.Json; using System.Text.Json; namespace HSchool.AppHost.Tests; [Collection(AppHostCollection.Name)] public class GradebookApiTests(AppHostFixture fixture) { private static readonly DateTime Start = new(2012, 4, 3, 6, 0, 0, DateTimeKind.Utc); [Fact] public async Task PostAttendanceAndMarks_AreNotAccepted() { using var client = fixture.App.CreateHttpClient("server"); await SchoolApiTests.ResetAsync(client); var school = await SchoolApiTests.CreateAsync(client, "Журнал API", Start, seed: 75); var page = await client.GetFromJsonAsync( $"/api/schools/{school.Id}/people?role=student&pageSize=1", TestContext.Current.CancellationToken); Assert.NotNull(page); Assert.NotEmpty(page.People); var personId = page.People[0].Id; using var markPost = await client.PostAsJsonAsync( $"/api/schools/{school.Id}/people/{personId}/marks", new { subject = "Mathematics", value = 5, period = 1 }, TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, markPost.StatusCode); using var markPut = await client.PutAsJsonAsync( $"/api/schools/{school.Id}/people/{personId}/marks", new { subject = "Mathematics", value = 5, period = 1 }, TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, markPut.StatusCode); using var attendancePost = await client.PostAsJsonAsync( $"/api/schools/{school.Id}/people/{personId}/attendance", new { subject = "Mathematics", status = "absent", period = 1 }, TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, attendancePost.StatusCode); using var attendancePut = await client.PutAsJsonAsync( $"/api/schools/{school.Id}/people/{personId}/attendance", new { subject = "Mathematics", status = "present", period = 1 }, TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, attendancePut.StatusCode); using var summonPost = await client.PostAsJsonAsync( $"/api/schools/{school.Id}/people/{personId}/summon", new { reason = "mark", value = 2 }, TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, summonPost.StatusCode); using var summonForMark = await client.PostAsJsonAsync( $"/api/schools/{school.Id}/people/{personId}/summon-for-mark", new { value = 2 }, TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, summonForMark.StatusCode); } [Fact] public async Task PeopleList_DoesNotIncludeGradebookFields() { using var client = fixture.App.CreateHttpClient("server"); await SchoolApiTests.ResetAsync(client); var school = await SchoolApiTests.CreateAsync(client, "Список без журнала", Start, seed: 75); using var response = await client.GetAsync( $"/api/schools/{school.Id}/people?role=student&pageSize=1&lang=ru", TestContext.Current.CancellationToken); response.EnsureSuccessStatusCode(); await using var stream = await response.Content.ReadAsStreamAsync(TestContext.Current.CancellationToken); using var doc = await JsonDocument.ParseAsync(stream, cancellationToken: TestContext.Current.CancellationToken); var person = doc.RootElement.GetProperty("people")[0]; Assert.False(person.TryGetProperty("lessonMarks", out _)); Assert.False(person.TryGetProperty("attendance", out _)); Assert.False(person.TryGetProperty("averageMark", out _)); } [Fact] public async Task PersonCard_IncludesEmptyGradebookArrays() { using var client = fixture.App.CreateHttpClient("server"); await SchoolApiTests.ResetAsync(client); var school = await SchoolApiTests.CreateAsync(client, "Карточка журнал", Start, seed: 75); var page = await client.GetFromJsonAsync( $"/api/schools/{school.Id}/people?role=student&pageSize=1", TestContext.Current.CancellationToken); Assert.NotNull(page); var personId = page.People[0].Id; var card = await client.GetFromJsonAsync( $"/api/schools/{school.Id}/people/{Uri.EscapeDataString(personId)}?lang=ru", TestContext.Current.CancellationToken); Assert.NotNull(card); Assert.NotNull(card!.LessonMarks); Assert.NotNull(card.Attendance); Assert.Empty(card.LessonMarks); Assert.Empty(card.Attendance); } [Fact] public async Task Guest_CanReadPersonCardGradebook_ButNotWrite() { using var owner = fixture.App.CreateHttpClient("server"); await SchoolApiTests.ResetAsync(owner); var school = await SchoolApiTests.CreateAsync(owner, "Гость журнал", Start, seed: 75); var page = await owner.GetFromJsonAsync( $"/api/schools/{school.Id}/people?role=student&pageSize=1", TestContext.Current.CancellationToken); Assert.NotNull(page); var personId = page.People[0].Id; using var guest = await SchoolApiTests.CreateIsolatedClientAsync(fixture.App, "GradebookGuest"); var card = await guest.GetFromJsonAsync( $"/api/schools/{school.Id}/people/{Uri.EscapeDataString(personId)}?lang=ru", TestContext.Current.CancellationToken); Assert.NotNull(card); Assert.NotNull(card!.LessonMarks); Assert.NotNull(card.Attendance); using var write = await guest.PostAsJsonAsync( $"/api/schools/{school.Id}/people/{personId}/marks", new { subject = "Mathematics", value = 5, period = 1 }, TestContext.Current.CancellationToken); Assert.Equal(HttpStatusCode.NotFound, write.StatusCode); } private sealed record PeoplePage(IReadOnlyList People); private sealed record PersonRow(string Id); private sealed record PersonCardDto( string Id, IReadOnlyList LessonMarks, IReadOnlyList Attendance); }