mirror of
https://github.com/JogmansonReal/Radicade.git
synced 2026-10-25 23:18:56 -07:00
Radicade Public Code
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using RadicadeServer.API;
|
||||
using RadicadeServer.DB;
|
||||
using RadicadeServer.RecNet.Config;
|
||||
using RadicadeServer.RecNet.Enums;
|
||||
using RadicadeServer.RecNet.VersionCheck;
|
||||
using Xunit;
|
||||
|
||||
namespace RadicadeServer.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// A Game Update is not a notification. The client registers no handler for 26 or 27 - and none for
|
||||
/// ModerationUpdateRequired (21) either - so a frame under any of those ids is dropped in silence.
|
||||
/// What the client does read is its REST version check, api/versioncheck/v4, and that answer is what
|
||||
/// raises its own "Update Required" screen. So a published Game Update row has to change this
|
||||
/// answer, and these tests pin both halves: the status flip, and the no-game-update case staying
|
||||
/// exactly the shape it has always been.
|
||||
/// </summary>
|
||||
public class GameUpdateVersionCheckTests
|
||||
{
|
||||
private const string Live = "[{\"id\":1,\"type\":\"Game Update\"}]";
|
||||
private const string Expired = "[{\"id\":1,\"type\":\"Game Update\",\"expires_at\":\"2000-01-01T00:00:00Z\"}]";
|
||||
private const string Future = "[{\"id\":1,\"type\":\"Game Update\",\"expires_at\":\"2999-01-01T00:00:00Z\"}]";
|
||||
private const string Regular = "[{\"id\":1,\"type\":\"Regular Announcement\"}]";
|
||||
|
||||
private static RecDBContext NewDb() => new(
|
||||
TestDbOptions.Create()
|
||||
.UseInMemoryDatabase(Guid.NewGuid().ToString())
|
||||
.Options);
|
||||
|
||||
[Fact]
|
||||
public void NoAnnouncementConfigLeavesTheVersionCheckAlone()
|
||||
{
|
||||
var result = GameUpdateVersionCheck.Resolve(null, DateTime.UtcNow);
|
||||
|
||||
Assert.Equal(VersionCheckStatus.ValidForPlay, result.VersionStatus);
|
||||
Assert.Equal(0, result.UpdateNotificationStage);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("[]")]
|
||||
[InlineData(Regular)]
|
||||
[InlineData("not json at all")]
|
||||
[InlineData("{\"type\":\"Game Update\"}")]
|
||||
[InlineData(Expired)]
|
||||
public void AnythingThatIsNotALiveGameUpdateKeepsPlayingAllowed(string json)
|
||||
{
|
||||
var result = GameUpdateVersionCheck.Resolve(json, DateTime.UtcNow);
|
||||
|
||||
Assert.Equal(VersionCheckStatus.ValidForPlay, result.VersionStatus);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(Live)]
|
||||
[InlineData(Future)]
|
||||
[InlineData("[{\"id\":1,\"type\":\"game update\"}]")]
|
||||
[InlineData("[{\"id\":1,\"type\":\"Regular Announcement\"},{\"id\":2,\"type\":\"Game Update\"}]")]
|
||||
public void ALiveGameUpdateAsksTheClientToUpdate(string json)
|
||||
{
|
||||
var result = GameUpdateVersionCheck.Resolve(json, DateTime.UtcNow);
|
||||
|
||||
Assert.Equal(VersionCheckStatus.UpdateRequired, result.VersionStatus);
|
||||
// Not 0: 0 is what a healthy boot already gets, so it is the one value that could also mean
|
||||
// "nothing to show".
|
||||
Assert.True(result.UpdateNotificationStage > 0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TheVersionCheckAnswerCarriesUpdateRequiredWhileAGameUpdateIsLive()
|
||||
{
|
||||
using var db = NewDb();
|
||||
db.ServerConfig.Add(new ServerConfigVal(GameUpdateVersionCheck.AnnouncementConfigKey, Live));
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var api = new VersionCheckAPI(db);
|
||||
var ok = Assert.IsType<OkObjectResult>(await api.Get("20230831", "20230831"));
|
||||
using var doc = JsonDocument.Parse(JsonSerializer.Serialize(ok.Value));
|
||||
|
||||
Assert.Equal((int)VersionCheckStatus.UpdateRequired, doc.RootElement.GetProperty("VersionStatus").GetInt32());
|
||||
Assert.True(doc.RootElement.GetProperty("UpdateNotificationStage").GetInt32() > 0);
|
||||
Assert.Equal(0, doc.RootElement.GetProperty("ValidVersion").GetInt32());
|
||||
Assert.False(doc.RootElement.GetProperty("IsVersionIslanded").GetBoolean());
|
||||
Assert.False(doc.RootElement.GetProperty("IsCrossPlayDisabled").GetBoolean());
|
||||
|
||||
// The key set is what the client's strict lookups depend on: ValidVersion must be present or
|
||||
// the client aborts boot. It must not grow or shrink either.
|
||||
Assert.Equal(5, doc.RootElement.EnumerateObject().Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TheVersionCheckAnswerIsUnchangedWhenThereIsNoGameUpdate()
|
||||
{
|
||||
using var db = NewDb();
|
||||
db.ServerConfig.Add(new ServerConfigVal(GameUpdateVersionCheck.AnnouncementConfigKey, Regular));
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var api = new VersionCheckAPI(db);
|
||||
var ok = Assert.IsType<OkObjectResult>(await api.Get("20230831", "20230831"));
|
||||
using var doc = JsonDocument.Parse(JsonSerializer.Serialize(ok.Value));
|
||||
|
||||
Assert.Equal(0, doc.RootElement.GetProperty("VersionStatus").GetInt32());
|
||||
Assert.Equal(0, doc.RootElement.GetProperty("UpdateNotificationStage").GetInt32());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TheLiveRecheckFrameGoesOutUnderTheNameTheClientRegisters()
|
||||
|
||||
{
|
||||
// The one game-update-relevant key in the client's handler table; 26 and 27 are not in it.
|
||||
Assert.Equal("AppVersionUpdate", GameUpdateVersionCheck.AppVersionUpdateNotificationId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user