105 lines
3.4 KiB
JavaScript
105 lines
3.4 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import vm from 'node:vm';
|
|
|
|
import {
|
|
injectMindSpaceRybbit,
|
|
resolveMindSpaceRybbitConfig,
|
|
} from './mindspace-rybbit.mjs';
|
|
|
|
test('rybbit config is disabled unless explicitly enabled and configured', () => {
|
|
assert.equal(resolveMindSpaceRybbitConfig({ MEMIND_RYBBIT_ENABLED: 'true' }).enabled, false);
|
|
assert.equal(resolveMindSpaceRybbitConfig({
|
|
MEMIND_RYBBIT_ENABLED: 'true',
|
|
MEMIND_RYBBIT_SITE_ID: '2',
|
|
}).enabled, false);
|
|
const config = resolveMindSpaceRybbitConfig({
|
|
MEMIND_RYBBIT_ENABLED: 'true',
|
|
MEMIND_RYBBIT_SITE_ID: '2',
|
|
MEMIND_RYBBIT_ID_SECRET: 'local-secret',
|
|
MEMIND_RYBBIT_URL: 'https://rybbit.tkmind.cn',
|
|
});
|
|
assert.equal(config.enabled, true);
|
|
assert.equal(config.siteId, '2');
|
|
assert.equal(config.rybbitUrl, 'https://rybbit.tkmind.cn');
|
|
assert.equal(config.hostPath, '/rybbit');
|
|
assert.equal(config.scriptPath, '/rybbit/script.js');
|
|
});
|
|
|
|
test('injects one local same-origin rybbit tracker with page dimensions', () => {
|
|
const html = '<!doctype html><html><head><title>Demo</title></head><body><h1>Demo</h1></body></html>';
|
|
const out = injectMindSpaceRybbit(html, {
|
|
ownerId: 'user-123',
|
|
ownerLabel: '张三',
|
|
pageId: 'page-1',
|
|
publicationId: 'pub-1',
|
|
config: {
|
|
enabled: true,
|
|
siteId: '2',
|
|
idSecret: 'secret',
|
|
scriptPath: '/rybbit/script.js',
|
|
hostPath: '/rybbit',
|
|
},
|
|
});
|
|
assert.match(out, /src="\/rybbit\/script\.js"/);
|
|
assert.match(out, /data-site-id="2"/);
|
|
assert.match(out, /data-memind-rybbit="1"/);
|
|
assert.match(out, /r\.identify\(d\.owner_id,/);
|
|
assert.match(out, /r\.event\(n,p\)/);
|
|
assert.match(out, /page_click/);
|
|
assert.match(out, /page_form_submit/);
|
|
assert.match(out, /page_scroll_/);
|
|
assert.match(out, /page_engaged_10s/);
|
|
assert.match(out, /"username":"张三"/);
|
|
assert.doesNotMatch(out, /user-123/);
|
|
assert.equal(injectMindSpaceRybbit(out, {
|
|
ownerId: 'user-123',
|
|
config: { enabled: true, siteId: '2', idSecret: 'secret' },
|
|
}), out);
|
|
});
|
|
|
|
test('identifies the pseudonymous owner once rybbit is ready', () => {
|
|
const out = injectMindSpaceRybbit('<!doctype html><html><head></head><body></body></html>', {
|
|
ownerId: 'user-123',
|
|
ownerSegment: 'plan:pro',
|
|
ownerLabel: '张三',
|
|
channel: 'h5',
|
|
config: {
|
|
enabled: true,
|
|
siteId: '2',
|
|
idSecret: 'secret',
|
|
scriptPath: '/rybbit/script.js',
|
|
hostPath: '/rybbit',
|
|
},
|
|
});
|
|
const inlineScript = out.match(/<script data-memind-rybbit="1">([\s\S]*?)<\/script>/)?.[1];
|
|
assert.ok(inlineScript);
|
|
|
|
const calls = [];
|
|
const timers = [];
|
|
vm.runInNewContext(inlineScript, {
|
|
window: {
|
|
rybbit: {
|
|
identify: (...args) => calls.push(['identify', ...args]),
|
|
event: (...args) => calls.push(['event', ...args]),
|
|
},
|
|
innerHeight: 800,
|
|
scrollY: 0,
|
|
addEventListener: () => {},
|
|
},
|
|
document: {
|
|
readyState: 'complete',
|
|
title: 'Demo',
|
|
documentElement: { scrollHeight: 1600 },
|
|
addEventListener: () => {},
|
|
},
|
|
location: { href: 'http://127.0.0.1:8081/MindSpace/demo/public/page.html' },
|
|
setTimeout: (fn) => { timers.push(fn); },
|
|
});
|
|
|
|
assert.equal(calls[0]?.[0], 'identify');
|
|
assert.match(String(calls[0]?.[1] ?? ''), /^[a-f0-9]{32}$/);
|
|
assert.equal(calls[0]?.[2]?.username, '张三');
|
|
assert.equal(calls[0]?.[2]?.owner_segment, 'plan:pro');
|
|
});
|