Skip to content

Commit

Permalink
Add project ancestor groups logic (#715)
Browse files Browse the repository at this point in the history
* Add project ancestor groups logic

* fix tests

* fix test again

* Update NGitLab/Models/ProjectGroupsQuery.cs

Co-authored-by: Louis Zanella <[email protected]>

* Update NGitLab/Impl/ProjectClient.cs

Co-authored-by: Louis Zanella <[email protected]>

* Update NGitLab.Tests/ProjectsTests.cs

Co-authored-by: Louis Zanella <[email protected]>

* fix API

* remove using

* update System Text Json

---------

Co-authored-by: Louis Zanella <[email protected]>
  • Loading branch information
BallyB and louis-z authored Jul 10, 2024
1 parent a086479 commit d666dc7
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 4 deletions.
5 changes: 5 additions & 0 deletions NGitLab.Mock/Clients/ProjectClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,9 @@ public UploadedProjectFile UploadFile(string id, FormDataContent data)
{
return GitLabCollectionResponse.Create(GetForks(id, query));
}

public GitLabCollectionResponse<Models.Group> GetGroupsAsync(ProjectId projectId, ProjectGroupsQuery query)
{
throw new NotImplementedException();
}
}
2 changes: 1 addition & 1 deletion NGitLab.Tests/NGitLab.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="NSubstitute" Version="5.1.0" />
<PackageReference Include="Polly" Version="8.4.1" />
<PackageReference Include="System.Text.Json" Version="8.0.3" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
Expand Down
33 changes: 33 additions & 0 deletions NGitLab.Tests/ProjectsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -735,4 +735,37 @@ public async Task CreateProjectWithSquashOption(SquashOption? inputSquashOption)

projectClient.Delete(createdProject.Id);
}

[Test]
[NGitLabRetry]
public async Task Test_project_groups_query_returns_searched_group()
{
using var context = await GitLabTestContext.CreateAsync();
var projectClient = context.Client.Projects;
var group = context.CreateGroup();
var project = context.CreateProject(group.Id);
context.CreateGroup();

var groups = projectClient.GetGroupsAsync(project.Id, new ProjectGroupsQuery
{
Search = group.Name,
}).ToArray();

Assert.That(groups.Select(g => g.Id), Is.EquivalentTo(new int[] { group.Id }));
}

[Test]
[NGitLabRetry]
public async Task Test_project_groups_query_returns_ancestor_groups()
{
using var context = await GitLabTestContext.CreateAsync();
var projectClient = context.Client.Projects;
var group = context.CreateGroup();
var subgroup = context.CreateSubgroup(group.Id);
var project = context.CreateProject(subgroup.Id);

var groups = projectClient.GetGroupsAsync(project.Id, new ProjectGroupsQuery()).ToArray();

Assert.That(groups.Select(g => g.Id), Is.EquivalentTo(new int[] { group.Id, subgroup.Id }));
}
}
12 changes: 10 additions & 2 deletions NGitLab/IProjectClient.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using NGitLab.Models;
Expand Down Expand Up @@ -76,5 +75,14 @@ public interface IProjectClient

GitLabCollectionResponse<Project> GetForksAsync(string id, ForkedProjectQuery query);

/// <summary>
/// Gets a list of ancestor groups for this project.
/// See https://docs.gitlab.com/ee/api/projects.html#list-a-projects-groups
/// </summary>
/// <param name="projectId">The project's id or path.</param>
/// <param name="query">The query parameters</param>
/// <returns>All ancestor groups.</returns>
GitLabCollectionResponse<Group> GetGroupsAsync(ProjectId projectId, ProjectGroupsQuery query);

Dictionary<string, double> GetLanguages(string id);
}
34 changes: 34 additions & 0 deletions NGitLab/Impl/ProjectClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class ProjectClient : IProjectClient
{
private readonly API _api;

public const string Url = Project.Url;

public ProjectClient(API api)
{
_api = api;
Expand Down Expand Up @@ -173,6 +175,38 @@ public GitLabCollectionResponse<Project> GetForksAsync(string id, ForkedProjectQ
return _api.Get().GetAllAsync<Project>(url);
}

public GitLabCollectionResponse<Group> GetGroupsAsync(ProjectId id, ProjectGroupsQuery query)
{
var url = CreateGetGroupsUrl(id, query);
return _api.Get().GetAllAsync<Group>(url);
}

private static string CreateGetGroupsUrl(ProjectId projectId, ProjectGroupsQuery query)
{
var url = $"{Url}/{projectId.ValueAsUriParameter()}/groups";

if (query is null)
{
return url;
}

if (query.SharedMinAccessLevel is not null)
{
url = Utils.AddParameter(url, "shared_min_access_level", (int)query.SharedMinAccessLevel);
}

if (query.SkipGroups is not null)
{
url = Utils.AddParameter(url, "skip_groups", query.SkipGroups);
}

url = Utils.AddParameter(url, "shared_visible_only", query.SharedVisibleOnly);
url = Utils.AddParameter(url, "search", query.Search);
url = Utils.AddParameter(url, "with_shared", query.WithShared);

return url;
}

private static string CreateGetForksUrl(string id, ForkedProjectQuery query)
{
var url = $"{Project.Url}/{id}/forks";
Expand Down
29 changes: 29 additions & 0 deletions NGitLab/Models/ProjectGroupsQuery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
namespace NGitLab.Models;

public sealed class ProjectGroupsQuery
{
/// <summary>
/// Return list of authorized groups matching the search criteria
/// </summary>
public string Search { get; set; }

/// <summary>
/// Include groups shared to this project. Default is false
/// </summary>
public bool? WithShared { get; set; }

/// <summary>
/// Include projects in subgroups of this group. Default is false
/// </summary>
public bool? SharedVisibleOnly { get; set; }

/// <summary>
/// Limit to shared groups with at least this access level
/// </summary>
public AccessLevel? SharedMinAccessLevel { get; set; }

/// <summary>
/// Skip the group IDs passed
/// </summary>
public int[] SkipGroups { get; set; }
}
2 changes: 1 addition & 1 deletion NGitLab/NGitLab.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Text.Json" Version="8.0.2" />
<PackageReference Include="System.Text.Json" Version="8.0.4" />
</ItemGroup>
</Project>
15 changes: 15 additions & 0 deletions NGitLab/PublicAPI.Unshipped.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const NGitLab.Impl.GroupsClient.Url = "/groups" -> string
const NGitLab.Impl.LabelClient.GroupLabelUrl = "/groups/{0}/labels" -> string
const NGitLab.Impl.LabelClient.ProjectLabelUrl = "/projects/{0}/labels" -> string
const NGitLab.Impl.NamespacesClient.Url = "/namespaces" -> string
const NGitLab.Impl.ProjectClient.Url = "/projects" -> string
const NGitLab.Models.Commit.Url = "/commits" -> string
const NGitLab.Models.Contributor.Url = "/contributors" -> string
const NGitLab.Models.Group.Url = "/groups" -> string
Expand Down Expand Up @@ -846,6 +847,7 @@ NGitLab.Impl.ProjectClient.GetByIdAsync(int id, NGitLab.Models.SingleProjectQuer
NGitLab.Impl.ProjectClient.GetByNamespacedPathAsync(string path, NGitLab.Models.SingleProjectQuery query = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<NGitLab.Models.Project>
NGitLab.Impl.ProjectClient.GetForks(string id, NGitLab.Models.ForkedProjectQuery query) -> System.Collections.Generic.IEnumerable<NGitLab.Models.Project>
NGitLab.Impl.ProjectClient.GetForksAsync(string id, NGitLab.Models.ForkedProjectQuery query) -> NGitLab.GitLabCollectionResponse<NGitLab.Models.Project>
NGitLab.Impl.ProjectClient.GetGroupsAsync(NGitLab.Models.ProjectId id, NGitLab.Models.ProjectGroupsQuery query) -> NGitLab.GitLabCollectionResponse<NGitLab.Models.Group>
NGitLab.Impl.ProjectClient.GetLanguages(string id) -> System.Collections.Generic.Dictionary<string, double>
NGitLab.Impl.ProjectClient.Owned.get -> System.Collections.Generic.IEnumerable<NGitLab.Models.Project>
NGitLab.Impl.ProjectClient.ProjectClient(NGitLab.Impl.API api) -> void
Expand Down Expand Up @@ -1051,6 +1053,7 @@ NGitLab.IProjectClient.GetByIdAsync(int id, NGitLab.Models.SingleProjectQuery qu
NGitLab.IProjectClient.GetByNamespacedPathAsync(string path, NGitLab.Models.SingleProjectQuery query = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task<NGitLab.Models.Project>
NGitLab.IProjectClient.GetForks(string id, NGitLab.Models.ForkedProjectQuery query) -> System.Collections.Generic.IEnumerable<NGitLab.Models.Project>
NGitLab.IProjectClient.GetForksAsync(string id, NGitLab.Models.ForkedProjectQuery query) -> NGitLab.GitLabCollectionResponse<NGitLab.Models.Project>
NGitLab.IProjectClient.GetGroupsAsync(NGitLab.Models.ProjectId projectId, NGitLab.Models.ProjectGroupsQuery query) -> NGitLab.GitLabCollectionResponse<NGitLab.Models.Group>
NGitLab.IProjectClient.GetLanguages(string id) -> System.Collections.Generic.Dictionary<string, double>
NGitLab.IProjectClient.Owned.get -> System.Collections.Generic.IEnumerable<NGitLab.Models.Project>
NGitLab.IProjectClient.this[int id].get -> NGitLab.Models.Project
Expand Down Expand Up @@ -2991,6 +2994,18 @@ NGitLab.Models.ProjectCreate.VisibilityLevel -> NGitLab.Models.VisibilityLevel
NGitLab.Models.ProjectCreate.WallEnabled -> bool
NGitLab.Models.ProjectCreate.WikiAccessLevel -> string
NGitLab.Models.ProjectCreate.WikiEnabled -> bool
NGitLab.Models.ProjectGroupsQuery
NGitLab.Models.ProjectGroupsQuery.ProjectGroupsQuery() -> void
NGitLab.Models.ProjectGroupsQuery.Search.get -> string
NGitLab.Models.ProjectGroupsQuery.Search.set -> void
NGitLab.Models.ProjectGroupsQuery.SharedMinAccessLevel.get -> NGitLab.Models.AccessLevel?
NGitLab.Models.ProjectGroupsQuery.SharedMinAccessLevel.set -> void
NGitLab.Models.ProjectGroupsQuery.SharedVisibleOnly.get -> bool?
NGitLab.Models.ProjectGroupsQuery.SharedVisibleOnly.set -> void
NGitLab.Models.ProjectGroupsQuery.SkipGroups.get -> int[]
NGitLab.Models.ProjectGroupsQuery.SkipGroups.set -> void
NGitLab.Models.ProjectGroupsQuery.WithShared.get -> bool?
NGitLab.Models.ProjectGroupsQuery.WithShared.set -> void
NGitLab.Models.ProjectHook
NGitLab.Models.ProjectHook.CreatedAt -> System.DateTime
NGitLab.Models.ProjectHook.EnableSslVerification -> bool
Expand Down

0 comments on commit d666dc7

Please sign in to comment.