Skip to content

Commit

Permalink
fix: Cannot create commit with Repository mock on existing branch (#760)
Browse files Browse the repository at this point in the history
* fix: Cannot create commit with Repository mock on existing branch

* Add tests to Repository mock

* Fix test

* Fix test
  • Loading branch information
mchanyeechoy authored Sep 18, 2024
1 parent 16bca23 commit 8bb0a06
Show file tree
Hide file tree
Showing 3 changed files with 273 additions and 9 deletions.
226 changes: 226 additions & 0 deletions NGitLab.Mock.Tests/RepositoryMockTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
using System.Collections.Generic;
using System.Net;
using FluentAssertions;
using NGitLab.Mock.Clients;
using NGitLab.Models;
using NUnit.Framework;

namespace NGitLab.Mock.Tests;

public class RepositoryMockTests
{
[Test]
public void Test_create_commit_in_new_branch_fails_if_both_start_branch_and_sha_specified()
{
// Arrange
using var server = new GitLabServer();
var user = server.Users.AddNew();
var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal);
var initCommit = project.Repository.Commit(user, "Initial commit");

var startBranch = project.DefaultBranch;

Assert.That(() => project.Repository.Commit(new()
{
Branch = "new-branch",
StartBranch = startBranch,
StartSha = initCommit.Sha,
CommitMessage = "First commit in new branch",
Actions = new List<CreateCommitAction>
{
new()
{
Action = "update",
Content = "This is in a new branch",
FilePath = "README.md",
},
},
}), Throws.TypeOf<GitLabBadRequestException>()
.With.Message.Contains("GitLab server returned an error (BadRequest): start_branch, start_sha are mutually exclusive."));
}

[Test]
public void Test_create_a_new_commit_with_start_branch_fails_if_branch_already_exists()
{
// Arrange
using var server = new GitLabServer();
var user = server.Users.AddNew();
var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal);
var initCommit = project.Repository.Commit(user, "Initial commit");

project.Repository.CreateBranch("new-branch", initCommit.Sha);

var startBranch = project.DefaultBranch;
var newBranch = "new-branch";

// Act & Assert
Assert.That(() => project.Repository.Commit(new()
{
Branch = newBranch,
StartBranch = startBranch,
CommitMessage = "First commit in new branch",
Actions = new List<CreateCommitAction>
{
new()
{
Action = "update",
Content = "This is in a new branch",
FilePath = "README.md",
},
},
}), Throws.TypeOf<GitLabBadRequestException>()
.With.Message.Contains($"A branch called '{newBranch}' already exists."));
}

[Test]
public void Test_create_a_new_commit_with_start_sha_fails_if_branch_already_exists()
{
// Arrange
using var server = new GitLabServer();
var user = server.Users.AddNew();
var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal);
var initCommit = project.Repository.Commit(user, "Initial commit");

project.Repository.CreateBranch("new-branch", initCommit.Sha);

var startBranch = project.DefaultBranch;
var newBranch = "new-branch";

// Act & Assert
Assert.That(() => project.Repository.Commit(new()
{
Branch = newBranch,
StartSha = initCommit.Sha,
CommitMessage = "First commit in new branch",
Actions = new List<CreateCommitAction>
{
new()
{
Action = "create",
Content = "This is in a new branch",
FilePath = "README.md",
},
},
}), Throws.TypeOf<GitLabBadRequestException>()
.With.Message.Contains($"A branch called '{newBranch}' already exists."));
}

[Test]
public void Test_create_a_new_commit_on_new_branch_with_start_branch()
{
// Arrange
using var server = new GitLabServer();
var user = server.Users.AddNew();
var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal);
var initCommit = project.Repository.Commit(user, "Initial commit");

var startBranch = project.DefaultBranch;
var newBranch = "new-branch";

// Act & Assert
var commitMessage = "First commit in new branch";
var newCommit = project.Repository.Commit(new()
{
Branch = newBranch,
StartBranch = startBranch,
CommitMessage = commitMessage,
Actions = new List<CreateCommitAction>
{
new()
{
Action = "create",
Content = "This is in a new branch",
FilePath = "README.md",
},
},
});
newCommit.Message.Trim().Should().Be(commitMessage);
}

[Test]
public void Test_create_a_new_commit_on_new_branch_with_start_sha()
{
// Arrange
using var server = new GitLabServer();
var user = server.Users.AddNew();
var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal);
var initCommit = project.Repository.Commit(user, "Initial commit");

var newBranch = "new-branch";

// Act & Assert
var commitMessage = "First commit in new branch";
var newCommit = project.Repository.Commit(new()
{
Branch = newBranch,
StartSha = initCommit.Sha,
CommitMessage = commitMessage,
Actions = new List<CreateCommitAction>
{
new()
{
Action = "create",
Content = "This is in a new branch",
FilePath = "README.md",
},
},
});
newCommit.Message.Trim().Should().Be(commitMessage);
}

[Test]
public void Test_create_a_new_commit_on_nonexistent_branch()
{
// Arrange
using var server = new GitLabServer();
var user = server.Users.AddNew();
var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal);
var initCommit = project.Repository.Commit(user, "Initial commit");

// Act & Assert
var commitMessage = "First commit in non existing branch";
Assert.That(() => project.Repository.Commit(new()
{
Branch = "new-branch",
CommitMessage = commitMessage,
Actions = new List<CreateCommitAction>
{
new()
{
Action = "create",
Content = "This is in a new branch",
FilePath = "README.md",
},
},
}), Throws.TypeOf<GitLabBadRequestException>()
.With.Message.Contains("You can only create or edit files when you are on a branch."));
}

[Test]
public void Test_create_a_new_commit_on_existing_branch()
{
// Arrange
using var server = new GitLabServer();
var user = server.Users.AddNew();
var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal);
var initCommit = project.Repository.Commit(user, "Initial commit");

// Act & Assert
var commitMessage = "First commit in existing branch";
var newCommit = project.Repository.Commit(new()
{
Branch = project.DefaultBranch,
CommitMessage = commitMessage,
Actions = new List<CreateCommitAction>
{
new()
{
Action = "create",
Content = "This is in an existing branch",
FilePath = "README.md",
},
},
});
newCommit.Message.Trim().Should().Be(commitMessage);
}
}
15 changes: 8 additions & 7 deletions NGitLab.Mock/Repository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,26 +201,27 @@ public Commit Commit(User user, string message, string targetBranch, IEnumerable
public Commit Commit(CommitCreate commitCreate)
{
var repo = GetGitRepository();
var branchExists = repo.Branches.Any(b => string.Equals(b.FriendlyName, commitCreate.Branch, StringComparison.Ordinal));
var hasStartBranch = !string.IsNullOrWhiteSpace(commitCreate.StartBranch);
var hasStartSha = !string.IsNullOrWhiteSpace(commitCreate.StartSha);
var isCreatingBranch = hasStartBranch || hasStartSha;

if (branchExists)
var branchExistsAlready = repo.Branches.Any(b => string.Equals(b.FriendlyName, commitCreate.Branch, StringComparison.Ordinal));

if (isCreatingBranch && branchExistsAlready)
{
throw new GitLabBadRequestException($"A branch called '{commitCreate.Branch}' already exists.");
}

var isRepoEmpty = !repo.Commits.Any();
if (!isRepoEmpty)
{
var hasStartBranch = !string.IsNullOrWhiteSpace(commitCreate.StartBranch);
var hasStartSha = !string.IsNullOrWhiteSpace(commitCreate.StartSha);

var @ref = (hasStartBranch, hasStartSha) switch
{
(true, true) => throw new GitLabBadRequestException(
"GitLab server returned an error (BadRequest): start_branch, start_sha are mutually exclusive."),
(true, _) => commitCreate.StartBranch,
(_, true) => commitCreate.StartSha,
_ => throw new GitLabBadRequestException(
_ => branchExistsAlready ? commitCreate.Branch : throw new GitLabBadRequestException(
"GitLab server returned an error (BadRequest): You can only create or edit files when you are on a branch.")
};

Expand All @@ -229,7 +230,7 @@ public Commit Commit(CommitCreate commitCreate)

var commit = CreateOnNonBareRepo(commitCreate);
var branchStillMissing = !repo.Branches.Any(b => string.Equals(b.FriendlyName, commitCreate.Branch, StringComparison.Ordinal));
if (!isRepoEmpty || branchStillMissing)
if ((isCreatingBranch || isRepoEmpty) && (!isRepoEmpty || branchStillMissing))
{
repo.Branches.Add(commitCreate.Branch, commit.Sha);
}
Expand Down
41 changes: 39 additions & 2 deletions NGitLab.Tests/CommitsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ public async Task Test_create_commit_in_new_branch_fails_if_both_start_branch_an

[Test]
[NGitLabRetry]
public async Task Test_create_commit_in_so_called_new_branch_fails_if_branch_exists()
public async Task Test_create_a_new_commit_with_start_branch_fails_if_branch_already_exists()
{
// Arrange
using var context = await GitLabTestContext.CreateAsync();
Expand Down Expand Up @@ -227,7 +227,44 @@ public async Task Test_create_commit_in_so_called_new_branch_fails_if_branch_exi
}

[Test]
public async Task Test_create_commit_when_neither_start_branch_nor_start_sha_specified()
[NGitLabRetry]
public async Task Test_create_a_new_commit_with_start_sha_fails_if_branch_already_exists()
{
// Arrange
using var context = await GitLabTestContext.CreateAsync();
var project = context.CreateProject(initializeWithCommits: true);

var repoClient = context.Client.GetRepository(project.Id);
var commitClient = context.Client.GetCommits(project.Id);
var startCommit = context.Client.GetCommits(project.Id).GetCommit(project.DefaultBranch);

var startBranch = project.DefaultBranch;
var startSha = startCommit.Id;

repoClient.Branches.Create(new BranchCreate { Name = "new-branch", Ref = startBranch });

// Act/Assert
Assert.That(() => commitClient.Create(new CommitCreate
{
Branch = "new-branch",
StartSha = startSha.ToString().ToLowerInvariant(),
CommitMessage = "First commit in new branch",
Actions = new List<CreateCommitAction>
{
new()
{
Action = "update",
Content = "This is in a new branch",
FilePath = "README.md",
},
},
}), Throws.TypeOf<GitLabException>()
.With.Property(nameof(GitLabException.StatusCode)).EqualTo(HttpStatusCode.BadRequest)
.With.Message.Contains("A branch called 'new-branch' already exists."));
}

[Test]
public async Task Test_create_commit_on_nonexistent_branch_fails_when_neither_start_branch_nor_start_sha_specified()
{
// Arrange
using var context = await GitLabTestContext.CreateAsync();
Expand Down

0 comments on commit 8bb0a06

Please sign in to comment.