package workspaceruntime import ( "context" "os" "path/filepath" "testing" "time" "inbox/internal/base/timeutil" "inbox/internal/domain/workspace" sqlitestore "inbox/internal/store/sqlite" ) func TestEnsureRepairsMissingRegisteredWorkspaceWorktree(t *testing.T) { ctx := context.Background() clock := timeutil.FixedClock{Time: time.Date(2026, 3, 18, 2, 0, 0, 0, time.UTC)} store, err := sqlitestore.OpenInMemory(clock) if err != nil { t.Fatalf("OpenInMemory() error = %v", err) } defer store.Close() rootDir := t.TempDir() projectDir := filepath.Join(rootDir, "project") workspacesDir := filepath.Join(rootDir, "workspaces") if err := os.MkdirAll(projectDir, 0755); err != nil { t.Fatalf("MkdirAll(projectDir) error = %v", err) } project, err := store.CreateProject(ctx, workspace.NormalizeProjectForCreate(workspace.Project{ Slug: "demo-project", Name: "demo-project", RootPath: projectDir, DefaultBranch: "main", })) if err != nil { t.Fatalf("CreateProject() error = %v", err) } ws, err := store.CreateWorkspace(ctx, workspace.NormalizeWorkspaceForCreate(workspace.Workspace{ ProjectID: project.ID, Slug: "todo", Name: "todo", RootPath: filepath.Join(workspacesDir, "todo"), BaseBranch: "main", WorktreeBranch: "worktree/todo", })) if err != nil { t.Fatalf("CreateWorkspace() error = %v", err) } service := NewService(store, rootDir, workspacesDir, 3000, clock, nil) ensured, runtime, err := service.Ensure(ctx, ws.ID) if err != nil { t.Fatalf("Ensure() initial error = %v", err) } if !runtime.Ensured { t.Fatalf("expected initial ensure to succeed, got %#v", runtime) } if _, err := os.Stat(ensured.RootPath); err != nil { t.Fatalf("Stat(initial worktree) error = %v", err) } if err := os.RemoveAll(ensured.RootPath); err != nil { t.Fatalf("RemoveAll(worktree) error = %v", err) } if _, err := os.Stat(ensured.RootPath); !os.IsNotExist(err) { t.Fatalf("expected worktree path to be removed, stat err = %v", err) } ensured, runtime, err = service.Ensure(ctx, ws.ID) if err != nil { t.Fatalf("Ensure() repair error = %v", err) } if !runtime.Ensured { t.Fatalf("expected repaired ensure to succeed, got %#v", runtime) } if _, err := os.Stat(ensured.RootPath); err != nil { t.Fatalf("Stat(repaired worktree) error = %v", err) } if ensured.ProvisionState != "ready" { t.Fatalf("expected workspace to be ready after repair, got %#v", ensured) } }