diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index 6cd9d2d94..001f76e1f 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -408,11 +408,11 @@ export class PlayerInfo { public readonly nation?: Nation | null, ) { // Compute clan from name - if (!name.startsWith("[") || !name.includes("]")) { + if (!name.includes("[") || !name.includes("]")) { this.clan = null; } else { - const clanMatch = name.match(/^\[([a-zA-Z]{2,5})\]/); - this.clan = clanMatch ? clanMatch[1] : null; + const clanMatch = name.match(/\[([a-zA-Z0-9]{2,5})\]/); + this.clan = clanMatch ? clanMatch[1].toUpperCase() : null; } } } diff --git a/tests/PlayerInfo.test.ts b/tests/PlayerInfo.test.ts index 72ca1cceb..c1fa8b559 100644 --- a/tests/PlayerInfo.test.ts +++ b/tests/PlayerInfo.test.ts @@ -2,7 +2,7 @@ import { PlayerInfo, PlayerType } from "../src/core/game/Game"; describe("PlayerInfo", () => { describe("clan", () => { - test("should extract clan from name when format is [XX]Name", () => { + test("should extract clan from name when format contains [XX]", () => { const playerInfo = new PlayerInfo( "[CL]PlayerName", PlayerType.Human, @@ -12,7 +12,7 @@ describe("PlayerInfo", () => { expect(playerInfo.clan).toBe("CL"); }); - test("should extract clan from name when format is [XXX]Name", () => { + test("should extract clan from name when format contains [XXX]", () => { const playerInfo = new PlayerInfo( "[ABC]PlayerName", PlayerType.Human, @@ -22,7 +22,7 @@ describe("PlayerInfo", () => { expect(playerInfo.clan).toBe("ABC"); }); - test("should extract clan from name when format is [XXXX]Name", () => { + test("should extract clan from name when format contains [XXXX]", () => { const playerInfo = new PlayerInfo( "[ABCD]PlayerName", PlayerType.Human, @@ -32,7 +32,7 @@ describe("PlayerInfo", () => { expect(playerInfo.clan).toBe("ABCD"); }); - test("should extract clan from name when format is [XXXXX]Name", () => { + test("should extract clan from name when format contains [XXXXX]", () => { const playerInfo = new PlayerInfo( "[ABCDE]PlayerName", PlayerType.Human, @@ -42,27 +42,37 @@ describe("PlayerInfo", () => { expect(playerInfo.clan).toBe("ABCDE"); }); - test("should extract clan from name when format is [xxxxx]Name", () => { + test("should extract uppercase clan from name when format contains [xxxxx]", () => { const playerInfo = new PlayerInfo( "[abcde]PlayerName", PlayerType.Human, null, "player_id", ); - expect(playerInfo.clan).toBe("abcde"); + expect(playerInfo.clan).toBe("ABCDE"); }); - test("should extract clan from name when format is [XxXxX]Name", () => { + test("should extract uppercase clan from name when format contains [XxXxX]", () => { const playerInfo = new PlayerInfo( "[AbCdE]PlayerName", PlayerType.Human, null, "player_id", ); - expect(playerInfo.clan).toBe("AbCdE"); + expect(playerInfo.clan).toBe("ABCDE"); }); - test("should return null when name doesn't start with [", () => { + test("should extract uppercase clan from name when format contains [Xx#xX]", () => { + const playerInfo = new PlayerInfo( + "[Ab1cD]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("AB1CD"); + }); + + test("should return null when name doesn't contain [", () => { const playerInfo = new PlayerInfo( "PlayerName", PlayerType.Human, @@ -82,7 +92,7 @@ describe("PlayerInfo", () => { expect(playerInfo.clan).toBeNull(); }); - test("should return null when clan tag is not 2-5 uppercase letters", () => { + test("should return null when clan tag is not 2-5 alphanumeric letters", () => { const playerInfo = new PlayerInfo( "[A]PlayerName", PlayerType.Human, @@ -94,7 +104,7 @@ describe("PlayerInfo", () => { test("should return null when clan tag contains non alphanumeric characters", () => { const playerInfo = new PlayerInfo( - "[A1c]PlayerName", + "[A?c]PlayerName", PlayerType.Human, null, "player_id", @@ -111,5 +121,95 @@ describe("PlayerInfo", () => { ); expect(playerInfo.clan).toBeNull(); }); + + test("should extract uppercase clan name from any location in the player name", () => { + const playerInfo = new PlayerInfo( + "Player[aa]Name", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("AA"); + }); + + test("should extract only the first occurrence of a clan name match", () => { + const playerInfo = new PlayerInfo( + "[Ab1cD]Player[aa]Name", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("AB1CD"); + }); + + test("should extract only the first occurrence of a valid clan name match and extract as uppercase", () => { + const playerInfo = new PlayerInfo( + "[Ab1cDEF]Player[aa]Name", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("AA"); + }); + + test("should extract numeric-only clan names", () => { + const playerInfo = new PlayerInfo( + "[012]PlayerName", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("012"); + }); + + test("should extract numeric-only clan names and only the first valid clan name", () => { + const playerInfo = new PlayerInfo( + "[012]Player[aa]Name", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("012"); + }); + + test("should extract numeric-only clan names from anywhere within the name", () => { + const playerInfo = new PlayerInfo( + "Player[012]Name", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("012"); + }); + + test("should extract numeric-only clan names from the end of the name", () => { + const playerInfo = new PlayerInfo( + "PlayerName[012]", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("012"); + }); + + test("should extract uppercase alphanumeric clan names from anywhere within the name", () => { + const playerInfo = new PlayerInfo( + "Player[0a1B2]Name", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("0A1B2"); + }); + + test("should extract uppercase alphanumeric clan names from the end of the name", () => { + const playerInfo = new PlayerInfo( + "PlayerName[0a1B2]", + PlayerType.Human, + null, + "player_id", + ); + expect(playerInfo.clan).toBe("0A1B2"); + }); }); });