104 lines
3.0 KiB
JavaScript
104 lines
3.0 KiB
JavaScript
import { describe, expect, it } from 'bun:test';
|
|||
|
|
import os from 'os';
|
||
|
|
import path from 'path';
|
||
|
|
import { mkdtemp, rm } from 'fs/promises';
|
||
|
|
import { createProjectConfigRuntime } from './project-config.js';
|
||
|
|
|
||
|
|
const createRuntime = async () => {
|
||
|
|
const tempRoot = await mkdtemp(path.join(os.tmpdir(), 'oc-scheduled-project-config-'));
|
||
|
|
const runtime = createProjectConfigRuntime({
|
||
|
|
fsPromises: await import('fs/promises'),
|
||
|
|
path,
|
||
|
|
projectsDirPath: tempRoot,
|
||
|
|
createTaskID: () => 'task-fixed-id',
|
||
|
|
});
|
||
|
|
return {
|
||
|
|
runtime,
|
||
|
|
cleanup: async () => {
|
||
|
|
await rm(tempRoot, { recursive: true, force: true });
|
||
|
|
},
|
||
|
|
};
|
||
|
|
};
|
||
|
|
|
||
|
|
describe('project-config runtime', () => {
|
||
|
|
it('creates and persists a scheduled task', async () => {
|
||
|
|
const { runtime, cleanup } = await createRuntime();
|
||
|
|
try {
|
||
|
|
const result = await runtime.upsertScheduledTask('project-test', {
|
||
|
|
name: 'Nightly digest',
|
||
|
|
enabled: true,
|
||
|
|
schedule: {
|
||
|
|
kind: 'daily',
|
||
|
|
time: '09:30',
|
||
|
|
timezone: 'UTC',
|
||
|
|
},
|
||
|
|
execution: {
|
||
|
|
prompt: 'Summarize repository changes',
|
||
|
|
providerID: 'openai',
|
||
|
|
modelID: 'gpt-4.1',
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(result.created).toBe(true);
|
||
|
|
expect(result.task.id).toBe('task-fixed-id');
|
||
|
|
const reloaded = await runtime.listScheduledTasks('project-test');
|
||
|
|
expect(reloaded).toHaveLength(1);
|
||
|
|
expect(reloaded[0].name).toBe('Nightly digest');
|
||
|
|
expect(reloaded[0].schedule.timezone).toBe('UTC');
|
||
|
|
expect(reloaded[0].schedule.times).toEqual(['09:30']);
|
||
|
|
} finally {
|
||
|
|
await cleanup();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
it('rejects invalid cron expressions', async () => {
|
||
|
|
const { runtime, cleanup } = await createRuntime();
|
||
|
|
try {
|
||
|
|
await expect(runtime.upsertScheduledTask('project-test', {
|
||
|
|
name: 'Invalid cron task',
|
||
|
|
enabled: true,
|
||
|
|
schedule: {
|
||
|
|
kind: 'cron',
|
||
|
|
cron: 'invalid cron',
|
||
|
|
timezone: 'UTC',
|
||
|
|
},
|
||
|
|
execution: {
|
||
|
|
prompt: 'Run checks',
|
||
|
|
providerID: 'openai',
|
||
|
|
modelID: 'gpt-4.1',
|
||
|
|
},
|
||
|
|
})).rejects.toThrow('schedule.cron is invalid');
|
||
|
|
} finally {
|
||
|
|
await cleanup();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
it('accepts one-time schedule with date and time', async () => {
|
||
|
|
const { runtime, cleanup } = await createRuntime();
|
||
|
|
try {
|
||
|
|
const result = await runtime.upsertScheduledTask('project-test', {
|
||
|
|
name: 'One-time review',
|
||
|
|
enabled: true,
|
||
|
|
schedule: {
|
||
|
|
kind: 'once',
|
||
|
|
date: '2026-04-20',
|
||
|
|
time: '13:45',
|
||
|
|
timezone: 'Europe/Kyiv',
|
||
|
|
},
|
||
|
|
execution: {
|
||
|
|
prompt: 'Create a release summary',
|
||
|
|
providerID: 'openai',
|
||
|
|
modelID: 'gpt-4.1',
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
expect(result.task.schedule.kind).toBe('once');
|
||
|
|
expect(result.task.schedule.date).toBe('2026-04-20');
|
||
|
|
expect(result.task.schedule.time).toBe('13:45');
|
||
|
|
expect(result.task.schedule.timezone).toBe('Europe/Kyiv');
|
||
|
|
} finally {
|
||
|
|
await cleanup();
|
||
|
|
}
|
||
|
|
});
|
||
|
|
});
|