Implement per-school save functionality by introducing a dedicated save directory and updating the school management system to support loading and saving school states. Revise documentation to reflect these changes, including updates to the architecture and design documents, and enhance the API for reloading schools from disk. Update tests to ensure proper functionality of the new save and reload features.
This commit is contained in:
@@ -5,7 +5,6 @@ namespace HSchool.AppHost.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Talks to the realtime channel the way the browser does: binary frames over a WebSocket.
|
||||
/// The clock only moves while a connection has the school open, which is what these assert.
|
||||
/// </summary>
|
||||
[Collection(AppHostCollection.Name)]
|
||||
public class GameSocketTests(AppHostFixture fixture)
|
||||
@@ -208,6 +207,58 @@ public class GameSocketTests(AppHostFixture fixture)
|
||||
Assert.Equal(999999, gone.SchoolId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task PausingOneSchool_DoesNotStopAnother()
|
||||
{
|
||||
using var client = fixture.App.CreateHttpClient("server");
|
||||
await SchoolApiTests.ResetAsync(client);
|
||||
var paused = await SchoolApiTests.CreateAsync(client, "На паузе", StartDate);
|
||||
var running = await SchoolApiTests.CreateAsync(client, "Идёт дальше", StartDate);
|
||||
|
||||
using var socket = await OpenSchoolAsync(paused.Id);
|
||||
await ReceiveClockAsync(socket);
|
||||
await SendAsync(socket, buffer =>
|
||||
ProtocolCodec.WriteSetRunning(buffer, new ClientSetRunningMessage(Running: false)));
|
||||
await ReceiveClockWhereAsync(socket, clock => !clock.Running);
|
||||
|
||||
var pausedAt = await FindAsync(client, paused.Id);
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), TestContext.Current.CancellationToken);
|
||||
var pausedLater = await FindAsync(client, paused.Id);
|
||||
var runningLater = await FindAsync(client, running.Id);
|
||||
|
||||
Assert.False(pausedLater.Running);
|
||||
Assert.Equal(pausedAt.GameTime, pausedLater.GameTime);
|
||||
Assert.True(runningLater.Running);
|
||||
Assert.True(runningLater.GameTime > running.GameTime, "Pausing one school stopped the other.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReloadFromDisk_RestoresAPausedClock()
|
||||
{
|
||||
using var client = fixture.App.CreateHttpClient("server");
|
||||
await SchoolApiTests.ResetAsync(client);
|
||||
var school = await SchoolApiTests.CreateAsync(client, "Снимок паузы", StartDate);
|
||||
|
||||
using (var socket = await OpenSchoolAsync(school.Id))
|
||||
{
|
||||
await ReceiveClockAsync(socket);
|
||||
await SendAsync(socket, buffer =>
|
||||
ProtocolCodec.WriteSetRunning(buffer, new ClientSetRunningMessage(Running: false)));
|
||||
await ReceiveClockWhereAsync(socket, clock => !clock.Running);
|
||||
}
|
||||
|
||||
var paused = await FindAsync(client, school.Id);
|
||||
|
||||
using var reload = await client.PostAsync("/api/dev/reload-schools", content: null, TestContext.Current.CancellationToken);
|
||||
reload.EnsureSuccessStatusCode();
|
||||
|
||||
var restored = await FindAsync(client, school.Id);
|
||||
Assert.Equal(paused.Name, restored.Name);
|
||||
Assert.False(restored.Running);
|
||||
Assert.Equal(paused.GameTime, restored.GameTime);
|
||||
Assert.Equal(paused.SpeedIndex, restored.SpeedIndex);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Ping_IsAnsweredWithTheSameTimestamp()
|
||||
{
|
||||
|
||||
@@ -145,6 +145,21 @@ public class SchoolApiTests(AppHostFixture fixture)
|
||||
Assert.True(status.Tick > 0, "The loop should have ticked by now.");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ReloadFromDisk_RestoresCreatedSchools()
|
||||
{
|
||||
using var client = fixture.App.CreateHttpClient("server");
|
||||
await ResetAsync(client);
|
||||
var created = await CreateAsync(client, "После перезагрузки", ExpectedDefaultStart);
|
||||
|
||||
using var reload = await client.PostAsync("/api/dev/reload-schools", content: null, TestContext.Current.CancellationToken);
|
||||
reload.EnsureSuccessStatusCode();
|
||||
|
||||
var restored = (await GetSchoolsAsync(client)).Schools.Single(school => school.Id == created.Id);
|
||||
Assert.Equal(created.Name, restored.Name);
|
||||
Assert.True(restored.Running);
|
||||
}
|
||||
|
||||
internal static async Task ResetAsync(HttpClient client)
|
||||
{
|
||||
var state = await GetSchoolsAsync(client);
|
||||
|
||||
Reference in New Issue
Block a user