Initial curated chimera source from a8ae5b1db07fb49926c94585e2718e5130330974
This commit is contained in:
commit
c737a37f71
531 files changed
+119270
No files matched your search
@@ -0,0 +1,63 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const test = require('node:test');
|
||||
const { deriveResumeState, nextFocusIndex, normalizeFileSelection, validateWizardStep } = require('../../renderer/modules/import-wizard');
|
||||
const { buildManifest, validateManifest } = require('../../src/services/portable-manifest-service');
|
||||
|
||||
const evidence = (value, source = 'test', confidence = 'high') => ({ value, source, confidence, observedAt: 1 });
|
||||
function component(id, type, relativePath) { return { id, type: evidence(type), relativePath, size: 4, sha256: id[0].repeat(64), platform: 'ps4', titleId: evidence('CUSA12345'), contentId: evidence(`UP0001-CUSA12345_00-${id.slice(0, 16).toUpperCase()}`), version: evidence('1.00'), provenance: [{ source: 'staging-sha256', confidence: 'verified', observedAt: 1 }] }; }
|
||||
function classification() {
|
||||
const components = [component('a'.repeat(24), 'base', 'base.pkg'), component('b'.repeat(24), 'patch_bundle', 'patches/fix.zip'), component('c'.repeat(24), 'image', 'art/cover.png')];
|
||||
return { status: 'classified', jobId: 'job', title: { id: evidence('CUSA12345'), platform: 'ps4' }, components, notes: [], recipeProposal: { installOrder: components.map((item, index) => ({ order: index + 1, componentId: item.id, componentType: item.type.value, action: 'proposal-only' })) } };
|
||||
}
|
||||
|
||||
test('folder and multi-file selections normalize relative names and reject empty files', () => {
|
||||
const selected = normalizeFileSelection([{ name: 'base.pkg', webkitRelativePath: 'Game/base.pkg', size: 4 }, { name: 'empty.txt', size: 0 }]);
|
||||
assert.deepEqual(selected.map(item => item.relativePath), ['Game/base.pkg']);
|
||||
});
|
||||
|
||||
test('resume progress uses durable server offsets', () => {
|
||||
assert.deepEqual(deriveResumeState({ state: 'uploading', files: [{ size: 8, offset: 4 }, { size: 2, bytesReceived: 2 }] }), { resumable: true, expected: 10, received: 6, percent: 60 });
|
||||
assert.equal(deriveResumeState({ state: 'uploaded', files: [] }).resumable, false);
|
||||
});
|
||||
|
||||
test('keyboard focus wraps in both directions and validation errors are explicit', () => {
|
||||
assert.equal(nextFocusIndex(2, 3, false), 0);
|
||||
assert.equal(nextFocusIndex(0, 3, true), 2);
|
||||
assert.equal(validateWizardStep({ step: 0, selection: [], session: null }), 'importWizard.error.selection');
|
||||
assert.equal(validateWizardStep({ step: 3, classification: { status: 'classified' }, destinationId: '' }), 'importWizard.error.destination');
|
||||
assert.equal(validateWizardStep({ step: 4, classification: { status: 'classified' }, destinationId: 'library', confirmed: false }), 'importWizard.error.confirm');
|
||||
});
|
||||
|
||||
test('editable order, non-executable notes, patch/APR and artwork selections persist in the manifest', () => {
|
||||
const source = classification();
|
||||
const order = source.components.map(item => item.id).reverse();
|
||||
const manifest = buildManifest(source, { titleName: 'Wizard', componentOrder: order, installNotes: 'Review first; never execute.', patchComponentIds: [source.components[1].id], artworkComponentIds: [source.components[2].id] }, 2);
|
||||
assert.deepEqual(manifest.recipe.installOrder.map(item => item.componentId), order);
|
||||
assert.equal(manifest.recipe.installNotes, 'Review first; never execute.');
|
||||
assert.deepEqual(manifest.recipe.attachments.patches, [{ componentId: source.components[1].id, type: 'patch_bundle' }]);
|
||||
assert.deepEqual(manifest.recipe.attachments.artwork, [{ componentId: source.components[2].id, type: 'image' }]);
|
||||
assert.equal(manifest.recipe.notesExecutable, false);
|
||||
assert.deepEqual(validateManifest(manifest), { valid: true, errors: [] });
|
||||
assert.throws(() => buildManifest(source, { componentOrder: [order[0], order[0], order[2]] }), error => error.code === 'MANIFEST_ORDER');
|
||||
});
|
||||
|
||||
test('wizard is core-loaded with responsive styling and complete English/Dutch keys', () => {
|
||||
const root = path.resolve(__dirname, '../..');
|
||||
const index = fs.readFileSync(path.join(root, 'renderer/index.html'), 'utf8');
|
||||
const bootstrap = fs.readFileSync(path.join(root, 'renderer/bootstrap.js'), 'utf8');
|
||||
const css = fs.readFileSync(path.join(root, 'renderer/styles/import-wizard.css'), 'utf8');
|
||||
const source = fs.readFileSync(path.join(root, 'renderer/modules/import-wizard.js'), 'utf8');
|
||||
const en = JSON.parse(fs.readFileSync(path.join(root, 'build/lang/en.json'), 'utf8'));
|
||||
const nl = JSON.parse(fs.readFileSync(path.join(root, 'build/lang/nl.json'), 'utf8'));
|
||||
assert.doesNotMatch(index, /styles\/import-wizard\.css/);
|
||||
assert.doesNotMatch(bootstrap, /modules\/import-wizard\.js/);
|
||||
assert.match(index, /type="module" src="modules\/import-wizard\.js"/);
|
||||
assert.match(source, /styles\/import-wizard\.css/);
|
||||
assert.match(css, /@media\(max-width:640px\)/);
|
||||
assert.match(source, /role=\"dialog\" aria-modal=\"true\"/);
|
||||
for (const key of ['importWizard.open', 'importWizard.resume', 'importWizard.reviewRequired', 'importWizard.finalizeAction']) { assert.equal(typeof en.strings[key], 'string'); assert.equal(typeof nl.strings[key], 'string'); }
|
||||
});
|
||||
Reference in new issue
Block a user