Initial
This commit is contained in:
89
server/test/runplan-schedules.test.mjs
Normal file
89
server/test/runplan-schedules.test.mjs
Normal file
@@ -0,0 +1,89 @@
|
||||
import { db, load, makeUser } from './setup.mjs';
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
const { createCredential } = await load('../models/credentialModel.js');
|
||||
const { createHost } = await load('../models/hostModel.js');
|
||||
const { updateSettings } = await load('../models/settingsModel.js');
|
||||
const {
|
||||
computeNextRun,
|
||||
createRunPlanSchedule,
|
||||
listDueRunPlanSchedules,
|
||||
listRunPlanScheduleRuns,
|
||||
previewScheduleOccurrences
|
||||
} = await load('../models/runPlanScheduleModel.js');
|
||||
const { dispatchDueRunPlanSchedules } = await load('../services/runPlanScheduleWorker.js');
|
||||
|
||||
const owner = makeUser({ email: 'schedule-owner@test.local' });
|
||||
const ts = new Date().toISOString();
|
||||
|
||||
function createRunnableRunPlan() {
|
||||
const scriptId = 'scr_schedule_test';
|
||||
db.prepare(`INSERT INTO scripts (id, name, content, visibility, owner_user_id, version, created_at, updated_at)
|
||||
VALUES (?, 'Scheduled Script.ps1', 'Write-Output scheduled', 'personal', ?, 1, ?, ?)`).run(scriptId, owner, ts, ts);
|
||||
const credential = createCredential({
|
||||
name: 'Schedule Credential',
|
||||
kind: 'username_password',
|
||||
username: 'TEST\\svc',
|
||||
secret: 'secret',
|
||||
visibility: 'personal'
|
||||
}, owner);
|
||||
const host = createHost({
|
||||
name: 'Schedule Host',
|
||||
address: 'schedule.local',
|
||||
transport: 'local',
|
||||
osFamily: 'linux',
|
||||
credentialId: credential.id,
|
||||
visibility: 'personal'
|
||||
}, owner);
|
||||
const runplanId = 'run_schedule_test';
|
||||
db.prepare(`INSERT INTO runplans (id, name, script_id, visibility, owner_user_id, parallel, created_at, updated_at)
|
||||
VALUES (?, 'Scheduled RunPlan', ?, 'personal', ?, 1, ?, ?)`).run(runplanId, scriptId, owner, ts, ts);
|
||||
db.prepare('INSERT INTO runplan_hosts (runplan_id, host_id) VALUES (?, ?)').run(runplanId, host.id);
|
||||
return runplanId;
|
||||
}
|
||||
|
||||
test('recurrence preview covers weekly and interval schedules', () => {
|
||||
const weekly = {
|
||||
scheduleType: 'weekly',
|
||||
startAt: '2026-06-01T14:00:00.000Z',
|
||||
timeOfDay: '09:30',
|
||||
daysOfWeek: [1, 3]
|
||||
};
|
||||
const preview = previewScheduleOccurrences(weekly, 3, new Date('2026-06-02T00:00:00.000Z'));
|
||||
assert.equal(preview.length, 3);
|
||||
assert.ok(preview.every((date) => [1, 3].includes(new Date(date).getDay())));
|
||||
|
||||
const intervalNext = computeNextRun({
|
||||
scheduleType: 'interval',
|
||||
startAt: '2026-06-01T00:00:00.000Z',
|
||||
intervalValue: 6,
|
||||
intervalUnit: 'hours'
|
||||
}, new Date('2026-06-01T07:00:00.000Z'));
|
||||
assert.equal(intervalNext, '2026-06-01T12:00:00.000Z');
|
||||
});
|
||||
|
||||
test('due RunPlan schedules dispatch jobs and record scheduler history', async () => {
|
||||
updateSettings({ allow_script_execution: 'false' });
|
||||
const runplanId = createRunnableRunPlan();
|
||||
const schedule = createRunPlanSchedule({
|
||||
name: 'Every minute schedule',
|
||||
runplanId,
|
||||
scheduleType: 'interval',
|
||||
startAt: '2026-01-01T00:00:00.000Z',
|
||||
intervalValue: 1,
|
||||
intervalUnit: 'minutes',
|
||||
visibility: 'personal'
|
||||
}, owner);
|
||||
db.prepare('UPDATE runplan_schedules SET next_run_at = ? WHERE id = ?').run('2026-01-01T00:02:00.000Z', schedule.id);
|
||||
|
||||
assert.ok(listDueRunPlanSchedules('2026-01-01T00:02:00.000Z').some((row) => row.id === schedule.id));
|
||||
const summary = await dispatchDueRunPlanSchedules({ nowIso: '2026-01-01T00:02:00.000Z' });
|
||||
|
||||
assert.equal(summary.dispatched, 1);
|
||||
const job = db.prepare('SELECT * FROM jobs WHERE runplan_id = ? ORDER BY created_at DESC').get(runplanId);
|
||||
assert.ok(job);
|
||||
const history = listRunPlanScheduleRuns(owner, false, 20);
|
||||
assert.ok(history.some((event) => event.scheduleId === schedule.id && event.jobId === job.id));
|
||||
updateSettings({ allow_script_execution: 'true' });
|
||||
});
|
||||
Reference in New Issue
Block a user