diff --git a/src/core/StatsSchemas.ts b/src/core/StatsSchemas.ts index e6e6fa519..03d151ad2 100644 --- a/src/core/StatsSchemas.ts +++ b/src/core/StatsSchemas.ts @@ -98,10 +98,10 @@ export const PlayerStatsSchema = z .object({ attacks: AtLeastOneNumberSchema.optional(), betrayals: BigIntStringSchema.optional(), - boats: z.record(BoatUnitSchema, AtLeastOneNumberSchema).optional(), - bombs: z.record(BombUnitSchema, AtLeastOneNumberSchema).optional(), + boats: z.partialRecord(BoatUnitSchema, AtLeastOneNumberSchema).optional(), + bombs: z.partialRecord(BombUnitSchema, AtLeastOneNumberSchema).optional(), gold: AtLeastOneNumberSchema.optional(), - units: z.record(OtherUnitSchema, AtLeastOneNumberSchema).optional(), + units: z.partialRecord(OtherUnitSchema, AtLeastOneNumberSchema).optional(), }) .optional(); export type PlayerStats = z.infer; diff --git a/tests/StatsSchema.test.ts b/tests/StatsSchema.test.ts new file mode 100644 index 000000000..8b8f6b5dd --- /dev/null +++ b/tests/StatsSchema.test.ts @@ -0,0 +1,48 @@ +import { PlayerStatsSchema } from "../src/core/StatsSchemas"; + +function testPlayerSchema( + json: string, + expectSuccess = true, + expectThrow = false, +): void { + const parse = () => { + const raw = JSON.parse(json); + const result = PlayerStatsSchema.safeParse(raw); + return result.success; + }; + + if (expectSuccess) { + // Expect success + expect(parse()).toBeTruthy(); + } else if (!expectThrow) { + // Expect failure + expect(parse()).toBeFalsy(); + } else { + // Expect throw + expect(parse).toThrow(); + } +} + +describe("StatsSchema", () => { + test("Parse empty", () => { + testPlayerSchema("{}"); + }); + + test("Parse partial", () => { + testPlayerSchema('{"units":{"port":["0","0","0","1"]}}'); + }); + + test("Parse invalid", () => { + testPlayerSchema("[]", false); + testPlayerSchema("null", false); + testPlayerSchema('"null"', false); + testPlayerSchema('"undefined"', false); + }); + + test("Parse failure", () => { + testPlayerSchema("", false, true); + testPlayerSchema("undefined", false, true); + testPlayerSchema("{", false, true); + testPlayerSchema("{}}", false, true); + }); +});