The theme was renamed Zibll/子比 → AKSRT → Jio, but upstream branding survived the sweeps in CSS classes, the SVG sprite prefix, a persisted widget field ID, JS events, admin Vue class names, test infrastructure and docblocks. Renames: - zib-widget / zib-widget-wrap / zib-slider → jio-widget-box / jio-widget-box-wrap / jio-slider-box (jio-widget is taken by the modern widget shell, jio-box-* by the card primitives) - zib-partners-scroll + zps-* → jio-partners-scroll + jps-* - zib-combo-info-card + zci-* → jio-combo-info-card + jci-* - zibsvg- → jiosvg-, including the exported picker helpers and the fa-zibsvg- family-prefix guard - zibpay_type → pay_type; the dual-read fallback in PostQuery collapses to a single key - [zibajax="submit"] dropped (no PHP emitter); zib_ajax.success → jio_ajax.success - aks-* admin Vue classes → jio-* - zib_palette() → palette() User-facing vendor traces are gone: the floating "more" button default no longer ships a zibll.com link or 子比主题 marketing copy, the notice widget ships no preset promo entries, and the four 官网教程 links are removed from the post-list admin schema. Test infrastructure renamed to neutral names (docker-compose.reference.yml, Caddyfile, article-baseline.json, modern-widgets-contract.test.cjs) with their DB/volume/env/slug identifiers following. Kept intentionally, documented in tests/fixtures/README.md: the golden fixture reference fingerprint (a SHA-256 record of an external directory, read by validate-widget-golden / generate-widget-golden-fixture / audit-widget-system), the doesNotMatch guards that prove the old tokens are gone, and the reference theme's own meta key in the visual fixtures. No backward-compat or data migration: saved widget configs holding old icon keys or the old field ID silently lose them, per the project's rewrite-over-compatibility rule. Verified: 132/132 node contract tests, php tests/widget-system/run.php (146 assertions), audit-admin-contracts, audit-psr4-paths and validate-widget-golden all green; tracked bundles regenerated and in sync. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
204 lines
9.4 KiB
JavaScript
204 lines
9.4 KiB
JavaScript
'use strict';
|
||
|
||
/**
|
||
* 「百度推送」后台设置页契约:
|
||
* 1) PHP schema(SchemaExtensionsPush.php)与 JS schema(push.js)字段键、顺序、默认值一致;
|
||
* 2) 参考主题字段全集存在:自动推送 JS、普通收录、快速收录、准入 Token、发布/更新触发;
|
||
* 3) 双路/迁移字段(SEO 页 seo_baidu_*、熊掌号 xzh_*、批量推送 batch_*)已彻底移除,无双路兼容;
|
||
* 4) 运行时(SearchPush + ExtensionRuntime)只读取 canonical 键,快速收录走 type=daily;
|
||
* 5) 分类法 saved_term 推送、meta 去重、「重新提交」nonce 与编辑页面板均已接入,
|
||
* 并由 PHP harness 驱动真实逻辑验证。
|
||
*/
|
||
|
||
const assert = require('node:assert/strict');
|
||
const { execFileSync } = require('node:child_process');
|
||
const fs = require('node:fs');
|
||
const path = require('node:path');
|
||
const test = require('node:test');
|
||
|
||
const root = path.resolve(__dirname, '..', '..');
|
||
const php = fs.readFileSync(path.join(root, 'src/Admin/Schema/SchemaExtensionsPush.php'), 'utf8');
|
||
const js = fs.readFileSync(path.join(root, 'assets/admin/src/schema/sections/extensions/push.js'), 'utf8');
|
||
const runtime = fs.readFileSync(path.join(root, 'src/Extensions/SearchPush.php'), 'utf8');
|
||
const extensionRuntime = fs.readFileSync(path.join(root, 'src/Settings/ExtensionRuntime.php'), 'utf8');
|
||
const globalPhp = fs.readFileSync(path.join(root, 'src/Admin/Schema/GlobalSchema.php'), 'utf8');
|
||
const seoJs = fs.readFileSync(path.join(root, 'assets/admin/src/schema/sections/global/seo.js'), 'utf8');
|
||
const displayGroups = fs.readFileSync(path.join(root, 'src/Settings/DisplayPageGroups.php'), 'utf8');
|
||
const metaBox = fs.readFileSync(path.join(root, 'src/Extensions/SearchPushMetaBox.php'), 'utf8');
|
||
const functions = fs.readFileSync(path.join(root, 'functions.php'), 'utf8');
|
||
|
||
// 百度推送字段全集,Jio 单一 canonical 配置面(扩展&增强 → 百度推送)。
|
||
const REFERENCE_KEYS = [
|
||
'baidu_push_enabled',
|
||
'baidu_push_token',
|
||
'baidu_push_auto',
|
||
'baidu_push_on_publish',
|
||
'baidu_push_on_update',
|
||
'baidu_push_normal',
|
||
'baidu_push_fast',
|
||
'baidu_push_log_enabled',
|
||
];
|
||
|
||
// 双路 / 迁移 / 死代码字段:SEO 页 seo_baidu_*、熊掌号 xzh_*、批量推送与校验占位。
|
||
const DUAL_KEYS = [
|
||
'seo_baidu_push',
|
||
'seo_baidu_normal',
|
||
'seo_baidu_fast',
|
||
'seo_baidu_token',
|
||
'xzh_on',
|
||
'xzh_appid',
|
||
'xzh_render_tail',
|
||
'xzh_jsonld_single',
|
||
'xzh_jsonld_page',
|
||
'xzh_jsonld_img',
|
||
'baidu_push_batch_size',
|
||
'baidu_push_verified',
|
||
'push_batch',
|
||
'batch_size',
|
||
];
|
||
|
||
function phpFieldKeys(src) {
|
||
const found = [];
|
||
const re = /'key'\s*=>\s*'([a-z0-9_]+)',\s*'label'/g;
|
||
let m;
|
||
while ((m = re.exec(src)) !== null) found.push(m[1]);
|
||
return found;
|
||
}
|
||
|
||
function jsFieldKeys(src) {
|
||
const found = [];
|
||
const re = /key:\s*'([a-z0-9_]+)',\s*label:/g;
|
||
let m;
|
||
while ((m = re.exec(src)) !== null) found.push(m[1]);
|
||
return found;
|
||
}
|
||
|
||
test('PHP push schema 字段键与顺序对齐参考主题', () => {
|
||
assert.deepEqual(phpFieldKeys(php), REFERENCE_KEYS);
|
||
});
|
||
|
||
test('JS push schema 字段键与顺序对齐参考主题', () => {
|
||
assert.deepEqual(jsFieldKeys(js), REFERENCE_KEYS);
|
||
});
|
||
|
||
test('PHP schema 默认值对齐', () => {
|
||
assert.match(php, /'baidu_push_enabled',\s*'label'\s*=>\s*'启用百度推送',\s*'type'\s*=>\s*'switch',\s*'default'\s*=>\s*false/);
|
||
assert.match(php, /'baidu_push_token',\s*'label'\s*=>\s*'推送 Token',\s*'type'\s*=>\s*'input',\s*'default'\s*=>\s*''/);
|
||
assert.match(php, /'baidu_push_auto',\s*'label'\s*=>\s*'自动推送',\s*'type'\s*=>\s*'switch',\s*'default'\s*=>\s*true/);
|
||
assert.match(php, /'baidu_push_on_publish',\s*'label'\s*=>\s*'发布时主动推送',\s*'type'\s*=>\s*'switch',\s*'default'\s*=>\s*true/);
|
||
assert.match(php, /'baidu_push_on_update',\s*'label'\s*=>\s*'更新时推送',\s*'type'\s*=>\s*'switch',\s*'default'\s*=>\s*false/);
|
||
assert.match(php, /'baidu_push_normal',\s*'label'\s*=>\s*'普通收录',\s*'type'\s*=>\s*'switch',\s*'default'\s*=>\s*true/);
|
||
assert.match(php, /'baidu_push_fast',\s*'label'\s*=>\s*'快速收录',\s*'type'\s*=>\s*'switch',\s*'default'\s*=>\s*false/);
|
||
assert.match(php, /'baidu_push_log_enabled',\s*'label'\s*=>\s*'记录推送日志',\s*'type'\s*=>\s*'switch',\s*'default'\s*=>\s*true/);
|
||
});
|
||
|
||
test('JS schema 默认值对齐', () => {
|
||
assert.match(js, /baidu_push_enabled:\s*false/);
|
||
assert.match(js, /baidu_push_token:\s*''/);
|
||
assert.match(js, /baidu_push_auto:\s*true/);
|
||
assert.match(js, /baidu_push_on_publish:\s*true/);
|
||
assert.match(js, /baidu_push_on_update:\s*false/);
|
||
assert.match(js, /baidu_push_normal:\s*true/);
|
||
assert.match(js, /baidu_push_fast:\s*false/);
|
||
assert.match(js, /baidu_push_log_enabled:\s*true/);
|
||
});
|
||
|
||
test('双路/迁移/死代码字段在 schema、运行时与展示层均已移除(无双路)', () => {
|
||
for (const legacy of DUAL_KEYS) {
|
||
assert.ok(!php.includes(legacy), `SchemaExtensionsPush 残留: ${legacy}`);
|
||
assert.ok(!js.includes(legacy), `push.js 残留: ${legacy}`);
|
||
assert.ok(!runtime.includes(legacy), `SearchPush 残留: ${legacy}`);
|
||
assert.ok(!extensionRuntime.includes(legacy), `ExtensionRuntime 残留: ${legacy}`);
|
||
assert.ok(!globalPhp.includes(legacy), `GlobalSchema 残留: ${legacy}`);
|
||
assert.ok(!seoJs.includes(legacy), `seo.js 残留: ${legacy}`);
|
||
assert.ok(!displayGroups.includes(legacy), `DisplayPageGroups 残留: ${legacy}`);
|
||
assert.ok(!metaBox.includes(legacy), `SearchPushMetaBox 残留: ${legacy}`);
|
||
assert.ok(!functions.includes(legacy), `functions.php 残留: ${legacy}`);
|
||
}
|
||
assert.ok(!globalPhp.includes("'baidu'"), 'GlobalSchema SEO 分组残留百度重复配置面');
|
||
assert.ok(!seoJs.includes("key: 'baidu'"), 'seo.js 残留百度重复配置面');
|
||
});
|
||
|
||
test('普通/快速收录通道接入百度链接提交接口', () => {
|
||
assert.match(runtime, /data\.zz\.baidu\.com\/urls\?site=/);
|
||
assert.match(runtime, /'baidu_push_normal'/);
|
||
assert.match(runtime, /'baidu_push_fast'/);
|
||
assert.match(runtime, /&type=daily/);
|
||
assert.match(extensionRuntime, /'baidu_push_normal'\s*=>/);
|
||
assert.match(extensionRuntime, /'baidu_push_fast'\s*=>/);
|
||
});
|
||
|
||
test('前台自动推送 JS 与参考主题一致', () => {
|
||
assert.match(runtime, /zz\.bdstatic\.com\/linksubmit\/push\.js/);
|
||
assert.match(runtime, /push\.zhanzhang\.baidu\.com\/push\.js/);
|
||
assert.match(runtime, /add_action\('wp_footer'/);
|
||
});
|
||
|
||
test('发布/更新触发沿用 transition_post_status 且仅限可检索内容类型', () => {
|
||
assert.match(runtime, /transition_post_status/);
|
||
assert.match(runtime, /jio_searchable_post_types/);
|
||
assert.match(runtime, /wp_is_post_revision/);
|
||
assert.match(runtime, /wp_is_post_autosave/);
|
||
});
|
||
|
||
test('推送日志开关接入运行时', () => {
|
||
assert.match(runtime, /baidu_push_log_enabled/);
|
||
assert.match(extensionRuntime, /'baidu_push_log_enabled'/);
|
||
});
|
||
|
||
test('服务状态契约保留扩展总览消费的键', () => {
|
||
for (const key of ['enabled', 'provider', 'configured', 'available', 'verified', 'transport', 'missing_fields']) {
|
||
assert.ok(runtime.includes(`'${key}'`), `get_status 缺少 ${key}`);
|
||
}
|
||
});
|
||
|
||
test('分类法推送接入 saved_term 且排除文章形式', () => {
|
||
assert.match(runtime, /add_action\('saved_term'/);
|
||
assert.match(runtime, /public static function pushable_taxonomies/);
|
||
assert.match(runtime, /array_diff\(\(array\) \$taxonomies, \['post_format', 'nav_menu'\]\)/);
|
||
assert.match(runtime, /jio_baidu_push_taxonomies/);
|
||
assert.match(runtime, /get_term_link\(\$term_id, \$taxonomy\)/);
|
||
});
|
||
|
||
test('推送结果写入 meta 并按记录去重', () => {
|
||
assert.match(runtime, /META_KEY\s*=\s*'_jio_baidu_push_back'/);
|
||
assert.match(runtime, /private function record_is_complete/);
|
||
assert.match(runtime, /private function build_record/);
|
||
assert.match(runtime, /'normal_push'/);
|
||
assert.match(runtime, /'daily_push'/);
|
||
assert.match(runtime, /'update_time'/);
|
||
assert.match(runtime, /update_term_meta\(/);
|
||
assert.match(runtime, /delete_term_meta\(/);
|
||
});
|
||
|
||
test('「重新提交」勾选需通过 metabox nonce 校验', () => {
|
||
assert.match(runtime, /NONCE_ACTION\s*=\s*'jio_push_meta_save'/);
|
||
assert.match(runtime, /NONCE_FIELD\s*=\s*'jio_push_meta_nonce'/);
|
||
assert.match(runtime, /RESUBMIT_FIELD\s*=\s*'jio_push_resubmit'/);
|
||
assert.match(runtime, /wp_verify_nonce\(\$nonce, self::NONCE_ACTION\)/);
|
||
});
|
||
|
||
test('编辑页面板与参考主题「百度资源提交」Metabox 对齐', () => {
|
||
assert.match(metaBox, /add_meta_box\(\s*'jio_baidu_push',\s*__\('百度资源提交', 'jio'\)/);
|
||
assert.match(metaBox, /'side',\s*'high'/);
|
||
assert.match(metaBox, /\{\$taxonomy\}_edit_form_fields/);
|
||
assert.match(metaBox, /\{\$taxonomy\}_add_form_fields/);
|
||
assert.match(metaBox, /普通收录:成功/);
|
||
assert.match(metaBox, /快速收录:失败/);
|
||
assert.match(metaBox, /更新时间:/);
|
||
assert.match(metaBox, /重新提交/);
|
||
assert.match(metaBox, /发布、更新后刷新页面后可查看提交结果/);
|
||
assert.match(metaBox, /wp_nonce_field\(SearchPush::NONCE_ACTION, SearchPush::NONCE_FIELD\)/);
|
||
assert.match(metaBox, /esc_html\(\$line\[1\]\)/, '接口结果需转义后输出');
|
||
});
|
||
|
||
test('functions.php 接线推送面板', () => {
|
||
assert.match(functions, /SearchPushMetaBox::get_instance\(\)->init\(\)/);
|
||
});
|
||
|
||
test('百度推送行为 harness 通过', () => {
|
||
const harness = path.join(root, 'tests', 'admin', 'baidu-push-harness.php');
|
||
const output = execFileSync('php', [harness], { encoding: 'utf8' });
|
||
assert.match(output, /Baidu push harness passed/);
|
||
});
|