'use strict'; const assert = require('node:assert/strict'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const test = require('node:test'); const { createImportedTrophyDefinitionService, parsePackage } = require('../../src/services/imported-trophy-definition-service'); const { importedCatalogMarkup } = require('../../src/renderer/trophies'); function fixture(title = 'Historical Game') { return { schema: 'chimera-trophy-definition', schemaVersion: 1, catalogKey: 'np:00112233445566778899aabbccddeeff', revision: '3-example', game: { title, description: 'Imported locally', trophyCount: 1 }, trophies: [ { id: 0, grade: 'bronze', groupId: -1, hidden: false, name: 'First', description: 'Begin' } ] }; } test('strict package parser rejects unknown fields and non-sequential trophies', () => { assert.equal(parsePackage(fixture()).game.title, 'Historical Game'); assert.throws(() => parsePackage({ ...fixture(), extra: true }), /shape/); const invalid = fixture(); invalid.trophies[0].id = 2; assert.throws(() => parsePackage(invalid), /row/); }); test('imports idempotently and survives a service restart', t => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'chimera-trophy-definitions-')); t.after(() => fs.rmSync(root, { recursive: true, force: true })); const first = createImportedTrophyDefinitionService({ root }); const imported = first.importPackage(fixture()); assert.equal(imported.trophyCount, 1); assert.match(imported.digest, /^[a-f0-9]{64}$/); first.importPackage(fixture()); assert.equal(fs.readdirSync(root).length, 1); const second = createImportedTrophyDefinitionService({ root }); assert.equal(second.list().games[0].game.title, 'Historical Game'); assert.equal(second.list().persisted, true); }); test('renderer and command registry expose a local-only import path', () => { const markup = importedCatalogMarkup({ available: true, count: 1, games: [fixture()] }, (_key, fallback) => fallback); assert.match(markup, /Historical Game/); assert.match(markup, /trophy-definition-json/); const registry = fs.readFileSync(path.join(__dirname, '../../src/server/register-functional-modules.js'), 'utf8'); const preload = fs.readFileSync(path.join(__dirname, '../../preload.js'), 'utf8'); assert.match(registry, /trophy:imported-catalog:import'.+classification: 'mutating'/); assert.match(registry, /maxBodyBytes: 1024 \* 1024/); assert.match(preload, /trophyImportDefinition/); });