- cmd/serve.go: starts scheduler, optionally starts Telegram bot with --telegram flag - cmd/schedule.go: add/list/remove/run subcommands for scheduled scan job CRUD - pkg/scheduler/: gocron v2 based scheduler with DB-backed jobs and scan execution - pkg/storage/scheduled_jobs.go: scheduled_jobs table CRUD with tests - Remove serve and schedule stubs from cmd/stubs.go Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
105 lines
2.5 KiB
Go
105 lines
2.5 KiB
Go
package storage
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestScheduledJobCRUD(t *testing.T) {
|
|
db, err := Open(":memory:")
|
|
require.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
// Add a job.
|
|
job := ScheduledJob{
|
|
Name: "nightly-scan",
|
|
CronExpr: "0 0 * * *",
|
|
ScanPath: "/tmp/repo",
|
|
Enabled: true,
|
|
Notify: true,
|
|
}
|
|
id, err := db.SaveScheduledJob(job)
|
|
require.NoError(t, err)
|
|
assert.True(t, id > 0)
|
|
|
|
// Get the job by ID.
|
|
got, err := db.GetScheduledJob(id)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "nightly-scan", got.Name)
|
|
assert.Equal(t, "0 0 * * *", got.CronExpr)
|
|
assert.Equal(t, "/tmp/repo", got.ScanPath)
|
|
assert.True(t, got.Enabled)
|
|
assert.True(t, got.Notify)
|
|
assert.Nil(t, got.LastRunAt)
|
|
|
|
// List all jobs.
|
|
jobs, err := db.ListScheduledJobs()
|
|
require.NoError(t, err)
|
|
assert.Len(t, jobs, 1)
|
|
assert.Equal(t, "nightly-scan", jobs[0].Name)
|
|
|
|
// Add a second job (disabled).
|
|
job2 := ScheduledJob{
|
|
Name: "weekly-scan",
|
|
CronExpr: "0 0 * * 0",
|
|
ScanPath: "/tmp/other",
|
|
Enabled: false,
|
|
Notify: false,
|
|
}
|
|
id2, err := db.SaveScheduledJob(job2)
|
|
require.NoError(t, err)
|
|
|
|
// List enabled only.
|
|
enabled, err := db.ListEnabledScheduledJobs()
|
|
require.NoError(t, err)
|
|
assert.Len(t, enabled, 1)
|
|
assert.Equal(t, id, enabled[0].ID)
|
|
|
|
// Delete the first job.
|
|
affected, err := db.DeleteScheduledJob(id)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(1), affected)
|
|
|
|
// Only the second job should remain.
|
|
jobs, err = db.ListScheduledJobs()
|
|
require.NoError(t, err)
|
|
assert.Len(t, jobs, 1)
|
|
assert.Equal(t, id2, jobs[0].ID)
|
|
|
|
// Delete non-existent returns 0 affected.
|
|
affected, err = db.DeleteScheduledJob(999)
|
|
require.NoError(t, err)
|
|
assert.Equal(t, int64(0), affected)
|
|
}
|
|
|
|
func TestUpdateJobLastRun(t *testing.T) {
|
|
db, err := Open(":memory:")
|
|
require.NoError(t, err)
|
|
defer db.Close()
|
|
|
|
id, err := db.SaveScheduledJob(ScheduledJob{
|
|
Name: "test",
|
|
CronExpr: "*/5 * * * *",
|
|
ScanPath: "/tmp/test",
|
|
Enabled: true,
|
|
Notify: true,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
job, err := db.GetScheduledJob(id)
|
|
require.NoError(t, err)
|
|
assert.Nil(t, job.LastRunAt)
|
|
|
|
// Update last run.
|
|
now := time.Now().Truncate(time.Second)
|
|
require.NoError(t, db.UpdateJobLastRun(id, now))
|
|
|
|
job, err = db.GetScheduledJob(id)
|
|
require.NoError(t, err)
|
|
require.NotNil(t, job.LastRunAt, "LastRunAt should be set after UpdateJobLastRun")
|
|
assert.Equal(t, now.Format("2006-01-02 15:04:05"), job.LastRunAt.Format("2006-01-02 15:04:05"))
|
|
}
|