47 lines
3.0 KiB
JavaScript
47 lines
3.0 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { appendRelease, artifactPath } from './release-catalog.mjs';
|
|
|
|
const initial = { schemaVersion: 1, id: 'trove-qa', name: 'QA', generatedAt: '2026-09-01T00:00:00Z', curios: [] };
|
|
const manifest = { id: 'dev.trove.qa.example', name: 'Example', version: '1.0.0', engine: { trove: '^0.1.0' } };
|
|
const arm = { target: 'aarch64-apple-darwin', url: 'https://example.org/1.0.0/arm.curio', sha256: 'a'.repeat(64), size: 100 };
|
|
const timestamp = '2026-09-09T00:00:00Z';
|
|
const released = () => appendRelease(initial, manifest, arm, timestamp);
|
|
|
|
test('publishing a new version retains all earlier releases', () => {
|
|
const original = released();
|
|
const updated = appendRelease(original, { ...manifest, version: '1.1.0' }, { ...arm, url: 'https://example.org/1.1.0/arm.curio', sha256: 'b'.repeat(64) }, '2026-09-10T00:00:00Z');
|
|
assert.equal(updated.curios[0].versions.length, 2);
|
|
assert.deepEqual(updated.curios[0].versions[1], original.curios[0].versions[0]);
|
|
assert.equal(initial.curios.length, 0);
|
|
});
|
|
test('repeating an identical release does not change dates or metadata', () => {
|
|
const original = released();
|
|
assert.deepEqual(appendRelease(original, manifest, arm, '2026-10-01T00:00:00Z'), original);
|
|
});
|
|
test('one version can add a second architecture without replacing the first', () => {
|
|
const original = released();
|
|
const updated = appendRelease(original, manifest, { ...arm, target: 'x86_64-apple-darwin', url: 'https://example.org/1.0.0/intel.curio', sha256: 'c'.repeat(64) }, '2026-09-10T00:00:00Z');
|
|
assert.equal(updated.curios[0].versions.length, 1);
|
|
assert.equal(updated.curios[0].versions[0].artifacts.length, 2);
|
|
assert.deepEqual(updated.curios[0].versions[0].artifacts[0], arm);
|
|
assert.equal(updated.curios[0].versions[0].releasedAt, timestamp);
|
|
});
|
|
for (const [key, value] of [['sha256', 'd'.repeat(64)], ['size', 101], ['url', 'https://example.org/replaced.curio']]) {
|
|
test(`same version and architecture cannot replace ${key}`, () => {
|
|
const original = released();
|
|
assert.throws(() => appendRelease(original, manifest, { ...arm, [key]: value }, timestamp), /bump the plugin version/);
|
|
assert.deepEqual(original.curios[0].versions[0].artifacts[0], arm);
|
|
});
|
|
}
|
|
test('published engine compatibility cannot change silently', () => {
|
|
assert.throws(() => appendRelease(released(), { ...manifest, engine: { trove: '^0.2.0' } }, arm, timestamp), /engine range cannot change/);
|
|
});
|
|
test('artifact paths distinguish architecture, ID and version and reject traversal', () => {
|
|
assert.equal(artifactPath(manifest, 'any'), 'packages/dev.trove.qa.example/1.0.0/any.curio');
|
|
assert.notEqual(artifactPath(manifest, 'aarch64-apple-darwin'), artifactPath(manifest, 'x86_64-apple-darwin'));
|
|
assert.throws(() => artifactPath({ ...manifest, id: '../outside' }, 'any'));
|
|
assert.throws(() => artifactPath({ ...manifest, version: '../outside' }, 'any'));
|
|
assert.throws(() => artifactPath(manifest, '../outside'));
|
|
});
|