bugfix: trim archived map names (#4632)

## Description:

fixed a bug where "Deglaciated Antarctica" had a trailing space in an
earlier version of the game and caused visual issues:
<img width="1045" height="323" alt="image"
src="https://github.com/user-attachments/assets/11628e19-523e-43f9-b3dc-15a5ee1bcd8a"
/>
and prevented stats from loading:
<img width="1070" height="529" alt="image"
src="https://github.com/user-attachments/assets/590a7c2b-7dc5-4d8d-816f-469731d42fd4"
/>
 

now works:
<img width="969" height="387" alt="image"
src="https://github.com/user-attachments/assets/35d4ac89-5f97-4534-adbc-d0ce824ea4d8"
/>
<img width="1013" height="787" alt="image"
src="https://github.com/user-attachments/assets/44d6c20a-caf6-417a-b7fe-08f0765e1b16"
/>


## 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

## Please put your Discord username so you can be contacted if a bug or
regression is found:

w.o.n
This commit is contained in:
Ryan
2026-07-17 15:09:39 -07:00
committed by GitHub
parent c269354c74
commit 774d98ddad
6 changed files with 39 additions and 2 deletions
+1 -1
View File
@@ -246,7 +246,7 @@ export const PublicPlayerGameSchema = z.object({
gameId: z.string(),
start: z.iso.datetime(),
durationSeconds: z.number().int().nonnegative(),
map: z.string(),
map: z.string().trim(),
mode: z.string(),
type: z.string(),
playerTeams: z.string().nullable(),
+1 -1
View File
@@ -198,7 +198,7 @@ export const ClanGameSchema = z.object({
gameId: z.string(),
start: z.iso.datetime(),
durationSeconds: z.number().int().nonnegative(),
map: z.string().optional(),
map: z.string().trim().optional(),
mode: z.string().optional(),
// playerTeams is `null` (not absent) for FFA / non-team games — use
// `.nullish()` so the wire `null` doesn't fail the parse.
+4
View File
@@ -947,6 +947,10 @@ const ArchivedPlayerRecordSchema = PlayerRecordSchema.extend({
export const ArchivedAnalyticsRecordSchema = AnalyticsRecordSchema.extend({
info: GameEndInfoSchema.extend({
config: GameConfigSchema.extend({
gameMap: z.preprocess(
(value) => (typeof value === "string" ? value.trim() : value),
GameConfigSchema.shape.gameMap,
),
// predates configurable nation count
nations: GameConfigSchema.shape.nations
.catch("default")
+11
View File
@@ -119,6 +119,17 @@ describe("PublicPlayerGameSchema", () => {
expect(PublicPlayerGameSchema.safeParse(validGame).success).toBe(true);
});
it("normalizes accidental whitespace around archived map names", () => {
const result = PublicPlayerGameSchema.safeParse({
...validGame,
map: "Deglaciated Antarctica ",
});
expect(result.success).toBe(true);
if (!result.success) return;
expect(result.data.map).toBe("Deglaciated Antarctica");
});
it("accepts clanTag: null (not repping a clan)", () => {
expect(
PublicPlayerGameSchema.safeParse({ ...validGame, clanTag: null }).success,
+11
View File
@@ -95,4 +95,15 @@ describe("ArchivedAnalyticsRecordSchema", () => {
expect(result.data.info.players[0].clanTag).toBe("ABC");
expect(result.data.info.players[0].stats?.conquests).toEqual([1n, 2n, 0n]);
});
test("normalizes accidental whitespace around an archived map name", () => {
const record = oldRecord();
record.info.config.gameMap = "Deglaciated Antarctica ";
const result = ArchivedAnalyticsRecordSchema.safeParse(record);
expect(result.success).toBe(true);
if (!result.success) return;
expect(result.data.info.config.gameMap).toBe("Deglaciated Antarctica");
});
});
+11
View File
@@ -291,6 +291,17 @@ describe("ClanGameSchema", () => {
expect(ClanGameSchema.safeParse(validGame).success).toBe(true);
});
it("normalizes accidental whitespace around archived map names", () => {
const result = ClanGameSchema.safeParse({
...validGame,
map: "Deglaciated Antarctica ",
});
expect(result.success).toBe(true);
if (!result.success) return;
expect(result.data.map).toBe("Deglaciated Antarctica");
});
it("accepts playerTeams: null (FFA / non-team games)", () => {
const result = ClanGameSchema.safeParse({
...validGame,