Files
makelore/tests/unit/release-job.test.ts

63 lines
2.7 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest';
import { ReleaseJobManager } from '@electron/services/release-job';
import { ProjectReleaseBuildError } from '@electron/services/project-release-builder';
function preparedRelease() {
return {
sourceArchive: {
path: '/tmp/project.zip',
name: 'project.zip' as const,
bytes: Buffer.from('zip'),
summary: {
archivePath: '/tmp/project.zip',
archiveName: 'project.zip',
sha256: 'a'.repeat(64),
fileCount: 1,
sourceBytes: 3,
archiveBytes: 3,
excludedCount: 0,
excludedPaths: [],
manifest: {
schema_version: 1 as const,
kind: 'web' as const,
runtime: 'static' as const,
build: { preset: 'vite' as const, package_manager: 'npm' as const, entry: 'index.html' as const },
},
},
},
builtArchive: { path: '/tmp/built.zip', name: 'built-project.zip' as const, bytes: Buffer.from('built') },
contract: {} as never,
distRoot: '/tmp/dist',
staticArtifact: {} as never,
dispose: vi.fn(async () => undefined),
};
}
describe('ReleaseJobManager', () => {
it('serializes jobs per project and publishes terminal status', async () => {
const prepare = vi.fn(async () => preparedRelease());
const manager = new ReleaseJobManager({ prepare });
const first = manager.start({ projectId: 'project-1', projectPath: '/tmp/project-1', clientVersion: '2.0.0' });
expect(first.state).toBe('running');
expect(() => manager.start({ projectId: 'project-1', projectPath: '/tmp/project-1', clientVersion: '2.0.0' }))
.toThrowError(ProjectReleaseBuildError);
await vi.waitFor(() => expect(manager.get(first.jobId)?.state).toBe('complete'));
expect(prepare).toHaveBeenCalledTimes(1);
expect(manager.get(first.jobId)?.result?.package.archiveName).toBe('project.zip');
});
it('cancels an in-flight build and releases the project lock', async () => {
let resolveBuild!: (value: ReturnType<typeof preparedRelease>) => void;
const prepare = vi.fn(() => new Promise<ReturnType<typeof preparedRelease>>((resolve) => {
resolveBuild = resolve;
}));
const manager = new ReleaseJobManager({ prepare });
const job = manager.start({ projectId: 'project-2', projectPath: '/tmp/project-2', clientVersion: '2.0.0' });
expect(manager.cancel(job.jobId)?.state).toBe('cancelled');
resolveBuild(preparedRelease());
await vi.waitFor(() => expect(manager.get(job.jobId)?.state).toBe('cancelled'));
await new Promise((resolve) => setTimeout(resolve, 0));
expect(() => manager.start({ projectId: 'project-2', projectPath: '/tmp/project-2', clientVersion: '2.0.0' })).not.toThrow();
});
});