'use strict'; const assert = require('node:assert/strict'); const fs = require('node:fs'); const path = require('node:path'); const test = require('node:test'); const root = path.resolve(__dirname, '../..'); const read = relative => fs.readFileSync(path.join(root, relative), 'utf8'); const { createUnsupportedLiveTrophyAdapter, createTrophyReconstructionSimulator } = require('../../src/services/trophy-reconstruction-action-service'); const { createExperimentalBarAdapter } = require('../../src/services/system-backup-recovery-lab-service'); const { createUnsupportedDirectSaveExtractionProvider } = require('../../src/services/save-recovery-plan-service'); test('A-050 through A-059 map to concrete P9 automated evidence', () => { const evidence = { 'A-050': ['test/server/ch-0903-trophy-mapping-diff.test.js', /psn_only/], 'A-051': ['test/server/ch-0903-trophy-mapping-diff.test.js', /local_only/], 'A-052': ['test/server/ch-0904-trophy-reconstruction-plan.test.js', /unearned/i], 'A-053': ['test/server/ch-0903-trophy-mapping-diff.test.js', /unmappable/], 'A-054': ['test/server/ch-0903-trophy-mapping-diff.test.js', /ambiguous|diagnostic/i], 'A-055': ['test/server/ch-0905-trophy-action.test.js', /unsupported exact timestamp capability/i], 'A-056': ['test/server/ch-0905-trophy-action.test.js', /backup failure/i], 'A-057': ['test/server/ch-0905-trophy-action.test.js', /mid-action failure/i], 'A-058': ['test/server/ch-0905-trophy-action.test.js', /no network or PSN provider/i], 'A-059': ['test/server/ch-0906-trophy-ui.test.js', /arbitrary trophy ID or unlock-all/i], }; assert.deepEqual(Object.keys(evidence), Array.from({ length: 10 }, (_, index) => `A-05${index}`)); for (const [acceptance, [file, pattern]] of Object.entries(evidence)) assert.match(read(file), pattern, `${acceptance} evidence missing`); }); test('trophy apply dependency graph has no network or PSN provider and source provider is GET-only', () => { const action = read('src/services/trophy-reconstruction-action-service.js'); assert.doesNotMatch(action, /node:https?|node-fetch|axios|\bfetch\s*\(|psn-provider|psn-client/i); const source = read('src/services/trophy-snapshot-service.js'); assert.doesNotMatch(source, /method\s*:\s*['"](?:POST|PUT|PATCH|DELETE)['"]/i); assert.doesNotMatch(source, /unlock[-_ ]?all|syncTroph|writeTroph|deleteTroph/i); const registries = `${read('src/server/create-registry.js')}\n${read('src/server/register-functional-modules.js')}`; assert.match(registries, /name:\s*'trophy:history-import:preview'.+classification:\s*'read-only'/); assert.match(registries, /name:\s*'trophy:history-import:apply'.+classification:\s*'mutating'/); assert.doesNotMatch(registries, /name\s*:\s*['"][^'"]*troph[^'"]*(?:sync|psn-write|write-psn)[^'"]*['"]/i); }); test('all unproven live P9 actions remain unavailable and tests use simulators', () => { const liveTrophy = createUnsupportedLiveTrophyAdapter().status(); assert.equal(liveTrophy.available, false); assert.equal(liveTrophy.simulated, false); const simulator = createTrophyReconstructionSimulator().status(); assert.equal(simulator.available, true); assert.equal(simulator.simulated, true); const bar = createExperimentalBarAdapter().status(); assert.equal(bar.available, false); assert.equal(bar.state, 'wip'); assert.ok(bar.limitations.includes('no-restore')); const directSave = createUnsupportedDirectSaveExtractionProvider().status(); assert.equal(directSave.available, false); assert.deepEqual(directSave.capabilities, []); for (const file of ['test/server/ch-0905-trophy-action.test.js','test/server/ch-0907-system-backup-recovery-lab.test.js','test/server/ch-0908-save-recovery-plan.test.js']) { const source = read(file); assert.doesNotMatch(source, /(?:192\.168\.|10\.\d+\.|172\.(?:1[6-9]|2\d|3[01])\.)/); assert.doesNotMatch(source, /ssh|ftp:\/\//i); } }); test('P9 security boundaries retain immutable evidence, exact confirmation and rollback', () => { assert.match(read('src/database/migrations/0012-create-trophy-psn-snapshots.js'), /immutable/i); assert.match(read('src/database/migrations/0016-create-trophy-reconstruction-journals.js'), /immutable/i); assert.match(read('src/services/trophy-reconstruction-action-service.js'), /RECONSTRUCT LOCAL TROPHIES/); assert.match(read('src/services/save-recovery-plan-service.js'), /manualStart !== true/); assert.match(read('src/services/save-recovery-plan-service.js'), /restoreBackup/); assert.match(read('src/services/system-backup-recovery-lab-service.js'), /promises\.open\(filePath, 'r'\)/); });