diff --git a/docs/phases/10-craft/59-dump-nodes.md b/docs/phases/10-craft/59-dump-nodes.md index 43e6ebe..0292ec7 100644 --- a/docs/phases/10-craft/59-dump-nodes.md +++ b/docs/phases/10-craft/59-dump-nodes.md @@ -11,17 +11,17 @@ ## Задачи -- [ ] `Dump_ReturnsPeopleNodesAndTimetable`: нанять, **включить** часы, дождаться человека с +- [x] `Dump_ReturnsPeopleNodesAndTimetable`: нанять, **включить** часы, дождаться человека с `NodeId`, затем дамп. Не ждать людей на паузе -- [ ] Нужды по-прежнему не пустые у всех в выборке, но явка — отдельный assert -- [ ] Урок математики в дампе — как сейчас +- [x] Нужды по-прежнему не пустые у всех в выборке, но явка — отдельный assert +- [x] Урок математики в дампе — как сейчас ## Тесты, без которых фаза не закрыта -- [ ] После найма математика и хода часов дамп содержит человека с непустым `NodeId` -- [ ] Все люди в дампе с id, именем и непустым `Needs` -- [ ] В `dump.Lessons` есть Mathematics -- [ ] Неизвестный id — по-прежнему 404 `unknown-school` +- [x] После найма математика и хода часов дамп содержит человека с непустым `NodeId` +- [x] Все люди в дампе с id, именем и непустым `Needs` +- [x] В `dump.Lessons` есть Mathematics +- [x] Неизвестный id — по-прежнему 404 `unknown-school` ## Критерий готовности diff --git a/docs/phases/10-craft/README.md b/docs/phases/10-craft/README.md index ef4b1d4..30c9b99 100644 --- a/docs/phases/10-craft/README.md +++ b/docs/phases/10-craft/README.md @@ -28,4 +28,4 @@ | Фаза | Статус | Зачем | | --- | --- | --- | -| [59. Дамп проверяет узлы](59-dump-nodes.md) | 🔄 | После найма в дампе есть `NodeId` | +| [59. Дамп проверяет узлы](59-dump-nodes.md) | ✅ | После найма в дампе есть `NodeId` | diff --git a/tests/HSchool.AppHost.Tests/ServiceabilityTests.cs b/tests/HSchool.AppHost.Tests/ServiceabilityTests.cs index dc90d48..3db08c6 100644 --- a/tests/HSchool.AppHost.Tests/ServiceabilityTests.cs +++ b/tests/HSchool.AppHost.Tests/ServiceabilityTests.cs @@ -89,16 +89,17 @@ public class ServiceabilityTests(AppHostFixture fixture) using var client = fixture.App.CreateHttpClient("server"); await SchoolApiTests.ResetAsync(client); var school = await SchoolApiTests.CreateAsync(client, "Дамп", TuesdayMorning); + // Create starts the clock. Presence still goes out while paused (often empty); waiting + // for people then hangs. Hire, keep time moving, then dump. + Assert.True(school.Running); await HireMathAsync(client, school.Id); - var dump = await client.GetFromJsonAsync( - $"/api/dev/schools/{school.Id}/dump", - TestContext.Current.CancellationToken); + var dump = await WaitUntilSomeoneIsOnANodeAsync(client, school.Id); - Assert.NotNull(dump); Assert.Equal(school.Id, dump.Id); + Assert.True(dump.Running); Assert.NotEmpty(dump.People); - Assert.Contains(dump.People, person => person.NodeId is not null || person.Needs.Count > 0); + Assert.Contains(dump.People, person => !string.IsNullOrWhiteSpace(person.NodeId)); Assert.All(dump.People, person => { Assert.False(string.IsNullOrWhiteSpace(person.Id)); @@ -119,6 +120,36 @@ public class ServiceabilityTests(AppHostFixture fixture) Assert.Equal("unknown-school", await ProblemCodeAsync(response)); } + /// + /// Polls the dump while the clock is moving. A paused school would keep answering with empty + /// occupancy; fail immediately instead of waiting that out. + /// + private static async Task WaitUntilSomeoneIsOnANodeAsync(HttpClient client, int schoolId) + { + SchoolDumpResponse? dump = null; + for (var attempt = 0; attempt < 120; attempt++) + { + dump = await client.GetFromJsonAsync( + $"/api/dev/schools/{schoolId}/dump", + TestContext.Current.CancellationToken); + Assert.NotNull(dump); + if (!dump.Running) + { + Assert.Fail("Clock is paused; occupancy stays empty and this wait would hang."); + } + + if (dump.People.Any(person => !string.IsNullOrWhiteSpace(person.NodeId))) + { + return dump; + } + + await Task.Delay(250, TestContext.Current.CancellationToken); + } + + throw new InvalidOperationException( + $"Nobody had a NodeId after hire with the clock running at {dump?.GameTime:HH:mm}."); + } + private static async Task HireMathAsync(HttpClient client, int schoolId) { var staffing = await client.GetFromJsonAsync(