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) => \`\`); `; 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'] }, }); });