Files
memind/mindspace-public-image-retry.test.mjs
T
john ac520d8ae5 fix(mindspace-public): 公开页区分作者与访客视图 + 图片加载自动重试
工作区直链 /MindSpace/<userId>/public/*.html 此前对所有人(含匿名访客、
转发链接收到的其他登录用户)展示完全相同的悬浮操作按钮,导致非作者也能
看到"发布 Plaza"入口——而 Plaza 发布会把内容归属到操作者自己的账号下,
必须只对作者开放。

- server.mjs: serveUserPublishFile 用现有 session/cookie 鉴权判断访问者是
  否等于 URL 中的 ownerKey,结果透传给 sendPublishFile;该响应内容因人
  而异,显式加 Cache-Control: private, no-store(原来未设置任何缓存头)
- mindspace-public-share-widget.mjs: injectPublicFileShareButton 新增
  isOwner 参数(默认 true 保持兼容),非作者时隐藏"发布 Plaza"按钮与确认
  弹窗,"保存长图"/"公开分享"对所有访客保留
- mindspace-public-delivery.mjs: 透传 isOwner,并注入图片重试脚本
- mindspace-public-image-retry.mjs(新增): 页面级 onerror 之前用捕获阶段
  监听拦截 mindspace 资产图片的加载失败,带退避自动重试 3 次,避免刚生成
  页面时的资产物化竞态被"永久占位符"放大成显示故障

本地起服务用 owner / 非 owner 已登录用户 / 匿名访客三种身份实测验证。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-07 10:56:26 +08:00

38 lines
1.8 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
injectPublicImageRetryScript,
publicImageRetryInternals,
} from './mindspace-public-image-retry.mjs';
test('injectPublicImageRetryScript injects retry script before </body>', () => {
const result = injectPublicImageRetryScript('<!doctype html><html><body><h1>Hi</h1></body></html>');
assert.match(result.html, /data-mindspace-image-retry="1"/);
assert.match(result.html, /addEventListener\('error'/);
assert.match(result.html, /mindspace\\\/v1\\\/assets/);
assert.match(result.html, /stopImmediatePropagation/);
assert.equal(result.html.indexOf('data-mindspace-image-retry'), result.html.lastIndexOf('data-mindspace-image-retry'));
assert.match(result.html, /<script data-mindspace-image-retry="1">[\s\S]*<\/script><\/body>/);
assert.equal(result.scriptHashes.length, 1);
assert.equal(result.scriptHashes[0], publicImageRetryInternals.IMAGE_RETRY_SCRIPT_HASH);
});
test('injectPublicImageRetryScript appends when no closing body tag exists', () => {
const result = injectPublicImageRetryScript('<div>fragment</div>');
assert.match(result.html, /^<div>fragment<\/div><script data-mindspace-image-retry="1">/);
assert.equal(result.scriptHashes.length, 1);
});
test('injectPublicImageRetryScript is idempotent (skips if already injected)', () => {
const first = injectPublicImageRetryScript('<html><body>x</body></html>');
const second = injectPublicImageRetryScript(first.html);
assert.equal(second.html, first.html);
assert.equal(second.scriptHashes.length, 0);
});
test('injectPublicImageRetryScript handles empty input safely', () => {
const result = injectPublicImageRetryScript('');
assert.equal(result.html, '');
assert.equal(result.scriptHashes.length, 0);
});