Skip to content

Commit

Permalink
Add support for creating pull requests as drafts
Browse files Browse the repository at this point in the history
  • Loading branch information
geofflamrock committed Dec 10, 2024
1 parent 29e0dee commit b35a40c
Show file tree
Hide file tree
Showing 5 changed files with 209 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,22 @@ public async Task WhenNoPullRequestsExistForAStackWithMultipleBranches_CreatesPu
inputProvider.Text(Questions.PullRequestTitle("branch-3", "branch-1")).Returns("PR Title for branch-3");
inputProvider.Text(Questions.PullRequestTitle("branch-5", "branch-3")).Returns("PR Title for branch-5");

var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty)
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false)
.Returns(prForBranch3);

var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty)
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false)
.Returns(prForBranch5);

// Act
await handler.Handle(CreatePullRequestsCommandInputs.Empty);

// Assert
gitHubOperations.Received().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty);
gitHubOperations.Received().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false);
}

[Fact]
Expand Down Expand Up @@ -114,14 +114,14 @@ public async Task WhenCreatingPullRequestsForAStackWithMultipleBranches_EachPull
inputProvider.Text(Questions.PullRequestTitle("branch-5", "branch-3")).Returns("PR Title for branch-5");
inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any<string>()).Returns("A custom description");

var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty)
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false)
.Returns(prForBranch3);

var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty)
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false)
.Returns(prForBranch5);

gitHubOperations
Expand Down Expand Up @@ -189,12 +189,12 @@ public async Task WhenAPullRequestExistForABranch_AndNoneForAnotherBranch_Create
inputProvider.Text(Questions.PullRequestTitle("branch-5", "branch-3")).Returns("PR Title for branch-5");
inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any<string>()).Returns("A custom description");

var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations.GetPullRequest("branch-3").Returns(prForBranch3);

var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty)
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false)
.Returns(prForBranch5);

gitHubOperations
Expand All @@ -209,8 +209,8 @@ public async Task WhenAPullRequestExistForABranch_AndNoneForAnotherBranch_Create
await handler.Handle(CreatePullRequestsCommandInputs.Empty);

// Assert
gitHubOperations.DidNotReceive().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty);
gitHubOperations.DidNotReceive().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false);
var expectedStackDescription = $@"<!-- stack-pr-list -->
A custom description
Expand Down Expand Up @@ -264,22 +264,22 @@ public async Task WhenStackNameIsProvided_PullRequestsAreCreatedForThatStack()
inputProvider.Text(Questions.PullRequestTitle("branch-3", "branch-1")).Returns("PR Title for branch-3");
inputProvider.Text(Questions.PullRequestTitle("branch-5", "branch-3")).Returns("PR Title for branch-5");

var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty)
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false)
.Returns(prForBranch3);

var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty)
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false)
.Returns(prForBranch5);

// Act
await handler.Handle(new CreatePullRequestsCommandInputs("Stack1"));
await handler.Handle(new CreatePullRequestsCommandInputs("Stack1", null));

// Assert
gitHubOperations.Received().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty);
gitHubOperations.Received().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false);
}

[Fact]
Expand Down Expand Up @@ -319,22 +319,22 @@ public async Task WhenOnlyOneStackExists_DoesNotAskForStackName_PullRequestsAreC
inputProvider.Text(Questions.PullRequestTitle("branch-3", "branch-1")).Returns("PR Title for branch-3");
inputProvider.Text(Questions.PullRequestTitle("branch-5", "branch-3")).Returns("PR Title for branch-5");

var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty)
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false)
.Returns(prForBranch3);

var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty)
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false)
.Returns(prForBranch5);

// Act
await handler.Handle(CreatePullRequestsCommandInputs.Empty);

// Assert
gitHubOperations.Received().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty);
gitHubOperations.Received().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, false);
}

[Fact]
Expand Down Expand Up @@ -362,7 +362,7 @@ public async Task WhenStackNameIsProvided_ButTheStackDoesNotExist_Throws()

// Act and assert
var invalidStackName = Some.Name();
await handler.Invoking(h => h.Handle(new CreatePullRequestsCommandInputs(invalidStackName)))
await handler.Invoking(h => h.Handle(new CreatePullRequestsCommandInputs(invalidStackName, null)))
.Should()
.ThrowAsync<InvalidOperationException>()
.WithMessage($"Stack '{invalidStackName}' not found.");
Expand Down Expand Up @@ -410,12 +410,12 @@ public async Task WhenAPullRequestExistForABranch_AndHasBeenMerged_AndNoneForAno
inputProvider.Text(Questions.PullRequestTitle("branch-5", "branch-1")).Returns("PR Title for branch-5");
inputProvider.Text(Questions.PullRequestStackDescription, Arg.Any<string>()).Returns("A custom description");

var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Merged, Some.HttpsUri());
var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Merged, Some.HttpsUri(), false);
gitHubOperations.GetPullRequest("branch-3").Returns(prForBranch3);

var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri());
var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), false);
gitHubOperations
.CreatePullRequest("branch-5", "branch-1", "PR Title for branch-5", string.Empty)
.CreatePullRequest("branch-5", "branch-1", "PR Title for branch-5", string.Empty, false)
.Returns(prForBranch5);

gitHubOperations
Expand All @@ -430,8 +430,8 @@ public async Task WhenAPullRequestExistForABranch_AndHasBeenMerged_AndNoneForAno
await handler.Handle(CreatePullRequestsCommandInputs.Empty);

// Assert
gitHubOperations.DidNotReceive().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-1", "PR Title for branch-5", string.Empty);
gitHubOperations.DidNotReceive().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, false);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-1", "PR Title for branch-5", string.Empty, false);
var expectedStackDescription = $@"<!-- stack-pr-list -->
A custom description
Expand All @@ -442,4 +442,126 @@ A custom description
prForBranch3.Body.Should().Be(expectedStackDescription);
prForBranch5.Body.Should().Be(expectedStackDescription);
}

[Fact]
public async Task WhenAskedWhetherToCreateAPullRequestAsADraft_AndTheAnswerIsYes_PullRequestsCreatedAsADraft()
{
// Arrange
var gitOperations = Substitute.For<IGitOperations>();
var gitHubOperations = Substitute.For<IGitHubOperations>();
var stackConfig = Substitute.For<IStackConfig>();
var inputProvider = Substitute.For<IInputProvider>();
var outputProvider = Substitute.For<IOutputProvider>();
var handler = new CreatePullRequestsCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig);

var remoteUri = Some.HttpsUri().ToString();
outputProvider
.WhenForAnyArgs(o => o.Status(Arg.Any<string>(), Arg.Any<Action>()))
.Do(ci => ci.ArgAt<Action>(1)());

gitOperations.GetRemoteUri().Returns(remoteUri);
gitOperations.GetCurrentBranch().Returns("branch-1");
gitOperations
.GetBranchesThatExistInRemote(Arg.Any<string[]>())
.Returns(["branch-1", "branch-3", "branch-5"]);

gitOperations
.GetBranchesThatExistLocally(Arg.Any<string[]>())
.Returns(["branch-1", "branch-3", "branch-5"]);

var stacks = new List<Config.Stack>(
[
new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]),
new("Stack2", remoteUri, "branch-2", ["branch-4"])
]);
stackConfig.Load().Returns(stacks);
stackConfig
.WhenForAnyArgs(s => s.Save(Arg.Any<List<Config.Stack>>()))
.Do(ci => stacks = ci.ArgAt<List<Config.Stack>>(0));

inputProvider.Select(Questions.SelectStack, Arg.Any<string[]>()).Returns("Stack1");
inputProvider.Confirm(Questions.ConfirmStartCreatePullRequests(2)).Returns(true);
inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true);
inputProvider.Confirm(Questions.CreatePullRequestsAsDrafts, false).Returns(true);
inputProvider.Text(Questions.PullRequestTitle("branch-3", "branch-1")).Returns("PR Title for branch-3");
inputProvider.Text(Questions.PullRequestTitle("branch-5", "branch-3")).Returns("PR Title for branch-5");

var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), true);
gitHubOperations
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, true)
.Returns(prForBranch3);

var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), true);
gitHubOperations
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, true)
.Returns(prForBranch5);

// Act
await handler.Handle(CreatePullRequestsCommandInputs.Empty);

// Assert
gitHubOperations.Received().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, true);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, true);
}

[Fact]
public async Task WhenDraftIsProvided_PullRequestsAreCreatedAsDrafts()
{
// Arrange
var gitOperations = Substitute.For<IGitOperations>();
var gitHubOperations = Substitute.For<IGitHubOperations>();
var stackConfig = Substitute.For<IStackConfig>();
var inputProvider = Substitute.For<IInputProvider>();
var outputProvider = Substitute.For<IOutputProvider>();
var handler = new CreatePullRequestsCommandHandler(inputProvider, outputProvider, gitOperations, gitHubOperations, stackConfig);

var remoteUri = Some.HttpsUri().ToString();
outputProvider
.WhenForAnyArgs(o => o.Status(Arg.Any<string>(), Arg.Any<Action>()))
.Do(ci => ci.ArgAt<Action>(1)());

gitOperations.GetRemoteUri().Returns(remoteUri);
gitOperations.GetCurrentBranch().Returns("branch-1");
gitOperations
.GetBranchesThatExistInRemote(Arg.Any<string[]>())
.Returns(["branch-1", "branch-3", "branch-5"]);

gitOperations
.GetBranchesThatExistLocally(Arg.Any<string[]>())
.Returns(["branch-1", "branch-3", "branch-5"]);

var stacks = new List<Config.Stack>(
[
new("Stack1", remoteUri, "branch-1", ["branch-3", "branch-5"]),
new("Stack2", remoteUri, "branch-2", ["branch-4"])
]);
stackConfig.Load().Returns(stacks);
stackConfig
.WhenForAnyArgs(s => s.Save(Arg.Any<List<Config.Stack>>()))
.Do(ci => stacks = ci.ArgAt<List<Config.Stack>>(0));

inputProvider.Select(Questions.SelectStack, Arg.Any<string[]>()).Returns("Stack1");
inputProvider.Confirm(Questions.ConfirmStartCreatePullRequests(2)).Returns(true);
inputProvider.Confirm(Questions.ConfirmCreatePullRequests).Returns(true);
inputProvider.Text(Questions.PullRequestTitle("branch-3", "branch-1")).Returns("PR Title for branch-3");
inputProvider.Text(Questions.PullRequestTitle("branch-5", "branch-3")).Returns("PR Title for branch-5");

var prForBranch3 = new GitHubPullRequest(1, "PR Title for branch-3", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), true);
gitHubOperations
.CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, true)
.Returns(prForBranch3);

var prForBranch5 = new GitHubPullRequest(2, "PR Title for branch-5", string.Empty, GitHubPullRequestStates.Open, Some.HttpsUri(), true);
gitHubOperations
.CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, true)
.Returns(prForBranch5);

// Act
await handler.Handle(new CreatePullRequestsCommandInputs(null, true));

// Assert
gitHubOperations.Received().CreatePullRequest("branch-3", "branch-1", "PR Title for branch-3", string.Empty, true);
gitHubOperations.Received().CreatePullRequest("branch-5", "branch-3", "PR Title for branch-5", string.Empty, true);
inputProvider.DidNotReceive().Confirm(Questions.CreatePullRequestsAsDrafts, false);
}
}
1 change: 1 addition & 0 deletions src/Stack/Commands/Helpers/Questions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ public static class Questions
public static string PullRequestTitle(string sourceBranch, string targetBranch) => $"Title for pull request from {sourceBranch.Branch()} -> {targetBranch.Branch()}:";
public const string PullRequestStackDescription = "Stack description for pull request:";
public const string OpenPullRequests = "Open the pull requests in the browser?";
public const string CreatePullRequestsAsDrafts = "Create pull requests as drafts?";
}
Loading

0 comments on commit b35a40c

Please sign in to comment.