Add smart ACK provider for WeChat MP replies
Replace fixed ackText with a rule-based AckProvider that picks response templates by message type and intent (translate, summary, rewrite, poster, ppt, mindmap, code, search, schedule). Pure sync, zero I/O, auto-falls back to config.ackText on any error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import fs from 'node:fs/promises';
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
import test from 'node:test';
|
||||
import { publicationInternals } from './mindspace-publications.mjs';
|
||||
|
||||
@@ -135,3 +138,60 @@ test('publicHomepageResponse summarizes public cards and total views', () => {
|
||||
assert.equal(result.pageCount, 2);
|
||||
assert.equal(result.pages[0].publicUrl, '/u/john/pages/one');
|
||||
});
|
||||
|
||||
test('buildPublicationThumbnailFallback points private resources at the public page thumbnail', () => {
|
||||
assert.equal(
|
||||
publicationInternals.buildPublicationThumbnailFallback('john', 'page-037d497f'),
|
||||
'/u/john/pages/page-037d497f.thumbnail.png',
|
||||
);
|
||||
assert.equal(
|
||||
publicationInternals.buildPublicationThumbnailFallback('木子', 'demo-page'),
|
||||
'/u/%E6%9C%A8%E5%AD%90/pages/demo-page.thumbnail.png',
|
||||
);
|
||||
});
|
||||
|
||||
test('prepareHtmlPublishContent inlines owned private image assets before scanning', async () => {
|
||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'mindspace-publish-'));
|
||||
const storageKey = 'users/user-1/assets/asset-1/current.png';
|
||||
await fs.mkdir(path.dirname(path.join(root, storageKey)), { recursive: true });
|
||||
await fs.writeFile(path.join(root, storageKey), Buffer.from('png-bytes'));
|
||||
|
||||
const pool = {
|
||||
async query(sql, params) {
|
||||
assert.match(sql, /h5_assets/);
|
||||
assert.equal(params[0], 'user-1');
|
||||
assert.deepEqual(params[1], ['asset-1']);
|
||||
return [
|
||||
[
|
||||
{
|
||||
id: 'asset-1',
|
||||
mime_type: 'image/png',
|
||||
storage_key: storageKey,
|
||||
},
|
||||
],
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
try {
|
||||
const html = '<!doctype html><img src="/api/mindspace/v1/assets/asset-1/download?inline=1&v=1">';
|
||||
const prepared = await publicationInternals.prepareHtmlPublishContent({
|
||||
pool,
|
||||
userId: 'user-1',
|
||||
html,
|
||||
ownerSlug: 'john',
|
||||
urlSlug: 'korean-daily-look',
|
||||
absoluteStoragePath: (key) => path.join(root, key),
|
||||
});
|
||||
|
||||
assert.match(prepared, /src="data:image\/png;base64,/);
|
||||
assert.doesNotMatch(prepared, /\/api\/mindspace\/v1\/assets\//);
|
||||
const scan = publicationInternals.scanContent(prepared, { format: 'html' });
|
||||
assert.equal(
|
||||
scan.findings.some((finding) => finding.type === 'private_resource_reference'),
|
||||
false,
|
||||
);
|
||||
} finally {
|
||||
await fs.rm(root, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user