mirror of
https://github.com/KuekHaoYang/KVideo.git
synced 2026-08-14 08:13:43 +08:00
65 lines
3.0 KiB
JavaScript
65 lines
3.0 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { numericCandidate, prepareActionState } from '../src/browser/action-state.mjs';
|
|
import { getConfig } from '../src/config.mjs';
|
|
import { latestDeployment } from '../src/checks/deployment.mjs';
|
|
import { findDangerousConstructs } from '../src/checks/security-scan.mjs';
|
|
import { redact, redactText } from '../src/core/redact.mjs';
|
|
import { escapeXml } from '../src/core/xml.mjs';
|
|
|
|
test('redacts keyed secrets recursively', () => {
|
|
assert.deepEqual(redact({ nested: { password: 'value', safe: 'visible' } }), {
|
|
nested: { password: '[REDACTED]', safe: 'visible' },
|
|
});
|
|
});
|
|
|
|
test('redacts bearer, GitHub, JWT, and query credentials', () => {
|
|
const token = ['gho', '_abcdefghijklmnopqrstuvwxyz123456'].join('');
|
|
const raw = `Bearer abc.def ${token} ?token=secret-value`;
|
|
const result = redactText(raw);
|
|
assert.doesNotMatch(result, /abcdefghijklmnopqrstuvwxyz|secret-value/);
|
|
});
|
|
|
|
test('escapes XML metacharacters', () => {
|
|
assert.equal(escapeXml(`<a x="1">Tom & 'Ada'</a>`), '<a x="1">Tom & 'Ada'</a>');
|
|
});
|
|
|
|
test('chooses valid alternative values for numeric and range inputs', () => {
|
|
assert.equal(numericCandidate({ min: '0', max: '1', value: '0.5', step: '0.01' }), '0');
|
|
assert.equal(numericCandidate({ min: '10', max: '100', value: '70', step: '1' }), '55');
|
|
});
|
|
|
|
test('maps play and pause controls to deterministic media preconditions', async () => {
|
|
const modes = [];
|
|
const page = { evaluate: async (_callback, mode) => modes.push(mode) };
|
|
await prepareActionState(page, { aria: '播放' });
|
|
await prepareActionState(page, { aria: 'Pause' });
|
|
await prepareActionState(page, { aria: '搜索' });
|
|
assert.deepEqual(modes, ['paused', 'playing']);
|
|
});
|
|
|
|
test('accepts explicit full-run action budgets', () => {
|
|
const config = getConfig(['node', 'verify', '--root', process.cwd(), '--max-actions', '1234', '--max-action-depth', '7']);
|
|
assert.equal(config.maxActionStates, 1234);
|
|
assert.equal(config.maxActionDepth, 7);
|
|
});
|
|
|
|
test('selects the newest Cloudflare production deployment', () => {
|
|
const output = JSON.stringify([
|
|
{ Environment: 'Production', Source: 'abcdef1', Deployment: 'https://new.pages.dev' },
|
|
{ Environment: 'Production', Source: '1234567', Deployment: 'https://old.pages.dev' },
|
|
]);
|
|
assert.equal(latestDeployment(output)?.Source, 'abcdef1');
|
|
assert.equal(latestDeployment('not json'), null);
|
|
});
|
|
|
|
test('dangerous construct scan ignores matcher text and finds runtime use', () => {
|
|
const scanner = "const name = 'dangerouslySetInnerHTML'; const matcher = /eval\\s*\\(/;";
|
|
assert.deepEqual(findDangerousConstructs('scanner.mjs', scanner), []);
|
|
const runtime = "export const View = () => <div dangerouslySetInnerHTML={{ __html: 'x' }} />; eval('x');";
|
|
assert.deepEqual(findDangerousConstructs('view.tsx', runtime), [
|
|
{ file: 'view.tsx', construct: 'dangerouslySetInnerHTML' },
|
|
{ file: 'view.tsx', construct: 'eval' },
|
|
]);
|
|
});
|