Files
wordpress-theme-aksrt/tests/front-submit/video-cover-contract.test.cjs
T
kate522 daee4cd67f feat(submit): make video cover row icon-only with hover titles
Replace the video-pic/video/clear button labels with icon-only buttons
carrying title + aria-label (设置视频封面/视频/清除), center the glyphs
via flex to fix the upward icon shift, rename the media picker title to
为视频设置封面, and drop the unused setVideoCover i18n key. Contract
test updated to pin the new markup and string set.
2026-09-06 10:10:12 +08:00

101 lines
5.4 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');
test('featured box renders a playable video preview and a video-cover button', () => {
const featured = read('templates/parts/submit/featured.php');
assert.match(featured, /class="new-dplayer dplayer-scale-height"/);
assert.match(featured, /video-url="<\?php echo esc_url\(\(string\) \(\$data\['url'\] \?\? ''\)\); \?>"/);
assert.match(featured, /video-pic="<\?php echo esc_url\(\(string\) \(\$data\['pic'\] \?\? ''\)\); \?>"/);
assert.match(featured, /fa fas fa-play-circle/);
// The video-cover button is capability-gated like the video button.
assert.match(featured, /if \(\$can_video\) : \?>\s*\n\s*<button type="button" class="but btn-video-pic" data-featured-action="video_pic"\s*\n\s*title="<\?php esc_attr_e\('设置视频封面', 'aksrt'\); \?>"/);
// The video row (video cover / video / clear) is icon-only with hover titles.
assert.match(featured, /btn-video" data-featured-action="video"\s*\n\s*title="<\?php esc_attr_e\('视频', 'aksrt'\); \?>"\s*\n\s*aria-label="<\?php esc_attr_e\('视频', 'aksrt'\); \?>">\s*\n\s*<i class="fa fas fa-video"><\/i>\s*\n\s*<\/button>/);
assert.match(featured, /btn-delete" data-featured-action="close"[\s\S]*?title="<\?php esc_attr_e\('清除', 'aksrt'\); \?>"/);
assert.doesNotMatch(featured, /首图|>视频<|>清除</);
// Dead capability attributes are gone.
assert.doesNotMatch(featured, /data-can-(image|slide|video)=/);
// The static image fallback for video covers must not come back.
assert.doesNotMatch(featured, /featured-video-placeholder/);
});
test('front-submit.js re-renders the preview as a DPlayer and reuses the runtime initializer', () => {
const js = read('assets/js/front-submit.js');
assert.match(js, /new-dplayer dplayer-scale-height/);
assert.match(js, /video-url="' \+\s*escapeHtml\(d\.url \|\| ''\)/);
assert.match(js, /video-pic="' \+\s*escapeHtml\(d\.pic \|\| ''\)/);
assert.match(js, /typeof window\.auto_fun === 'function'/);
assert.match(js, /destroyFeaturedPlayer/);
assert.match(js, /data\('dplayer'\)/);
// The dedicated video-cover picker action.
assert.match(js, /act === 'video_pic'/);
assert.match(js, /i18n\.setVideoCoverTitle/);
assert.match(js, /pic_id: cover \? \(cover\.attachment_id \|\| cover\.id \|\| 0\) : 0/);
});
test('submit.css toggles the video-cover button like the reference theme', () => {
const css = read('assets/css/frontend/pages/submit.css');
assert.match(css, /\.featured-edit \.btns-full \.btn-video-pic \{\s*\n display: none;\s*\n\}/);
assert.match(css, /\.featured-loaded\.video \.btns-full \.btn-video-pic \{\s*\n display: inline-flex;\s*\n align-items: center;\s*\n justify-content: center;\s*\n\}/);
assert.match(css, /\.featured-edit \.btns-full \.btn-video,\s*\n\.featured-edit \.btns-full \.btn-delete:not\(\[hidden\]\) \{\s*\n display: inline-flex;\s*\n align-items: center;\s*\n justify-content: center;\s*\n\}/);
assert.match(css, /\.featured-edit \.btns-full \.btn-video-pic > \.fa,[\s\S]*?\.featured-edit \.btns-full \.btn-delete > \.fa \{\s*\n margin-right: 0;\s*\n\}/);
assert.doesNotMatch(css, /featured-video-placeholder/);
});
test('the backend accepts pic_id and never wipes the thumbnail before validation', () => {
const featured = read('src/Core/FrontSubmitFeatured.php');
const videoBranch = featured.slice(featured.indexOf("case 'video':"), featured.indexOf("case 'slide':"));
assert.match(videoBranch, /absint\(\$payload\['pic_id'\] \?\? 0\)/);
assert.match(videoBranch, /!\$this->can_use_front_submit_image\(\$pic_id, \$user_id\)/);
assert.match(videoBranch, /wp_get_attachment_image_url\(\$pic_id, 'full'\)/);
assert.match(videoBranch, /set_post_thumbnail\(\$post_id, \$pic_id\)/);
// delete_post_thumbnail only runs when no valid cover picture remains.
const deletePos = videoBranch.indexOf('delete_post_thumbnail($post_id)');
const picGuard = videoBranch.indexOf("if ($pic !== '') {");
assert.ok(picGuard !== -1 && deletePos > picGuard, 'delete_post_thumbnail must be guarded by the pic check');
assert.doesNotMatch(videoBranch, /upload_submit_image/);
});
test('i18n exposes the video-cover strings and dead keys are removed', () => {
const page = read('templates/pages/page-submit.php');
const editorJs = read('assets/js/front-submit-editor.js');
const submitJs = read('assets/js/front-submit.js');
assert.match(page, /'setVideoCoverTitle' => __\('为视频设置封面', 'aksrt'\)/);
// The unused setVideoCover key died with the visible button label it served.
assert.doesNotMatch(page, /'setVideoCover' =>/);
assert.doesNotMatch(page, /首图/);
assert.doesNotMatch(submitJs, /首图/);
assert.doesNotMatch(page, /'(pickImage|pickVideo|pickVideoCover|pickVideoResource|videoUrl)'/);
// data-video-name / mediaUrl stay: pinned by tinymce.css and the
// front-submit-attachment contract respectively.
assert.match(editorJs, /data-video-name/);
assert.match(editorJs, /cfg\.mediaUrl/);
assert.doesNotMatch(submitJs, /i18n\.pickVideoCover/);
});
test('the unused aksrt_update_post ajax endpoint is removed', () => {
const frontSubmit = read('src/Core/FrontSubmit.php');
assert.doesNotMatch(frontSubmit, /aksrt_update_post/);
assert.doesNotMatch(frontSubmit, /ajax_update_post/);
});