Files
memind/page-data-html-detect.test.mjs
T

92 lines
3.2 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {
assertPolicyMatchesHtmlDatasets,
buildPageDataPolicyDatasetsFromRegistry,
detectPageDataDatasetUsageFromHtml,
htmlUsesForbiddenLegacyPageDataApi,
htmlUsesPageDataApi,
} from './page-data-html-detect.mjs';
test('htmlUsesForbiddenLegacyPageDataApi detects /api/page-data passthrough', () => {
const html = `fetch('/api/page-data/daily_todo', { method: 'POST' })`;
assert.equal(htmlUsesForbiddenLegacyPageDataApi(html), true);
assert.equal(htmlUsesPageDataApi(html), true);
assert.equal(detectPageDataDatasetUsageFromHtml(html).size, 0);
});
test('detectPageDataDatasetUsageFromHtml treats browser deleteRow as a soft delete', () => {
const html = `
await c.insertRow('tkmind_exp_survey', { satisfaction: '满意' });
await c.listRows('tkmind_exp_survey', { limit: 10 });
await c.deleteRow('tkmind_exp_survey', 42);
`;
const usage = detectPageDataDatasetUsageFromHtml(html);
assert.equal(usage.size, 1);
assert.deepEqual(usage.get('tkmind_exp_survey'), { insert: true, read: true, softDelete: true });
});
test('buildPageDataPolicyDatasetsFromRegistry grants registered soft delete when HTML uses deleteRow', () => {
const datasets = buildPageDataPolicyDatasetsFromRegistry({
html: `const DATASET = 'mood_notes'; await c.deleteRow(DATASET, 1);`,
registryDatasets: [{ name: 'mood_notes', columns: { soft_delete: ['id'] } }],
});
assert.equal(datasets.mood_notes.softDelete, true);
assert.deepEqual(datasets.mood_notes.columns.soft_delete, ['id']);
});
test('detectPageDataDatasetUsageFromHtml resolves dataset constants', () => {
const html = `
const DATASET = 'reading_survey';
await client.listRows(DATASET, { limit: 500 });
`;
const usage = detectPageDataDatasetUsageFromHtml(html);
assert.deepEqual(usage.get('reading_survey'), { read: true });
});
test('detectPageDataDatasetUsageFromHtml ignores template-literal row id interpolation', () => {
const html = `
const DATASET = 'daily_log';
await client.listRows(DATASET, { limit: 200 });
rows.map((row) => \`<button onclick="window.deleteRow(\${row.id})">删除</button>\`);
`;
const usage = detectPageDataDatasetUsageFromHtml(html);
assert.deepEqual([...usage.entries()], [['daily_log', { read: true }]]);
assert.equal(usage.has('$'), false);
});
test('assertPolicyMatchesHtmlDatasets rejects mismatched dataset names', () => {
const html = `await c.insertRow('tkmind_exp_survey', {});`;
assert.throws(
() =>
assertPolicyMatchesHtmlDatasets(html, {
experience_survey_responses: { insert: true },
}),
/不一致/,
);
});
test('buildPageDataPolicyDatasetsFromRegistry infers insert-only policy', () => {
const html = `await c.insertRow('survey_responses', { q1: 'a' });`;
const datasets = buildPageDataPolicyDatasetsFromRegistry({
html,
registryDatasets: [
{
name: 'survey_responses',
columns: {
insert: ['q1'],
read: ['id', 'q1', 'created_at'],
},
},
],
});
assert.deepEqual(datasets.survey_responses, {
insert: true,
read: false,
update: false,
softDelete: false,
hardDelete: false,
columns: { insert: ['q1'] },
});
});