| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- import test from 'node:test';
- import assert from 'node:assert/strict';
- import fs from 'node:fs';
- import os from 'node:os';
- import path from 'node:path';
- import { fileURLToPath } from 'node:url';
- import { installWorkshopSkill } from '../scripts/install-workshop-skill.mjs';
- const source = fileURLToPath(new URL('../skills/ksf-workshop-runtime', import.meta.url));
- function fixture(t) {
- const root = fs.mkdtempSync(path.join(os.tmpdir(), 'ksf-skill-install-'));
- t.after(() => {
- assert.equal(path.dirname(root), fs.realpathSync(os.tmpdir()));
- assert.ok(path.basename(root).startsWith('ksf-skill-install-'));
- fs.rmSync(root, { recursive: true });
- });
- const destination = path.join(root, 'skills', 'ksf-workshop-runtime');
- fs.cpSync(source, destination, { recursive: true });
- fs.writeFileSync(path.join(destination, 'credential-binding.json'), 'fixture-private-binding');
- const state = path.join(root, 'ksf-workshop-state', 'participants');
- fs.mkdirSync(state, { recursive: true });
- fs.writeFileSync(path.join(state, 'fixture.json'), 'fixture-private-state');
- return { root, destination, state };
- }
- test('Skill只读预检与重复安装不改变绑定、状态和文件,也不创建备份', t => {
- const f = fixture(t);
- const check = installWorkshopSkill(source, f.destination, { apply: false });
- assert.equal(check.readOnly, true); assert.equal(check.filesChecked, 11); assert.deepEqual(check.changed, []);
- const result = installWorkshopSkill(source, f.destination);
- assert.deepEqual(result.changed, []); assert.equal(result.backup, null);
- assert.equal(fs.readFileSync(path.join(f.destination, 'credential-binding.json'), 'utf8'), 'fixture-private-binding');
- assert.equal(fs.readFileSync(path.join(f.state, 'fixture.json'), 'utf8'), 'fixture-private-state');
- assert.ok(!JSON.stringify(result).includes('fixture-private'));
- });
- test('未知目标修改在升级前停止,不覆盖维护人的Skill或清单', t => {
- for (const name of ['SKILL.md', 'FILES.sha256']) {
- const f = fixture(t), target = path.join(f.destination, name);
- fs.writeFileSync(target, 'maintainer-concurrent-edit');
- assert.throws(() => installWorkshopSkill(source, f.destination), { code: name === 'SKILL.md' ? 'TARGET_HAS_UNEXPECTED_CONTENT' : 'TARGET_MANIFEST_HAS_UNEXPECTED_CONTENT' });
- assert.equal(fs.readFileSync(target, 'utf8'), 'maintainer-concurrent-edit');
- assert.deepEqual(fs.readdirSync(f.root).sort(), ['ksf-workshop-state', 'skills']);
- }
- });
- test('包内脚本被篡改时拒绝升级且保留已有文件', t => {
- const f = fixture(t), altered = path.join(f.root, 'altered-package');
- fs.cpSync(source, altered, { recursive: true });
- fs.appendFileSync(path.join(altered, 'scripts', 'ksf-workshop.mjs'), '\n// tampered\n');
- const before = fs.readFileSync(path.join(f.destination, 'SKILL.md'));
- assert.throws(() => installWorkshopSkill(altered, f.destination), { code: 'PACKAGE_HASH_MISMATCH' });
- assert.deepEqual(fs.readFileSync(path.join(f.destination, 'SKILL.md')), before);
- });
|