package projectsync import ( "context" "errors" "os" "path/filepath" "testing" ) func TestFilesystemWorkspaceProvisionerAcceptsPreparedCheckouts(t *testing.T) { tmpDir := t.TempDir() plan := ProvisionPlan{ ProjectWorkspaceRoot: tmpDir, MainBranchPath: filepath.Join(tmpDir, "branches", "main"), DevelopBranchPath: filepath.Join(tmpDir, "branches", "develop"), DefaultSlotPath: filepath.Join(tmpDir, "slots", "000"), } // Create directories for _, path := range []string{plan.MainBranchPath, plan.DevelopBranchPath, plan.DefaultSlotPath} { if err := os.MkdirAll(path, 0755); err != nil { t.Fatalf("failed to create dir %s: %v", path, err) } // Create .git directory if err := os.MkdirAll(filepath.Join(path, ".git"), 0755); err != nil { t.Fatalf("failed to create .git in %s: %v", path, err) } } provisioner := FilesystemWorkspaceProvisioner{} err := provisioner.EnsureProvisioned(context.Background(), plan) if err != nil { t.Errorf("expected no error, got %v", err) } } func TestFilesystemWorkspaceProvisionerRejectsMissingCheckout(t *testing.T) { tmpDir := t.TempDir() plan := ProvisionPlan{ ProjectWorkspaceRoot: tmpDir, MainBranchPath: filepath.Join(tmpDir, "branches", "main"), DevelopBranchPath: filepath.Join(tmpDir, "branches", "develop"), DefaultSlotPath: filepath.Join(tmpDir, "slots", "000"), } // Create main and develop only, skip default slot for _, path := range []string{plan.MainBranchPath, plan.DevelopBranchPath} { if err := os.MkdirAll(path, 0755); err != nil { t.Fatalf("failed to create dir %s: %v", path, err) } if err := os.MkdirAll(filepath.Join(path, ".git"), 0755); err != nil { t.Fatalf("failed to create .git in %s: %v", path, err) } } provisioner := FilesystemWorkspaceProvisioner{} err := provisioner.EnsureProvisioned(context.Background(), plan) if !errors.Is(err, ErrWorkspaceProvisionNotReady) { t.Errorf("expected ErrWorkspaceProvisionNotReady error, got %v", err) } } func TestFilesystemWorkspaceProvisionerRejectsPathWithoutGitMetadata(t *testing.T) { tmpDir := t.TempDir() plan := ProvisionPlan{ ProjectWorkspaceRoot: tmpDir, MainBranchPath: filepath.Join(tmpDir, "branches", "main"), DevelopBranchPath: filepath.Join(tmpDir, "branches", "develop"), DefaultSlotPath: filepath.Join(tmpDir, "slots", "000"), } // Create directories but do not create .git for default slot for _, path := range []string{plan.MainBranchPath, plan.DevelopBranchPath, plan.DefaultSlotPath} { if err := os.MkdirAll(path, 0755); err != nil { t.Fatalf("failed to create dir %s: %v", path, err) } } // Create .git only for main and develop for _, path := range []string{plan.MainBranchPath, plan.DevelopBranchPath} { if err := os.MkdirAll(filepath.Join(path, ".git"), 0755); err != nil { t.Fatalf("failed to create .git in %s: %v", path, err) } } provisioner := FilesystemWorkspaceProvisioner{} err := provisioner.EnsureProvisioned(context.Background(), plan) if !errors.Is(err, ErrWorkspaceProvisionNotReady) { t.Errorf("expected ErrWorkspaceProvisionNotReady error, got %v", err) } } func TestFilesystemWorkspaceProvisionerHonorsCanceledContext(t *testing.T) { tmpDir := t.TempDir() plan := ProvisionPlan{ ProjectWorkspaceRoot: tmpDir, MainBranchPath: filepath.Join(tmpDir, "branches", "main"), DevelopBranchPath: filepath.Join(tmpDir, "branches", "develop"), DefaultSlotPath: filepath.Join(tmpDir, "slots", "000"), } ctx, cancel := context.WithCancel(context.Background()) cancel() // Cancel immediately provisioner := FilesystemWorkspaceProvisioner{} err := provisioner.EnsureProvisioned(ctx, plan) if !errors.Is(err, context.Canceled) { t.Errorf("expected context.Canceled, got %v", err) } }