Skip to content

Commit

Permalink
Support searching branches (#433)
Browse files Browse the repository at this point in the history
* Support search branches

* Add tests for `BranchClient.Search`

* Improve tests for `BranchClient.Search`
  • Loading branch information
PMExtra authored May 1, 2023
1 parent 5b79104 commit 37e07f3
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 0 deletions.
42 changes: 42 additions & 0 deletions NGitLab.Mock.Tests/BranchesMockTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Linq;
using NGitLab.Mock.Config;
using NUnit.Framework;

namespace NGitLab.Mock.Tests
{
public class BranchesMockTests
{
[Test]
public void Test_search_branches()
{
using var server = new GitLabConfig()
.WithUser("user1", isDefault: true)
.WithProject("test-project", id: 1, addDefaultUserAsMaintainer: true, defaultBranch: "main", configure: project => project
.WithCommit("Initial commit")
.WithCommit("Commit for branch_1", sourceBranch: "branch_1"))
.BuildServer();

var client = server.CreateClient("user1");
var branchClient = client.GetRepository(1).Branches;

var branches = branchClient.Search("main").ToList();
var expectedBranch = branches.Single();
Assert.AreEqual("main", expectedBranch.Name);

branches = branchClient.Search("^main$").ToList();
expectedBranch = branches.Single();
Assert.AreEqual("main", expectedBranch.Name);

branches = branchClient.Search("^branch").ToList();
expectedBranch = branches.Single();
Assert.AreEqual("branch_1", expectedBranch.Name);

branches = branchClient.Search("1$").ToList();
expectedBranch = branches.Single();
Assert.AreEqual("branch_1", expectedBranch.Name);

branches = branchClient.Search("foobar").ToList();
Assert.IsEmpty(branches);
}
}
}
45 changes: 45 additions & 0 deletions NGitLab.Mock/Clients/BranchClient.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using NGitLab.Mock.Internals;
using NGitLab.Models;

namespace NGitLab.Mock.Clients
Expand All @@ -15,6 +16,50 @@ public BranchClient(ClientContext context, int projectId)
_projectId = projectId;
}

public IEnumerable<Branch> Search(string search)
{
Func<string, bool> filterBranch;
switch (search)
{
case null:
case "":
filterBranch = _ => true;
break;

case not null when search[0] == '^' && search[search.Length - 1] == '$':
search = search.Substring(1, search.Length - 1 - 1);
filterBranch = branch => branch.Equals(search, StringComparison.OrdinalIgnoreCase);
break;

case not null when search[0] == '^':
search = search.Substring(1);
filterBranch = branch => branch.StartsWith(search, StringComparison.OrdinalIgnoreCase);
break;

case not null when search[search.Length - 1] == '$':
search = search.Substring(0, search.Length - 1);
filterBranch = branch => branch.EndsWith(search, StringComparison.OrdinalIgnoreCase);
break;

default:
filterBranch = branch => branch.Contains(search, StringComparison.OrdinalIgnoreCase);
break;
}

using (Context.BeginOperationScope())
{
var project = GetProject(_projectId, ProjectPermission.View);
return project.Repository.GetAllBranches()
.Where(branch => filterBranch(branch.FriendlyName))
.Select(branch => branch.ToBranchClient(project));
}
}

public GitLabCollectionResponse<Branch> SearchAsync(string search)
{
return GitLabCollectionResponse.Create(Search(search));
}

public Branch this[string name]
{
get
Expand Down
39 changes: 39 additions & 0 deletions NGitLab.Tests/BranchClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using NGitLab.Tests.Docker;
using NUnit.Framework;
Expand Down Expand Up @@ -43,5 +44,43 @@ public async Task Test_CommitInfoIsCorrectlyDeserialized()

Assert.IsTrue(Uri.TryCreate(commit.WebUrl, UriKind.Absolute, out _));
}

[Test]
[NGitLabRetry]
public async Task Test_search_branches()
{
using var context = await GitLabTestContext.CreateAsync();
var project = context.CreateProject(initializeWithCommits: true);
var branchClient = context.Client.GetRepository(project.Id).Branches;

var defaultBranch = project.DefaultBranch;

var branches = branchClient.Search(defaultBranch);
var expectedBranch = branches.Single();
Assert.AreEqual(defaultBranch, expectedBranch.Name);

// This case only worked with GitLab 15.7 and later
// https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104451
/*
branches = branchClient.Search($"^{defaultBranch}$");
expectedBranch = branches.Single();
Assert.AreEqual(defaultBranch, expectedBranch.Name);
*/

branches = branchClient.Search($"^{defaultBranch[..^1]}");
expectedBranch = branches.Single();
Assert.AreEqual(defaultBranch, expectedBranch.Name);

branches = branchClient.Search($"{defaultBranch[1..]}$");
expectedBranch = branches.Single();
Assert.AreEqual(defaultBranch, expectedBranch.Name);

branches = branchClient.Search(defaultBranch[1..^1]);
expectedBranch = branches.Single();
Assert.AreEqual(defaultBranch, expectedBranch.Name);

branches = branchClient.Search("foobar");
Assert.IsEmpty(branches);
}
}
}
4 changes: 4 additions & 0 deletions NGitLab/IBranchClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ public interface IBranchClient
{
IEnumerable<Branch> All { get; }

IEnumerable<Branch> Search(string search);

GitLabCollectionResponse<Branch> SearchAsync(string search);

Branch this[string name] { get; }

Branch Protect(string name);
Expand Down
6 changes: 6 additions & 0 deletions NGitLab/Impl/BranchClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ public BranchClient(API api, string repoPath)

public IEnumerable<Branch> All => _api.Get().GetAll<Branch>(_repoPath + "/branches");

public IEnumerable<Branch> Search(string search) =>
_api.Get().GetAll<Branch>(_repoPath + "/branches?search=" + Uri.EscapeDataString(search));

public GitLabCollectionResponse<Branch> SearchAsync(string search) =>
_api.Get().GetAllAsync<Branch>(_repoPath + "/branches?search=" + Uri.EscapeDataString(search));

public Branch this[string name] => _api.Get().To<Branch>(_repoPath + "/branches/" + Uri.EscapeDataString(name));

public Branch Protect(string name) => _api.Put().To<Branch>(_repoPath + "/branches/" + Uri.EscapeDataString(name) + "/protect");
Expand Down
4 changes: 4 additions & 0 deletions NGitLab/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ NGitLab.IBranchClient.All.get -> System.Collections.Generic.IEnumerable<NGitLab.
NGitLab.IBranchClient.Create(NGitLab.Models.BranchCreate branch) -> NGitLab.Models.Branch
NGitLab.IBranchClient.Delete(string name) -> void
NGitLab.IBranchClient.Protect(string name) -> NGitLab.Models.Branch
NGitLab.IBranchClient.Search(string search) -> System.Collections.Generic.IEnumerable<NGitLab.Models.Branch>
NGitLab.IBranchClient.SearchAsync(string search) -> NGitLab.GitLabCollectionResponse<NGitLab.Models.Branch>
NGitLab.IBranchClient.this[string name].get -> NGitLab.Models.Branch
NGitLab.IBranchClient.Unprotect(string name) -> NGitLab.Models.Branch
NGitLab.IClusterClient
Expand Down Expand Up @@ -384,6 +386,8 @@ NGitLab.Impl.BranchClient.BranchClient(NGitLab.Impl.API api, string repoPath) ->
NGitLab.Impl.BranchClient.Create(NGitLab.Models.BranchCreate branch) -> NGitLab.Models.Branch
NGitLab.Impl.BranchClient.Delete(string name) -> void
NGitLab.Impl.BranchClient.Protect(string name) -> NGitLab.Models.Branch
NGitLab.Impl.BranchClient.Search(string search) -> System.Collections.Generic.IEnumerable<NGitLab.Models.Branch>
NGitLab.Impl.BranchClient.SearchAsync(string search) -> NGitLab.GitLabCollectionResponse<NGitLab.Models.Branch>
NGitLab.Impl.BranchClient.this[string name].get -> NGitLab.Models.Branch
NGitLab.Impl.BranchClient.Unprotect(string name) -> NGitLab.Models.Branch
NGitLab.Impl.ClusterClient
Expand Down

0 comments on commit 37e07f3

Please sign in to comment.