Files
ft/CodexOutput/upserver/KVGameLoadTests/ClubPackSchemaTests.cs

60 lines
3.7 KiB
C#

using game.PlayerDataStorage;
static partial class Tests
{
static async Task RunClubPackSchemaTests()
{
await Run("M14-club-three-load-fields-only", () =>
{
var raw = new Dictionary<string,string> {
["ClubSignin"] = "2026-09-23T00:00:00.0000000Z",
["LureDonateData"] = "{\"DonateCountTime\":\"2026-09-22T00:00:00.0000000Z\",\"ClubLureDonateCount\":7,\"ClubLureRequestCDEnd\":\"2026-09-24T00:00:00.0000000Z\"}",
["IsOpenClubRed"] = ""
};
var state = PlayerKVSaveSchema.DecodeClub(raw,SchemaSnapshot(),new());
Check(state.SignTime.Value.Day == 23 && state.DonateTime.Day == 22 && state.DonateCount == 7 && state.RequestEnd.Day == 24 && !state.OpenRed,"all three load states");
var missing = PlayerKVSaveSchema.DecodeClub(new Dictionary<string,string>(),SchemaSnapshot(),new());
Check(missing.SignTime == null && missing.DonateTime == default && missing.DonateCount == 0 && missing.RequestEnd == default && missing.OpenRed,"missing exact zero state");
raw["ClubSignin"] = "";
Check(PlayerKVSaveSchema.DecodeClub(raw,SchemaSnapshot(),new()).SignTime == null,"empty signin supported");
foreach (var key in raw.Keys.ToArray())
{
var bad = new Dictionary<string,string>(raw) { [key] = null };
Check(PlayerKVSaveSchema.DecodeClub(bad,SchemaSnapshot(),new()) == null,"present null rejected");
}
foreach (var bad in new[] { "null", "{}", "{\"DonateCountTime\":0,\"ClubLureDonateCount\":1,\"ClubLureRequestCDEnd\":0}" })
{
raw["LureDonateData"] = bad;
Check(PlayerKVSaveSchema.DecodeClub(raw,SchemaSnapshot(),new()) == null,"bad donation DTO rejected");
}
raw = new() { ["ClubSignin"] = "03/04/2026" };
var errors = new PlayerKVSchemaDiagnostics();
Check(PlayerKVSaveSchema.DecodeClub(raw,SchemaSnapshot("en-GB"),errors) == null &&
errors.Count(14,PlayerKVSchemaError.UnsupportedSchema) == 1,"ambiguous date rejected");
return Task.CompletedTask;
});
await Run("M28-two-independent-four-slot-packs", () =>
{
var raw = new Dictionary<string,string> { ["ThanksGivingPackData"] = "1,2,3,4", ["ThanksGivingPackMigrationData"] = "5,6,7,8" };
foreach (bool migration in new[] { false,true })
{
var state = PlayerKVSaveSchema.DecodeProgressPack(raw,migration,new());
int offset = migration ? 4 : 0;
Check(state.IsPresent && state.EventId == 1 + offset && state.RedirectId == 2 + offset &&
state.TokenProgress == 3 + offset && state.ChainProgress == 4 + offset,"complete four slots");
var key = migration ? "ThanksGivingPackMigrationData" : "ThanksGivingPackData";
foreach (var bad in new[] { "", "null", "1,2,3", "1,2,3,4,5", "1,2,x,4", "1,2,3,2147483648", null })
{
var invalid = new Dictionary<string,string>(raw) { [key] = bad };
Check(PlayerKVSaveSchema.DecodeProgressPack(invalid,migration,new()) == null,"bad present pack rejected");
}
var absent = PlayerKVSaveSchema.DecodeProgressPack(new Dictionary<string,string>(),migration,new());
Check(!absent.IsPresent,"each missing is explicit");
var zero = PlayerKVSaveSchema.DecodeProgressPack(new Dictionary<string,string> { [key] = "0,0,0,0" },migration,new());
Check(zero.IsPresent && zero.EventId == 0 && zero.RedirectId == 0,"zero present not missing");
}
return Task.CompletedTask;
});
}
}