Skip to content

Commit b52d08d

Browse files
Codex04meziantoulouis-z
authored
Add protected branches client (#24)
Co-authored-by: Gérald Barré <meziantou@users.noreply.github.com> Co-authored-by: Louis Zanella <louis.zanella@ubisoft.com>
1 parent c08a5d0 commit b52d08d

12 files changed

+207
-3
lines changed

NGitLab.Mock/Clients/GitLabClient.cs

+5
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,10 @@ public IEventClient GetProjectEvents(int projectId)
8383
public IWikiClient GetWikiClient(int projectId) => new WikiClient(Context, projectId);
8484

8585
public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId) => new ProjectLevelApprovalRulesClient(Context, projectId);
86+
87+
public IProtectedBranchClient GetProtectedBranchClient(int projectId)
88+
{
89+
throw new System.NotImplementedException();
90+
}
8691
}
8792
}

NGitLab.Tests/ProtectedBranchTests.cs

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
using System.Threading.Tasks;
2+
using NGitLab.Models;
3+
using NGitLab.Tests.Docker;
4+
using NUnit.Framework;
5+
6+
namespace NGitLab.Tests
7+
{
8+
public class ProtectedBranchTests
9+
{
10+
[Test]
11+
public async Task ProtectBranch_Test()
12+
{
13+
using var context = await GitLabTestContext.CreateAsync();
14+
var project = context.CreateProject(initializeWithCommits: true);
15+
var branchClient = context.Client.GetRepository(project.Id).Branches;
16+
var branch = branchClient.Create(new BranchCreate() { Name = "protectedBranch", Ref = project.DefaultBranch });
17+
var protectedBranchClient = context.Client.GetProtectedBranchClient(project.Id);
18+
var branchProtect = new BranchProtect(branch.Name)
19+
{
20+
PushAccessLevel = AccessLevel.Maintainer,
21+
MergeAccessLevel = AccessLevel.NoAccess,
22+
AllowForcePush = true,
23+
AllowedToPush = new AccessLevelInfo[]
24+
{
25+
new AccessLevelInfo()
26+
{
27+
AccessLevel = AccessLevel.Admin,
28+
Description = "Admin",
29+
},
30+
},
31+
AllowedToUnprotect = new AccessLevelInfo[]
32+
{
33+
new AccessLevelInfo()
34+
{
35+
AccessLevel = AccessLevel.NoAccess,
36+
Description = "Example",
37+
},
38+
},
39+
};
40+
41+
// Protect branch
42+
ProtectedBranchAndBranchProtectAreEquals(branchProtect, protectedBranchClient.ProtectBranch(branchProtect));
43+
44+
// Get branch
45+
ProtectedBranchAndBranchProtectAreEquals(branchProtect, protectedBranchClient.GetProtectedBranch(branch.Name));
46+
47+
// Get branches
48+
Assert.IsNotEmpty(protectedBranchClient.GetProtectedBranches());
49+
var protectedBranches = protectedBranchClient.GetProtectedBranches(branch.Name);
50+
Assert.IsNotEmpty(protectedBranches);
51+
ProtectedBranchAndBranchProtectAreEquals(branchProtect, protectedBranches[0]);
52+
53+
// Unprotect branch
54+
protectedBranchClient.UnprotectBranch(branch.Name);
55+
Assert.IsEmpty(protectedBranchClient.GetProtectedBranches(branch.Name));
56+
}
57+
58+
private void ProtectedBranchAndBranchProtectAreEquals(BranchProtect branchProtect, ProtectedBranch protectedBranch)
59+
{
60+
Assert.AreEqual(branchProtect.BranchName, protectedBranch.Name);
61+
Assert.AreEqual(branchProtect.PushAccessLevel, protectedBranch.PushAccessLevels[0].AccessLevel);
62+
Assert.AreEqual(branchProtect.MergeAccessLevel, protectedBranch.MergeAccessLevels[0].AccessLevel);
63+
Assert.AreEqual(branchProtect.AllowForcePush, protectedBranch.AllowForcePush);
64+
}
65+
}
66+
}

NGitLab/GitLabClient.cs

+3
Original file line numberDiff line numberDiff line change
@@ -191,5 +191,8 @@ public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int p
191191
{
192192
return new ProjectLevelApprovalRulesClient(_api, projectId);
193193
}
194+
195+
public IProtectedBranchClient GetProtectedBranchClient(int projectId)
196+
=> new ProtectedBranchClient(_api, projectId);
194197
}
195198
}

NGitLab/IBranchClient.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@ public interface IBranchClient
1717

1818
void Delete(string name);
1919
}
20-
}
20+
}

NGitLab/IGitLabClient.cs

+2
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,7 @@ public interface IGitLabClient
7979
IGroupVariableClient GetGroupVariableClient(int groupId);
8080

8181
IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId);
82+
83+
IProtectedBranchClient GetProtectedBranchClient(int projectId);
8284
}
8385
}

NGitLab/IProtectedBranchClient.cs

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using NGitLab.Models;
2+
3+
namespace NGitLab
4+
{
5+
public interface IProtectedBranchClient
6+
{
7+
ProtectedBranch ProtectBranch(BranchProtect branchProtect);
8+
9+
void UnprotectBranch(string branchName);
10+
11+
ProtectedBranch GetProtectedBranch(string branchName);
12+
13+
ProtectedBranch[] GetProtectedBranches(string search = null);
14+
}
15+
}

NGitLab/Impl/BranchClient.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,4 @@ public BranchClient(API api, string repoPath)
2727

2828
public void Delete(string name) => _api.Delete().Execute(_repoPath + "/branches/" + Uri.EscapeDataString(name));
2929
}
30-
}
30+
}

NGitLab/Impl/ProtectedBranchClient.cs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using NGitLab.Models;
3+
4+
namespace NGitLab.Impl
5+
{
6+
internal sealed class ProtectedBranchClient : IProtectedBranchClient
7+
{
8+
private readonly API _api;
9+
private readonly int _projectId;
10+
private readonly string _protectedBranchesUrl;
11+
12+
public ProtectedBranchClient(API api, int projectId)
13+
{
14+
_api = api;
15+
_projectId = projectId;
16+
_protectedBranchesUrl = $"{Project.Url}/{_projectId}/protected_branches";
17+
}
18+
19+
public ProtectedBranch ProtectBranch(BranchProtect branchProtect)
20+
=> _api.Post().With(branchProtect).To<ProtectedBranch>(_protectedBranchesUrl);
21+
22+
public void UnprotectBranch(string branchName)
23+
=> _api.Delete().Execute($"{_protectedBranchesUrl}/{Uri.EscapeDataString(branchName)}");
24+
25+
public ProtectedBranch GetProtectedBranch(string branchName)
26+
=> _api.Get().To<ProtectedBranch>($"{_protectedBranchesUrl}/{Uri.EscapeDataString(branchName)}");
27+
28+
public ProtectedBranch[] GetProtectedBranches(string search = null)
29+
=> _api.Get().To<ProtectedBranch[]>(Utils.AddParameter(_protectedBranchesUrl, "search", search));
30+
}
31+
}

NGitLab/Models/AccessLevel.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ namespace NGitLab.Models
88
/// <remarks>https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/members.md</remarks>
99
public enum AccessLevel
1010
{
11+
NoAccess = 0,
1112
Guest = 10,
1213
Reporter = 20,
1314
Developer = 30,
@@ -19,5 +20,6 @@ public enum AccessLevel
1920
/// Only valid for groups.
2021
/// </summary>
2122
Owner = 50,
23+
Admin = 60,
2224
}
23-
}
25+
}

NGitLab/Models/AccessLevelInfo.cs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Runtime.Serialization;
2+
3+
namespace NGitLab.Models
4+
{
5+
[DataContract]
6+
public class AccessLevelInfo
7+
{
8+
[DataMember(Name = "access_level")]
9+
public AccessLevel AccessLevel { get; set; }
10+
11+
[DataMember(Name = "access_level_description")]
12+
public string Description { get; set; }
13+
}
14+
}

NGitLab/Models/BranchProtect.cs

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System.Runtime.Serialization;
2+
3+
namespace NGitLab.Models
4+
{
5+
[DataContract]
6+
public class BranchProtect
7+
{
8+
public BranchProtect(string branchName)
9+
{
10+
BranchName = branchName;
11+
}
12+
13+
[DataMember(Name = "name")]
14+
public string BranchName { get; set; }
15+
16+
[DataMember(Name = "push_access_level")]
17+
public AccessLevel? PushAccessLevel { get; set; } = null;
18+
19+
[DataMember(Name = "merge_access_level")]
20+
public AccessLevel? MergeAccessLevel { get; set; } = null;
21+
22+
[DataMember(Name = "unprotect_access_level")]
23+
public AccessLevel? UnprotectAccessLevel { get; set; } = null;
24+
25+
[DataMember(Name = "allow_force_push")]
26+
public bool AllowForcePush { get; set; } = false;
27+
28+
[DataMember(Name = "allowed_to_merge")]
29+
public AccessLevelInfo[] AllowedToMerge { get; set; }
30+
31+
[DataMember(Name = "allowed_to_push")]
32+
public AccessLevelInfo[] AllowedToPush { get; set; }
33+
34+
[DataMember(Name = "allowed_to_unprotect")]
35+
public AccessLevelInfo[] AllowedToUnprotect { get; set; }
36+
37+
[DataMember(Name = "code_owner_approval_required")]
38+
public bool CodeOwnerApprovalRequired { get; set; } = false;
39+
}
40+
}

NGitLab/Models/ProtectedBranch.cs

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Runtime.Serialization;
2+
3+
namespace NGitLab.Models
4+
{
5+
[DataContract]
6+
public class ProtectedBranch
7+
{
8+
[DataMember(Name = "id")]
9+
public long Id { get; set; }
10+
11+
[DataMember(Name = "name")]
12+
public string Name { get; set; }
13+
14+
[DataMember(Name = "push_access_levels")]
15+
public AccessLevelInfo[] PushAccessLevels { get; set; }
16+
17+
[DataMember(Name = "merge_access_levels")]
18+
public AccessLevelInfo[] MergeAccessLevels { get; set; }
19+
20+
[DataMember(Name = "allow_force_push")]
21+
public bool AllowForcePush { get; set; }
22+
23+
[DataMember(Name = "code_owner_approval_required")]
24+
public bool CodeOwnerApprovalRequired { get; set; }
25+
}
26+
}

0 commit comments

Comments
 (0)