From 0cc58a8f5a13f62a36f91eea2ed9d2c39419a442 Mon Sep 17 00:00:00 2001 From: Aotumuri Date: Wed, 28 Jan 2026 08:54:01 +0900 Subject: [PATCH] fix: add validation for unknown flags in manifest.json (#3044) Resolves #3041 ## Description: - Add a test to ensure an error is thrown when manifest.json specifies a non-existent flag. - Fix the underlying issue by removing the invalid flag specification (see error below). ``` resources/maps/straitofgibraltar/manifest.json -> nations[0].flag "Rif" does not exist in resources/flags resources/maps/straitofgibraltar/manifest.json -> nations[5].flag "Shilha" does not exist in resources/flags resources/maps/straitofgibraltar/manifest.json -> nations[6].flag "Andalusia" does not exist in resources/flags resources/maps/italia/manifest.json -> nations[0].flag "custom:Kingdom of the Two Sicilies" does not exist in resources/flags resources/maps/italia/manifest.json -> nations[3].flag "custom:Tuscany" does not exist in resources/flags resources/maps/italia/manifest.json -> nations[5].flag "custom:Modena" does not exist in resources/flags resources/maps/italia/manifest.json -> nations[6].flag "custom:Parma" does not exist in resources/flags resources/maps/italia/manifest.json -> nations[8].flag "custom:Kingdom of Sardinia" does not exist in resources/flags resources/maps/italia/manifest.json -> nations[11].flag "custom:Ottoman Empire2" does not exist in resources/flags resources/maps/britannia/manifest.json -> nations[19].flag "gb-nir" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[0].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[1].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[2].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[4].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[5].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[6].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[7].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[8].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[9].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[10].flag "quebec" does not exist in resources/flags resources/maps/montreal/manifest.json -> nations[11].flag "quebec" does not exist in resources/flags ``` ## 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: aotumuri --- map-generator/assets/maps/britannia/info.json | 3 +- map-generator/assets/maps/italia/info.json | 18 ++---- map-generator/assets/maps/montreal/info.json | 22 +++---- .../assets/maps/straitofgibraltar/info.json | 9 +-- resources/maps/britannia/manifest.json | 1 - resources/maps/italia/manifest.json | 6 -- resources/maps/montreal/manifest.json | 22 +++---- .../maps/straitofgibraltar/manifest.json | 3 - tests/MapManifestFlags.test.ts | 61 +++++++++++++++++++ 9 files changed, 93 insertions(+), 52 deletions(-) create mode 100644 tests/MapManifestFlags.test.ts diff --git a/map-generator/assets/maps/britannia/info.json b/map-generator/assets/maps/britannia/info.json index b72c54cbb..5d6ddd2b4 100644 --- a/map-generator/assets/maps/britannia/info.json +++ b/map-generator/assets/maps/britannia/info.json @@ -98,8 +98,7 @@ }, { "coordinates": [404, 1146], - "name": "Fermanagh", - "flag": "gb-nir" + "name": "Fermanagh" } ] } diff --git a/map-generator/assets/maps/italia/info.json b/map-generator/assets/maps/italia/info.json index 99465ddda..ea87c2146 100644 --- a/map-generator/assets/maps/italia/info.json +++ b/map-generator/assets/maps/italia/info.json @@ -3,8 +3,7 @@ "nations": [ { "coordinates": [1038, 993], - "name": "Kingdom of the Two Sicilies", - "flag": "custom:Kingdom of the Two Sicilies" + "name": "Kingdom of the Two Sicilies" }, { "coordinates": [370, 1137], @@ -18,8 +17,7 @@ }, { "coordinates": [625, 534], - "name": "Tuscany", - "flag": "custom:Tuscany" + "name": "Tuscany" }, { "coordinates": [595, 190], @@ -28,13 +26,11 @@ }, { "coordinates": [469, 386], - "name": "Modena", - "flag": "custom:Modena" + "name": "Modena" }, { "coordinates": [391, 254], - "name": "Parma", - "flag": "custom:Parma" + "name": "Parma" }, { "coordinates": [361, 68], @@ -43,8 +39,7 @@ }, { "coordinates": [278, 774], - "name": "Kingdom of Sardinia", - "flag": "custom:Kingdom of Sardinia" + "name": "Kingdom of Sardinia" }, { "coordinates": [29, 266], @@ -58,8 +53,7 @@ }, { "coordinates": [1238, 349], - "name": "Ottoman Empire", - "flag": "custom:Ottoman Empire2" + "name": "Ottoman Empire" } ] } diff --git a/map-generator/assets/maps/montreal/info.json b/map-generator/assets/maps/montreal/info.json index 0cb6c3e75..85d3756a6 100644 --- a/map-generator/assets/maps/montreal/info.json +++ b/map-generator/assets/maps/montreal/info.json @@ -3,17 +3,17 @@ "nations": [ { "coordinates": [800, 430], - "flag": "quebec", + "flag": "Quebec", "name": "Laval" }, { "coordinates": [1110, 930], - "flag": "quebec", + "flag": "Quebec", "name": "Royal Mount park" }, { "coordinates": [1220, 1360], - "flag": "quebec", + "flag": "Quebec", "name": "Hochelaga Archipelago" }, { @@ -23,42 +23,42 @@ }, { "coordinates": [1400, 1000], - "flag": "quebec", + "flag": "Quebec", "name": "Saint-Lambert" }, { "coordinates": [500, 130], - "flag": "quebec", + "flag": "Quebec", "name": "Blainville" }, { "coordinates": [350, 650], - "flag": "quebec", + "flag": "Quebec", "name": "Saint-Eustache" }, { "coordinates": [200, 1350], - "flag": "quebec", + "flag": "Quebec", "name": "Perrot Island" }, { "coordinates": [25, 950], - "flag": "quebec", + "flag": "Quebec", "name": "Kanesatake Lands" }, { "coordinates": [50, 450], - "flag": "quebec", + "flag": "Quebec", "name": "Mirabel" }, { "coordinates": [650, 1450], - "flag": "quebec", + "flag": "Quebec", "name": "Chateauguay" }, { "coordinates": [1330, 300], - "flag": "quebec", + "flag": "Quebec", "name": "Pointe-aux-Trembles" } ] diff --git a/map-generator/assets/maps/straitofgibraltar/info.json b/map-generator/assets/maps/straitofgibraltar/info.json index edc797671..1a826d7e7 100644 --- a/map-generator/assets/maps/straitofgibraltar/info.json +++ b/map-generator/assets/maps/straitofgibraltar/info.json @@ -3,8 +3,7 @@ "nations": [ { "coordinates": [1941, 1031], - "name": "Rif", - "flag": "Rif" + "name": "Rif" }, { "coordinates": [2733, 1190], @@ -28,13 +27,11 @@ }, { "coordinates": [1271, 1393], - "name": "Shilha", - "flag": "Shilha" + "name": "Shilha" }, { "coordinates": [1555, 258], - "name": "Andalusia", - "flag": "Andalusia" + "name": "Andalusia" } ] } diff --git a/resources/maps/britannia/manifest.json b/resources/maps/britannia/manifest.json index 7a0db2a33..415dac416 100644 --- a/resources/maps/britannia/manifest.json +++ b/resources/maps/britannia/manifest.json @@ -113,7 +113,6 @@ }, { "coordinates": [404, 1146], - "flag": "gb-nir", "name": "Fermanagh" } ] diff --git a/resources/maps/italia/manifest.json b/resources/maps/italia/manifest.json index d8242ba2b..ed721cb36 100644 --- a/resources/maps/italia/manifest.json +++ b/resources/maps/italia/manifest.json @@ -18,7 +18,6 @@ "nations": [ { "coordinates": [1038, 993], - "flag": "custom:Kingdom of the Two Sicilies", "name": "Kingdom of the Two Sicilies" }, { @@ -33,7 +32,6 @@ }, { "coordinates": [625, 534], - "flag": "custom:Tuscany", "name": "Tuscany" }, { @@ -43,12 +41,10 @@ }, { "coordinates": [469, 386], - "flag": "custom:Modena", "name": "Modena" }, { "coordinates": [391, 254], - "flag": "custom:Parma", "name": "Parma" }, { @@ -58,7 +54,6 @@ }, { "coordinates": [278, 774], - "flag": "custom:Kingdom of Sardinia", "name": "Kingdom of Sardinia" }, { @@ -73,7 +68,6 @@ }, { "coordinates": [1238, 349], - "flag": "custom:Ottoman Empire2", "name": "Ottoman Empire" } ] diff --git a/resources/maps/montreal/manifest.json b/resources/maps/montreal/manifest.json index 78ce3f637..4c17fa2f8 100644 --- a/resources/maps/montreal/manifest.json +++ b/resources/maps/montreal/manifest.json @@ -18,17 +18,17 @@ "nations": [ { "coordinates": [800, 430], - "flag": "quebec", + "flag": "Quebec", "name": "Laval" }, { "coordinates": [1110, 930], - "flag": "quebec", + "flag": "Quebec", "name": "Royal Mount park" }, { "coordinates": [1220, 1360], - "flag": "quebec", + "flag": "Quebec", "name": "Hochelaga Archipelago" }, { @@ -38,42 +38,42 @@ }, { "coordinates": [1400, 1000], - "flag": "quebec", + "flag": "Quebec", "name": "Saint-Lambert" }, { "coordinates": [500, 130], - "flag": "quebec", + "flag": "Quebec", "name": "Blainville" }, { "coordinates": [350, 650], - "flag": "quebec", + "flag": "Quebec", "name": "Saint-Eustache" }, { "coordinates": [200, 1350], - "flag": "quebec", + "flag": "Quebec", "name": "Perrot Island" }, { "coordinates": [25, 950], - "flag": "quebec", + "flag": "Quebec", "name": "Kanesatake Lands" }, { "coordinates": [50, 450], - "flag": "quebec", + "flag": "Quebec", "name": "Mirabel" }, { "coordinates": [650, 1450], - "flag": "quebec", + "flag": "Quebec", "name": "Chateauguay" }, { "coordinates": [1330, 300], - "flag": "quebec", + "flag": "Quebec", "name": "Pointe-aux-Trembles" } ] diff --git a/resources/maps/straitofgibraltar/manifest.json b/resources/maps/straitofgibraltar/manifest.json index 930ef92a5..790ecf015 100644 --- a/resources/maps/straitofgibraltar/manifest.json +++ b/resources/maps/straitofgibraltar/manifest.json @@ -18,7 +18,6 @@ "nations": [ { "coordinates": [1941, 1031], - "flag": "Rif", "name": "Rif" }, { @@ -43,12 +42,10 @@ }, { "coordinates": [1271, 1393], - "flag": "Shilha", "name": "Shilha" }, { "coordinates": [1555, 258], - "flag": "Andalusia", "name": "Andalusia" } ] diff --git a/tests/MapManifestFlags.test.ts b/tests/MapManifestFlags.test.ts new file mode 100644 index 000000000..dee46bf7d --- /dev/null +++ b/tests/MapManifestFlags.test.ts @@ -0,0 +1,61 @@ +import fs from "fs"; +import { globSync } from "glob"; +import path from "path"; + +type Nation = { + flag?: string; +}; + +type Manifest = { + nations?: Nation[]; +}; + +describe("Map manifests: nation flags exist", () => { + test("All nations' flags reference existing SVG files", () => { + const manifestPaths = globSync("resources/maps/**/manifest.json"); + + expect(manifestPaths.length).toBeGreaterThan(0); + + const flagDir = path.join(__dirname, "../resources/flags"); + const errors: string[] = []; + + for (const manifestPath of manifestPaths) { + try { + const raw = fs.readFileSync(manifestPath, "utf8"); + const manifest = JSON.parse(raw) as Manifest; + + (manifest.nations ?? []).forEach((nation, idx) => { + const flag = nation?.flag; + if (flag === undefined || flag === null) return; + if (typeof flag !== "string") { + errors.push( + `${manifestPath} -> nations[${idx}].flag is not a string`, + ); + return; + } + + if (flag.trim().length === 0) return; + if (flag.startsWith("!")) return; + + const svgFile = flag.endsWith(".svg") ? flag : `${flag}.svg`; + const flagPath = path.join(flagDir, svgFile); + if (!fs.existsSync(flagPath)) { + errors.push( + `${manifestPath} -> nations[${idx}].flag "${flag}" does not exist in resources/flags`, + ); + } + }); + } catch (err) { + errors.push( + `Failed to parse ${manifestPath}: ${(err as Error).message}`, + ); + } + } + + if (errors.length > 0) { + throw new Error( + "Map manifest flag file violations:\n" + errors.join("\n"), + ); + } + }); +});