generated from Labyricorn/labyricorn-project-template
Fix translation fallbacks, start menu lifecycle, add user last name, and verifier certificate print
This commit is contained in:
+19
-8
@@ -90,6 +90,16 @@ async function runAllTests() {
|
||||
assert(res.includes('NexaCore'));
|
||||
});
|
||||
|
||||
await test('Default embedded English catalog contains all cert.* keys without missing labels', async () => {
|
||||
const rawI18n = new I18nService({ defaultLocale: 'en' });
|
||||
const certTitle = rawI18n.t('cert.title');
|
||||
const compTitle = rawI18n.t('cert.competencyTitle');
|
||||
const env = rawI18n.t('cert.environment');
|
||||
assert(!certTitle.startsWith('[missing:'));
|
||||
assert(!compTitle.startsWith('[missing:'));
|
||||
assert(!env.startsWith('[missing:'));
|
||||
});
|
||||
|
||||
console.log('\n--- 2. Corporate Branding Tests ---');
|
||||
const customConfig = {
|
||||
organization: {
|
||||
@@ -117,25 +127,26 @@ async function runAllTests() {
|
||||
});
|
||||
|
||||
console.log('\n--- 3. Personalization & Safe Template Interpolation Tests ---');
|
||||
await test('ActionDispatcher resolves {{learner.firstName}} and {{learner.name}}', async () => {
|
||||
await test('ActionDispatcher resolves {{learner.firstName}}, {{learner.lastName}}, and {{learner.name}}', async () => {
|
||||
const mockScenario = {
|
||||
learner: { firstName: 'Alex', name: 'Alex Rivera', role: 'Specialist' },
|
||||
learner: { firstName: 'Chris', lastName: 'Morgan', name: 'Chris Morgan', role: 'Specialist' },
|
||||
organizations: [{ name: 'NexaCore' }]
|
||||
};
|
||||
const dispatcher = new ActionDispatcher({ scenario: mockScenario });
|
||||
const ctx = dispatcher._buildInterpolationContext();
|
||||
assert.equal(ctx['learner.firstName'], 'Alex');
|
||||
assert.equal(ctx['learner.name'], 'Alex Rivera');
|
||||
assert.equal(ctx['learner.firstName'], 'Chris');
|
||||
assert.equal(ctx['learner.lastName'], 'Morgan');
|
||||
assert.equal(ctx['learner.name'], 'Chris Morgan');
|
||||
|
||||
const tmpl = 'Hello {{learner.firstName}}, your full name is {{learner.name}}.';
|
||||
const tmpl = 'Hello {{learner.firstName}} {{learner.lastName}}, full: {{learner.name}}.';
|
||||
const interpolated = dispatcher.interpolate(tmpl, ctx);
|
||||
assert.equal(interpolated, 'Hello Alex, your full name is Alex Rivera.');
|
||||
assert.equal(interpolated, 'Hello Chris Morgan, full: Chris Morgan.');
|
||||
});
|
||||
|
||||
await test('Malicious HTML entered as first name is escaped harmlessly', async () => {
|
||||
await test('Malicious HTML entered as first/last name is escaped harmlessly', async () => {
|
||||
const xssPayload = '<script>alert("pwned")</script><img src=x onerror=alert(1)>';
|
||||
const mockScenario = {
|
||||
learner: { firstName: xssPayload, name: xssPayload },
|
||||
learner: { firstName: xssPayload, lastName: xssPayload, name: xssPayload },
|
||||
organizations: [{ name: 'NexaCore' }]
|
||||
};
|
||||
const dispatcher = new ActionDispatcher({ scenario: mockScenario });
|
||||
|
||||
Reference in New Issue
Block a user