feat(submit): add video cover picker with playable video preview
Featured video preview now renders a real DPlayer (video-url/video-pic) like the reference theme instead of a static image, so the cover video plays on the submit page. Top-right bar gains the video-cover button shown only when a video cover is loaded; backend honors pic_id and no longer deletes the thumbnail before cover validation. Drop dead i18n keys and data-can-* attributes.
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
'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">/);
|
||||
|
||||
// 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\}/);
|
||||
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, /'setVideoCover' => __\('设置视频首图封面', 'aksrt'\)/);
|
||||
assert.match(page, /'setVideoCoverTitle' => __\('为视频设置首图封面', 'aksrt'\)/);
|
||||
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/);
|
||||
});
|
||||
Reference in New Issue
Block a user