package janitor import ( "fmt" "os" "path/filepath" "testing" "time" "forge.secuaas.ovh/olivier/claude-failover/internal/state" ) func TestNew(t *testing.T) { s := state.New("/tmp/test-state.json") j := New(s, "/tmp/projects") if j == nil { t.Fatal("New() returned nil") } if j.interval != defaultInterval { t.Errorf("expected interval %v, got %v", defaultInterval, j.interval) } if j.state != s { t.Error("state not assigned correctly") } if j.projectsDir != "/tmp/projects" { t.Errorf("projectsDir not assigned correctly: %s", j.projectsDir) } if j.logger == nil { t.Error("logger should not be nil") } } func TestCleanupStaleAgentDoneFiles(t *testing.T) { // Create a stale file (older than 1h). staleFile := fmt.Sprintf("/tmp/agent-done-test-%d", time.Now().UnixNano()) if err := os.WriteFile(staleFile, []byte("done"), 0644); err != nil { t.Fatalf("create stale file: %v", err) } // Age the file to 2 hours ago. old := time.Now().Add(-2 * time.Hour) if err := os.Chtimes(staleFile, old, old); err != nil { t.Fatalf("chtimes: %v", err) } // Create a recent file (should NOT be deleted). recentFile := fmt.Sprintf("/tmp/agent-done-test-recent-%d", time.Now().UnixNano()) if err := os.WriteFile(recentFile, []byte("recent"), 0644); err != nil { t.Fatalf("create recent file: %v", err) } defer os.Remove(recentFile) s := state.New("/tmp/test-state.json") j := New(s, "/tmp/projects") j.cleanupStaleAgentDoneFiles() // Stale file should be gone. if _, err := os.Stat(staleFile); !os.IsNotExist(err) { os.Remove(staleFile) t.Errorf("stale file %s should have been deleted", staleFile) } // Recent file should still exist. if _, err := os.Stat(recentFile); os.IsNotExist(err) { t.Errorf("recent file %s should NOT have been deleted", recentFile) } } func TestCleanupOrphanDispatchMeta(t *testing.T) { tmpDir := t.TempDir() inboxDir := filepath.Join(tmpDir, ".agent-queue", "inbox") if err := os.MkdirAll(inboxDir, 0755); err != nil { t.Fatal(err) } // Create a task file and its dispatch-meta. taskFile := filepath.Join(inboxDir, "my-task.md") metaFile := taskFile + ".dispatch-meta" os.WriteFile(taskFile, []byte("task"), 0644) os.WriteFile(metaFile, []byte("meta"), 0644) s := state.New("/tmp/test-state.json") j := New(s, tmpDir) // No working sessions → dispatch-meta should be removed. workingByTask := make(map[string]struct{}) j.cleanupOrphanDispatchMeta(inboxDir, workingByTask) if _, err := os.Stat(metaFile); !os.IsNotExist(err) { t.Errorf("orphan dispatch-meta %s should have been deleted", metaFile) } // Task file itself should still exist. if _, err := os.Stat(taskFile); os.IsNotExist(err) { t.Errorf("task file %s should NOT have been deleted", taskFile) } }