Today's history is a paged HTTP log on the worker, not on the card or in people.json. Co-authored-by: Cursor <cursoragent@cursor.com>
107 lines
4.3 KiB
C#
107 lines
4.3 KiB
C#
using System.Net.Http.Json;
|
|
using System.Text.Json;
|
|
|
|
namespace HSchool.AppHost.Tests;
|
|
|
|
[Collection(AppHostCollection.Name)]
|
|
public class PersonLogApiTests(AppHostFixture fixture)
|
|
{
|
|
private static readonly DateTime Start = new(2012, 4, 3, 6, 0, 0, DateTimeKind.Utc);
|
|
|
|
[Fact]
|
|
public async Task Card_DoesNotIncludeTheLog()
|
|
{
|
|
using var client = fixture.App.CreateHttpClient("server");
|
|
await SchoolApiTests.ResetAsync(client);
|
|
var school = await SchoolApiTests.CreateAsync(client, "Карточка без лога", Start, seed: 36);
|
|
|
|
var page = await GetPeopleAsync(client, school.Id);
|
|
var id = page.People[0].Id;
|
|
using var response = await client.GetAsync(
|
|
$"/api/schools/{school.Id}/people/{Uri.EscapeDataString(id)}",
|
|
TestContext.Current.CancellationToken);
|
|
response.EnsureSuccessStatusCode();
|
|
using var json = JsonDocument.Parse(await response.Content.ReadAsStringAsync(TestContext.Current.CancellationToken));
|
|
Assert.False(json.RootElement.TryGetProperty("entries", out _));
|
|
Assert.False(json.RootElement.TryGetProperty("log", out _));
|
|
|
|
var log = await client.GetFromJsonAsync<PersonLogResponse>(
|
|
$"/api/schools/{school.Id}/people/{Uri.EscapeDataString(id)}/log?pageSize=20",
|
|
TestContext.Current.CancellationToken);
|
|
Assert.NotNull(log);
|
|
Assert.Equal(1, log.Page);
|
|
Assert.Equal(20, log.PageSize);
|
|
Assert.True(log.Total >= 0);
|
|
Assert.NotNull(log.Entries);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Log_UnknownPerson_IsNotFound()
|
|
{
|
|
using var client = fixture.App.CreateHttpClient("server");
|
|
await SchoolApiTests.ResetAsync(client);
|
|
var school = await SchoolApiTests.CreateAsync(client, "Лог 404", Start, seed: 36);
|
|
|
|
using var response = await client.GetAsync(
|
|
$"/api/schools/{school.Id}/people/nobody/log",
|
|
TestContext.Current.CancellationToken);
|
|
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
|
|
Assert.Equal("unknown-person", await ProblemCodeAsync(response));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Log_PagesDoNotOverlap()
|
|
{
|
|
using var client = fixture.App.CreateHttpClient("server");
|
|
await SchoolApiTests.ResetAsync(client);
|
|
var school = await SchoolApiTests.CreateAsync(client, "Лог страницы", Start, seed: 36);
|
|
var page = await GetPeopleAsync(client, school.Id);
|
|
var id = page.People[0].Id;
|
|
|
|
var first = await GetLogAsync(client, school.Id, id, "page=1&pageSize=10&dir=asc");
|
|
var second = await GetLogAsync(client, school.Id, id, "page=2&pageSize=10&dir=asc");
|
|
Assert.Equal(first.Total, second.Total);
|
|
Assert.Empty(first.Entries.Select(row => (row.Time, row.Type, row.ThingDef))
|
|
.Intersect(second.Entries.Select(row => (row.Time, row.Type, row.ThingDef))));
|
|
}
|
|
|
|
private static async Task<PeopleList> GetPeopleAsync(HttpClient client, int schoolId)
|
|
{
|
|
var page = await client.GetFromJsonAsync<PeopleList>(
|
|
$"/api/schools/{schoolId}/people?pageSize=10",
|
|
TestContext.Current.CancellationToken);
|
|
Assert.NotNull(page);
|
|
Assert.NotEmpty(page.People);
|
|
return page;
|
|
}
|
|
|
|
private static async Task<PersonLogResponse> GetLogAsync(HttpClient client, int schoolId, string personId, string query)
|
|
{
|
|
var page = await client.GetFromJsonAsync<PersonLogResponse>(
|
|
$"/api/schools/{schoolId}/people/{Uri.EscapeDataString(personId)}/log?{query}",
|
|
TestContext.Current.CancellationToken);
|
|
Assert.NotNull(page);
|
|
return page;
|
|
}
|
|
|
|
private static async Task<string?> ProblemCodeAsync(HttpResponseMessage response)
|
|
{
|
|
var problem = await response.Content.ReadFromJsonAsync<ProblemResponse>(TestContext.Current.CancellationToken);
|
|
return problem?.Code;
|
|
}
|
|
|
|
private sealed record ProblemResponse(string? Code);
|
|
|
|
private sealed record PeopleList(IReadOnlyList<PersonRow> People);
|
|
|
|
private sealed record PersonRow(string Id);
|
|
|
|
private sealed record PersonLogResponse(
|
|
int Total,
|
|
int Page,
|
|
int PageSize,
|
|
IReadOnlyList<PersonLogEntry> Entries);
|
|
|
|
private sealed record PersonLogEntry(DateTime Time, string Type, string Label, string? ThingDef);
|
|
}
|