114 lines
4.2 KiB
JavaScript
114 lines
4.2 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const test = require('node:test');
|
|
|
|
const createConfig = require('../config.js');
|
|
const projectRoot = path.resolve(__dirname, '..');
|
|
|
|
function read(relativePath) {
|
|
return fs.readFileSync(path.join(projectRoot, relativePath), 'utf8');
|
|
}
|
|
|
|
test('NavigationUtil 在隔离的新窗口中打开有效地址', () => {
|
|
const openedWindow = { opener: 'source-window' };
|
|
const calls = [];
|
|
const root = {
|
|
location: { hostname: 'localhost', port: '5500' },
|
|
open(...args) {
|
|
calls.push(args);
|
|
return openedWindow;
|
|
}
|
|
};
|
|
|
|
createConfig(root);
|
|
const result = root.NavigationUtil.open('profile.html');
|
|
|
|
assert.equal(result, openedWindow);
|
|
assert.deepEqual(calls, [['profile.html', '_blank', 'noopener']]);
|
|
assert.equal(openedWindow.opener, null);
|
|
});
|
|
|
|
test('NavigationUtil 拒绝可执行协议', () => {
|
|
let openCount = 0;
|
|
const root = {
|
|
location: { hostname: 'localhost', port: '5500' },
|
|
open() {
|
|
openCount += 1;
|
|
}
|
|
};
|
|
|
|
createConfig(root);
|
|
assert.equal(root.NavigationUtil.open('javascript:alert(1)'), null);
|
|
assert.equal(root.NavigationUtil.open('data:text/html,unsafe'), null);
|
|
assert.equal(openCount, 0);
|
|
});
|
|
|
|
test('所有页面在公共交互脚本前加载全站跳转配置', () => {
|
|
const htmlFiles = fs.readdirSync(projectRoot).filter((file) => file.endsWith('.html'));
|
|
|
|
htmlFiles.forEach((file) => {
|
|
const source = read(file);
|
|
const configIndex = source.indexOf('<script src="config.js"></script>');
|
|
const effectsIndex = source.indexOf('<script src="public/js/page-effects.js"></script>');
|
|
|
|
assert.ok(configIndex >= 0, `${file} 缺少 config.js`);
|
|
assert.ok(effectsIndex > configIndex, `${file} 必须先加载 config.js`);
|
|
});
|
|
});
|
|
|
|
test('全站链接覆盖初始和动态生成的有效链接', () => {
|
|
const source = read('public/js/page-effects.js');
|
|
|
|
assert.match(source, /link\.target = "_blank"/);
|
|
assert.match(source, /link\.setAttribute\("rel", \[\.\.\.relValues, "noopener"\]/);
|
|
assert.match(source, /new MutationObserver/);
|
|
assert.match(source, /attributeFilter: \["href", "target", "download"\]/);
|
|
});
|
|
|
|
test('Logo 和首页提供稳定入口,主导航不注入重复返回操作', () => {
|
|
const htmlFiles = fs.readdirSync(projectRoot).filter((file) => file.endsWith('.html'));
|
|
const effects = read('public/js/page-effects.js');
|
|
const profileCommon = read('public/js/profile-common.js');
|
|
|
|
htmlFiles.forEach((file) => {
|
|
const source = read(file);
|
|
const brandLinks = [...source.matchAll(/<a\s+class="[^"]*\bbrand\b[^"]*"\s+href="([^"]+)"/g)];
|
|
|
|
brandLinks.forEach((match) => {
|
|
assert.equal(match[1], 'index.html', `${file} 的 Logo 没有指向首页`);
|
|
});
|
|
});
|
|
assert.doesNotMatch(effects, /data-page-navigation-controls|data-navigation-back/);
|
|
assert.match(profileCommon, /\{ label: '首页', href: 'index\.html' \}/);
|
|
assert.match(profileCommon, /\.attr\('href', 'index\.html'\)/);
|
|
assert.doesNotMatch(profileCommon, /data-navigation-back/);
|
|
});
|
|
|
|
test('登录态顶栏以头像和昵称作为唯一账户入口', () => {
|
|
const effects = read('public/js/page-effects.js');
|
|
const authPages = read('public/js/auth-pages.js');
|
|
const profilePages = read('public/js/profile-pages.js');
|
|
|
|
assert.match(effects, /className = "nav-user-entry"/);
|
|
assert.match(effects, /className = "nav-user-avatar"/);
|
|
assert.match(effects, /name\.textContent = user\.nickName/);
|
|
assert.doesNotMatch(effects, /loginLink\.textContent = "个人中心"/);
|
|
assert.doesNotMatch(effects, /registerLink\.textContent = "账户资料"/);
|
|
assert.match(authPages, /storeUser\(await api\.currentProfile\(\)\)/);
|
|
assert.match(profilePages, /PublicNavigation\.storeUser\(profile\)/);
|
|
});
|
|
|
|
test('业务脚本不再直接覆盖当前窗口地址', () => {
|
|
const scriptsDirectory = path.join(projectRoot, 'public', 'js');
|
|
const scriptFiles = fs.readdirSync(scriptsDirectory).filter((file) => file.endsWith('.js'));
|
|
|
|
scriptFiles.forEach((file) => {
|
|
assert.doesNotMatch(
|
|
read(path.join('public', 'js', file)),
|
|
/(?:root|window)\.location\.(?:href\s*=|replace\()/,
|
|
`${file} 仍在当前窗口跳转`
|
|
);
|
|
});
|
|
});
|