116 lines
4.2 KiB
JavaScript
116 lines
4.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('detectPageDataDatasetUsageFromHtml detects updateRow for literal and constant datasets', () => {
|
|
const usage = detectPageDataDatasetUsageFromHtml(`
|
|
const PRODUCTS = 'products';
|
|
await c.updateRow(PRODUCTS, 1, { status: 'inactive' });
|
|
await c.updateRow('orders', 2, { status: 'shipped' });
|
|
`);
|
|
assert.deepEqual(usage.get('products'), { update: true });
|
|
assert.deepEqual(usage.get('orders'), { update: true });
|
|
});
|
|
|
|
test('buildPageDataPolicyDatasetsFromRegistry grants registered update columns', () => {
|
|
const datasets = buildPageDataPolicyDatasetsFromRegistry({
|
|
html: `await c.listRows('orders'); await c.updateRow('orders', 1, { status: 'shipped' });`,
|
|
registryDatasets: [{
|
|
name: 'orders',
|
|
actions: ['read', 'update'],
|
|
columns: { read: ['id', 'status'], update: ['status'] },
|
|
}],
|
|
});
|
|
assert.equal(datasets.orders.read, true);
|
|
assert.equal(datasets.orders.update, true);
|
|
assert.deepEqual(datasets.orders.columns.update, ['status']);
|
|
});
|
|
|
|
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'] },
|
|
});
|
|
});
|