feat(topics): restore topic taxonomy workflow
This commit is contained in:
1 parent
f3dd1ec3b1
commit
a254cbd3e9
59 files changed
+771
-192
No files matched your search
@@ -1,9 +1,4 @@
|
||||
/**
|
||||
* 高级筛选设置页参考主题 1:1 契约。
|
||||
*
|
||||
* 参考实现「高级筛选」区块与前台链路(分类/标签归档的 AJAX 选项菜单、自定义
|
||||
* 筛选按钮、每页筛选条数)。
|
||||
*/
|
||||
/** 高级筛选设置页与归档查询的字段契约。 */
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const fs = require('node:fs');
|
||||
@@ -23,9 +18,9 @@ const tagTpl = read('tag.php');
|
||||
const listJs = read('assets/js/runtime/main.js');
|
||||
const globalController = read('src/Admin/GlobalController.php');
|
||||
|
||||
// 参考主题字段键(顺序即参考主题定义顺序)。
|
||||
// 保存字段的顺序。
|
||||
const REFERENCE_KEYS = ['custom_filter_show', 'custom_filter', 'cat_custom_filter'];
|
||||
// Jio 私有旧字段(参考主题无此配置,须移除避免双路)。
|
||||
// 已移除的旧字段。
|
||||
const LEGACY_KEYS = [
|
||||
'filter_enabled',
|
||||
'filter_categories',
|
||||
@@ -37,8 +32,6 @@ const LEGACY_KEYS = [
|
||||
'filter_tag_show_cat',
|
||||
'filter_tag_show_tag',
|
||||
];
|
||||
// 参考主题字段中本项目不做的部分(无 topics 专题分类法)。
|
||||
const EXCLUDED_KEYS = ['topics_s', 'topics_lists'];
|
||||
|
||||
test('JS schema 字段键与顺序对齐参考主题', () => {
|
||||
const found = [...js.matchAll(/key:\s*'([a-z0-9_]+)',\s*(?:label|type):/g)].map((m) => m[1]);
|
||||
@@ -53,7 +46,7 @@ test('JS schema 字段键与顺序对齐参考主题', () => {
|
||||
assert.ok(new RegExp(`key:\\s*'${sub}',\\s*label:`).test(js), `custom_filter 缺少子字段 ${sub}`);
|
||||
}
|
||||
const catSub = js.slice(js.indexOf("key: 'cat_custom_filter'"));
|
||||
const catOrder = ['cats', 'cat_s', 'cat_lists', 'tag_s', 'tag_lists', 'orderby_s', 'orderby_lists', 'custom_filters'];
|
||||
const catOrder = ['cats', 'cat_s', 'cat_lists', 'tag_s', 'tag_lists', 'topics_s', 'topics_lists', 'orderby_s', 'orderby_lists', 'custom_filters'];
|
||||
const catIdx = catOrder.map((k) => catSub.indexOf(`key: '${k}'`));
|
||||
assert.ok(catIdx.every((v) => v !== -1), 'cat_custom_filter 缺少子字段');
|
||||
assert.ok(catIdx.every((v, i) => i === 0 || v > catIdx[i - 1]), 'cat_custom_filter 子字段顺序应符合参考主题');
|
||||
@@ -66,7 +59,7 @@ test('PHP schema 字段键与顺序对齐参考主题', () => {
|
||||
const order = REFERENCE_KEYS.map((k) => filterSection.indexOf(`'${k}'`));
|
||||
assert.ok(order.every((v) => v !== -1), `PHP schema 缺少字段: ${REFERENCE_KEYS.filter((k) => order.indexOf(-1) === -1)}`);
|
||||
assert.ok(order.every((v, i) => i === 0 || v > order[i - 1]), 'PHP 字段顺序应符合参考主题');
|
||||
const catOrder = ['cats', 'cat_s', 'cat_lists', 'tag_s', 'tag_lists', 'orderby_s', 'orderby_lists', 'custom_filters'];
|
||||
const catOrder = ['cats', 'cat_s', 'cat_lists', 'tag_s', 'tag_lists', 'topics_s', 'topics_lists', 'orderby_s', 'orderby_lists', 'custom_filters'];
|
||||
const catSub = filterSection.slice(filterSection.indexOf("'cat_custom_filter'"));
|
||||
const catIdx = catOrder.map((k) => catSub.indexOf(`'${k}'`));
|
||||
assert.ok(catIdx.every((v) => v !== -1), 'PHP cat_custom_filter 缺少子字段');
|
||||
@@ -77,36 +70,36 @@ test('JS schema 默认值、选项与依赖对齐参考主题', () => {
|
||||
assert.match(js, /custom_filter_show:\s*\[\]/);
|
||||
assert.match(js, /custom_filter:\s*\[\]/);
|
||||
assert.match(js, /cat_custom_filter:\s*\[\]/);
|
||||
for (const option of ['分类页面显示', '标签页面显示']) {
|
||||
for (const option of ['分类页面显示', '标签页面显示', '专题页面显示']) {
|
||||
assert.ok(js.includes(option), `custom_filter_show 缺少选项 ${option}`);
|
||||
}
|
||||
// 排序方式默认值与参考主题一致(orderby() default)。
|
||||
// 排序方式默认值。
|
||||
assert.match(js, /default:\s*\[\s*'modified',\s*'views',\s*'like',\s*'comment_count'\s*\]/);
|
||||
for (const option of ['更新', '发布', '浏览', '点赞', '评论', '收藏', '随机']) {
|
||||
assert.ok(js.includes(`label: '${option}'`), `排序方式缺少选项 ${option}`);
|
||||
}
|
||||
// 依赖链(参考主题 dependency)。
|
||||
// 表单依赖链。
|
||||
assert.match(js, /key: 'cat_lists',[\s\S]{0,200}?dependsOn:\s*\{\s*key:\s*'cat_s',\s*value:\s*true\s*\}/);
|
||||
assert.match(js, /key: 'tag_lists',[\s\S]{0,200}?dependsOn:\s*\{\s*key:\s*'tag_s',\s*value:\s*true\s*\}/);
|
||||
assert.match(js, /key: 'topics_lists',[\s\S]{0,200}?dependsOn:\s*\{\s*key:\s*'topics_s',\s*value:\s*true\s*\}/);
|
||||
assert.match(js, /key: 'orderby_lists',[\s\S]{0,220}?dependsOn:\s*\{\s*key:\s*'orderby_s',\s*value:\s*true\s*\}/);
|
||||
// custom_filters 为动态选项 checkbox(引用 custom_filter 维度定义)。
|
||||
assert.match(js, /key: 'custom_filters',[\s\S]{0,400}?options:\s*'custom_filter'/);
|
||||
// 提示行承载筛选说明,且不得再指向第三方站点。
|
||||
assert.match(js, /type:\s*'content'/);
|
||||
assert.match(js, /ui_only:\s*true/);
|
||||
assert.doesNotMatch(js, /zibll\.com/);
|
||||
assert.match(js, /避免与其他mate_key重复/);
|
||||
});
|
||||
|
||||
test('旧字段与 topics 在 schema 中均已移除(无双路)', () => {
|
||||
test('旧字段已移除,专题筛选由单一字段组驱动', () => {
|
||||
for (const legacy of LEGACY_KEYS) {
|
||||
assert.ok(!js.includes(legacy), `JS schema 残留旧字段: ${legacy}`);
|
||||
assert.ok(!php.includes(legacy), `PHP schema 残留旧字段: ${legacy}`);
|
||||
assert.ok(!postDisplay.includes(`$settings['${legacy}']`), `PostDisplay 残留旧字段读取: ${legacy}`);
|
||||
}
|
||||
for (const excluded of EXCLUDED_KEYS) {
|
||||
assert.ok(!js.includes(excluded), `JS schema 不应包含 ${excluded}(本项目无专题分类法)`);
|
||||
assert.ok(!php.includes(excluded), `PHP schema 不应包含 ${excluded}`);
|
||||
for (const key of ['topics_s', 'topics_lists']) {
|
||||
assert.ok(js.includes(`key: '${key}'`), `JS schema 缺少 ${key}`);
|
||||
assert.ok(php.includes(`'key' => '${key}'`), `PHP schema 缺少 ${key}`);
|
||||
}
|
||||
// 运行时只读新键。
|
||||
assert.match(postDisplay, /\$settings\['custom_filter_show'\]/);
|
||||
@@ -119,7 +112,7 @@ test('JS schema 与 PHP schema 一致性', () => {
|
||||
for (const key of REFERENCE_KEYS) {
|
||||
assert.ok(php.includes(`'${key}'`), `PHP schema 缺少 ${key}`);
|
||||
}
|
||||
// addText 与参考主题 button_title 一致。
|
||||
// 添加按钮文案。
|
||||
assert.match(js, /addText:\s*'添加筛选类别'/);
|
||||
assert.match(js, /addText:\s*'添加值'/);
|
||||
assert.match(js, /addText:\s*'添加自定义分类筛选'/);
|
||||
@@ -147,7 +140,7 @@ test('前台链路:覆盖与门禁', () => {
|
||||
});
|
||||
|
||||
test('前台链路:维度筛选渲染与查询过滤', () => {
|
||||
// 渲染:维度 chip 组(全部 chip 参考主题 focus 语义)。
|
||||
// 渲染维度按钮组。
|
||||
assert.match(filtersHelper, /function jio_archive_build_custom_filter_groups\(/);
|
||||
assert.match(filtersHelper, /ajax-replace="true" class="ajax-next/);
|
||||
assert.match(filtersHelper, /\$keys !== 'all' && !in_array\(\$dim_key, \(array\) \$keys, true\)/);
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* 「前台投稿」后台设置页契约(对齐参考主题 1:1,不含专题):
|
||||
* 1) PHP schema(SchemaPostList.php submit section)字段键、顺序、默认值与
|
||||
* JS schema(assets/admin/src/schema/sections/post-list/submit.js)一致;
|
||||
* 2) 参考主题字段全集存在:post_article_s / post_article_btn_txte / post_article_cat /
|
||||
* post_article_custom_filter_s / post_article_tag / post_article_user /
|
||||
* post_article_title_strlen_limit / post_article_pay_free_s /
|
||||
* post_article_pay_price_limit / post_article_pay_vip_price_s /
|
||||
* post_article_pay_vip_1_discount / post_article_pay_vip_2_discount /
|
||||
* post_t_placeholder / post_c_placeholder;
|
||||
* 3) 专题(topics)相关字段不存在;
|
||||
* 4) 旧 Jio 私有字段(front_submit_*、post_article_title_strlen_limit_min/max、
|
||||
* post_article_pay_price_min/max)已彻底移除,无双路兼容;
|
||||
* 5) 运行时(PostDisplay::get_submit_settings)只读取新键。
|
||||
*/
|
||||
/** 前台投稿设置的字段顺序、默认值与运行时契约。 */
|
||||
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
@@ -30,6 +16,8 @@ const REFERENCE_KEYS = [
|
||||
'post_article_s',
|
||||
'post_article_btn_txte',
|
||||
'post_article_cat',
|
||||
'post_article_topics_s',
|
||||
'post_article_topics',
|
||||
'post_article_custom_filter_s',
|
||||
'post_article_tag',
|
||||
'post_article_user',
|
||||
@@ -114,9 +102,9 @@ test('PHP submit section 字段键与参考主题一致且顺序相同', () => {
|
||||
assert.deepEqual(found, PHP_FIELD_ORDER);
|
||||
});
|
||||
|
||||
test('PHP submit section 不含专题字段', () => {
|
||||
assert.doesNotMatch(submitPhp, /post_article_topics/);
|
||||
assert.doesNotMatch(submitPhp, /'topics'/);
|
||||
test('PHP submit section 包含专题开关与可选专题', () => {
|
||||
assert.match(submitPhp, /'post_article_topics_s',\s*'label'\s*=>\s*'允许选择专题',\s*'type'\s*=>\s*'switch',\s*'default'\s*=>\s*false/);
|
||||
assert.match(submitPhp, /'post_article_topics',\s*'label'\s*=>\s*'投稿允许选择的专题',\s*'type'\s*=>\s*'taxonomy_select',\s*'taxonomy'\s*=>\s*'topics'/);
|
||||
});
|
||||
|
||||
test('PHP submit section 默认值对齐参考主题', () => {
|
||||
@@ -154,7 +142,7 @@ test('JS schema 与 PHP 字段键一致(ui_only content 行除外)', () => {
|
||||
for (const legacy of LEGACY_KEYS) {
|
||||
assert.ok(!keys.includes(legacy), `JS schema 残留旧字段: ${legacy}`);
|
||||
}
|
||||
// 两个 ui_only 提示行承载参考主题 desc 中的【去设置】链接。
|
||||
// 两个 ui_only 提示行承载【去设置】链接。
|
||||
assert.match(js, /permissions\/capabilities/);
|
||||
assert.match(js, /post-list\/filter/);
|
||||
assert.match(js, /ui_only:\s*true/);
|
||||
|
||||
Reference in new issue
Block a user