mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 13:40:46 +00:00
bug: StatsSchema zod validation error (#1267)
## Description: Fix a bug in the StatsSchema zod validation logic. In zod v4, the `record` function has been renamed to `partialRecord`, and the new `record` function requires that all keys are present. We intentionally omit empty stats, so this causes a zod validation error. Example error: ``` Connection error! game id: VSEtmKpJ, client id: 0UMrA84F Error: ✖ Invalid input: expected array, received undefined → at allPlayersStats.0UMrA84F.units.wshp ✖ Invalid input: expected array, received undefined → at allPlayersStats.0UMrA84F.units.saml Stack: ``` ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors
This commit is contained in:
@@ -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<typeof PlayerStatsSchema>;
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user