From 972e4f007509438abb78b1bdf7b542c3c276530c Mon Sep 17 00:00:00 2001 From: ReenigneArcher <42013603+ReenigneArcher@users.noreply.github.com> Date: Sun, 22 Feb 2026 16:35:11 -0500 Subject: [PATCH] refactor: remove duplicated code --- eslint.config.mjs | 1 + .../assets/js/collection_detail.js | 35 ---- .../assets/js/franchise_detail.js | 35 ---- gh-pages-template/assets/js/game_detail.js | 22 --- gh-pages-template/assets/js/group_detail.js | 62 +++++++ gh-pages-template/assets/js/item_detail.js | 22 +++ .../assets/js/platform_detail.js | 17 -- gh-pages-template/browse/collections.html | 3 +- gh-pages-template/browse/franchises.html | 3 +- tests/collection_detail.test.js | 89 ---------- tests/franchise_detail.test.js | 89 ---------- tests/game_detail.test.js | 22 +-- tests/group_detail.test.js | 153 ++++++++++++++++++ tests/item_detail.test.js | 21 +++ tests/platform_detail.test.js | 22 +-- 15 files changed, 265 insertions(+), 331 deletions(-) delete mode 100644 gh-pages-template/assets/js/collection_detail.js delete mode 100644 gh-pages-template/assets/js/franchise_detail.js create mode 100644 gh-pages-template/assets/js/group_detail.js delete mode 100644 tests/collection_detail.test.js delete mode 100644 tests/franchise_detail.test.js create mode 100644 tests/group_detail.test.js diff --git a/eslint.config.mjs b/eslint.config.mjs index 9073c35f6c5c..85c6cd10f82d 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -20,6 +20,7 @@ export default [ "base_url": "readonly", "base_path": "readonly", "igdbImageUrl": "readonly", + "getRegionFlag": "readonly", "makeBadge": "readonly", "addDlRow": "readonly", "loadItemDetail": "readonly", diff --git a/gh-pages-template/assets/js/collection_detail.js b/gh-pages-template/assets/js/collection_detail.js deleted file mode 100644 index cfa16457b6b4..000000000000 --- a/gh-pages-template/assets/js/collection_detail.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * collection_detail.js - * Renders a single collection (series) detail page. - * Depends on item_detail.js being loaded first. - */ - -function renderCollection(data) { - document.title = (data.name || "Series") + " – GameDB"; - document.getElementById("collection-name").textContent = data.name || "Unknown Series"; - - // IGDB link - if (data.url) { - const igdbLink = document.getElementById("collection-igdb-link"); - igdbLink.href = data.url; - igdbLink.classList.remove("d-none"); - } - - // Games - if (data.games && data.games.length > 0) { - const section = document.getElementById("collection-games-section"); - section.classList.remove("d-none"); - renderGameList(document.getElementById("collection-games"), data.games); - } -} - -document.addEventListener("DOMContentLoaded", () => { - loadItemDetail("collections", renderCollection); -}); - -/* istanbul ignore next */ -if (typeof module !== "undefined") { - module.exports = { - renderCollection, - }; -} diff --git a/gh-pages-template/assets/js/franchise_detail.js b/gh-pages-template/assets/js/franchise_detail.js deleted file mode 100644 index f9dd768fbe47..000000000000 --- a/gh-pages-template/assets/js/franchise_detail.js +++ /dev/null @@ -1,35 +0,0 @@ -/** - * franchise_detail.js - * Renders a single franchise detail page. - * Depends on item_detail.js being loaded first. - */ - -function renderFranchise(data) { - document.title = (data.name || "Franchise") + " – GameDB"; - document.getElementById("franchise-name").textContent = data.name || "Unknown Franchise"; - - // IGDB link - if (data.url) { - const igdbLink = document.getElementById("franchise-igdb-link"); - igdbLink.href = data.url; - igdbLink.classList.remove("d-none"); - } - - // Games - if (data.games && data.games.length > 0) { - const section = document.getElementById("franchise-games-section"); - section.classList.remove("d-none"); - renderGameList(document.getElementById("franchise-games"), data.games); - } -} - -document.addEventListener("DOMContentLoaded", () => { - loadItemDetail("franchises", renderFranchise); -}); - -/* istanbul ignore next */ -if (typeof module !== "undefined") { - module.exports = { - renderFranchise, - }; -} diff --git a/gh-pages-template/assets/js/game_detail.js b/gh-pages-template/assets/js/game_detail.js index 3a7d69af457d..cb9a36ca92e7 100644 --- a/gh-pages-template/assets/js/game_detail.js +++ b/gh-pages-template/assets/js/game_detail.js @@ -434,27 +434,6 @@ function renderCharacters(data) { } } -/** - * Map region string (from release_region.region) to an emoji flag. - * @param {string} regionName - * @returns {string} - */ -function getRegionFlag(regionName) { - const map = { - "europe": "πŸ‡ͺπŸ‡Ί", - "north_america": "πŸ‡ΊπŸ‡Έ", - "australia": "πŸ‡¦πŸ‡Ί", - "new_zealand": "πŸ‡³πŸ‡Ώ", - "japan": "πŸ‡―πŸ‡΅", - "china": "πŸ‡¨πŸ‡³", - "asia": "🌏", - "worldwide": "🌍", - "korea": "πŸ‡°πŸ‡·", - "brazil": "πŸ‡§πŸ‡·", - }; - return map[regionName] || "🌐"; -} - /** * Initialize game banner with cycling images (mimics beautiful-jekyll-next behavior) */ @@ -551,7 +530,6 @@ if (typeof module !== "undefined") { renderVideos, renderExternalLinks, renderCharacters, - getRegionFlag, initGameBanner, }; } diff --git a/gh-pages-template/assets/js/group_detail.js b/gh-pages-template/assets/js/group_detail.js new file mode 100644 index 000000000000..6e074e7dd71b --- /dev/null +++ b/gh-pages-template/assets/js/group_detail.js @@ -0,0 +1,62 @@ +/** + * group_detail.js + * Renders a single collection (series) or franchise detail page. + * Depends on item_detail.js being loaded first. + * + * The page must define a `GAMEDB_GROUP_TYPE` global before loading this script: + * (for collections) + * (for franchises) + * + * Expected DOM element IDs follow the pattern `-*`, e.g.: + * collection-name, collection-igdb-link, collection-games-section, collection-games + * franchise-name, franchise-igdb-link, franchise-games-section, franchise-games + */ + +const GROUP_CONFIG = { + collection: { + endpoint: "collections", + defaultTitle: "Series", + defaultName: "Unknown Series", + }, + franchise: { + endpoint: "franchises", + defaultTitle: "Franchise", + defaultName: "Unknown Franchise", + }, +}; + +function renderGroup(data) { + const type = globalThis.GAMEDB_GROUP_TYPE || "collection"; + const config = GROUP_CONFIG[type]; + + document.title = (data.name || config.defaultTitle) + " – GameDB"; + document.getElementById(`${type}-name`).textContent = data.name || config.defaultName; + + // IGDB link + if (data.url) { + const igdbLink = document.getElementById(`${type}-igdb-link`); + igdbLink.href = data.url; + igdbLink.classList.remove("d-none"); + } + + // Games + if (data.games && data.games.length > 0) { + const section = document.getElementById(`${type}-games-section`); + section.classList.remove("d-none"); + renderGameList(document.getElementById(`${type}-games`), data.games); + } +} + +document.addEventListener("DOMContentLoaded", () => { + const type = globalThis.GAMEDB_GROUP_TYPE || "collection"; + const config = GROUP_CONFIG[type]; + loadItemDetail(config.endpoint, renderGroup); +}); + +/* istanbul ignore next */ +if (typeof module !== "undefined") { + module.exports = { + GROUP_CONFIG, + renderGroup, + }; +} diff --git a/gh-pages-template/assets/js/item_detail.js b/gh-pages-template/assets/js/item_detail.js index 66542df483cf..009f4303f986 100644 --- a/gh-pages-template/assets/js/item_detail.js +++ b/gh-pages-template/assets/js/item_detail.js @@ -10,6 +10,27 @@ * window.GAMEDB_CONFIG = { base_path: "{{ site.baseurl }}", base_url: "{{ site.url }}{{ site.baseurl }}" }; */ +/** + * Map a release region string (from release_region.region) to an emoji flag. + * @param {string} regionName + * @returns {string} + */ +function getRegionFlag(regionName) { + const map = { + "europe": "πŸ‡ͺπŸ‡Ί", + "north_america": "πŸ‡ΊπŸ‡Έ", + "australia": "πŸ‡¦πŸ‡Ί", + "new_zealand": "πŸ‡³πŸ‡Ώ", + "japan": "πŸ‡―πŸ‡΅", + "china": "πŸ‡¨πŸ‡³", + "asia": "🌏", + "worldwide": "🌍", + "korea": "πŸ‡°πŸ‡·", + "brazil": "πŸ‡§πŸ‡·", + }; + return map[regionName] || "🌐"; +} + const base_path = (globalThis.GAMEDB_CONFIG?.base_path ? ("/" + globalThis.GAMEDB_CONFIG.base_path).replaceAll(/\/+/g, "/").replace(/\/$/, "") : "/GameDB"); @@ -235,6 +256,7 @@ if (typeof module !== "undefined") { module.exports = { getQueryParam, igdbImageUrl, + getRegionFlag, makeBadge, addDlRow, showError, diff --git a/gh-pages-template/assets/js/platform_detail.js b/gh-pages-template/assets/js/platform_detail.js index 0c0f80d96013..46d35ac2bb16 100644 --- a/gh-pages-template/assets/js/platform_detail.js +++ b/gh-pages-template/assets/js/platform_detail.js @@ -26,22 +26,6 @@ const CATEGORY_NAMES = { 6: "Computer", }; -function getRegionFlag(regionName) { - const map = { - "europe": "πŸ‡ͺπŸ‡Ί", - "north_america": "πŸ‡ΊπŸ‡Έ", - "australia": "πŸ‡¦πŸ‡Ί", - "new_zealand": "πŸ‡³πŸ‡Ώ", - "japan": "πŸ‡―πŸ‡΅", - "china": "πŸ‡¨πŸ‡³", - "asia": "🌏", - "worldwide": "🌍", - "korea": "πŸ‡°πŸ‡·", - "brazil": "πŸ‡§πŸ‡·", - }; - return map[regionName] || "🌐"; -} - /** * Render platform logo or placeholder */ @@ -257,7 +241,6 @@ document.addEventListener("DOMContentLoaded", () => { /* istanbul ignore next */ if (typeof module !== "undefined") { module.exports = { - getRegionFlag, renderPlatformLogo, renderPlatformBadges, renderPlatformMetadata, diff --git a/gh-pages-template/browse/collections.html b/gh-pages-template/browse/collections.html index d618bcf03899..e8a035bfeefa 100644 --- a/gh-pages-template/browse/collections.html +++ b/gh-pages-template/browse/collections.html @@ -6,7 +6,7 @@ - /assets/css/hide-heading.css js: - /GameDB/assets/js/item_detail.js - - /GameDB/assets/js/collection_detail.js + - /GameDB/assets/js/group_detail.js ext-css: - href: https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200 --- @@ -15,6 +15,7 @@ globalThis.GAMEDB_CONFIG = { base_path: "{{ site.baseurl }}" }; +globalThis.GAMEDB_GROUP_TYPE = "collection";
diff --git a/gh-pages-template/browse/franchises.html b/gh-pages-template/browse/franchises.html index ada56e0030c5..0e9690029727 100644 --- a/gh-pages-template/browse/franchises.html +++ b/gh-pages-template/browse/franchises.html @@ -6,7 +6,7 @@ - /assets/css/hide-heading.css js: - /GameDB/assets/js/item_detail.js - - /GameDB/assets/js/franchise_detail.js + - /GameDB/assets/js/group_detail.js ext-css: - href: https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200 --- @@ -15,6 +15,7 @@ globalThis.GAMEDB_CONFIG = { base_path: "{{ site.baseurl }}" }; +globalThis.GAMEDB_GROUP_TYPE = "franchise";
diff --git a/tests/collection_detail.test.js b/tests/collection_detail.test.js deleted file mode 100644 index 700a2725db67..000000000000 --- a/tests/collection_detail.test.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import { - describe, - test, - expect, - beforeEach, - afterEach, -} from '@jest/globals'; - -globalThis.GAMEDB_CONFIG = { base_path: '/GameDB' }; - -const itemDetail = require('../gh-pages-template/assets/js/item_detail.js'); -globalThis.makeBadge = itemDetail.makeBadge; -globalThis.addDlRow = itemDetail.addDlRow; -globalThis.loadItemDetail = itemDetail.loadItemDetail; -globalThis.renderGameList = itemDetail.renderGameList; -globalThis.igdbImageUrl = itemDetail.igdbImageUrl; -globalThis.base_path = '/GameDB'; -globalThis.base_url = 'http://localhost/GameDB'; - -const { renderCollection } = require('../gh-pages-template/assets/js/collection_detail.js'); - -const baseDom = ` - -

- -
-
-
-`; - -describe('collection_detail.js', () => { - beforeEach(() => { - document.body.innerHTML = baseDom; - }); - - afterEach(() => { - document.body.innerHTML = ''; - }); - - describe('renderCollection', () => { - test('sets title and name', () => { - renderCollection({ name: 'Sonic the Hedgehog' }); - expect(document.title).toContain('Sonic the Hedgehog'); - expect(document.getElementById('collection-name').textContent).toBe('Sonic the Hedgehog'); - }); - - test('uses fallback title and name when name absent', () => { - renderCollection({}); - expect(document.title).toContain('Series'); - expect(document.getElementById('collection-name').textContent).toBe('Unknown Series'); - }); - - test('shows IGDB link when URL provided', () => { - renderCollection({ name: 'Mario', url: 'https://igdb.com/collections/mario' }); - const link = document.getElementById('collection-igdb-link'); - expect(link.classList.contains('d-none')).toBe(false); - expect(link.href).toContain('igdb.com'); - }); - - test('keeps IGDB link hidden when no URL', () => { - renderCollection({ name: 'Zelda' }); - expect(document.getElementById('collection-igdb-link').classList.contains('d-none')).toBe(true); - }); - - test('shows games section when games present', () => { - renderCollection({ - name: 'Metroid', - games: [{ id: 1, name: 'Metroid Prime', cover: { url: '//img.igdb.com/t_thumb/c.jpg' } }], - }); - expect(document.getElementById('collection-games-section').classList.contains('d-none')).toBe(false); - }); - - test('keeps games section hidden when no games', () => { - renderCollection({ name: 'Empty' }); - expect(document.getElementById('collection-games-section').classList.contains('d-none')).toBe(true); - }); - }); - - describe('DOMContentLoaded integration', () => { - test('fires loadItemDetail on DOMContentLoaded', () => { - globalThis.history.pushState(null, '', '/'); - expect(() => document.dispatchEvent(new Event('DOMContentLoaded'))).not.toThrow(); - }); - }); -}); diff --git a/tests/franchise_detail.test.js b/tests/franchise_detail.test.js deleted file mode 100644 index 047ecb645e39..000000000000 --- a/tests/franchise_detail.test.js +++ /dev/null @@ -1,89 +0,0 @@ -/** - * @jest-environment jsdom - */ - -import { - describe, - test, - expect, - beforeEach, - afterEach, -} from '@jest/globals'; - -globalThis.GAMEDB_CONFIG = { base_path: '/GameDB' }; - -const itemDetail = require('../gh-pages-template/assets/js/item_detail.js'); -globalThis.makeBadge = itemDetail.makeBadge; -globalThis.addDlRow = itemDetail.addDlRow; -globalThis.loadItemDetail = itemDetail.loadItemDetail; -globalThis.renderGameList = itemDetail.renderGameList; -globalThis.igdbImageUrl = itemDetail.igdbImageUrl; -globalThis.base_path = '/GameDB'; -globalThis.base_url = 'http://localhost/GameDB'; - -const { renderFranchise } = require('../gh-pages-template/assets/js/franchise_detail.js'); - -const baseDom = ` - -

- -
-
-
-`; - -describe('franchise_detail.js', () => { - beforeEach(() => { - document.body.innerHTML = baseDom; - }); - - afterEach(() => { - document.body.innerHTML = ''; - }); - - describe('renderFranchise', () => { - test('sets title and name', () => { - renderFranchise({ name: 'The Legend of Zelda' }); - expect(document.title).toContain('The Legend of Zelda'); - expect(document.getElementById('franchise-name').textContent).toBe('The Legend of Zelda'); - }); - - test('uses fallback title and name when name absent', () => { - renderFranchise({}); - expect(document.title).toContain('Franchise'); - expect(document.getElementById('franchise-name').textContent).toBe('Unknown Franchise'); - }); - - test('shows IGDB link when URL provided', () => { - renderFranchise({ name: 'Zelda', url: 'https://igdb.com/franchises/zelda' }); - const link = document.getElementById('franchise-igdb-link'); - expect(link.classList.contains('d-none')).toBe(false); - expect(link.href).toContain('igdb.com'); - }); - - test('keeps IGDB link hidden when no URL', () => { - renderFranchise({ name: 'Mario' }); - expect(document.getElementById('franchise-igdb-link').classList.contains('d-none')).toBe(true); - }); - - test('shows games section when games present', () => { - renderFranchise({ - name: 'Halo', - games: [{ id: 5, name: 'Halo: CE', cover: { url: '//img.igdb.com/t_thumb/c.jpg' } }], - }); - expect(document.getElementById('franchise-games-section').classList.contains('d-none')).toBe(false); - }); - - test('keeps games section hidden when no games', () => { - renderFranchise({ name: 'Empty' }); - expect(document.getElementById('franchise-games-section').classList.contains('d-none')).toBe(true); - }); - }); - - describe('DOMContentLoaded integration', () => { - test('fires loadItemDetail on DOMContentLoaded', () => { - globalThis.history.pushState(null, '', '/'); - expect(() => document.dispatchEvent(new Event('DOMContentLoaded'))).not.toThrow(); - }); - }); -}); diff --git a/tests/game_detail.test.js b/tests/game_detail.test.js index 57f263eb9d2a..a68253d5155b 100644 --- a/tests/game_detail.test.js +++ b/tests/game_detail.test.js @@ -24,11 +24,11 @@ globalThis.makeBadge = itemDetail.makeBadge; globalThis.addDlRow = itemDetail.addDlRow; globalThis.loadItemDetail = itemDetail.loadItemDetail; globalThis.renderGameList = itemDetail.renderGameList; +globalThis.getRegionFlag = itemDetail.getRegionFlag; globalThis.base_path = '/GameDB'; globalThis.base_url = 'http://localhost/GameDB'; const { - getRegionFlag, renderGameCover, renderGameBadges, renderGameRatings, @@ -79,26 +79,6 @@ describe('game_detail.js', () => { jest.restoreAllMocks(); }); - describe('getRegionFlag', () => { - test('returns correct flags for all known regions', () => { - expect(getRegionFlag('europe')).toBe('πŸ‡ͺπŸ‡Ί'); - expect(getRegionFlag('north_america')).toBe('πŸ‡ΊπŸ‡Έ'); - expect(getRegionFlag('australia')).toBe('πŸ‡¦πŸ‡Ί'); - expect(getRegionFlag('new_zealand')).toBe('πŸ‡³πŸ‡Ώ'); - expect(getRegionFlag('japan')).toBe('πŸ‡―πŸ‡΅'); - expect(getRegionFlag('china')).toBe('πŸ‡¨πŸ‡³'); - expect(getRegionFlag('asia')).toBe('🌏'); - expect(getRegionFlag('worldwide')).toBe('🌍'); - expect(getRegionFlag('korea')).toBe('πŸ‡°πŸ‡·'); - expect(getRegionFlag('brazil')).toBe('πŸ‡§πŸ‡·'); - }); - - test('returns default globe for unknown region', () => { - expect(getRegionFlag('unknown')).toBe('🌐'); - expect(getRegionFlag('')).toBe('🌐'); - }); - }); - describe('renderGameCover', () => { test('shows cover image when URL provided', () => { renderGameCover({ name: 'Test', cover: { url: '//images.igdb.com/t_thumb/x.jpg' } }); diff --git a/tests/group_detail.test.js b/tests/group_detail.test.js new file mode 100644 index 000000000000..ad12eda02670 --- /dev/null +++ b/tests/group_detail.test.js @@ -0,0 +1,153 @@ +/** + * @jest-environment jsdom + */ + +import { + describe, + test, + expect, + beforeEach, + afterEach, +} from '@jest/globals'; + +globalThis.GAMEDB_CONFIG = { base_path: '/GameDB' }; + +const itemDetail = require('../gh-pages-template/assets/js/item_detail.js'); +globalThis.makeBadge = itemDetail.makeBadge; +globalThis.addDlRow = itemDetail.addDlRow; +globalThis.loadItemDetail = itemDetail.loadItemDetail; +globalThis.renderGameList = itemDetail.renderGameList; +globalThis.igdbImageUrl = itemDetail.igdbImageUrl; +globalThis.base_path = '/GameDB'; +globalThis.base_url = 'http://localhost/GameDB'; + +const { GROUP_CONFIG, renderGroup } = require('../gh-pages-template/assets/js/group_detail.js'); + +// --- Helpers --- + +function makeGroupDom(type) { + return ` + +

+ +
+
+
+ `; +} + +/** + * Shared renderGroup behaviour tests, run for each supported type. + * @param {'collection'|'franchise'} type + * @param {{ name: string, defaultTitle: string, defaultName: string }} config + */ +function describeRenderGroup(type, config) { + describe(`renderGroup – ${type} type`, () => { + beforeEach(() => { + globalThis.GAMEDB_GROUP_TYPE = type; + document.body.innerHTML = makeGroupDom(type); + }); + + test('sets title and name', () => { + renderGroup({ name: config.name }); + expect(document.title).toContain(config.name); + expect(document.getElementById(`${type}-name`).textContent).toBe(config.name); + }); + + test('uses fallback title and name when name absent', () => { + renderGroup({}); + expect(document.title).toContain(config.defaultTitle); + expect(document.getElementById(`${type}-name`).textContent).toBe(config.defaultName); + }); + + test('shows IGDB link when URL provided', () => { + renderGroup({ name: config.name, url: `https://igdb.com/${type}s/test` }); + const link = document.getElementById(`${type}-igdb-link`); + expect(link.classList.contains('d-none')).toBe(false); + expect(link.href).toContain('igdb.com'); + }); + + test('keeps IGDB link hidden when no URL', () => { + renderGroup({ name: config.name }); + expect(document.getElementById(`${type}-igdb-link`).classList.contains('d-none')).toBe(true); + }); + + test('shows games section when games present', () => { + renderGroup({ + name: config.name, + games: [{ id: 1, name: 'Test Game', cover: { url: '//img.igdb.com/t_thumb/c.jpg' } }], + }); + expect(document.getElementById(`${type}-games-section`).classList.contains('d-none')).toBe(false); + }); + + test('keeps games section hidden when no games', () => { + renderGroup({ name: config.name }); + expect(document.getElementById(`${type}-games-section`).classList.contains('d-none')).toBe(true); + }); + }); +} + +// --- Tests --- + +describe('group_detail.js', () => { + afterEach(() => { + document.body.innerHTML = ''; + delete globalThis.GAMEDB_GROUP_TYPE; + }); + + describe('GROUP_CONFIG', () => { + test('defines collection config', () => { + expect(GROUP_CONFIG.collection.endpoint).toBe('collections'); + expect(GROUP_CONFIG.collection.defaultTitle).toBe('Series'); + expect(GROUP_CONFIG.collection.defaultName).toBe('Unknown Series'); + }); + + test('defines franchise config', () => { + expect(GROUP_CONFIG.franchise.endpoint).toBe('franchises'); + expect(GROUP_CONFIG.franchise.defaultTitle).toBe('Franchise'); + expect(GROUP_CONFIG.franchise.defaultName).toBe('Unknown Franchise'); + }); + }); + + describeRenderGroup('collection', { + name: 'Sonic the Hedgehog', + defaultTitle: 'Series', + defaultName: 'Unknown Series', + }); + + describeRenderGroup('franchise', { + name: 'The Legend of Zelda', + defaultTitle: 'Franchise', + defaultName: 'Unknown Franchise', + }); + + describe('renderGroup – defaults to collection type when GAMEDB_GROUP_TYPE is unset', () => { + beforeEach(() => { + document.body.innerHTML = makeGroupDom('collection'); + }); + + test('falls back to collection type', () => { + renderGroup({ name: 'Default Series' }); + expect(document.getElementById('collection-name').textContent).toBe('Default Series'); + }); + }); + + describe('DOMContentLoaded integration', () => { + test('fires loadItemDetail for collection on DOMContentLoaded', () => { + globalThis.GAMEDB_GROUP_TYPE = 'collection'; + globalThis.history.pushState(null, '', '/'); + expect(() => document.dispatchEvent(new Event('DOMContentLoaded'))).not.toThrow(); + }); + + test('fires loadItemDetail for franchise on DOMContentLoaded', () => { + globalThis.GAMEDB_GROUP_TYPE = 'franchise'; + globalThis.history.pushState(null, '', '/'); + expect(() => document.dispatchEvent(new Event('DOMContentLoaded'))).not.toThrow(); + }); + + test('fires loadItemDetail with default collection type when GAMEDB_GROUP_TYPE is unset', () => { + globalThis.history.pushState(null, '', '/'); + expect(() => document.dispatchEvent(new Event('DOMContentLoaded'))).not.toThrow(); + }); + }); +}); diff --git a/tests/item_detail.test.js b/tests/item_detail.test.js index a6608340cc00..392d8f14930c 100644 --- a/tests/item_detail.test.js +++ b/tests/item_detail.test.js @@ -16,6 +16,7 @@ globalThis.GAMEDB_CONFIG = { base_path: '/GameDB' }; const { igdbImageUrl, + getRegionFlag, makeBadge, addDlRow, showError, @@ -70,6 +71,26 @@ describe('item_detail.js', () => { }); }); + describe('getRegionFlag', () => { + test('returns correct flags for all known regions', () => { + expect(getRegionFlag('europe')).toBe('πŸ‡ͺπŸ‡Ί'); + expect(getRegionFlag('north_america')).toBe('πŸ‡ΊπŸ‡Έ'); + expect(getRegionFlag('australia')).toBe('πŸ‡¦πŸ‡Ί'); + expect(getRegionFlag('new_zealand')).toBe('πŸ‡³πŸ‡Ώ'); + expect(getRegionFlag('japan')).toBe('πŸ‡―πŸ‡΅'); + expect(getRegionFlag('china')).toBe('πŸ‡¨πŸ‡³'); + expect(getRegionFlag('asia')).toBe('🌏'); + expect(getRegionFlag('worldwide')).toBe('🌍'); + expect(getRegionFlag('korea')).toBe('πŸ‡°πŸ‡·'); + expect(getRegionFlag('brazil')).toBe('πŸ‡§πŸ‡·'); + }); + + test('returns default globe for unknown region', () => { + expect(getRegionFlag('unknown')).toBe('🌐'); + expect(getRegionFlag('')).toBe('🌐'); + }); + }); + describe('makeBadge', () => { test('creates badge with provided class', () => { const badge = makeBadge('Action', 'bg-primary'); diff --git a/tests/platform_detail.test.js b/tests/platform_detail.test.js index 1593ddc1e908..9420e4d49f31 100644 --- a/tests/platform_detail.test.js +++ b/tests/platform_detail.test.js @@ -18,11 +18,11 @@ globalThis.makeBadge = itemDetail.makeBadge; globalThis.addDlRow = itemDetail.addDlRow; globalThis.loadItemDetail = itemDetail.loadItemDetail; globalThis.renderGameList = itemDetail.renderGameList; +globalThis.getRegionFlag = itemDetail.getRegionFlag; globalThis.base_path = '/GameDB'; globalThis.base_url = 'http://localhost/GameDB'; const { - getRegionFlag, renderPlatformLogo, renderPlatformBadges, renderPlatformMetadata, @@ -59,26 +59,6 @@ describe('platform_detail.js', () => { document.body.innerHTML = ''; }); - describe('getRegionFlag', () => { - test('returns correct flags for all known regions', () => { - expect(getRegionFlag('europe')).toBe('πŸ‡ͺπŸ‡Ί'); - expect(getRegionFlag('north_america')).toBe('πŸ‡ΊπŸ‡Έ'); - expect(getRegionFlag('australia')).toBe('πŸ‡¦πŸ‡Ί'); - expect(getRegionFlag('new_zealand')).toBe('πŸ‡³πŸ‡Ώ'); - expect(getRegionFlag('japan')).toBe('πŸ‡―πŸ‡΅'); - expect(getRegionFlag('china')).toBe('πŸ‡¨πŸ‡³'); - expect(getRegionFlag('asia')).toBe('🌏'); - expect(getRegionFlag('worldwide')).toBe('🌍'); - expect(getRegionFlag('korea')).toBe('πŸ‡°πŸ‡·'); - expect(getRegionFlag('brazil')).toBe('πŸ‡§πŸ‡·'); - }); - - test('returns default globe for unknown region', () => { - expect(getRegionFlag('unknown')).toBe('🌐'); - expect(getRegionFlag('')).toBe('🌐'); - }); - }); - describe('renderPlatformLogo', () => { test('renders logo when URL provided', () => { renderPlatformLogo({