mirror of
https://github.com/block/buzz.git
synced 2026-10-29 13:31:44 +00:00
37 lines
3.1 KiB
TypeScript
37 lines
3.1 KiB
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { createGenesis } from '../src/assignment.ts';
|
|
import { hash, semanticHash, sameSelection, moveSelection, validateAssignment, type Grant } from '../src/handoff.ts';
|
|
import { message, newKey, publicKey } from '../src/protocol.ts';
|
|
import { profileRevision } from '../src/profiles.ts';
|
|
|
|
const reorder = (v: any): any => Array.isArray(v) ? v.map(reorder) : v !== null && typeof v === 'object' ? Object.fromEntries(Object.entries(v).reverse().map(([k,x]) => [k,reorder(x)])) : v;
|
|
test('validated grant selections are semantic; legacy identity hashes and ordered protocol arrays remain exact', () => {
|
|
const genesis = createGenesis(publicKey(newKey()), publicKey(newKey()), 'source');
|
|
const behavior = { name: 'Source', parent: null, instructions: 'Exact source instructions', revision: profileRevision('Source', null, 'Exact source instructions') };
|
|
const requested = { model: 'fixture-model', workspace: '/fixture', profile: behavior.revision, configuration: { name: 'Destination', revision: 1 }, behavior };
|
|
const operation = message('move', 'source', genesis.agent, 2, { target: 'target', targetRevision: 1, selection: reorder(requested) });
|
|
const base: Grant = { root: hash(genesis), predecessor: hash(genesis), source: 'source', target: 'target', agent: genesis.agent, operation, prepared: 'immutable-token', selection: requested, targetRevision: 1, sourceRun: null };
|
|
const validate = (g: Grant) => validateAssignment({ genesis, assignedHost: 'target', chain: [g] });
|
|
validate(base); // Historical grants retain their existing hash and selection meaning.
|
|
const grant: Grant = { ...base, materialization: 'named-v1', selection: moveSelection(requested, 1, 'named-v1') };
|
|
validate(grant); validate({ ...grant, selection: reorder(grant.selection) });
|
|
assert.ok(sameSelection(requested, reorder(requested)));
|
|
assert.notEqual(hash(requested), hash(reorder(requested)));
|
|
assert.equal(semanticHash(requested), semanticHash(reorder(requested)));
|
|
assert.notEqual(semanticHash(['a','b']), semanticHash(['b','a']));
|
|
for (const selection of [
|
|
{ ...grant.selection, workspace: '/other' }, { ...grant.selection, extra: true },
|
|
{ ...grant.selection, behavior: { ...behavior, extra: true } },
|
|
{ ...grant.selection, configuration: { name: 'Destination', revision: 1 } },
|
|
{ ...grant.selection, profile: 'default' },
|
|
Object.fromEntries(Object.entries(grant.selection).filter(([k]) => k !== 'model')),
|
|
]) assert.throws(() => validate({ ...grant, selection } as Grant));
|
|
assert.throws(() => validate({ ...grant, extra: true } as Grant));
|
|
assert.throws(() => validate({ ...grant, materialization: 'unknown' } as any));
|
|
const missing = { ...grant } as any; delete missing.prepared; assert.throws(() => validate(missing));
|
|
const { configuration: _configuration, ...implicit } = requested;
|
|
assert.deepEqual(moveSelection(implicit, 0, 'named-v1').configuration, { name: 'default', revision: 2 });
|
|
assert.equal(moveSelection(requested, 0, 'named-v1').configuration!.revision, 2, 'initial projected @1 is never reused');
|
|
});
|