/** * Unit Tests — job-manager.js */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import fs from 'fs'; describe('JobManager', () => { let JobManager, jm; const STORE_PATH = '/tmp/test-jobs.json'; beforeAll(() => { if (fs.existsSync(STORE_PATH)) fs.unlinkSync(STORE_PATH); ({ JobManager } = require('../../services/job-manager')); jm = new JobManager({ storePath: STORE_PATH }); }); afterAll(() => { try { fs.unlinkSync(STORE_PATH); } catch {} }); it('should create a job with unique ID', () => { const job = jm.createJob({ domain: 'test', description: 'Test job' }); expect(job.jobId).toBeDefined(); expect(job.status).toBe('queued'); }); it('should get a job by ID', () => { const created = jm.createJob({ domain: 'test2' }); const fetched = jm.getJob(created.jobId); expect(fetched).toBeDefined(); expect(fetched.jobId).toBe(created.jobId); }); it('should return null for non-existent job', () => { expect(jm.getJob('nonexistent-id')).toBeNull(); }); it('should update job status', () => { const job = jm.createJob({ domain: 'update-test' }); jm.updateJob(job.jobId, { status: 'running', progress: '50%' }); const updated = jm.getJob(job.jobId); expect(updated.status).toBe('running'); expect(updated.progress).toBe('50%'); }); it('should list jobs', () => { const jobs = jm.listJobs({ limit: 100 }); expect(Array.isArray(jobs)).toBe(true); expect(jobs.length).toBeGreaterThanOrEqual(2); }); it('should filter jobs by apiKey', () => { const job = jm.createJob({ domain: 'keyed', apiKey: 'test-key-123' }); const filtered = jm.listJobs({ apiKey: 'test-key-123' }); expect(filtered.some(j => j.jobId === job.jobId)).toBe(true); }); it('should provide public job view', () => { const job = jm.createJob({ domain: 'public-test', apiKey: 'secret-key' }); const pub = jm.getPublicJob(job.jobId); expect(pub).toBeDefined(); expect(pub.jobId).toBe(job.jobId); // Public view should not expose internal apiKey }); it('should persist jobs to file', () => { expect(fs.existsSync(STORE_PATH)).toBe(true); const data = JSON.parse(fs.readFileSync(STORE_PATH, 'utf-8')); expect(Array.isArray(data) || typeof data === 'object').toBe(true); }); });