- utils/accentColor (8): hexToRgb parsing, lighten/darken channel math, rgba clamping, WCAG relativeLuminance (black=0/white=1), contrastingText threshold, varNameFromToken, and derivePrimaryPalette's full 10-token output. - utils/matrix-uia (7): UIA flow helpers — getSupportedUIAFlows, completed/params/session/errcode/error accessors, getUIAFlowForStages (incl. the single-extra-dummy rule), has/requiredStageInFlows, and getLoginTermUrl language fallback. Full suite now 123 tests, all passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
85 lines
3.3 KiB
TypeScript
85 lines
3.3 KiB
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { AuthType, IAuthData, UIAFlow } from 'matrix-js-sdk';
|
|
import {
|
|
getSupportedUIAFlows,
|
|
getUIACompleted,
|
|
getUIAParams,
|
|
getUIASession,
|
|
getUIAErrorCode,
|
|
getUIAError,
|
|
getUIAFlowForStages,
|
|
hasStageInFlows,
|
|
requiredStageInFlows,
|
|
getLoginTermUrl,
|
|
} from './matrix-uia';
|
|
|
|
const flows = (...stageLists: string[][]): UIAFlow[] =>
|
|
stageLists.map((stages) => ({ stages })) as UIAFlow[];
|
|
const auth = (data: Record<string, unknown>): IAuthData => data as unknown as IAuthData;
|
|
|
|
test('getSupportedUIAFlows keeps only fully-supported flows', () => {
|
|
const f = flows(['a', 'b'], ['a', 'c']);
|
|
assert.deepEqual(getSupportedUIAFlows(f, ['a', 'b']), [{ stages: ['a', 'b'] }]);
|
|
assert.deepEqual(getSupportedUIAFlows(f, ['a', 'b', 'c']), f);
|
|
assert.deepEqual(getSupportedUIAFlows(f, ['x']), []);
|
|
});
|
|
|
|
test('getUIACompleted / Params / Session default sensibly', () => {
|
|
assert.deepEqual(getUIACompleted(auth({ completed: ['m.login.password'] })), [
|
|
'm.login.password',
|
|
]);
|
|
assert.deepEqual(getUIACompleted(auth({})), []);
|
|
assert.deepEqual(getUIAParams(auth({ params: { x: { y: 1 } } })), { x: { y: 1 } });
|
|
assert.deepEqual(getUIAParams(auth({})), {});
|
|
assert.equal(getUIASession(auth({ session: 'abc' })), 'abc');
|
|
assert.equal(getUIASession(auth({})), undefined);
|
|
});
|
|
|
|
test('getUIAErrorCode / getUIAError read string fields only', () => {
|
|
assert.equal(getUIAErrorCode(auth({ errcode: 'M_FORBIDDEN' })), 'M_FORBIDDEN');
|
|
assert.equal(getUIAErrorCode(auth({ errcode: 42 })), undefined);
|
|
assert.equal(getUIAErrorCode(auth({})), undefined);
|
|
assert.equal(getUIAError(auth({ error: 'Bad' })), 'Bad');
|
|
assert.equal(getUIAError(auth({})), undefined);
|
|
});
|
|
|
|
test('getUIAFlowForStages: exact match and no match', () => {
|
|
const f = flows(['m.login.password'], ['m.login.recaptcha', 'm.login.password']);
|
|
assert.deepEqual(getUIAFlowForStages(f, ['m.login.password']), { stages: ['m.login.password'] });
|
|
assert.equal(getUIAFlowForStages(f, ['m.login.sso']), undefined);
|
|
});
|
|
|
|
test('getUIAFlowForStages allows a single extra m.login.dummy stage', () => {
|
|
const f = flows(['m.login.recaptcha', AuthType.Dummy]);
|
|
assert.deepEqual(getUIAFlowForStages(f, ['m.login.recaptcha']), {
|
|
stages: ['m.login.recaptcha', AuthType.Dummy],
|
|
});
|
|
// two extra stages (more than dummy) → no match
|
|
assert.equal(getUIAFlowForStages(flows(['a', 'b', AuthType.Dummy]), ['a']), undefined);
|
|
});
|
|
|
|
test('hasStageInFlows / requiredStageInFlows', () => {
|
|
const f = flows(['m.login.password'], ['m.login.recaptcha', 'm.login.password']);
|
|
assert.equal(hasStageInFlows(f, 'm.login.recaptcha'), true);
|
|
assert.equal(hasStageInFlows(f, 'm.login.sso'), false);
|
|
assert.equal(requiredStageInFlows(f, 'm.login.password'), true);
|
|
assert.equal(requiredStageInFlows(f, 'm.login.recaptcha'), false);
|
|
});
|
|
|
|
test('getLoginTermUrl prefers en, else the first language', () => {
|
|
const base = (policies: unknown) => ({ [AuthType.Terms]: { policies } });
|
|
assert.equal(
|
|
getLoginTermUrl(
|
|
base({ privacy_policy: { en: { url: 'https://en' }, fr: { url: 'https://fr' } } }),
|
|
),
|
|
'https://en',
|
|
);
|
|
assert.equal(
|
|
getLoginTermUrl(base({ privacy_policy: { fr: { url: 'https://fr' } } })),
|
|
'https://fr',
|
|
);
|
|
assert.equal(getLoginTermUrl({}), undefined);
|
|
assert.equal(getLoginTermUrl(base(null)), undefined);
|
|
});
|