| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 |
- import test from 'node:test';
- import assert from 'node:assert/strict';
- import fs from 'node:fs';
- import path from 'node:path';
- import { deployBoardSeries, patchPublicBoardCode } from '../scripts/deploy-workshop-board-series.mjs';
- const code = `const fields={artifact:'objectId rawText report ownerName version dataMode dashboardState workshopKey'};function ksfGetPublicBoard(){};/*existing account wrapper retained*/`;
- function fixture() {
- let row = { objectId: 'fn', name: 'ksfGetPublicBoard', path: '/ksfGetPublicBoard', code, ACL: {} };
- const puts = [];
- return { puts, get row() { return row; }, request: async (method, route, body) => {
- if (route.startsWith('/classes/Function?')) return { results: [structuredClone(row)] };
- if (route === '/schemas') return { results: [{ className: 'KfArtifact', fields: { reportSeriesKey: { type: 'String' } } }] };
- if (method === 'PUT') { puts.push(body);row = { ...row, ...body }; }
- return structuredClone(row);
- } };
- }
- test('补字段保持当前完整函数与身份包装,默认只读;正常应用与重复执行不重写', async () => {
- const f = fixture(), dir = fs.mkdtempSync(path.resolve('work/series-deploy-test-'));
- const plan = await deployBoardSeries({ request: f.request });assert.equal(plan.changed, true);assert.equal(f.puts.length, 0);
- const result = await deployBoardSeries({ request: f.request, manifest: plan, apply: true, backupDir: dir });
- assert.equal(result.readbackVerified, true);assert.equal(result.schemaAndPermissionsPreserved, true);assert.equal(f.puts.length, 1);
- assert.equal(f.row.code, code.replace('version dataMode', 'version reportSeriesKey dataMode'));
- const repeat = await deployBoardSeries({ request: f.request, manifest: plan, apply: true, backupDir: dir });
- assert.equal(repeat.alreadyDeployed, true);assert.equal(f.puts.length, 1);
- });
- test('未知合同、模糊字段集与部署基线变化在写入前拒绝', async () => {
- assert.throws(() => patchPublicBoardCode('ksfGetPublicBoard'), { code: 'PUBLIC_ARTIFACT_WHITELIST_AMBIGUOUS' });
- assert.throws(() => patchPublicBoardCode(code + code), { code: 'PUBLIC_ARTIFACT_WHITELIST_AMBIGUOUS' });
- const f = fixture(), plan = await deployBoardSeries({ request: f.request });
- await assert.rejects(() => deployBoardSeries({ request: f.request, apply: true, manifest: { ...plan, beforeSha256: 'changed' }, backupDir: path.resolve('work') }), { code: 'DEPLOYMENT_BASELINE_CHANGED' });
- assert.equal(f.puts.length, 0);
- });
- test('不确定写结果先回读,再恢复本次字段变更;不覆盖并发版本', async () => {
- for (const concurrent of [false, true]) {
- const f = fixture(), plan = await deployBoardSeries({ request: f.request });let once = false;
- const request = async (m, r, b) => {
- const result = await f.request(m, r, b);
- if (m === 'PUT' && !once) { once = true;if (concurrent) await f.request('PUT', r, { code: f.row.code + '//another publisher' });throw Error('response lost'); }
- return result;
- };
- await assert.rejects(() => deployBoardSeries({ request, manifest: plan, apply: true, backupDir: fs.mkdtempSync(path.resolve('work/series-deploy-failure-')) }), e => {
- assert.equal(e.receipt.rollbackComplete, !concurrent);return true;
- });
- assert.equal(f.row.code === code, !concurrent);
- }
- });
|