This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { newFixture, type Fixture } from '../helpers/fixture.js';
|
||||
import {
|
||||
manifestVersion,
|
||||
parseScriptVersions,
|
||||
scriptVersionError
|
||||
} from '../../src/lib/script-version.js';
|
||||
import { artifactVersionLabel } from '../../src/lib/artifact-version.js';
|
||||
|
||||
it('validates numeric release versions and exact manifest filenames', () => {
|
||||
for (const value of [
|
||||
undefined,
|
||||
null,
|
||||
'',
|
||||
' ',
|
||||
'v1.0.0',
|
||||
'01.0.0',
|
||||
'1.0',
|
||||
'1.0.0-beta',
|
||||
'1.0.0\nextra',
|
||||
'1.'.repeat(50)
|
||||
])
|
||||
expect(scriptVersionError(value)).not.toBe('');
|
||||
for (const value of ['0.0.0', '1.20.3', ' 1.2.0 ']) expect(scriptVersionError(value)).toBe('');
|
||||
expect(manifestVersion({}, 'constructor')).toBe('');
|
||||
expect(parseScriptVersions('{"hud.gsc":"1.2.0","HUD.gsc":"2.0.0","t5-plugin":"tag"}')).toEqual({
|
||||
'hud.gsc': '1.2.0',
|
||||
'HUD.gsc': '2.0.0'
|
||||
});
|
||||
for (const text of [
|
||||
'oops',
|
||||
'[]',
|
||||
'null',
|
||||
'{}',
|
||||
'{"hud.gsc":1}',
|
||||
'{"hud.gsc":"1"}',
|
||||
'{"path/hud.gsc":"1.0.0"}'
|
||||
])
|
||||
expect(() => parseScriptVersions(text)).toThrow();
|
||||
});
|
||||
|
||||
it('distinguishes historical script uploads from publisher versions', () => {
|
||||
expect(artifactVersionLabel({ version: 3 }, 'script')).toBe('Unversioned (upload 3)');
|
||||
expect(artifactVersionLabel({ version: 3, release_version: '1.2.0' }, 'script')).toBe(
|
||||
'1.2.0 (upload 3)'
|
||||
);
|
||||
expect(artifactVersionLabel({ version: 3 }, 'config')).toBe('v3');
|
||||
});
|
||||
|
||||
let fixture: Fixture;
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
fixture = await newFixture();
|
||||
});
|
||||
afterEach(async () => {
|
||||
await fixture.cleanup();
|
||||
});
|
||||
const script = { name: 'HUD', targetRelPath: 'hud.gsc', content: Buffer.from('main(){}') };
|
||||
|
||||
describe('mandatory script releases', () => {
|
||||
it('rejects missing and invalid versions without creating records', async () => {
|
||||
const { createScript, uploadNewVersion, listScripts, listVersions } =
|
||||
await import('../../src/lib/server/fleet/scripts.js');
|
||||
for (const releaseVersion of [undefined, '', 'v1.0.0', '1.0', '1.0.0-rc1']) {
|
||||
expect(() => createScript({ ...script, releaseVersion })).toThrow(/release version/);
|
||||
}
|
||||
expect(listScripts()).toHaveLength(0);
|
||||
const saved = createScript({ ...script, releaseVersion: ' 1.0.0 ' });
|
||||
expect(saved.version.release_version).toBe('1.0.0');
|
||||
expect(() => uploadNewVersion(saved.script.id, script.content)).toThrow(/required/);
|
||||
expect(listVersions(saved.script.id)).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('reuses identical releases, rejects changed contents and accepts older versions', async () => {
|
||||
const { createScript, uploadNewVersion, listVersions } =
|
||||
await import('../../src/lib/server/fleet/scripts.js');
|
||||
const saved = createScript({ ...script, releaseVersion: '2.0.0' });
|
||||
expect(uploadNewVersion(saved.script.id, script.content, 'retry', '2.0.0')).toEqual(
|
||||
saved.version
|
||||
);
|
||||
expect(() =>
|
||||
uploadNewVersion(saved.script.id, Buffer.from('changed'), undefined, '2.0.0')
|
||||
).toThrow(/Bump/);
|
||||
const older = uploadNewVersion(
|
||||
saved.script.id,
|
||||
Buffer.from('old release'),
|
||||
undefined,
|
||||
'1.0.0'
|
||||
);
|
||||
expect(older).toMatchObject({ version: 2, release_version: '1.0.0' });
|
||||
expect(listVersions(saved.script.id)).toHaveLength(2);
|
||||
expect(
|
||||
createScript({ ...script, name: 'Other', releaseVersion: '2.0.0' }).version
|
||||
.release_version
|
||||
).toBe('2.0.0');
|
||||
});
|
||||
|
||||
it('preserves legacy content and does not infer a release from matching bytes', async () => {
|
||||
const { createScript, uploadNewVersion, getVersion, getVersionContent } =
|
||||
await import('../../src/lib/server/fleet/scripts.js');
|
||||
const { db } = await import('../../src/lib/server/db/index.js');
|
||||
const saved = createScript({ ...script, releaseVersion: '1.0.0' });
|
||||
db()
|
||||
.prepare('UPDATE script_versions SET release_version = NULL WHERE id = ?')
|
||||
.run(saved.version.id);
|
||||
const next = uploadNewVersion(saved.script.id, script.content, undefined, '1.0.0');
|
||||
expect(next).toMatchObject({ version: 2, release_version: '1.0.0' });
|
||||
expect(getVersion(saved.version.id)!.release_version).toBeNull();
|
||||
expect(getVersionContent(saved.version.id)).toEqual(script.content);
|
||||
});
|
||||
|
||||
it('enforces the API contract even when reuseExisting is requested', async () => {
|
||||
const create = await import('../../src/routes/api/scripts/+server.js');
|
||||
const upload = await import('../../src/routes/api/scripts/[id]/versions/+server.js');
|
||||
const { listScripts, listVersions } = await import('../../src/lib/server/fleet/scripts.js');
|
||||
const url = new URL('http://test/api/scripts');
|
||||
const form = new FormData();
|
||||
form.set('name', 'HUD');
|
||||
form.set('content', new File(['main(){}'], 'hud.gsc'));
|
||||
const request = () => new Request(url, { method: 'POST', body: form });
|
||||
expect((await create.POST({ url, request: request() })).status).toBe(400);
|
||||
expect(listScripts()).toHaveLength(0);
|
||||
form.set('releaseVersion', '1.0.0');
|
||||
const saved = await (await create.POST({ url, request: request() })).json();
|
||||
const params = { id: String(saved.script.id) };
|
||||
form.set('reuseExisting', 'true');
|
||||
form.delete('releaseVersion');
|
||||
expect((await upload.POST({ params, request: request() })).status).toBe(400);
|
||||
form.set('releaseVersion', '1.0.0');
|
||||
expect(await (await upload.POST({ params, request: request() })).json()).toMatchObject({
|
||||
reused: true,
|
||||
version: { id: saved.versionId, release_version: '1.0.0' }
|
||||
});
|
||||
form.set('content', new File(['different'], 'hud.gsc'));
|
||||
expect((await upload.POST({ params, request: request() })).status).toBe(409);
|
||||
expect(listVersions(saved.script.id)).toHaveLength(1);
|
||||
form.set('releaseVersion', '0.9.0');
|
||||
expect((await upload.POST({ params, request: request() })).status).toBe(200);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user