Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Cannot create commit with Repository mock on existing branch #760

Merged
merged 4 commits into from
Sep 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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