package task import ( "testing" "time" "gpt-plus/internal/db" "github.com/glebarez/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" ) func setupTaskTestDB(t *testing.T) *gorm.DB { t.Helper() d, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), }) if err != nil { t.Fatalf("open db: %v", err) } d.AutoMigrate(&db.SystemConfig{}, &db.EmailRecord{}, &db.Task{}, &db.TaskLog{}, &db.CardCode{}, &db.Card{}, &db.Account{}) db.DB = d return d } func TestTaskManagerInit(t *testing.T) { d := setupTaskTestDB(t) // Create a "leftover" running task d.Create(&db.Task{ID: "left-1", Type: "plus", Status: StatusRunning, TotalCount: 10}) d.Create(&db.Task{ID: "left-2", Type: "team", Status: StatusStopping, TotalCount: 5}) tm := NewTaskManager(d) tm.Init() var t1, t2 db.Task d.First(&t1, "id = ?", "left-1") d.First(&t2, "id = ?", "left-2") if t1.Status != StatusInterrupted { t.Fatalf("left-1 status = %q, want interrupted", t1.Status) } if t2.Status != StatusInterrupted { t.Fatalf("left-2 status = %q, want interrupted", t2.Status) } if t1.StoppedAt == nil { t.Fatal("left-1 stopped_at should be set") } } func TestTaskManagerStartNonexistent(t *testing.T) { d := setupTaskTestDB(t) tm := NewTaskManager(d) err := tm.Start("nonexistent-id") if err == nil { t.Fatal("expected error for nonexistent task") } } func TestTaskManagerStartWrongStatus(t *testing.T) { d := setupTaskTestDB(t) d.Create(&db.Task{ID: "completed-1", Type: "plus", Status: StatusCompleted, TotalCount: 10}) tm := NewTaskManager(d) err := tm.Start("completed-1") if err == nil { t.Fatal("expected error for completed task") } } func TestTaskManagerStopNoRunning(t *testing.T) { d := setupTaskTestDB(t) tm := NewTaskManager(d) err := tm.Stop("any-id") if err == nil { t.Fatal("expected error when no task running") } } func TestTaskManagerForceStopNoRunning(t *testing.T) { d := setupTaskTestDB(t) tm := NewTaskManager(d) err := tm.ForceStop("any-id") if err == nil { t.Fatal("expected error when no task running") } } func TestTaskManagerIsRunning(t *testing.T) { d := setupTaskTestDB(t) tm := NewTaskManager(d) if tm.IsRunning() { t.Fatal("should not be running initially") } } func TestTaskManagerStopWrongID(t *testing.T) { d := setupTaskTestDB(t) tm := NewTaskManager(d) // Simulate a running task by setting current directly tm.current = &TaskRunner{taskID: "real-id"} tm.current.running.Store(true) err := tm.Stop("wrong-id") if err == nil { t.Fatal("expected error for wrong task ID") } } func TestTaskManagerInitDoesNotAffectPending(t *testing.T) { d := setupTaskTestDB(t) d.Create(&db.Task{ID: "pending-1", Type: "plus", Status: StatusPending, TotalCount: 5}) tm := NewTaskManager(d) tm.Init() var task db.Task d.First(&task, "id = ?", "pending-1") if task.Status != StatusPending { t.Fatalf("pending task should stay pending, got %q", task.Status) } } func TestTaskManagerInitDoesNotAffectCompleted(t *testing.T) { d := setupTaskTestDB(t) stopped := time.Now() d.Create(&db.Task{ID: "done-1", Type: "plus", Status: StatusCompleted, TotalCount: 10, StoppedAt: &stopped}) tm := NewTaskManager(d) tm.Init() var task db.Task d.First(&task, "id = ?", "done-1") if task.Status != StatusCompleted { t.Fatalf("completed task should stay completed, got %q", task.Status) } }