265 lines
14 KiB
JavaScript
265 lines
14 KiB
JavaScript
'use strict';
|
|
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const path = require('node:path');
|
|
const test = require('node:test');
|
|
|
|
const root = path.resolve(__dirname, '..', '..');
|
|
const read = (file) => fs.readFileSync(path.join(root, file), 'utf8');
|
|
const join = (files) => files.map(read).join('\n');
|
|
|
|
const articleFiles = [
|
|
'src/Settings/PostDisplay.php',
|
|
'src/Admin/Schema/PostList/SchemaPostListList.php',
|
|
'src/Admin/Schema/SchemaPostList.php',
|
|
'assets/admin/src/schema/sections/post-list/list.js',
|
|
'assets/admin/src/schema/sections/post-list/thumb.js',
|
|
'assets/admin/src/schema/sections/post-list/page.js',
|
|
'inc/helpers/posts-renderer/config.php',
|
|
'inc/helpers/posts-renderer/post-data.php',
|
|
'inc/helpers/posts-renderer/markup.php',
|
|
'inc/helpers/aksrt-archive.php',
|
|
'inc/helpers/aksrt-single-render.php',
|
|
];
|
|
|
|
test('the article stream exposes only the new typed renderer contract', () => {
|
|
const markup = read('inc/helpers/posts-renderer/markup.php');
|
|
const consumers = join([
|
|
'index.php',
|
|
'category.php',
|
|
'tag.php',
|
|
'search.php',
|
|
'archive-resources.php',
|
|
'src/Admin/Admin.php',
|
|
'src/Admin/GlobalController.php',
|
|
'src/Core/Shortcodes.php',
|
|
'src/WidgetSystem/PostRenderer.php',
|
|
'inc/helpers/homepage/content.php',
|
|
'templates/parts/user-home/panels-core.php',
|
|
]);
|
|
|
|
assert.match(markup, /function aksrt_render_post_list\(array \$args = \[\], \?WP_Query \$query = null, bool \$echo = true\): string/);
|
|
assert.doesNotMatch(consumers, /function_exists\(['"]aksrt_render_post_list/);
|
|
assert.doesNotMatch(consumers, /aksrt_render_post_list\(\s*\$query\s*,/);
|
|
assert.doesNotMatch(consumers, /content-post-card|aksrt_homepage_render_post_card/);
|
|
});
|
|
|
|
test('settings use Zibll list modes, grouped options, and destructive related keys', () => {
|
|
const source = join(articleFiles);
|
|
const listSchema = read('assets/admin/src/schema/sections/post-list/list.js');
|
|
const pageSchema = read('assets/admin/src/schema/sections/post-list/page.js');
|
|
const legacyKeys = [
|
|
'post_card_style',
|
|
'list_list_style',
|
|
'list_card_style',
|
|
'grid-cms',
|
|
'large_thumb',
|
|
'multi_thumb',
|
|
'layout_override',
|
|
'homepage_card_style',
|
|
'homepage_multi_thumb',
|
|
'homepage_default_view',
|
|
'post_related_enabled',
|
|
'post_related_count',
|
|
'post_related_style',
|
|
'post_related_source',
|
|
'post_related_title',
|
|
];
|
|
|
|
assert.match(listSchema, /list_type: 'thumb'/);
|
|
for (const value of ['text', 'thumb', 'thumb_if_has', 'card']) {
|
|
assert.match(listSchema, new RegExp(`value: '${value}'`));
|
|
}
|
|
assert.match(listSchema, /list_list_option: \{ style: 'null', img_position: 'left', scale: 70 \}/);
|
|
assert.match(listSchema, /list_card_option: \{ style: 'null', scale: 70 \}/);
|
|
assert.match(pageSchema, /post_related_s: true/);
|
|
assert.match(pageSchema, /post_related_type: 'img'/);
|
|
assert.match(pageSchema, /related_title: '相关推荐'/);
|
|
assert.match(pageSchema, /post_related_n: 6/);
|
|
assert.match(pageSchema, /post_related_orderby: 'views'/);
|
|
for (const key of legacyKeys) {
|
|
assert.equal(source.includes(key), false, `legacy article key remains: ${key}`);
|
|
}
|
|
assert.doesNotMatch(source, /list_card_topics|is_topics|\btopics\b/);
|
|
});
|
|
|
|
test('forced mode wins and thumb_if_has ignores spare and lazy placeholders', () => {
|
|
const config = read('inc/helpers/posts-renderer/config.php');
|
|
const data = read('inc/helpers/posts-renderer/post-data.php');
|
|
|
|
const forced = config.indexOf("$is_forced = in_array($forced_type, ['list', 'card'], true)");
|
|
const globalCard = config.indexOf("$list_type === 'card'");
|
|
const contextCard = config.indexOf("$list['list_card_tag']");
|
|
const categoryCard = config.indexOf("$list['list_card_cat']");
|
|
assert.ok(forced >= 0 && forced < globalCard && globalCard < contextCard && contextCard < categoryCard);
|
|
assert.match(config, /\$is_card = \$forced_type === 'card' \|\| \(!\$is_forced/);
|
|
|
|
const hasReal = config.indexOf("$has_real = $primary !== '';");
|
|
const spareCall = config.lastIndexOf('aksrt_renderer_spare_image($thumb)');
|
|
const lazy = config.lastIndexOf('aksrt_get_lazy_thumb');
|
|
assert.ok(hasReal >= 0 && hasReal < spareCall && spareCall < lazy);
|
|
assert.match(data, /'thumb_if_has' && empty\(\$images\['has_real'\]\)/);
|
|
assert.match(data, /count\(\$gallery\) > 2/);
|
|
assert.match(data, /has_post_format\(\['image', 'gallery'\]/);
|
|
});
|
|
|
|
test('image resolution counts only content images and applies the configured WordPress size', () => {
|
|
const config = read('inc/helpers/posts-renderer/config.php');
|
|
const data = read('inc/helpers/posts-renderer/post-data.php');
|
|
const thumbSchema = read('assets/admin/src/schema/sections/post-list/thumb.js');
|
|
const phpSchema = read('src/Admin/Schema/SchemaPostList.php');
|
|
|
|
assert.match(config, /function aksrt_renderer_content_images\(int \$post_id, string \$size\)/);
|
|
assert.match(config, /strip_shortcodes\(\(string\) get_post_field\('post_content'/);
|
|
assert.match(config, /\$slides = aksrt_renderer_curated_images\(\$post_id, \$size\);\s*\$gallery = aksrt_renderer_content_images\(\$post_id, \$size\);/);
|
|
assert.match(config, /get_post_thumbnail_id\(\$post_id\).*aksrt_renderer_sized_image\(\(string\) \$thumbnail_id, \$size\)/s);
|
|
assert.match(config, /aksrt_renderer_category_image\(\$post_id, \$size\)/);
|
|
assert.doesNotMatch(config, /aksrt_get_post_gallery_images|cover_images|featured_video_episode|_aksrt_featured_video|_video_url|_aksrt_thumbnail_url|_thumbnail_url/);
|
|
assert.doesNotMatch(config, /\['aksrt_category_cover_id',/);
|
|
assert.match(data, /'gallery_count'\s*=>\s*count\(\$content_images\)/);
|
|
assert.match(data, /\(int\) \$data\['gallery_count'\] - 4/);
|
|
assert.match(thumbSchema, /spareThumbnailDefault = \[\{ img: `\$\{themeRoot\}\/assets\/img\/thumbnail\.svg` \}\]/);
|
|
assert.match(phpSchema, /'spare_thumbnail'.*'default' => \[\['img' => get_template_directory_uri\(\) \. '\/assets\/img\/thumbnail\.svg'\]\]/);
|
|
});
|
|
|
|
test('list, card, media, badge and Mini DOM follow dedicated Zibll structures', () => {
|
|
const markup = read('inc/helpers/posts-renderer/markup.php');
|
|
const data = read('inc/helpers/posts-renderer/post-data.php');
|
|
const card = markup.slice(markup.indexOf('function aksrt_renderer_card'), markup.indexOf('function aksrt_renderer_mini'));
|
|
const mini = markup.slice(markup.indexOf('function aksrt_renderer_mini'), markup.indexOf('function aksrt_render_post'));
|
|
|
|
assert.match(markup, /\['posts-item', 'list', 'ajax-item'\]/);
|
|
assert.match(markup, /\$classes\[\] = .*'flex xx'.*'flex'/s);
|
|
assert.match(markup, /<posts class=/);
|
|
assert.match(markup, /<div class="post-graphic/);
|
|
assert.match(markup, /<div class="item-body flex xx flex1 jsb/);
|
|
assert.doesNotMatch(card, /item-excerpt|renderer_excerpt_markup|thumb-items/);
|
|
assert.match(data, /<div class="item-thumbnail/);
|
|
assert.match(data, /relative zib-slider.*new-swiper item-thumbnail/s);
|
|
assert.match(data, /swiper-slide.*gradient-bg.*data-opacity="0\.2"/s);
|
|
assert.match(data, /\$fit = \$is_contain && !\$has_slides \? ' contain gradient-bg' : ''/);
|
|
assert.match(data, /video-thumb-box.*data-post-thumb-video/s);
|
|
assert.match(data, /class="thumb-items/);
|
|
assert.match(data, /empty\(\$cfg\['is_category'\]\).*in_array\('cat'/s);
|
|
assert.match(data, /empty\(\$cfg\['is_tag'\]\).*in_array\('tag'/s);
|
|
assert.doesNotMatch(data, /meta-mobile-show/);
|
|
|
|
assert.match(mini, /<div class="mr10"><div class="item-thumbnail"><a/);
|
|
assert.match(mini, /posts-mini-con flex xx flex1 jsb/);
|
|
assert.match(mini, /\['c-red', 'c-yellow', 'c-purple', 'c-blue', 'c-green'\]/);
|
|
assert.match(mini, /aksrt_renderer_pay_badge\(\$data, true\)/);
|
|
assert.match(data, /meta-pay badg badg-sm mr6/);
|
|
assert.doesNotMatch(mini, /posts-mini-row/);
|
|
|
|
assert.doesNotMatch(markup, /--posts-(?:list|card)-scale|<posts[^>]+style=/);
|
|
assert.match(data, /\['c-blue', 'c-yellow', 'c-green', 'c-purple', 'c-red'\]/);
|
|
assert.match(data, /查看更多分类文章/);
|
|
assert.match(data, /usort\(\$tags,.*->count.*->count/s);
|
|
assert.match(data, /查看此标签更多文章/);
|
|
|
|
const commentMeta = data.indexOf("aksrt_renderer_svg_icon('comment')");
|
|
const viewMeta = data.indexOf("aksrt_renderer_svg_icon('view')", commentMeta);
|
|
const likeMeta = data.indexOf("aksrt_renderer_svg_icon('like')", viewMeta);
|
|
assert.ok(commentMeta >= 0 && commentMeta < viewMeta && viewMeta < likeMeta);
|
|
assert.match(data, /comments_open.*close_comments/s);
|
|
assert.match(data, /show_like.*post_type.*=== 'post'/s);
|
|
assert.match(data, /<use xlink:href="#icon-/);
|
|
});
|
|
|
|
test('post-card CSS owns the exact desktop and 767/640 responsive matrix', () => {
|
|
const css = read('assets/css/frontend/post-card.css');
|
|
const mobile767 = css.slice(css.indexOf('@media (max-width: 767px)'), css.indexOf('@media (max-width: 640px)'));
|
|
const mobile640 = css.slice(css.indexOf('@media (max-width: 640px)'));
|
|
|
|
assert.match(css, /\.posts-row\s*\{[^}]*margin-right:\s*-8px;[^}]*margin-left:\s*-8px;/s);
|
|
assert.match(css, /\.posts-item\.card\s*\{[^}]*width:\s*calc\(33\.333% - 16px\)/s);
|
|
assert.match(css, /\.fluid-widget-wrap \.posts-item\.card,[\s\S]*?\.site-layout-1 \.posts-item\.card\s*\{[^}]*width:\s*calc\(25% - 16px\)/);
|
|
assert.match(css, /\.site-layout-1 \.posts-item:not\(\.card\)\s*\{[^}]*width:\s*calc\(50% - 16px\)/s);
|
|
assert.match(mobile767, /\.posts-item\.card\s*\{[^}]*width:\s*calc\(50% - 10px\)/s);
|
|
assert.doesNotMatch(mobile767, /\.posts-mini\s*\{[^}]*width:\s*100%/s);
|
|
assert.match(mobile640, /\.posts-mini\s*\{[^}]*width:\s*100%/s);
|
|
assert.match(mobile640, /\.posts-item:not\(\.no-thumb\) \.meta-right item\s*\{[^}]*display:\s*none/s);
|
|
assert.doesNotMatch(css, /\.aksrt-|post-card-cms|grid-cms/);
|
|
});
|
|
|
|
test('related posts, author page and widgets use their dedicated renderers', () => {
|
|
const related = read('inc/helpers/aksrt-single-render.php');
|
|
const relatedCard = read('inc/helpers/aksrt-single-components.php');
|
|
const resourceRelated = read('templates/parts/resource-related.php');
|
|
const author = read('templates/parts/user-home/panels-core.php');
|
|
const authorPosts = author.slice(author.indexOf("in_array('posts'"), author.indexOf("in_array('comments'"));
|
|
const widgets = read('src/WidgetSystem/PostRenderer.php');
|
|
|
|
assert.match(related, /\['img', 'list', 'text'\]/);
|
|
assert.match(related, /aksrt_renderer_mini\(\$data, \$mini_cfg\)/);
|
|
assert.match(related, /aksrt_render_related_graphic_card\(\$post\)/);
|
|
assert.match(related, /<li><a class="icon-circle"/);
|
|
assert.doesNotMatch(related, /topics|post_related_source/);
|
|
assert.match(relatedCard, /aksrt_renderer_resolve_images/);
|
|
assert.match(resourceRelated, /swiper-container swiper-scroll/);
|
|
assert.match(resourceRelated, /aksrt_render_related_graphic_card/);
|
|
assert.doesNotMatch(resourceRelated, /aksrt_render_post_list/);
|
|
assert.match(authorPosts, /aksrt_render_post_list/);
|
|
assert.match(authorPosts, /aksrt_render_pagination/);
|
|
assert.match(authorPosts, /'page_var'\s*=>\s*'posts_page'/);
|
|
assert.doesNotMatch(authorPosts, /aksrt_render_profile_pagination/);
|
|
assert.match(widgets, /aksrt_render_mini_list/);
|
|
assert.match(widgets, /swiper-container swiper-scroll/);
|
|
});
|
|
|
|
test('AJAX pagination can recover, caps auto loading and rehydrates appended media', () => {
|
|
const php = read('inc/helpers/template-tags/pagination-permissions.php');
|
|
const admin = read('src/Admin/Admin.php');
|
|
const js = read('assets/js/core/pagination.js');
|
|
const media = read('assets/js/core/misc.js');
|
|
|
|
assert.match(php, /class="text-center theme-pagination ajax-pag"/);
|
|
assert.match(php, /class="next-page ajax-next/);
|
|
assert.match(php, /lazyload-action="ias"/);
|
|
assert.match(php, /class="post_ajax_loader"/);
|
|
assert.match(php, /data-page-var/);
|
|
assert.match(admin, /'author', 'author_name'/);
|
|
assert.match(admin, /'category__in'.*'tag__in'/s);
|
|
assert.match(admin, /\$query_vars\['paged'\] = \$page/);
|
|
assert.match(js, /failed = false;\s*loadNextPage\(fromAuto\)/);
|
|
assert.match(js, /successfulAutoLoads >= iasMax/);
|
|
assert.match(js, /AksrtFrontend\.rehydrate\(target, "ajax"\)/);
|
|
assert.match(js, /classList\.add\("lazyload"\)/);
|
|
assert.match(media, /thumb-dplayer-playing/);
|
|
assert.match(media, /data-post-thumb-slider/);
|
|
assert.match(media, /data-post-thumb-video/);
|
|
assert.match(media, /window\.Grade\(container/);
|
|
assert.match(media, /linear-gradient\(135deg/);
|
|
assert.match(media, /aksrtGradientState/);
|
|
assert.match(read('src/Core/ScriptsPart1c.php'), /'aksrt-grade'/);
|
|
});
|
|
|
|
test('the pinned Zibll baseline records all source checksums', () => {
|
|
const baseline = JSON.parse(read('tests/visual/zibll-9.0-article-baseline.json'));
|
|
assert.equal(baseline.theme, 'Zibll');
|
|
assert.equal(baseline.version, '9.0');
|
|
const files = Object.values(baseline.files);
|
|
assert.ok(files.length >= 6);
|
|
for (const file of files) {
|
|
assert.match(file.sha256, /^[a-f0-9]{64}$/);
|
|
}
|
|
});
|
|
|
|
test('article visual matrix pins every breakpoint, state and strict threshold', () => {
|
|
const matrix = JSON.parse(read('tests/visual/article-visual-matrix-v1.json'));
|
|
assert.deepEqual(matrix.viewports.map((item) => item.width), [1440, 1024, 768, 767, 641, 640, 390]);
|
|
assert.deepEqual(matrix.colorSchemes, ['light', 'dark']);
|
|
assert.deepEqual(matrix.layouts, ['sidebar', 'no-sidebar']);
|
|
assert.deepEqual(matrix.listModes, ['thumb', 'text', 'thumb_if_has', 'card']);
|
|
assert.deepEqual(matrix.styles, ['default', 'style2', 'style3']);
|
|
assert.ok(matrix.routes.some((route) => route.id === 'author-a'));
|
|
assert.ok(matrix.routes.some((route) => route.states.includes('infinite')));
|
|
assert.ok(matrix.postScenarios.includes('no-image'));
|
|
assert.ok(matrix.postScenarios.includes('multi'));
|
|
assert.ok(matrix.postScenarios.includes('video'));
|
|
assert.ok(matrix.postScenarios.includes('slides'));
|
|
assert.equal(matrix.acceptance.dimensionDeltaPxMax, 1);
|
|
assert.equal(matrix.acceptance.pixelDifferencePercentMax, 1.5);
|
|
});
|