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,135 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const test = require('node:test');
|
||||
const { DIFF_STATES, buildTrophyMarkup, canExecute, normalizeOverview } = require('../../src/renderer/trophies');
|
||||
|
||||
const root = path.resolve(__dirname, '../..');
|
||||
const frozenPlan = {
|
||||
id: 'plan-0906', status: 'ready', confirmationPhrase: 'RECONSTRUCT LOCAL TROPHIES 2',
|
||||
backup: { status: 'verified', verified: true },
|
||||
adapter: { id: 'simulated-local-adapter', version: '1.0.0', available: true },
|
||||
timestampPolicy: 'preserve_exact',
|
||||
items: [
|
||||
{ title: 'Example', identity: 'NPWR12345_00/default/2', eligible: true, reasons: [] },
|
||||
{ title: 'Blocked', identity: 'NPWR12345_00/default/3', eligible: false, reasons: ['Local scan coverage is partial.'] },
|
||||
],
|
||||
};
|
||||
const overview = {
|
||||
source: { provider: 'json-import', fetchedAt: '2026-07-22T00:00:00.000Z', accountIdentity: 'je***@example' },
|
||||
local: { profileIdentity: 'local-***-7', coverage: 'complete', differs: true },
|
||||
diffs: DIFF_STATES.map((state, index) => ({ state, title: `Title ${index}`, identity: `NPWR${index}` })),
|
||||
plan: frozenPlan,
|
||||
};
|
||||
|
||||
test('normal mode renders source and all read-only diff states without Expert controls', () => {
|
||||
const markup = buildTrophyMarkup(overview, { expert: false });
|
||||
assert.match(markup, /Read-only evidence/);
|
||||
assert.match(markup, /Local profile differs/);
|
||||
for (const state of DIFF_STATES) assert.match(markup, new RegExp(`data-diff-state="${state}"`));
|
||||
assert.doesNotMatch(markup, /trophy-confirmation|trophy-reconstruct-submit|Frozen plan items/);
|
||||
});
|
||||
|
||||
test('Expert mode shows exact eligible and ineligible reasons plus safety state', () => {
|
||||
const markup = buildTrophyMarkup(overview, { expert: true });
|
||||
assert.match(markup, /data-expert-only="true"/);
|
||||
assert.match(markup, /NPWR12345_00\/default\/2/);
|
||||
assert.match(markup, /Local scan coverage is partial/);
|
||||
assert.match(markup, /Verified backup/);
|
||||
assert.match(markup, /simulated-local-adapter 1\.0\.0/);
|
||||
assert.match(markup, /preserve_exact/);
|
||||
assert.match(markup, /Local PS5 only - never written to PSN/);
|
||||
});
|
||||
|
||||
test('exact confirmation and every safety gate are required', () => {
|
||||
const safe = { ...overview, plan: { ...frozenPlan, items: [frozenPlan.items[0]] } };
|
||||
assert.equal(canExecute(safe, { expert: false, confirmation: frozenPlan.confirmationPhrase }), false);
|
||||
assert.equal(canExecute(safe, { expert: true, confirmation: 'RECONSTRUCT' }), false);
|
||||
assert.equal(canExecute(safe, { expert: true, confirmation: frozenPlan.confirmationPhrase }), true);
|
||||
assert.equal(canExecute({ ...safe, plan: { ...safe.plan, backup: { status: 'required', verified: false } } }, { expert: true, confirmation: frozenPlan.confirmationPhrase }), false);
|
||||
assert.equal(canExecute({ ...safe, plan: { ...safe.plan, timestampPolicy: 'current_time_only' } }, { expert: true, confirmation: frozenPlan.confirmationPhrase }), false);
|
||||
assert.equal(canExecute(overview, { expert: true, confirmation: frozenPlan.confirmationPhrase }), false);
|
||||
});
|
||||
|
||||
test('UI has no arbitrary trophy ID or unlock-all input and uses local reconstruction language', () => {
|
||||
const markup = buildTrophyMarkup(overview, { expert: true });
|
||||
assert.doesNotMatch(markup, /name="(?:trophyId|groupId|npCommunicationId)"/i);
|
||||
assert.doesNotMatch(markup, /unlock[- ]?all|sync trophies/i);
|
||||
assert.match(markup, /Reconstruct locally from PSN snapshot/);
|
||||
assert.equal((markup.match(/<input/g) || []).length, 4);
|
||||
assert.match(markup, /id="trophy-reveal-hidden" type="checkbox"/);
|
||||
assert.match(markup, /name="confirmation"/);
|
||||
});
|
||||
|
||||
test('historical import UI supports PSN-ID preview, selective import and exact-date messaging', () => {
|
||||
const markup = buildTrophyMarkup(overview, { historyStatus: { configured: true }, historyPreview: { onlineId: 'Nuklear_Rabbit', games: [{ key: 'NPWR1|trophy2', name: 'Native PS5 Game', platform: 'PS5', earned: 4, progress: 50, lastUpdatedDateTime: '2024-01-02T03:04:05Z' }] }, historySelected: new Set(['NPWR1|trophy2']) });
|
||||
assert.match(markup, /id="trophy-history-online-id"/);
|
||||
assert.match(markup, /Native PS5 Game/);
|
||||
assert.match(markup, /Import selection \(1\)/);
|
||||
assert.match(markup, /Import all games/);
|
||||
assert.match(markup, /preserves earned dates exactly/);
|
||||
});
|
||||
|
||||
test('desktop UI offers automated Sony login while retaining manual fallback', () => {
|
||||
const markup = buildTrophyMarkup(overview, { historyStatus: { configured: false }, historyBrowserAuthAvailable: true });
|
||||
assert.match(markup, /Sign in securely with Sony/); assert.match(markup, /temporary isolated sign-in window/);
|
||||
assert.match(markup, /NPSSO token/);
|
||||
});
|
||||
|
||||
test('historical snapshot UI displays PS5 earned state while concealing hidden names by default', () => {
|
||||
const snapshot = { id: `psn-${'a'.repeat(64)}`, account: { onlineId: 'Player_One' }, titleCount: 1, fetchedAt: '2026-08-11T12:00:00Z', titles: [{ name: 'Native PS5 Game', platform: 'PS5', trophies: [{ trophyId: 7, name: 'Secret ending', grade: 'gold', hidden: true, earned: true, earnedDateTime: '2024-02-03T04:05:06.789Z' }] }] };
|
||||
const concealed = buildTrophyMarkup(overview, { historySnapshots: [snapshot], historyDetail: snapshot });
|
||||
assert.match(concealed, /Native PS5 Game/); assert.match(concealed, /Hidden trophy/); assert.doesNotMatch(concealed, /Secret ending/);
|
||||
const revealed = buildTrophyMarkup(overview, { historySnapshots: [snapshot], historyDetail: snapshot, revealHidden: true });
|
||||
assert.match(revealed, /Secret ending/); assert.match(revealed, /2024/);
|
||||
});
|
||||
|
||||
test('progression UI works without PSN history and clearly separates preview from live apply', () => {
|
||||
const catalogs = { available: true, games: [{ catalogKey: 'np:11111111111111111111111111111111', catalogSha256: 'a'.repeat(64), revision: 'one', game: { title: 'Local Definition', trophyCount: 2 }, trophies: [
|
||||
{ id: 0, groupId: 0, grade: 'bronze', hidden: false, name: 'First', description: 'Begin', earned: false },
|
||||
{ id: 1, groupId: 0, grade: 'platinum', hidden: false, name: 'Platinum', description: 'All', earned: false },
|
||||
] }] };
|
||||
const plan = { confirmationPhrase: 'APPLY LOCAL PROGRESSION 2 Local Definition', items: [
|
||||
{ trophyId: 0, grade: 'bronze', name: 'First', proposedEarnedDateTime: '2021-01-01T01:00:00.000Z', timestampKind: 'synthetic-estimate', confidence: { level: 'estimated' } },
|
||||
{ trophyId: 1, grade: 'platinum', name: 'Platinum', proposedEarnedDateTime: '2021-01-03T01:00:00.000Z', timestampKind: 'synthetic-estimate', confidence: { level: 'estimated' } },
|
||||
] };
|
||||
const markup = buildTrophyMarkup(overview, { progressionState: { catalogs, catalogKey: catalogs.games[0].catalogKey, selected: new Set([0, 1]), mode: 'synthetic_unlock', strategy: 'balanced', startDateTime: '2021-01-01T00:00', endDateTime: '2021-01-04T00:00', minimumIntervalMinutes: 30, plan } });
|
||||
assert.match(markup, /Progression timeline planner/);
|
||||
assert.match(markup, /without a PSN import/);
|
||||
assert.match(markup, /Synthetic estimate — not original PSN history/);
|
||||
assert.match(markup, /Live PS5 apply remains unavailable/);
|
||||
assert.match(markup, /id="trophy-progression-create"/);
|
||||
assert.doesNotMatch(markup, /id="trophy-progression-apply"/);
|
||||
const timeline = markup.match(/<div class="trophy-progression-preview">[\s\S]*?<ol>([\s\S]*?)<\/ol>/);
|
||||
assert.ok(timeline);
|
||||
assert.match(timeline[1], /<strong>First<\/strong>[\s\S]*<strong>Platinum<\/strong>/);
|
||||
});
|
||||
|
||||
test('trophy UI preserves accessibility and English/Dutch i18n contracts', () => {
|
||||
const markup = buildTrophyMarkup(normalizeOverview(overview), { expert: true });
|
||||
assert.match(markup, /aria-labelledby="trophy-evidence-title"/);
|
||||
assert.match(markup, /aria-live="assertive"/);
|
||||
assert.match(markup, /aria-describedby="trophy-confirm-help"/);
|
||||
assert.match(markup, /<label for="trophy-confirmation">/);
|
||||
const en = JSON.parse(fs.readFileSync(path.join(root, 'build/lang/en.json'), 'utf8')).strings;
|
||||
const nl = JSON.parse(fs.readFileSync(path.join(root, 'build/lang/nl.json'), 'utf8')).strings;
|
||||
const keys = Object.keys(en).filter(key => key.startsWith('trophies.') || key.startsWith('navigation.routes.protection.trophies'));
|
||||
assert.ok(keys.length >= 40);
|
||||
for (const key of keys) assert.equal(typeof nl[key], 'string', `Dutch translation missing: ${key}`);
|
||||
});
|
||||
|
||||
test('route and bootstrap expose the normal trophy overview page', () => {
|
||||
const routes = require('../../renderer/modules/navigation-routes');
|
||||
const route = routes.routes.find(item => item.id === 'protection/trophies');
|
||||
assert.equal(route.page, 'trophies');
|
||||
assert.notEqual(route.expert, true);
|
||||
const bootstrap = fs.readFileSync(path.join(root, 'renderer/bootstrap.js'), 'utf8');
|
||||
const html = fs.readFileSync(path.join(root, 'renderer/index.html'), 'utf8');
|
||||
assert.match(bootstrap, /trophies: \['\.\.\/src\/renderer\/trophies\.js'\]/);
|
||||
assert.match(html, /id="page-trophies"/);
|
||||
assert.match(fs.readFileSync(path.join(root, 'src/renderer/trophies.js'), 'utf8'), /page\.id = 'page-trophies'/);
|
||||
assert.doesNotMatch(html, /styles\/trophies\.css/);
|
||||
assert.match(fs.readFileSync(path.join(root, 'src/renderer/trophies.js'), 'utf8'), /styles\/trophies\.css/);
|
||||
});
|
||||
Reference in new issue
Block a user