家谱现有接口调试50%
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
const assert = require('assert');
|
||||
const AlbumPages = require('../public/js/album-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(AlbumPages.normalizeList({ rows: [{ albumId: 1 }] }), [{ albumId: 1 }]);
|
||||
assert.deepStrictEqual(AlbumPages.normalizeList({ records: [{ albumId: 2 }] }), [{ albumId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(AlbumPages.buildAlbumBody({
|
||||
albumName: ' 老照片 ',
|
||||
albumDesc: ' 家族旧影 ',
|
||||
coverOssId: '',
|
||||
sortOrder: '',
|
||||
status: ''
|
||||
}), {
|
||||
albumName: '老照片',
|
||||
albumDesc: '家族旧影',
|
||||
coverOssId: undefined,
|
||||
sortOrder: 1,
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(AlbumPages.buildPhotoBody({
|
||||
ossId: ' 2060001 ',
|
||||
photoTitle: ' 老宅 ',
|
||||
photoDesc: ' 合影 ',
|
||||
photographer: ' 汤明 ',
|
||||
shootTime: '2026-07-09',
|
||||
sortOrder: '',
|
||||
status: ''
|
||||
}), {
|
||||
ossId: 2060001,
|
||||
photoTitle: '老宅',
|
||||
photoDesc: '合影',
|
||||
photographer: '汤明',
|
||||
shootTime: '2026-07-09',
|
||||
sortOrder: 1,
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
AlbumPages.buildAlbumRow({
|
||||
albumId: 301,
|
||||
albumName: '老照片',
|
||||
photoCount: 6,
|
||||
albumDesc: '家族旧影'
|
||||
}, '900001001'),
|
||||
'<button class="module-row album-row" type="button" data-album-id="301"><div><h3>老照片</h3><p>6 张照片 · 家族旧影</p></div><span class="pill">管理</span></button>'
|
||||
);
|
||||
|
||||
console.log('album-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,132 @@
|
||||
const assert = require('assert');
|
||||
const GenealogyApi = require('../public/js/api-client.js');
|
||||
|
||||
function createStore(initial) {
|
||||
const values = Object.assign({}, initial);
|
||||
|
||||
return {
|
||||
getItem(key) {
|
||||
return Object.prototype.hasOwnProperty.call(values, key) ? values[key] : null;
|
||||
},
|
||||
setItem(key, value) {
|
||||
values[key] = String(value);
|
||||
},
|
||||
removeItem(key) {
|
||||
delete values[key];
|
||||
},
|
||||
values
|
||||
};
|
||||
}
|
||||
|
||||
async function run() {
|
||||
const calls = [];
|
||||
const store = createStore({
|
||||
'token-key': 'abc-token'
|
||||
});
|
||||
|
||||
assert.strictEqual(GenealogyApi.DEFAULT_BASE_URL, 'http://test-genealogy-api.ddxcjp.cn');
|
||||
|
||||
const client = GenealogyApi.createClient({
|
||||
baseUrl: 'https://test-genealogy-api.ddxcjp.cn',
|
||||
clientId: 'client-x',
|
||||
tenantId: 'tenant-x',
|
||||
tokenKey: 'token-key',
|
||||
tokenHeaderName: 'Authorization',
|
||||
tokenStore: store,
|
||||
fetchImpl: async (url, options) => {
|
||||
calls.push({ url, options });
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: async () => ({
|
||||
code: 200,
|
||||
msg: '操作成功',
|
||||
data: { token: 'server-token', url }
|
||||
})
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
await client.login({ phone: '13800000000', password: 'md5' });
|
||||
assert.strictEqual(calls[0].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/pc/auth/login');
|
||||
assert.strictEqual(calls[0].options.headers.clientid, 'client-x');
|
||||
assert.strictEqual(calls[0].options.headers.Authorization, undefined);
|
||||
assert.strictEqual(JSON.parse(calls[0].options.body).tenantId, 'tenant-x');
|
||||
assert.strictEqual(store.values['token-key'], 'server-token');
|
||||
|
||||
await client.getProfile();
|
||||
assert.strictEqual(calls[1].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/pc/auth/profile');
|
||||
assert.strictEqual(calls[1].options.headers.Authorization, 'Bearer server-token');
|
||||
|
||||
await client.updateProfile({
|
||||
nickName: '张三',
|
||||
provinceCode: '510000',
|
||||
cityCode: '510100',
|
||||
districtCode: '510104'
|
||||
});
|
||||
assert.strictEqual(calls[2].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/pc/auth/profile');
|
||||
assert.strictEqual(calls[2].options.method, 'PUT');
|
||||
|
||||
await client.uploadFile('file-content');
|
||||
assert.strictEqual(calls[3].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/pc/files/upload');
|
||||
assert.strictEqual(calls[3].options.headers['Content-Type'], undefined);
|
||||
|
||||
await client.initResumableUpload({
|
||||
fileName: 'cover.jpg',
|
||||
fileSize: 9532,
|
||||
fileMd5: 'md5',
|
||||
chunkSize: 4194304,
|
||||
totalChunks: 1
|
||||
});
|
||||
assert.strictEqual(calls[4].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/pc/files/resumable/init');
|
||||
|
||||
await client.getRegionChildren('51');
|
||||
assert.strictEqual(calls[5].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/region/children?parentCode=51');
|
||||
|
||||
await client.captchaRequire({
|
||||
sceneCode: 'WEB_H5_LOGIN',
|
||||
subject: '13800000000'
|
||||
});
|
||||
assert.strictEqual(
|
||||
calls[6].url,
|
||||
'https://test-genealogy-api.ddxcjp.cn/captcha/require?tenantId=tenant-x&clientId=client-x&sceneCode=WEB_H5_LOGIN&subject=13800000000'
|
||||
);
|
||||
assert.strictEqual(calls[6].options.headers.Authorization, undefined);
|
||||
|
||||
await client.loginBySms({
|
||||
phone: '13800000000',
|
||||
smsCode: '6666',
|
||||
validToken: 'sms-ticket'
|
||||
});
|
||||
assert.strictEqual(calls[7].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/pc/auth/login/sms');
|
||||
assert.strictEqual(calls[7].options.headers.Authorization, undefined);
|
||||
assert.strictEqual(JSON.parse(calls[7].options.body).grantType, 'sms');
|
||||
assert.strictEqual(JSON.parse(calls[7].options.body).tenantId, 'tenant-x');
|
||||
assert.strictEqual(JSON.parse(calls[7].options.body).clientId, 'client-x');
|
||||
|
||||
await client.sendSmsCode({
|
||||
sceneCode: 'WEB_H5_LOGIN',
|
||||
phone: '13800000000',
|
||||
validToken: 'captcha-ticket'
|
||||
});
|
||||
assert.strictEqual(calls[8].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/pc/auth/sms/code');
|
||||
assert.strictEqual(calls[8].options.headers.Authorization, undefined);
|
||||
assert.strictEqual(JSON.parse(calls[8].options.body).grantType, 'sms');
|
||||
assert.strictEqual(JSON.parse(calls[8].options.body).sceneCode, 'WEB_H5_LOGIN');
|
||||
assert.strictEqual(JSON.parse(calls[8].options.body).validToken, 'captcha-ticket');
|
||||
|
||||
assert.throws(
|
||||
() => client.listGenealogies(),
|
||||
(error) => error.code === 'PC_API_NOT_AVAILABLE'
|
||||
);
|
||||
assert.throws(
|
||||
() => client.publicGenealogies(),
|
||||
(error) => error.code === 'PC_API_NOT_AVAILABLE'
|
||||
);
|
||||
assert.strictEqual(calls.length, 9);
|
||||
|
||||
console.log('api-client tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,45 @@
|
||||
const assert = require('assert');
|
||||
const ArticlePages = require('../public/js/article-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(ArticlePages.normalizeList({ rows: [{ articleId: 1 }] }), [{ articleId: 1 }]);
|
||||
assert.deepStrictEqual(ArticlePages.normalizeList({ records: [{ articleId: 2 }] }), [{ articleId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(ArticlePages.buildArticleBody({
|
||||
categoryId: ' 900040001 ',
|
||||
articleTitle: ' 族谱源流 ',
|
||||
articleSummary: ' 本支源流 ',
|
||||
coverOssId: '',
|
||||
articleContent: '<p>正文</p>',
|
||||
authorName: ' 管理员 ',
|
||||
sortOrder: '',
|
||||
status: ''
|
||||
}), {
|
||||
categoryId: 900040001,
|
||||
articleTitle: '族谱源流',
|
||||
articleSummary: '本支源流',
|
||||
coverOssId: undefined,
|
||||
articleContent: '<p>正文</p>',
|
||||
authorName: '管理员',
|
||||
sortOrder: 1,
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
ArticlePages.buildArticleRow({
|
||||
articleId: 801,
|
||||
articleTitle: '族谱源流',
|
||||
categoryName: '谱序',
|
||||
status: '0',
|
||||
updateTime: '2026-07-09'
|
||||
}, '900001001'),
|
||||
'<a class="module-row article-row" href="article-detail.html?id=801&genealogyId=900001001"><div><h3>族谱源流</h3><p>谱序 · 已发布 · 2026-07-09</p></div><span class="pill">查看</span></a>'
|
||||
);
|
||||
|
||||
assert.strictEqual(ArticlePages.formatStatus('0'), '已发布');
|
||||
assert.strictEqual(ArticlePages.formatStatus('1'), '草稿');
|
||||
|
||||
console.log('article-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,34 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
function readProjectFile(fileName) {
|
||||
return fs.readFileSync(path.join(__dirname, '..', fileName), 'utf8');
|
||||
}
|
||||
|
||||
function run() {
|
||||
[
|
||||
'public/js/auth-pages.js',
|
||||
'public/js/captcha-pages.js'
|
||||
].forEach((fileName) => {
|
||||
const content = readProjectFile(fileName);
|
||||
|
||||
assert.strictEqual(
|
||||
content.includes('root.alert'),
|
||||
false,
|
||||
`${fileName} 不应再使用浏览器原生 alert 作为提示`
|
||||
);
|
||||
});
|
||||
|
||||
const publicCss = readProjectFile('public/css/public.css');
|
||||
|
||||
assert.strictEqual(
|
||||
publicCss.includes('.auth-layer-message'),
|
||||
true,
|
||||
'public.css 应提供认证页 layui 提示皮肤'
|
||||
);
|
||||
|
||||
console.log('auth-message tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,35 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const pages = [
|
||||
'login.html',
|
||||
'register.html',
|
||||
'forgot-password.html'
|
||||
];
|
||||
|
||||
function readPage(fileName) {
|
||||
return fs.readFileSync(path.join(__dirname, '..', fileName), 'utf8');
|
||||
}
|
||||
|
||||
function run() {
|
||||
pages.forEach((fileName) => {
|
||||
const html = readPage(fileName);
|
||||
const formCaptchaBox = /<form[\s\S]*?data-captcha-box[\s\S]*?<\/form>/i.test(html);
|
||||
const pageModalBox = /class="[^"]*\bauth-captcha-modal\b[^"]*"[^>]*data-captcha-box/.test(html)
|
||||
|| /data-captcha-box[^>]*class="[^"]*\bauth-captcha-modal\b[^"]*"/.test(html);
|
||||
const hasLayuiCss = html.includes('href="public/layui/css/layui.css"');
|
||||
const layuiScriptIndex = html.indexOf('src="public/layui/layui.js"');
|
||||
const authScriptIndex = html.indexOf('src="public/js/auth-pages.js"');
|
||||
|
||||
assert.strictEqual(formCaptchaBox, false, `${fileName} 不应把 TAC 挂载点放在表单内部`);
|
||||
assert.strictEqual(pageModalBox, true, `${fileName} 应提供页面级 TAC 弹窗挂载点`);
|
||||
assert.strictEqual(hasLayuiCss, true, `${fileName} 应加载 layui.css 作为 layer 提示样式依赖`);
|
||||
assert.notStrictEqual(layuiScriptIndex, -1, `${fileName} 应加载 layui.js 使用 layer.msg`);
|
||||
assert.ok(layuiScriptIndex < authScriptIndex, `${fileName} 应在 auth-pages.js 之前加载 layui.js`);
|
||||
});
|
||||
|
||||
console.log('auth-page-structure tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,65 @@
|
||||
const assert = require('assert');
|
||||
const AuthPages = require('../public/js/auth-pages.js');
|
||||
|
||||
function fakeHash(value) {
|
||||
return `hashed:${value}`;
|
||||
}
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(AuthPages.buildLoginBody({
|
||||
phone: '13800000000',
|
||||
password: '123456',
|
||||
validToken: 'ticket'
|
||||
}, fakeHash), {
|
||||
phone: '13800000000',
|
||||
password: 'hashed:123456',
|
||||
validToken: 'ticket'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(AuthPages.buildSmsLoginBody({
|
||||
phone: '13800000000',
|
||||
smsCode: '6666',
|
||||
validToken: 'ticket'
|
||||
}), {
|
||||
phone: '13800000000',
|
||||
smsCode: '6666',
|
||||
validToken: 'ticket'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(AuthPages.buildRegisterBody({
|
||||
phone: '13800000000',
|
||||
password: '123456',
|
||||
nickName: '汤小明',
|
||||
validToken: 'ticket'
|
||||
}, fakeHash), {
|
||||
phone: '13800000000',
|
||||
password: 'hashed:123456',
|
||||
nickName: '汤小明',
|
||||
validToken: 'ticket'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(AuthPages.buildPasswordResetBody({
|
||||
phone: '13800000000',
|
||||
smsCode: '8888',
|
||||
newPassword: 'abcdef',
|
||||
validToken: 'ticket'
|
||||
}, fakeHash), {
|
||||
phone: '13800000000',
|
||||
smsCode: '8888',
|
||||
newPassword: 'hashed:abcdef',
|
||||
validToken: 'ticket'
|
||||
});
|
||||
|
||||
assert.strictEqual(AuthPages.getCaptchaScene('login'), 'WEB_H5_LOGIN');
|
||||
assert.strictEqual(AuthPages.getCaptchaScene('register'), 'WEB_H5_REGISTER');
|
||||
assert.strictEqual(AuthPages.getCaptchaScene('password-reset'), 'WEB_H5_FORGOT_PASSWORD');
|
||||
assert.strictEqual(AuthPages.getFormCaptchaScene({
|
||||
getAttribute(name) {
|
||||
return name === 'data-captcha-scene' ? 'WEB_H5_REGISTER' : '';
|
||||
}
|
||||
}, 'login'), 'WEB_H5_REGISTER');
|
||||
|
||||
console.log('auth-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,105 @@
|
||||
const assert = require('assert');
|
||||
const CaptchaPages = require('../public/js/captcha-pages.js');
|
||||
|
||||
const fakeApi = {
|
||||
clientId: 'client-x',
|
||||
tenantId: 'tenant-x'
|
||||
};
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(CaptchaPages.buildChallengeBody({
|
||||
sceneCode: 'WEB_H5_LOGIN',
|
||||
subject: '13800000000'
|
||||
}, fakeApi), {
|
||||
tenantId: 'tenant-x',
|
||||
clientId: 'client-x',
|
||||
sceneCode: 'WEB_H5_LOGIN',
|
||||
subject: '13800000000'
|
||||
});
|
||||
|
||||
const challenge = CaptchaPages.adaptChallengeResponse({
|
||||
code: 200,
|
||||
data: {
|
||||
required: true,
|
||||
providerCode: 'tianai',
|
||||
captchaType: 'SLIDER',
|
||||
challengeId: 'challenge-1',
|
||||
payload: {
|
||||
id: 'tianai-1',
|
||||
backgroundImage: 'bg.png',
|
||||
templateImage: 'tpl.png',
|
||||
backgroundImageWidth: 340
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assert.strictEqual(challenge.code, 200);
|
||||
assert.strictEqual(challenge.data.type, 'SLIDER');
|
||||
assert.strictEqual(challenge.data.id, 'tianai-1');
|
||||
assert.strictEqual(challenge.data.challengeId, 'challenge-1');
|
||||
assert.strictEqual(challenge.data.backgroundImage, 'bg.png');
|
||||
assert.strictEqual(challenge.data.templateImage, 'tpl.png');
|
||||
|
||||
assert.deepStrictEqual(CaptchaPages.buildVerifyBody({
|
||||
id: 'tianai-1',
|
||||
data: {
|
||||
trackList: [{ x: 10, y: 2 }]
|
||||
}
|
||||
}, {
|
||||
sceneCode: 'WEB_H5_LOGIN',
|
||||
subject: '13800000000',
|
||||
providerCode: 'tianai',
|
||||
captchaType: 'SLIDER',
|
||||
challengeId: 'challenge-1'
|
||||
}, fakeApi), {
|
||||
tenantId: 'tenant-x',
|
||||
clientId: 'client-x',
|
||||
sceneCode: 'WEB_H5_LOGIN',
|
||||
subject: '13800000000',
|
||||
challengeId: 'challenge-1',
|
||||
providerCode: 'tianai',
|
||||
captchaType: 'SLIDER',
|
||||
payload: {
|
||||
id: 'tianai-1',
|
||||
data: {
|
||||
trackList: [{ x: 10, y: 2 }]
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assert.strictEqual(CaptchaPages.extractValidToken({
|
||||
code: 200,
|
||||
data: {
|
||||
passed: true,
|
||||
validToken: 'captcha-ticket'
|
||||
}
|
||||
}), 'captcha-ticket');
|
||||
assert.strictEqual(CaptchaPages.shouldRequireCaptcha({
|
||||
required: false
|
||||
}), false);
|
||||
assert.strictEqual(CaptchaPages.shouldRequireCaptcha({
|
||||
required: true
|
||||
}), true);
|
||||
|
||||
const modalBox = { nodeName: 'modal' };
|
||||
const formBox = { nodeName: 'form-box' };
|
||||
const originalDocument = global.document;
|
||||
|
||||
global.document = {
|
||||
querySelector(selector) {
|
||||
return selector === '.auth-captcha-modal[data-captcha-box]' ? modalBox : null;
|
||||
}
|
||||
};
|
||||
|
||||
assert.strictEqual(CaptchaPages.getCaptchaBox({
|
||||
querySelector(selector) {
|
||||
return selector === '[data-captcha-box]' ? formBox : null;
|
||||
}
|
||||
}), modalBox);
|
||||
|
||||
global.document = originalDocument;
|
||||
|
||||
console.log('captcha-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,62 @@
|
||||
const assert = require('assert');
|
||||
const CeremonyPages = require('../public/js/ceremony-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(CeremonyPages.normalizeList({ rows: [{ ceremonyId: 1 }] }), [{ ceremonyId: 1 }]);
|
||||
assert.deepStrictEqual(CeremonyPages.normalizeList({ records: [{ ceremonyId: 2 }] }), [{ ceremonyId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(CeremonyPages.buildCeremonyBody({
|
||||
ceremonyType: ' wedding ',
|
||||
ceremonyTitle: ' 婚礼邀请 ',
|
||||
ceremonyDesc: ' 邀请亲友 ',
|
||||
ceremonyTime: '2026-07-09 10:00:00',
|
||||
location: ' 祠堂 ',
|
||||
coverOssId: '',
|
||||
sortOrder: '',
|
||||
status: ''
|
||||
}), {
|
||||
ceremonyType: 'wedding',
|
||||
ceremonyTitle: '婚礼邀请',
|
||||
ceremonyDesc: '邀请亲友',
|
||||
ceremonyTime: '2026-07-09 10:00:00',
|
||||
location: '祠堂',
|
||||
coverOssId: undefined,
|
||||
sortOrder: 1,
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(CeremonyPages.buildMeritBody({
|
||||
donorName: ' 汤明 ',
|
||||
meritType: '',
|
||||
meritTitle: ' 修谱捐款 ',
|
||||
meritContent: ' 支持修谱 ',
|
||||
amount: ' 100 ',
|
||||
meritTime: '',
|
||||
sortOrder: '',
|
||||
status: ''
|
||||
}), {
|
||||
donorName: '汤明',
|
||||
meritType: 'donation',
|
||||
meritTitle: '修谱捐款',
|
||||
meritContent: '支持修谱',
|
||||
amount: 100,
|
||||
meritTime: undefined,
|
||||
sortOrder: 1,
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
CeremonyPages.buildCeremonyRow({
|
||||
ceremonyId: 601,
|
||||
ceremonyTitle: '婚礼邀请',
|
||||
ceremonyType: 'wedding',
|
||||
ceremonyTime: '2026-07-09',
|
||||
giftCount: 2
|
||||
}, '900001001'),
|
||||
'<button class="module-row ceremony-row" type="button" data-ceremony-id="601"><div><h3>婚礼邀请</h3><p>wedding · 2026-07-09 · 2 条献礼</p></div><span class="pill">管理</span></button>'
|
||||
);
|
||||
|
||||
console.log('ceremony-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,26 @@
|
||||
const assert = require('assert');
|
||||
const configFactory = require('../config.js');
|
||||
|
||||
const store = {};
|
||||
const config = configFactory({
|
||||
localStorage: {
|
||||
getItem: (key) => Object.prototype.hasOwnProperty.call(store, key) ? store[key] : null,
|
||||
setItem: (key, value) => {
|
||||
store[key] = String(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
assert.strictEqual(config.getApiBaseUrl(), 'http://test-genealogy-api.ddxcjp.cn');
|
||||
assert.strictEqual(config.getClientId(), 'ced7e5f0498645c6ec642dcf450b036f');
|
||||
assert.strictEqual(config.getTenantId(), '000000');
|
||||
assert.strictEqual(config.getTokenKey(), 'genealogy_auth_token');
|
||||
assert.strictEqual(config.getConfig().tokenHeaderName, 'Authorization');
|
||||
|
||||
store.genealogy_api_base_url = 'https://custom.example.test';
|
||||
assert.strictEqual(config.getApiBaseUrl(), 'https://custom.example.test');
|
||||
|
||||
store.genealogy_api_base_url = 'https://test-genealogy-api.ddxcjp.cn';
|
||||
assert.strictEqual(config.getApiBaseUrl(), 'http://test-genealogy-api.ddxcjp.cn');
|
||||
|
||||
console.log('config tests passed');
|
||||
@@ -0,0 +1,45 @@
|
||||
const assert = require('assert');
|
||||
const FeedPages = require('../public/js/feed-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(FeedPages.normalizeList({ rows: [{ feedId: 1 }] }), [{ feedId: 1 }]);
|
||||
assert.deepStrictEqual(FeedPages.normalizeList({ records: [{ feedId: 2 }] }), [{ feedId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(FeedPages.buildFeedBody({
|
||||
content: ' 家族聚会 ',
|
||||
mediaOssIds: ' 1,2 ',
|
||||
visibility: '',
|
||||
status: ''
|
||||
}), {
|
||||
content: '家族聚会',
|
||||
mediaOssIds: '1,2',
|
||||
visibility: '2',
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(FeedPages.buildCommentBody({
|
||||
parentCommentId: '',
|
||||
replyUserId: ' 9001 ',
|
||||
content: ' 写得好 '
|
||||
}), {
|
||||
parentCommentId: undefined,
|
||||
replyUserId: 9001,
|
||||
content: '写得好'
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
FeedPages.buildFeedRow({
|
||||
feedId: 901,
|
||||
content: '家族聚会',
|
||||
authorName: '汤明',
|
||||
likeCount: 3,
|
||||
commentCount: 2,
|
||||
createTime: '2026-07-09'
|
||||
}),
|
||||
'<div class="module-row feed-row" data-feed-id="901"><div><h3>汤明</h3><p>家族聚会</p><small>2026-07-09 · 3 赞 · 2 评论</small></div><div class="row-actions"><button class="pill" type="button" data-feed-like="901">点赞</button><button class="pill" type="button" data-feed-comment="901">评论</button></div></div>'
|
||||
);
|
||||
|
||||
console.log('feed-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,33 @@
|
||||
const assert = require('assert');
|
||||
const FeedbackPages = require('../public/js/feedback-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(FeedbackPages.buildFeedbackBody({
|
||||
feedbackType: 'bug',
|
||||
feedbackTitle: '登录异常',
|
||||
feedbackContent: '页面打不开',
|
||||
contactInfo: '13800000000'
|
||||
}), {
|
||||
feedbackType: 'bug',
|
||||
feedbackContent: '【登录异常】页面打不开',
|
||||
contactInfo: '13800000000'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(FeedbackPages.normalizeList({
|
||||
rows: [{ id: 1 }]
|
||||
}), [{ id: 1 }]);
|
||||
|
||||
assert.strictEqual(
|
||||
FeedbackPages.buildFeedbackRow({
|
||||
feedbackType: 'bug',
|
||||
feedbackContent: '页面打不开',
|
||||
status: '已受理',
|
||||
createTime: '2026-07-09'
|
||||
}),
|
||||
'<div class="module-row"><div><h3>bug</h3><p>已受理 · 2026-07-09 · 页面打不开</p></div><span class="pill">查看</span></div>'
|
||||
);
|
||||
|
||||
console.log('feedback-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,70 @@
|
||||
const assert = require('assert');
|
||||
const GenealogyPages = require('../public/js/genealogy-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(GenealogyPages.buildGenealogyBody({
|
||||
genealogyName: '四川武胜汤氏族谱',
|
||||
surname: '汤',
|
||||
regionCode: '',
|
||||
addressDetail: '四川武胜',
|
||||
intro: '家族简介'
|
||||
}), {
|
||||
genealogyName: '四川武胜汤氏族谱',
|
||||
surname: '汤',
|
||||
regionCode: '',
|
||||
addressDetail: '四川武胜',
|
||||
intro: '家族简介',
|
||||
visibility: '1',
|
||||
joinMode: '1'
|
||||
});
|
||||
|
||||
assert.strictEqual(GenealogyPages.buildGenealogyBody({
|
||||
genealogyName: '成都陈氏族谱',
|
||||
surname: '陈',
|
||||
regionCode: '510104'
|
||||
}).regionCode, '510104');
|
||||
|
||||
assert.strictEqual(GenealogyPages.pick({
|
||||
genealogyName: '汤氏族谱',
|
||||
name: '备用名称'
|
||||
}, ['genealogyName', 'name'], '未命名'), '汤氏族谱');
|
||||
|
||||
assert.deepStrictEqual(GenealogyPages.normalizeList({ rows: [{ id: 1 }] }), [{ id: 1 }]);
|
||||
assert.deepStrictEqual(GenealogyPages.normalizeList([{ id: 2 }]), [{ id: 2 }]);
|
||||
assert.strictEqual(GenealogyPages.getQueryParam('?id=900001001&from=plaza', 'id'), '900001001');
|
||||
assert.strictEqual(GenealogyPages.getQueryParam('?genealogyId=42', 'id'), '');
|
||||
assert.deepStrictEqual(GenealogyPages.buildJoinApplyBody({
|
||||
applicantName: ' 汤小明 ',
|
||||
phone: ' 13800000000 ',
|
||||
relationDesc: ' 本族成员 ',
|
||||
applyReason: ''
|
||||
}), {
|
||||
applicantName: '汤小明',
|
||||
phone: '13800000000',
|
||||
relationDesc: '本族成员',
|
||||
applyReason: '申请加入家谱',
|
||||
inviterUserId: undefined
|
||||
});
|
||||
assert.strictEqual(
|
||||
GenealogyPages.buildFamilyHeroTitle({
|
||||
genealogyName: '汤氏族谱'
|
||||
}),
|
||||
'汤氏族谱'
|
||||
);
|
||||
assert.strictEqual(GenealogyPages.formatJoinMode('0'), '关闭加入');
|
||||
assert.strictEqual(GenealogyPages.formatJoinMode('1'), '审核加入');
|
||||
assert.strictEqual(GenealogyPages.formatJoinMode('2'), '邀请码加入');
|
||||
assert.strictEqual(
|
||||
GenealogyPages.buildMyGenealogyRow({
|
||||
genealogyId: 9,
|
||||
genealogyName: '汤氏族谱',
|
||||
roleName: '创建者',
|
||||
memberCount: 18
|
||||
}),
|
||||
'<a class="module-row" href="profile-family-home.html?id=9"><div><h3>汤氏族谱</h3><p>创建者 · 共修入 18 人</p></div><span class="pill">进入主页</span></a>'
|
||||
);
|
||||
|
||||
console.log('genealogy-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,52 @@
|
||||
const assert = require('assert');
|
||||
const GenerationPages = require('../public/js/generation-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(GenerationPages.normalizeList({ rows: [{ id: 1 }] }), [{ id: 1 }]);
|
||||
assert.deepStrictEqual(GenerationPages.normalizeList({ records: [{ id: 2 }] }), [{ id: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(GenerationPages.buildGenerationBody({
|
||||
generationNo: ' 5 ',
|
||||
generationText: ' 忠 ',
|
||||
description: ' 第五代 ',
|
||||
sortOrder: '',
|
||||
status: ''
|
||||
}), {
|
||||
generationNo: 5,
|
||||
generationText: '忠',
|
||||
description: '第五代',
|
||||
sortOrder: 5,
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
GenerationPages.buildGenerationRow({
|
||||
poemId: 77,
|
||||
generationNo: 5,
|
||||
generationText: '忠',
|
||||
memberCount: 8,
|
||||
description: '第五代'
|
||||
}, '900001001'),
|
||||
'<div class="module-row generation-row" data-generation-id="77"><div><h3>第 5 代:忠</h3><p>8 人 · 第五代</p></div><button class="pill" type="button" data-generation-edit="77" data-generation-no="5" data-generation-text="忠" data-genealogy-id="900001001">编辑</button></div>'
|
||||
);
|
||||
|
||||
assert.deepStrictEqual(GenerationPages.buildGenerationBatchBody({
|
||||
content: ' 德承家亦 ',
|
||||
stopMissingOldGeneration: 'on'
|
||||
}), {
|
||||
content: '德承家亦',
|
||||
stopMissingOldGeneration: true
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(GenerationPages.buildGenerationBatchBody({
|
||||
content: '',
|
||||
stopMissingOldGeneration: ''
|
||||
}), {
|
||||
content: '',
|
||||
stopMissingOldGeneration: false
|
||||
});
|
||||
|
||||
console.log('generation-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,43 @@
|
||||
const assert = require('assert');
|
||||
const GrowthPages = require('../public/js/growth-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(GrowthPages.normalizeList({ rows: [{ recordId: 1 }] }), [{ recordId: 1 }]);
|
||||
assert.deepStrictEqual(GrowthPages.normalizeList({ records: [{ recordId: 2 }] }), [{ recordId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(GrowthPages.buildGrowthBody({
|
||||
lineagePersonId: ' 900020001 ',
|
||||
recordType: '',
|
||||
recordTitle: ' 出生记录 ',
|
||||
recordContent: ' 成长内容 ',
|
||||
recordDate: '2026-07-09',
|
||||
remindTime: '',
|
||||
mediaOssIds: ' 2060001 ',
|
||||
sortOrder: '',
|
||||
status: ''
|
||||
}), {
|
||||
lineagePersonId: 900020001,
|
||||
recordType: 'growth',
|
||||
recordTitle: '出生记录',
|
||||
recordContent: '成长内容',
|
||||
recordDate: '2026-07-09',
|
||||
remindTime: undefined,
|
||||
mediaOssIds: '2060001',
|
||||
sortOrder: 1,
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
GrowthPages.buildGrowthRow({
|
||||
recordId: 701,
|
||||
recordTitle: '出生记录',
|
||||
recordType: 'birth',
|
||||
recordDate: '2026-07-09'
|
||||
}, '900001001'),
|
||||
'<a class="module-row growth-row" href="profile-growth-edit.html?recordId=701&genealogyId=900001001"><div><h3>出生记录</h3><p>birth · 2026-07-09</p></div><span class="pill">编辑</span></a>'
|
||||
);
|
||||
|
||||
console.log('growth-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,29 @@
|
||||
const assert = require('assert');
|
||||
const HelpPages = require('../public/js/help-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(HelpPages.normalizeList({ rows: [{ id: 1 }] }), [{ id: 1 }]);
|
||||
assert.deepStrictEqual(HelpPages.normalizeList({ records: [{ id: 2 }] }), [{ id: 2 }]);
|
||||
|
||||
assert.strictEqual(
|
||||
HelpPages.buildHelpItem({
|
||||
helpId: 88,
|
||||
title: '如何创建家谱?',
|
||||
summary: '填写名称、姓氏、地区即可创建。'
|
||||
}, 0),
|
||||
'<details open class="tilt-card" data-help-id="88" data-help-loaded="false"><summary>如何创建家谱?</summary><p>填写名称、姓氏、地区即可创建。</p></details>'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
HelpPages.buildHelpItem({
|
||||
id: 89,
|
||||
articleTitle: '资料填错了怎么办?',
|
||||
content: '<b>可以编辑成员资料</b>'
|
||||
}, 1),
|
||||
'<details class="tilt-card" data-help-id="89" data-help-loaded="true"><summary>资料填错了怎么办?</summary><p><b>可以编辑成员资料</b></p></details>'
|
||||
);
|
||||
|
||||
console.log('help-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,44 @@
|
||||
const assert = require('assert');
|
||||
const JoinApplyPages = require('../public/js/join-apply-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(JoinApplyPages.normalizeList({ rows: [{ id: 1 }] }), [{ id: 1 }]);
|
||||
assert.deepStrictEqual(JoinApplyPages.normalizeList({ records: [{ id: 2 }] }), [{ id: 2 }]);
|
||||
|
||||
assert.strictEqual(JoinApplyPages.formatApplyStatus('0'), '待审核');
|
||||
assert.strictEqual(JoinApplyPages.formatApplyStatus('1'), '已通过');
|
||||
assert.strictEqual(JoinApplyPages.formatApplyStatus('2'), '已拒绝');
|
||||
|
||||
assert.deepStrictEqual(JoinApplyPages.buildAuditBody('approve', ''), {
|
||||
status: '1',
|
||||
auditRemark: '信息核验通过'
|
||||
});
|
||||
assert.deepStrictEqual(JoinApplyPages.buildAuditBody('reject', '资料不完整'), {
|
||||
status: '2',
|
||||
auditRemark: '资料不完整'
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
JoinApplyPages.buildPendingRow({
|
||||
applyId: 66,
|
||||
applicantName: '汤小明',
|
||||
relationDesc: '本族成员',
|
||||
createTime: '2026-07-09'
|
||||
}, '900001001'),
|
||||
'<div class="module-row join-apply-row" data-join-apply-id="66"><div><h3>汤小明申请加入家谱</h3><p>2026-07-09 · 本族成员</p></div><div class="bottom-actions"><button class="btn primary" type="button" data-join-audit="approve" data-genealogy-id="900001001" data-apply-id="66">同意</button><button class="btn ghost" type="button" data-join-audit="reject" data-genealogy-id="900001001" data-apply-id="66">拒绝</button></div></div>'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
JoinApplyPages.buildMineRow({
|
||||
applyId: 67,
|
||||
genealogyName: '汤氏族谱',
|
||||
status: '0',
|
||||
relationDesc: '本族成员'
|
||||
}),
|
||||
'<div class="module-row join-apply-row" data-join-apply-id="67"><div><h3>汤氏族谱</h3><p>待审核 · 本族成员</p></div><button class="btn ghost" type="button" data-join-cancel="67">撤销申请</button></div>'
|
||||
);
|
||||
|
||||
console.log('join-apply-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,77 @@
|
||||
const assert = require('assert');
|
||||
const LineagePages = require('../public/js/lineage-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(LineagePages.normalizeList({ rows: [{ personId: 1 }] }), [{ personId: 1 }]);
|
||||
assert.deepStrictEqual(LineagePages.normalizeList({ records: [{ personId: 2 }] }), [{ personId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(LineagePages.buildLineagePersonBody({
|
||||
appUserId: '',
|
||||
personNo: ' P001 ',
|
||||
personName: ' 汤明 ',
|
||||
aliasName: ' 明公 ',
|
||||
sex: '0',
|
||||
generationNo: ' 3 ',
|
||||
generationName: '忠',
|
||||
birthDate: '1990-01-02',
|
||||
deathDate: '',
|
||||
introduction: ' 三世成员 '
|
||||
}), {
|
||||
appUserId: undefined,
|
||||
personNo: 'P001',
|
||||
personName: '汤明',
|
||||
aliasName: '明公',
|
||||
sex: '0',
|
||||
generationNo: 3,
|
||||
generationName: '忠',
|
||||
avatarOssId: undefined,
|
||||
birthDate: '1990-01-02',
|
||||
deathDate: undefined,
|
||||
introduction: '三世成员'
|
||||
});
|
||||
|
||||
assert.strictEqual(LineagePages.formatSex('0'), '男');
|
||||
assert.strictEqual(LineagePages.formatSex('1'), '女');
|
||||
assert.strictEqual(LineagePages.formatSex('9'), '未知');
|
||||
|
||||
assert.strictEqual(
|
||||
LineagePages.buildPersonRow({
|
||||
personId: 7001,
|
||||
personName: '汤明',
|
||||
generationNo: 3,
|
||||
generationName: '忠',
|
||||
sex: '0',
|
||||
boundAccount: true
|
||||
}),
|
||||
'<button class="module-row lineage-row" type="button" data-lineage-person="7001"><div><h3>汤明</h3><p>第 3 世 · 忠字辈 · 男 · 已绑定账号</p></div><span class="pill">查看资料</span></button>'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
LineagePages.buildTreeNode({
|
||||
personId: 7001,
|
||||
personName: '汤明',
|
||||
generationNo: 3,
|
||||
children: [
|
||||
{
|
||||
personId: 7002,
|
||||
personName: '汤小明',
|
||||
generationNo: 4
|
||||
}
|
||||
]
|
||||
}),
|
||||
'<li><button type="button" class="lineage-node" data-lineage-person="7001"><strong>汤明</strong><span>第 3 世</span></button><ul><li><button type="button" class="lineage-node" data-lineage-person="7002"><strong>汤小明</strong><span>第 4 世</span></button></li></ul></li>'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
LineagePages.buildHomeSummary({
|
||||
genealogyNo: 'JP001',
|
||||
hallName: '敦本堂',
|
||||
memberCount: 18
|
||||
}, 3),
|
||||
'JP001 · 堂号 敦本堂 · 共 18 人 · 3 个世系根节点'
|
||||
);
|
||||
|
||||
console.log('lineage-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,49 @@
|
||||
const assert = require('assert');
|
||||
const MemberAdminPages = require('../public/js/member-admin-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(MemberAdminPages.normalizeList({ rows: [{ memberId: 1 }] }), [{ memberId: 1 }]);
|
||||
assert.deepStrictEqual(MemberAdminPages.normalizeList({ records: [{ memberId: 2 }] }), [{ memberId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(MemberAdminPages.buildMemberUpdateBody({
|
||||
memberName: ' 汤明 ',
|
||||
relationName: ' 族亲 ',
|
||||
roleType: ' admin ',
|
||||
lineagePersonId: ' 90002 '
|
||||
}), {
|
||||
memberName: '汤明',
|
||||
relationName: '族亲',
|
||||
roleType: 'admin',
|
||||
lineagePersonId: 90002
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
MemberAdminPages.buildOverviewSummary({
|
||||
genealogyName: '汤氏族谱',
|
||||
memberCount: 18,
|
||||
articleCount: 3,
|
||||
albumCount: 2
|
||||
}),
|
||||
'汤氏族谱 · 18 位成员 · 3 篇谱文 · 2 个相册'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
MemberAdminPages.buildMemberRow({
|
||||
memberId: 501,
|
||||
memberName: '汤明',
|
||||
relationName: '族亲',
|
||||
roleType: 'admin',
|
||||
lineagePersonName: '忠字辈'
|
||||
}),
|
||||
'<div class="module-row member-admin-row" data-member-id="501"><div><h3>汤明</h3><p>族亲 · 管理员 · 绑定:忠字辈</p></div><div class="row-actions"><button class="pill" type="button" data-member-edit="501" data-member-name="汤明" data-member-relation="族亲" data-member-role="admin">权限</button><button class="pill is-danger" type="button" data-member-remove="501">移除</button></div></div>'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
MemberAdminPages.buildInviteLink('https://example.test/profile-invite.html?id=900001001', '900001001'),
|
||||
'https://example.test/join-genealogy.html?id=900001001'
|
||||
);
|
||||
|
||||
console.log('member-admin-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,39 @@
|
||||
const assert = require('assert');
|
||||
const MemoPages = require('../public/js/memo-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(MemoPages.normalizeList({ rows: [{ memoId: 1 }] }), [{ memoId: 1 }]);
|
||||
assert.deepStrictEqual(MemoPages.normalizeList({ records: [{ memoId: 2 }] }), [{ memoId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(MemoPages.buildMemoBody({
|
||||
memoTitle: ' 修谱事项 ',
|
||||
memoContent: ' 联系族亲 ',
|
||||
remindTime: '',
|
||||
completed: '',
|
||||
mediaOssIds: ' 2060001 ',
|
||||
sortOrder: '',
|
||||
status: ''
|
||||
}), {
|
||||
memoTitle: '修谱事项',
|
||||
memoContent: '联系族亲',
|
||||
remindTime: undefined,
|
||||
completed: '0',
|
||||
mediaOssIds: '2060001',
|
||||
sortOrder: 1,
|
||||
status: '0'
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
MemoPages.buildMemoRow({
|
||||
memoId: 801,
|
||||
memoTitle: '修谱事项',
|
||||
completed: '0',
|
||||
remindTime: '2026-08-01'
|
||||
}, '900001001'),
|
||||
'<a class="module-row memo-row" href="profile-memo-edit.html?memoId=801&genealogyId=900001001"><div><h3>修谱事项</h3><p>未完成 · 2026-08-01</p></div><span class="pill">编辑</span></a>'
|
||||
);
|
||||
|
||||
console.log('memo-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,32 @@
|
||||
const assert = require('assert');
|
||||
const NotificationPages = require('../public/js/notification-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.strictEqual(NotificationPages.formatNotificationStatus({
|
||||
readStatus: '0'
|
||||
}), '未读');
|
||||
assert.strictEqual(NotificationPages.formatNotificationStatus({
|
||||
readStatus: '1'
|
||||
}), '已读');
|
||||
assert.strictEqual(NotificationPages.formatNotificationStatus({
|
||||
readFlag: true
|
||||
}), '已读');
|
||||
|
||||
assert.strictEqual(
|
||||
NotificationPages.buildNotificationRow({
|
||||
notificationId: 77,
|
||||
title: '族人申请加入汤氏族谱',
|
||||
content: '需要管理员审核',
|
||||
createTime: '2026-07-09 12:00:00',
|
||||
readStatus: '0'
|
||||
}),
|
||||
'<div class="module-row notification-row is-unread" data-notification-id="77"><div><h3>族人申请加入汤氏族谱</h3><p>2026-07-09 12:00:00 · 需要管理员审核</p></div><button class="btn ghost" type="button" data-notification-read="77">标记已读</button></div>'
|
||||
);
|
||||
|
||||
assert.deepStrictEqual(NotificationPages.normalizeList({ rows: [{ id: 1 }] }), [{ id: 1 }]);
|
||||
assert.deepStrictEqual(NotificationPages.normalizeList({ records: [{ id: 2 }] }), [{ id: 2 }]);
|
||||
|
||||
console.log('notification-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,67 @@
|
||||
const assert = require('assert');
|
||||
const ProfilePages = require('../public/js/profile-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.strictEqual(ProfilePages.pick({
|
||||
nickName: '汤小明',
|
||||
userName: '备用'
|
||||
}, ['nickName', 'userName'], '未设置'), '汤小明');
|
||||
|
||||
assert.strictEqual(ProfilePages.getAvatarText({
|
||||
nickName: '汤小明'
|
||||
}), '汤');
|
||||
|
||||
assert.deepStrictEqual(ProfilePages.buildProfileView({
|
||||
nickName: '汤小明',
|
||||
phone: '13800000000',
|
||||
sex: '1',
|
||||
birthday: '2026-07-09',
|
||||
provinceCode: '510000',
|
||||
cityCode: '510100',
|
||||
districtCode: '510104'
|
||||
}), {
|
||||
displayName: '汤小明',
|
||||
avatarText: '汤',
|
||||
phone: '13800000000',
|
||||
sex: '1',
|
||||
birthday: '2026-07-09',
|
||||
regionText: '510000 / 510100 / 510104'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(ProfilePages.buildProfileUpdateBody({
|
||||
nickName: ' 汤小明 ',
|
||||
avatarOssId: '2060001',
|
||||
sex: '1',
|
||||
birthday: '2026-07-09',
|
||||
provinceCode: '510000',
|
||||
cityCode: '510100',
|
||||
districtCode: '510104'
|
||||
}), {
|
||||
nickName: '汤小明',
|
||||
avatarOssId: 2060001,
|
||||
sex: '1',
|
||||
birthday: '2026-07-09',
|
||||
provinceCode: '510000',
|
||||
cityCode: '510100',
|
||||
districtCode: '510104'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(ProfilePages.buildProfileUpdateBody({
|
||||
nickName: ' ',
|
||||
avatarOssId: '',
|
||||
sex: '',
|
||||
birthday: ''
|
||||
}), {
|
||||
nickName: undefined,
|
||||
avatarOssId: undefined,
|
||||
sex: undefined,
|
||||
birthday: undefined,
|
||||
provinceCode: undefined,
|
||||
cityCode: undefined,
|
||||
districtCode: undefined
|
||||
});
|
||||
|
||||
console.log('profile-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,53 @@
|
||||
const assert = require('assert');
|
||||
const PromotionPages = require('../public/js/promotion-pages.js');
|
||||
|
||||
function run() {
|
||||
const promotions = [
|
||||
{
|
||||
promotionId: 11,
|
||||
promotionTitle: '平台公告',
|
||||
promotionContent: '<p>公开展示规范</p>',
|
||||
summary: '保护家族资料安全',
|
||||
coverUrl: 'cover.jpg',
|
||||
linkUrl: 'download.html',
|
||||
publishTime: '2026-07-09'
|
||||
}
|
||||
];
|
||||
|
||||
assert.deepStrictEqual(PromotionPages.normalizeList({ rows: promotions }), promotions);
|
||||
assert.deepStrictEqual(PromotionPages.normalizeList({ records: promotions }), promotions);
|
||||
|
||||
assert.strictEqual(
|
||||
PromotionPages.buildPromotionCard(promotions[0]),
|
||||
'<a class="promotion-card" href="download.html" data-promotion-id="11"><img src="cover.jpg" alt="平台公告" /><div><h3>平台公告</h3><p>保护家族资料安全</p><span>2026-07-09</span></div></a>'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
PromotionPages.buildDownloadCard({
|
||||
promotionId: 12,
|
||||
title: 'Android 安装包',
|
||||
description: '适用于安卓手机',
|
||||
linkUrl: 'https://example.test/app.apk'
|
||||
}),
|
||||
'<a class="card soft download-card tilt-card" href="https://example.test/app.apk" data-promotion-id="12"><h3>Android 安装包</h3><p>适用于安卓手机</p></a>'
|
||||
);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
PromotionPages.pickPromotion(promotions, '11'),
|
||||
promotions[0]
|
||||
);
|
||||
|
||||
assert.deepStrictEqual(
|
||||
PromotionPages.buildNoticeDetail(promotions[0]),
|
||||
{
|
||||
title: '平台公告',
|
||||
summary: '保护家族资料安全',
|
||||
content: '<p>公开展示规范</p>',
|
||||
time: '2026-07-09'
|
||||
}
|
||||
);
|
||||
|
||||
console.log('promotion-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,50 @@
|
||||
const assert = require('assert');
|
||||
const RegionPages = require('../public/js/region-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(RegionPages.normalizeList({ rows: [{ regionCode: '51' }] }), [{ regionCode: '51' }]);
|
||||
assert.deepStrictEqual(RegionPages.normalizeList({ records: [{ regionCode: '510100' }] }), [{ regionCode: '510100' }]);
|
||||
|
||||
assert.strictEqual(
|
||||
RegionPages.buildRegionOption({
|
||||
regionCode: '510000',
|
||||
regionName: '四川省'
|
||||
}),
|
||||
'<option value="510000">四川省</option>'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
RegionPages.buildPathText([
|
||||
{ regionName: '四川省' },
|
||||
{ regionName: '成都市' },
|
||||
{ name: '锦江区' }
|
||||
]),
|
||||
'四川省 / 成都市 / 锦江区'
|
||||
);
|
||||
|
||||
assert.strictEqual(RegionPages.getFinalRegionCode({
|
||||
provinceCode: '510000',
|
||||
cityCode: '510100',
|
||||
districtCode: '510104'
|
||||
}), '510104');
|
||||
|
||||
assert.strictEqual(RegionPages.getFinalRegionCode({
|
||||
provinceCode: '510000',
|
||||
cityCode: '',
|
||||
districtCode: ''
|
||||
}), '510000');
|
||||
|
||||
assert.deepStrictEqual(RegionPages.buildProfileRegionBody({
|
||||
provinceCode: '510000',
|
||||
cityCode: '510100',
|
||||
districtCode: ''
|
||||
}), {
|
||||
provinceCode: '510000',
|
||||
cityCode: '510100',
|
||||
districtCode: undefined
|
||||
});
|
||||
|
||||
console.log('region-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,51 @@
|
||||
const assert = require('assert');
|
||||
const SecurityPages = require('../public/js/security-pages.js');
|
||||
|
||||
function hash(value) {
|
||||
return `hashed:${value}`;
|
||||
}
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(SecurityPages.buildPasswordChangeBody({
|
||||
oldPassword: '123456',
|
||||
newPassword: 'abcdef'
|
||||
}, hash), {
|
||||
oldPassword: 'hashed:123456',
|
||||
newPassword: 'hashed:abcdef'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(SecurityPages.buildPhoneChangeBody({
|
||||
newPhone: ' 13900000000 ',
|
||||
smsCode: ' 123456 ',
|
||||
validToken: ' ticket '
|
||||
}), {
|
||||
newPhone: '13900000000',
|
||||
smsCode: '123456',
|
||||
validToken: 'ticket'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(SecurityPages.buildSmsLoginBody({
|
||||
phone: '13900000000',
|
||||
smsCode: '123456',
|
||||
validToken: ''
|
||||
}), {
|
||||
phone: '13900000000',
|
||||
smsCode: '123456',
|
||||
validToken: undefined
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(SecurityPages.buildDeactivateBody({
|
||||
password: '123456',
|
||||
reason: ' 不再使用 '
|
||||
}, hash), {
|
||||
password: 'hashed:123456',
|
||||
reason: '不再使用'
|
||||
});
|
||||
|
||||
assert.strictEqual(SecurityPages.isDangerConfirmed('确认注销'), true);
|
||||
assert.strictEqual(SecurityPages.isDangerConfirmed('注销'), false);
|
||||
|
||||
console.log('security-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,33 @@
|
||||
const assert = require('assert');
|
||||
const UploadPages = require('../public/js/upload-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(UploadPages.normalizeUploadResult({
|
||||
ossId: 2060001,
|
||||
fileName: 'cover.jpg',
|
||||
url: 'https://cdn.example.test/cover.jpg'
|
||||
}), {
|
||||
ossId: '2060001',
|
||||
fileName: 'cover.jpg',
|
||||
url: 'https://cdn.example.test/cover.jpg'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(UploadPages.normalizeUploadResult({
|
||||
id: 2060002,
|
||||
originalName: 'old.png',
|
||||
fileUrl: '/old.png'
|
||||
}), {
|
||||
ossId: '2060002',
|
||||
fileName: 'old.png',
|
||||
url: '/old.png'
|
||||
});
|
||||
|
||||
assert.strictEqual(UploadPages.mergeOssIds('', '2060001', false), '2060001');
|
||||
assert.strictEqual(UploadPages.mergeOssIds('2060001', '2060002', true), '2060001,2060002');
|
||||
assert.strictEqual(UploadPages.mergeOssIds('2060001', '2060001', true), '2060001');
|
||||
assert.strictEqual(UploadPages.buildUploadStatus('cover.jpg', '2060001'), 'cover.jpg 上传完成,OSS ID:2060001');
|
||||
|
||||
console.log('upload-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
@@ -0,0 +1,54 @@
|
||||
const assert = require('assert');
|
||||
const StorageUtil = require('../utils/StorageUtil.js');
|
||||
const FormUtil = require('../utils/FormUtil.js');
|
||||
const RequestUtil = require('../utils/RequestUtil.js');
|
||||
|
||||
assert.strictEqual(FormUtil.trimOrUndefined(' 张三 '), '张三');
|
||||
assert.strictEqual(FormUtil.trimOrUndefined(' '), undefined);
|
||||
assert.strictEqual(FormUtil.toNumberOrUndefined('12'), 12);
|
||||
assert.strictEqual(FormUtil.toNumberOrUndefined(''), undefined);
|
||||
assert.strictEqual(FormUtil.toBoolean('on'), true);
|
||||
assert.strictEqual(FormUtil.toBoolean('0'), false);
|
||||
|
||||
const store = {};
|
||||
const storage = {
|
||||
getItem: (key) => Object.prototype.hasOwnProperty.call(store, key) ? store[key] : null,
|
||||
setItem: (key, value) => {
|
||||
store[key] = String(value);
|
||||
},
|
||||
removeItem: (key) => {
|
||||
delete store[key];
|
||||
}
|
||||
};
|
||||
|
||||
StorageUtil.write(storage, 'token', 'abc');
|
||||
assert.strictEqual(StorageUtil.read(storage, 'token'), 'abc');
|
||||
StorageUtil.remove(storage, 'token');
|
||||
assert.strictEqual(StorageUtil.read(storage, 'token'), null);
|
||||
|
||||
const calls = [];
|
||||
const requester = RequestUtil.createRequester({
|
||||
baseUrl: 'https://test-genealogy-api.ddxcjp.cn',
|
||||
clientId: 'pc-client',
|
||||
tokenHeaderName: 'Authorization',
|
||||
getToken: () => 'token-x',
|
||||
fetchImpl: async (url, options) => {
|
||||
calls.push({ url, options });
|
||||
|
||||
return {
|
||||
ok: true,
|
||||
status: 200,
|
||||
json: async () => ({ code: 200, data: { ok: true } })
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
requester('GET', '/genealogy/pc/auth/profile', {
|
||||
query: { keyword: '汤 氏' }
|
||||
}).then((data) => {
|
||||
assert.deepStrictEqual(data, { ok: true });
|
||||
assert.strictEqual(calls[0].url, 'https://test-genealogy-api.ddxcjp.cn/genealogy/pc/auth/profile?keyword=%E6%B1%A4+%E6%B0%8F');
|
||||
assert.strictEqual(calls[0].options.headers.clientid, 'pc-client');
|
||||
assert.strictEqual(calls[0].options.headers.Authorization, 'Bearer token-x');
|
||||
console.log('utils tests passed');
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
const assert = require('assert');
|
||||
const VipPages = require('../public/js/vip-pages.js');
|
||||
|
||||
function run() {
|
||||
assert.deepStrictEqual(VipPages.normalizeList({ rows: [{ packageId: 1 }] }), [{ packageId: 1 }]);
|
||||
assert.deepStrictEqual(VipPages.normalizeList({ records: [{ packageId: 2 }] }), [{ packageId: 2 }]);
|
||||
|
||||
assert.deepStrictEqual(VipPages.buildVipOrderBody({
|
||||
packageId: ' 900060001 ',
|
||||
genealogyId: ' 900001001 ',
|
||||
payType: 'wechat'
|
||||
}), {
|
||||
packageId: 900060001,
|
||||
genealogyId: 900001001,
|
||||
payType: 'wechat'
|
||||
});
|
||||
|
||||
assert.deepStrictEqual(VipPages.buildVipOrderBody({
|
||||
packageId: '900060002',
|
||||
genealogyId: '',
|
||||
payType: ''
|
||||
}), {
|
||||
packageId: 900060002,
|
||||
genealogyId: undefined,
|
||||
payType: undefined
|
||||
});
|
||||
|
||||
assert.strictEqual(
|
||||
VipPages.buildPackageCard({
|
||||
packageId: 900060001,
|
||||
packageName: '年度会员',
|
||||
price: 199,
|
||||
durationDays: 365,
|
||||
description: '适合长期维护家谱'
|
||||
}),
|
||||
'<button class="vip-package-card" type="button" data-vip-package-id="900060001"><span class="vip-package-name">年度会员</span><strong>¥199</strong><small>365天</small><p>适合长期维护家谱</p></button>'
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
VipPages.buildOrderRow({
|
||||
orderNo: 'VIP202607090001',
|
||||
packageName: '年度会员',
|
||||
payType: 'wechat',
|
||||
orderStatus: 'created'
|
||||
}),
|
||||
'<div class="module-row vip-order-row"><div><h3>年度会员</h3><p>VIP202607090001 · 微信支付 · created</p></div><span class="pill">订单</span></div>'
|
||||
);
|
||||
|
||||
console.log('vip-pages tests passed');
|
||||
}
|
||||
|
||||
run();
|
||||
Reference in New Issue
Block a user