|
8 | 8 |
|
9 | 9 | "github.com/github/gh-stack/internal/config" |
10 | 10 | "github.com/github/gh-stack/internal/git" |
| 11 | + "github.com/github/gh-stack/internal/github" |
11 | 12 | "github.com/github/gh-stack/internal/stack" |
12 | 13 | "github.com/stretchr/testify/assert" |
13 | 14 | "github.com/stretchr/testify/require" |
@@ -290,3 +291,91 @@ func TestInit_MultipleBranches_CreatesAll(t *testing.T) { |
290 | 291 | names := sf.Stacks[0].BranchNames() |
291 | 292 | assert.Equal(t, []string{"b1", "b2", "b3"}, names) |
292 | 293 | } |
| 294 | + |
| 295 | +func TestInit_AdoptWithExistingOpenPR(t *testing.T) { |
| 296 | + gitDir := t.TempDir() |
| 297 | + restore := git.SetOps(&git.MockOps{ |
| 298 | + GitDirFn: func() (string, error) { return gitDir, nil }, |
| 299 | + DefaultBranchFn: func() (string, error) { return "main", nil }, |
| 300 | + CurrentBranchFn: func() (string, error) { return "main", nil }, |
| 301 | + BranchExistsFn: func(string) bool { return true }, |
| 302 | + }) |
| 303 | + defer restore() |
| 304 | + |
| 305 | + cfg, outR, errR := config.NewTestConfig() |
| 306 | + cfg.GitHubClientOverride = &github.MockClient{ |
| 307 | + FindPRForBranchFn: func(branch string) (*github.PullRequest, error) { |
| 308 | + if branch == "b1" { |
| 309 | + return &github.PullRequest{ |
| 310 | + Number: 42, |
| 311 | + ID: "PR_42", |
| 312 | + URL: "https://github.com/owner/repo/pull/42", |
| 313 | + State: "OPEN", |
| 314 | + HeadRefName: "b1", |
| 315 | + }, nil |
| 316 | + } |
| 317 | + return nil, nil |
| 318 | + }, |
| 319 | + } |
| 320 | + |
| 321 | + err := runInit(cfg, &initOptions{ |
| 322 | + branches: []string{"b1", "b2"}, |
| 323 | + adopt: true, |
| 324 | + }) |
| 325 | + output := collectOutput(cfg, outR, errR) |
| 326 | + |
| 327 | + require.NoError(t, err, "adopt should succeed even when branch has an open PR") |
| 328 | + require.NotContains(t, output, "\u2717", "unexpected error in output") |
| 329 | + |
| 330 | + sf, err := stack.Load(gitDir) |
| 331 | + require.NoError(t, err, "loading stack") |
| 332 | + require.Len(t, sf.Stacks, 1) |
| 333 | + |
| 334 | + // b1 should have the open PR recorded |
| 335 | + b1 := sf.Stacks[0].Branches[0] |
| 336 | + require.NotNil(t, b1.PullRequest, "open PR should be recorded") |
| 337 | + assert.Equal(t, 42, b1.PullRequest.Number) |
| 338 | + assert.Equal(t, "https://github.com/owner/repo/pull/42", b1.PullRequest.URL) |
| 339 | + |
| 340 | + // b2 should have no PR |
| 341 | + b2 := sf.Stacks[0].Branches[1] |
| 342 | + assert.Nil(t, b2.PullRequest, "branch without PR should have nil PullRequest") |
| 343 | +} |
| 344 | + |
| 345 | +func TestInit_AdoptIgnoresClosedAndMergedPRs(t *testing.T) { |
| 346 | + gitDir := t.TempDir() |
| 347 | + restore := git.SetOps(&git.MockOps{ |
| 348 | + GitDirFn: func() (string, error) { return gitDir, nil }, |
| 349 | + DefaultBranchFn: func() (string, error) { return "main", nil }, |
| 350 | + CurrentBranchFn: func() (string, error) { return "main", nil }, |
| 351 | + BranchExistsFn: func(string) bool { return true }, |
| 352 | + }) |
| 353 | + defer restore() |
| 354 | + |
| 355 | + cfg, outR, errR := config.NewTestConfig() |
| 356 | + // FindPRForBranch only returns OPEN PRs — closed/merged PRs won't be |
| 357 | + // returned by the API, so the mock returns nil for all branches. |
| 358 | + cfg.GitHubClientOverride = &github.MockClient{ |
| 359 | + FindPRForBranchFn: func(branch string) (*github.PullRequest, error) { |
| 360 | + return nil, nil |
| 361 | + }, |
| 362 | + } |
| 363 | + |
| 364 | + err := runInit(cfg, &initOptions{ |
| 365 | + branches: []string{"b1", "b2"}, |
| 366 | + adopt: true, |
| 367 | + }) |
| 368 | + output := collectOutput(cfg, outR, errR) |
| 369 | + |
| 370 | + require.NoError(t, err, "adopt should succeed when branches have closed/merged PRs") |
| 371 | + require.NotContains(t, output, "\u2717", "unexpected error in output") |
| 372 | + |
| 373 | + sf, err := stack.Load(gitDir) |
| 374 | + require.NoError(t, err, "loading stack") |
| 375 | + require.Len(t, sf.Stacks, 1) |
| 376 | + |
| 377 | + // Neither branch should have a PR recorded (closed/merged are filtered out) |
| 378 | + for _, b := range sf.Stacks[0].Branches { |
| 379 | + assert.Nil(t, b.PullRequest, "closed/merged PRs should not be recorded for branch %s", b.Branch) |
| 380 | + } |
| 381 | +} |
0 commit comments