From 64ffd1d1bd2a8b6952ba11a9fe889591d412bef2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 08:02:03 -0400 Subject: [PATCH 001/122] Bump Meziantou.Analyzer from 2.0.84 to 2.0.85 (#526) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.84 to 2.0.85. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.84...2.0.85) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 14b7f1f8..1861a9b9 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From ab145aba7b512b6a5647e79d00058f82bfea0bf4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Sep 2023 08:28:13 -0400 Subject: [PATCH 002/122] Bump NSubstitute from 5.0.0 to 5.1.0 (#522) Bumps NSubstitute from 5.0.0 to 5.1.0. --- updated-dependencies: - dependency-name: NSubstitute dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index d0cdbcbc..314a6314 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -19,7 +19,7 @@ - + From 8817e1114e6fcca6eaca6e0dfb70e9d68982ad0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rald=20Barr=C3=A9?= Date: Mon, 18 Sep 2023 16:19:13 -0400 Subject: [PATCH 003/122] Support pipeline retry endpoint (#527) --- NGitLab.Mock/Clients/PipelineClient.cs | 14 +++++++++++ NGitLab.Tests/JobTests.cs | 3 ++- NGitLab.Tests/PipelineTests.cs | 33 +++++++++++++++++++++++--- NGitLab/IPipelineClient.cs | 2 ++ NGitLab/Impl/PipelineClient.cs | 6 +++++ NGitLab/PublicAPI.Unshipped.txt | 2 ++ 6 files changed, 56 insertions(+), 4 deletions(-) diff --git a/NGitLab.Mock/Clients/PipelineClient.cs b/NGitLab.Mock/Clients/PipelineClient.cs index 065e3e25..97c028c6 100644 --- a/NGitLab.Mock/Clients/PipelineClient.cs +++ b/NGitLab.Mock/Clients/PipelineClient.cs @@ -291,5 +291,19 @@ public GitLabCollectionResponse GetVariablesAsync(int pipeline { return GitLabCollectionResponse.Create(GetVariables(pipelineId)); } + + public Task RetryAsync(int pipelineId, CancellationToken cancellationToken = default) + { + using (Context.BeginOperationScope()) + { + var jobs = _jobClient.GetJobs(JobScopeMask.Failed).Where(j => j.Pipeline.Id == pipelineId); + foreach (var job in jobs) + { + _jobClient.RunAction(job.Id, JobAction.Retry); + } + + return Task.FromResult(this[pipelineId]); + } + } } } diff --git a/NGitLab.Tests/JobTests.cs b/NGitLab.Tests/JobTests.cs index 4911446c..247cdf6b 100644 --- a/NGitLab.Tests/JobTests.cs +++ b/NGitLab.Tests/JobTests.cs @@ -10,7 +10,7 @@ namespace NGitLab.Tests { public class JobTests { - internal static void AddGitLabCiFile(IGitLabClient client, Project project, int jobCount = 1, bool manualAction = false, string branch = null) + internal static void AddGitLabCiFile(IGitLabClient client, Project project, int jobCount = 1, bool manualAction = false, string branch = null, bool pipelineSucceeds = true) { var content = @" variables: @@ -24,6 +24,7 @@ internal static void AddGitLabCiFile(IGitLabClient client, Project project, int script: - echo test - echo test > file{i.ToString(CultureInfo.InvariantCulture)}.txt + - exit {(pipelineSucceeds ? "0" : "1")} artifacts: paths: - '*.txt' diff --git a/NGitLab.Tests/PipelineTests.cs b/NGitLab.Tests/PipelineTests.cs index bdf2ff38..80c004f9 100644 --- a/NGitLab.Tests/PipelineTests.cs +++ b/NGitLab.Tests/PipelineTests.cs @@ -200,13 +200,40 @@ public async Task Test_get_triggered_pipeline_variables() var trigger = triggers.Create("Test Trigger"); var ciJobToken = trigger.Token; - var pipeline = pipelineClient.CreatePipelineWithTrigger(ciJobToken, project.DefaultBranch, new Dictionary(StringComparer.InvariantCulture) { { "Test", "HelloWorld" } }); + var pipeline = pipelineClient.CreatePipelineWithTrigger(ciJobToken, project.DefaultBranch, new Dictionary(StringComparer.Ordinal) { { "Test", "HelloWorld" } }); var variables = pipelineClient.GetVariables(pipeline.Id); Assert.IsTrue(variables.Any(v => - v.Key.Equals("Test", StringComparison.InvariantCulture) && - v.Value.Equals("HelloWorld", StringComparison.InvariantCulture))); + v.Key.Equals("Test", StringComparison.Ordinal) && + v.Value.Equals("HelloWorld", StringComparison.Ordinal))); + } + + [Test] + [NGitLabRetry] + public async Task Test_retry() + { + using var context = await GitLabTestContext.CreateAsync(); + var project = context.CreateProject(); + var pipelineClient = context.Client.GetPipelines(project.Id); + + using (await context.StartRunnerForOneJobAsync(project.Id)) + { + JobTests.AddGitLabCiFile(context.Client, project, pipelineSucceeds: false); + var pipeline = await GitLabTestContext.RetryUntilAsync(() => pipelineClient.All.FirstOrDefault(), pipeline => + { + if (pipeline != null) + { + TestContext.WriteLine("Pipeline status: " + pipeline.Status); + return pipeline.Status is JobStatus.Failed; + } + + return false; + }, TimeSpan.FromMinutes(2)); + + var retriedPipeline = await pipelineClient.RetryAsync(pipeline.Id); + Assert.AreNotEqual(JobStatus.Failed, retriedPipeline.Status); // Should be created or running + } } } } diff --git a/NGitLab/IPipelineClient.cs b/NGitLab/IPipelineClient.cs index 151d0ee5..5240b9d0 100644 --- a/NGitLab/IPipelineClient.cs +++ b/NGitLab/IPipelineClient.cs @@ -115,5 +115,7 @@ public interface IPipelineClient /// /// GitLabCollectionResponse GetBridgesAsync(PipelineBridgeQuery query); + + Task RetryAsync(int pipelineId, CancellationToken cancellationToken = default); } } diff --git a/NGitLab/Impl/PipelineClient.cs b/NGitLab/Impl/PipelineClient.cs index aa9743dc..6f9305ac 100644 --- a/NGitLab/Impl/PipelineClient.cs +++ b/NGitLab/Impl/PipelineClient.cs @@ -209,5 +209,11 @@ private string CreateGetBridgesUrl(PipelineBridgeQuery query) url = Utils.AddParameter(url, "scope", query.Scope); return url; } + + public Task RetryAsync(int pipelineId, CancellationToken cancellationToken = default) + { + var url = $"{_pipelinesPath}/{pipelineId.ToStringInvariant()}/retry"; + return _api.Post().ToAsync(url, cancellationToken); + } } } diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index 75705c78..4f9b3455 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -685,6 +685,7 @@ NGitLab.Impl.PipelineClient.GetTestReportsSummary(int pipelineId) -> NGitLab.Mod NGitLab.Impl.PipelineClient.GetVariables(int pipelineId) -> System.Collections.Generic.IEnumerable NGitLab.Impl.PipelineClient.GetVariablesAsync(int pipelineId) -> NGitLab.GitLabCollectionResponse NGitLab.Impl.PipelineClient.PipelineClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.PipelineClient.RetryAsync(int pipelineId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.PipelineClient.Search(NGitLab.Models.PipelineQuery query) -> System.Collections.Generic.IEnumerable NGitLab.Impl.PipelineClient.SearchAsync(NGitLab.Models.PipelineQuery query) -> NGitLab.GitLabCollectionResponse NGitLab.Impl.PipelineClient.this[int id].get -> NGitLab.Models.Pipeline @@ -857,6 +858,7 @@ NGitLab.IPipelineClient.GetTestReports(int pipelineId) -> NGitLab.Models.TestRep NGitLab.IPipelineClient.GetTestReportsSummary(int pipelineId) -> NGitLab.Models.TestReportSummary NGitLab.IPipelineClient.GetVariables(int pipelineId) -> System.Collections.Generic.IEnumerable NGitLab.IPipelineClient.GetVariablesAsync(int pipelineId) -> NGitLab.GitLabCollectionResponse +NGitLab.IPipelineClient.RetryAsync(int pipelineId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.IPipelineClient.Search(NGitLab.Models.PipelineQuery query) -> System.Collections.Generic.IEnumerable NGitLab.IPipelineClient.SearchAsync(NGitLab.Models.PipelineQuery query) -> NGitLab.GitLabCollectionResponse NGitLab.IPipelineClient.this[int id].get -> NGitLab.Models.Pipeline From eb4f2619b17eca1af0fe234d43cec4f1da314cf2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 07:45:00 -0400 Subject: [PATCH 004/122] Bump Microsoft.Playwright from 1.37.1 to 1.38.0 (#529) Bumps [Microsoft.Playwright](https://github.com/microsoft/playwright-dotnet) from 1.37.1 to 1.38.0. - [Release notes](https://github.com/microsoft/playwright-dotnet/releases) - [Commits](https://github.com/microsoft/playwright-dotnet/compare/v1.37.1...v1.38.0) --- updated-dependencies: - dependency-name: Microsoft.Playwright dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index 314a6314..9652372f 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -15,7 +15,7 @@ - + From 1598f2e6e6fbd57bf8ceba8ae124efdaee92dd08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 08:23:27 -0400 Subject: [PATCH 005/122] Bump YamlDotNet from 13.3.1 to 13.4.0 (#530) Bumps [YamlDotNet](https://github.com/aaubry/YamlDotNet) from 13.3.1 to 13.4.0. - [Release notes](https://github.com/aaubry/YamlDotNet/releases) - [Commits](https://github.com/aaubry/YamlDotNet/compare/v13.3.1...v13.4.0) --- updated-dependencies: - dependency-name: YamlDotNet dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Mock/NGitLab.Mock.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Mock/NGitLab.Mock.csproj b/NGitLab.Mock/NGitLab.Mock.csproj index a47732f3..d44f59d7 100644 --- a/NGitLab.Mock/NGitLab.Mock.csproj +++ b/NGitLab.Mock/NGitLab.Mock.csproj @@ -13,7 +13,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + From adea3646cc736913f5142936d8b116a09241f0b4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Sep 2023 10:23:49 -0400 Subject: [PATCH 006/122] Bump Microsoft.NET.Test.Sdk from 17.7.1 to 17.7.2 (#519) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.7.1 to 17.7.2. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.7.1...v17.7.2) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj | 2 +- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj index d7e11b03..cb56d584 100644 --- a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj +++ b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index 9652372f..bab4a6bb 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -14,7 +14,7 @@ - + From 1f81a270a5a440f01bdf8ffa77c5274171bc5564 Mon Sep 17 00:00:00 2001 From: Julien Richard Date: Thu, 28 Sep 2023 18:33:04 +0200 Subject: [PATCH 007/122] Support sub modules in mocks (#528) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Support sub modules in mocks * Clean * Update NGitLab.Mock/Config/GitLabHelpers.cs Co-authored-by: Gérald Barré --------- Co-authored-by: Gérald Barré --- NGitLab.Mock.Tests/ProjectsMockTests.cs | 43 +++++++++++++ NGitLab.Mock/Config/GitLabCommit.cs | 5 ++ NGitLab.Mock/Config/GitLabHelpers.cs | 63 +++++++++++++++++-- .../Config/GitLabSubModuleDescriptor.cs | 13 ++++ NGitLab.Mock/PublicAPI.Unshipped.txt | 7 +++ NGitLab.Mock/Repository.cs | 12 +++- 6 files changed, 138 insertions(+), 5 deletions(-) create mode 100644 NGitLab.Mock/Config/GitLabSubModuleDescriptor.cs diff --git a/NGitLab.Mock.Tests/ProjectsMockTests.cs b/NGitLab.Mock.Tests/ProjectsMockTests.cs index ff865f98..062892d8 100644 --- a/NGitLab.Mock.Tests/ProjectsMockTests.cs +++ b/NGitLab.Mock.Tests/ProjectsMockTests.cs @@ -37,6 +37,49 @@ public void Test_project_can_be_cloned_by_default() Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git"))); } + [Test] + public void Test_project_with_submodules() + { + using var tempDir = TemporaryDirectory.Create(); + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("ModuleA", configure: x => x.WithCommit(configure: c => c.WithFile("A.txt"))) + .WithProject("ModuleB", configure: x => x.WithCommit(configure: c => c.WithFile("B.txt"))) + .WithProject("Test", clonePath: tempDir.FullPath, configure: x => + x.WithCommit("Init", configure: c + => c.WithSubModule("ModuleA") + .WithSubModule("ModuleB"))) + .BuildServer(); + + Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git"))); + Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/.git"))); + Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/A.txt"))); + Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git"))); + Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt"))); + } + + [Test] + public void Test_project_with_nested_submodules() + { + using var tempDir = TemporaryDirectory.Create(); + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("ModuleA", configure: x => x.WithCommit(configure: c => c.WithFile("A.txt"))) + .WithProject("ModuleB", configure: x => x.WithCommit(configure: c + => c.WithFile("B.txt") + .WithSubModule("ModuleA"))) + .WithProject("Test", clonePath: tempDir.FullPath, configure: x => + x.WithCommit(configure: c + => c.WithSubModule("ModuleB"))) + .BuildServer(); + + Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git"))); + Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git"))); + Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt"))); + Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/.git"))); + Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/A.txt"))); + } + [Test] public void Test_projects_created_url_ends_with_namespace_and_name() { diff --git a/NGitLab.Mock/Config/GitLabCommit.cs b/NGitLab.Mock/Config/GitLabCommit.cs index 585e879e..7034142e 100644 --- a/NGitLab.Mock/Config/GitLabCommit.cs +++ b/NGitLab.Mock/Config/GitLabCommit.cs @@ -24,6 +24,11 @@ public class GitLabCommit : GitLabObject /// public IList Files { get; } = new List(); + /// + /// Submodules added at this commit + /// + public IList SubModules { get; } = new List(); + public IList Tags { get; } = new List(); /// diff --git a/NGitLab.Mock/Config/GitLabHelpers.cs b/NGitLab.Mock/Config/GitLabHelpers.cs index f73a8833..3ae2e4c8 100644 --- a/NGitLab.Mock/Config/GitLabHelpers.cs +++ b/NGitLab.Mock/Config/GitLabHelpers.cs @@ -448,6 +448,20 @@ public static GitLabCommit WithFile(this GitLabCommit commit, string relativePat }); } + /// + /// Add a submodule in commit + /// + public static GitLabCommit WithSubModule(this GitLabCommit commit, string projectName) + { + return Configure(commit, _ => + { + commit.SubModules.Add(new GitLabSubModuleDescriptor + { + ProjectName = projectName, + }); + }); + } + /// /// Add an issue description in project /// @@ -1234,7 +1248,7 @@ private static void CreateProject(GitLabServer server, GitLabProject project) StartInfo = new ProcessStartInfo { FileName = "git", - Arguments = $"clone {project.CloneParameters} \"{prj.SshUrl}\" \"{Path.GetFileName(project.ClonePath)}\"", + Arguments = $"-c protocol.file.allow=always clone {project.CloneParameters} \"{prj.SshUrl}\" \"{Path.GetFileName(project.ClonePath)}\" --recursive", RedirectStandardError = true, UseShellExecute = false, WorkingDirectory = folderPath, @@ -1283,9 +1297,12 @@ private static Commit CreateCommit(GitLabServer server, Project prj, GitLabCommi prj.Repository.CreateBranch(commit.SourceBranch); var files = commit.Files.Count == 0 - ? new[] { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) } - : commit.Files.Select(x => File.CreateFromText(x.Path, x.Content ?? string.Empty)); - cmt = prj.Repository.Commit(user, commit.Message ?? Guid.NewGuid().ToString("D"), commit.SourceBranch, files); + ? new List() { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) } + : commit.Files.Select(x => File.CreateFromText(x.Path, x.Content ?? string.Empty)).ToList(); + + var submodules = CreateSubModules(server, prj, commit); + + cmt = prj.Repository.Commit(user, commit.Message ?? Guid.NewGuid().ToString("D"), commit.SourceBranch, files, submodules); } else { @@ -1302,6 +1319,44 @@ private static Commit CreateCommit(GitLabServer server, Project prj, GitLabCommi return cmt; } + private static IEnumerable CreateSubModules(GitLabServer server, Project prj, GitLabCommit commit) + { + List submodules = new(); + foreach (var submodule in commit.SubModules) + { + var subModuleProject = server.AllProjects.FirstOrDefault(x => + x.Name.Equals(submodule.ProjectName, StringComparison.OrdinalIgnoreCase)); + if (subModuleProject is null) + { + throw new GitLabException($"Project {submodule.ProjectName} can't be found."); + } + + if (!subModuleProject.Repository.GetCommits().Any()) + { + throw new GitLabException("Project added as a module must have least one commit."); + } + + using var process = Process.Start( + new ProcessStartInfo("git", $"-c protocol.file.allow=always submodule add \"{subModuleProject.SshUrl}\" \"{subModuleProject.Name}\"") + { + RedirectStandardError = true, + UseShellExecute = false, + WorkingDirectory = prj.Repository.FullPath, + }); + + process.WaitForExit(); + if (process.ExitCode != 0) + { + var error = process.StandardError.ReadToEnd(); + throw new GitLabException($"Cannot add submodule: {error}"); + } + + submodules.Add(subModuleProject.Name); + } + + return submodules; + } + private static void CreateLabel(Group group, GitLabLabel label) { group.Labels.Add(new Label diff --git a/NGitLab.Mock/Config/GitLabSubModuleDescriptor.cs b/NGitLab.Mock/Config/GitLabSubModuleDescriptor.cs new file mode 100644 index 00000000..588a0984 --- /dev/null +++ b/NGitLab.Mock/Config/GitLabSubModuleDescriptor.cs @@ -0,0 +1,13 @@ +namespace NGitLab.Mock.Config +{ + /// + /// Describe a sub module in project repository + /// + public class GitLabSubModuleDescriptor + { + /// + /// Project's ID added as a submodule + /// + public string ProjectName { get; init; } + } +} diff --git a/NGitLab.Mock/PublicAPI.Unshipped.txt b/NGitLab.Mock/PublicAPI.Unshipped.txt index 796103c3..2aa6ffc9 100644 --- a/NGitLab.Mock/PublicAPI.Unshipped.txt +++ b/NGitLab.Mock/PublicAPI.Unshipped.txt @@ -124,6 +124,7 @@ NGitLab.Mock.Config.GitLabCommit.DeleteSourceBranch.get -> bool NGitLab.Mock.Config.GitLabCommit.DeleteSourceBranch.set -> void NGitLab.Mock.Config.GitLabCommit.FromBranch.get -> string NGitLab.Mock.Config.GitLabCommit.FromBranch.set -> void +NGitLab.Mock.Config.GitLabCommit.SubModules.get -> System.Collections.Generic.IList NGitLab.Mock.Config.GitLabConfig.DefaultBranch.get -> string NGitLab.Mock.Config.GitLabConfig.DefaultBranch.set -> void NGitLab.Mock.Config.GitLabConfig.DefaultUser.get -> string @@ -210,6 +211,10 @@ NGitLab.Mock.Config.GitLabReleaseInfo.ReleasedAt.set -> void NGitLab.Mock.Config.GitLabReleaseInfo.TagName.get -> string NGitLab.Mock.Config.GitLabReleaseInfo.TagName.set -> void NGitLab.Mock.Config.GitLabReleaseInfoCollection +NGitLab.Mock.Config.GitLabSubModuleDescriptor +NGitLab.Mock.Config.GitLabSubModuleDescriptor.GitLabSubModuleDescriptor() -> void +NGitLab.Mock.Config.GitLabSubModuleDescriptor.ProjectName.get -> string +NGitLab.Mock.Config.GitLabSubModuleDescriptor.ProjectName.init -> void NGitLab.Mock.EffectivePermissions NGitLab.Mock.EffectivePermissions.GetAccessLevel(NGitLab.Mock.User user) -> NGitLab.Models.AccessLevel? NGitLab.Mock.EffectivePermissions.GetEffectivePermission(NGitLab.Mock.User user) -> NGitLab.Mock.EffectiveUserPermission @@ -956,6 +961,7 @@ NGitLab.Mock.Repository.Checkout(string committishOrBranchNameSpec) -> void NGitLab.Mock.Repository.CherryPick(NGitLab.Models.CommitCherryPick commitCherryPick) -> LibGit2Sharp.Commit NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message) -> LibGit2Sharp.Commit NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message, string targetBranch, System.Collections.Generic.IEnumerable files) -> LibGit2Sharp.Commit +NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message, string targetBranch, System.Collections.Generic.IEnumerable files, System.Collections.Generic.IEnumerable submodules) -> LibGit2Sharp.Commit NGitLab.Mock.Repository.Commit(NGitLab.Mock.User user, string message, System.Collections.Generic.IEnumerable files) -> LibGit2Sharp.Commit NGitLab.Mock.Repository.Commit(NGitLab.Models.CommitCreate commitCreate) -> LibGit2Sharp.Commit NGitLab.Mock.Repository.CreateAndCheckoutBranch(string branchName) -> LibGit2Sharp.Branch @@ -1230,6 +1236,7 @@ static NGitLab.Mock.Config.GitLabHelpers.WithMilestone(this NGitLab.Mock.Config. static NGitLab.Mock.Config.GitLabHelpers.WithPipeline(this NGitLab.Mock.Config.GitLabProject project, string ref, System.Action configure) -> NGitLab.Mock.Config.GitLabProject static NGitLab.Mock.Config.GitLabHelpers.WithProject(this NGitLab.Mock.Config.GitLabConfig config, string name = null, int id = 0, string namespace = null, string description = null, string defaultBranch = null, NGitLab.Models.VisibilityLevel visibility = NGitLab.Models.VisibilityLevel.Internal, bool initialCommit = false, bool addDefaultUserAsMaintainer = false, string clonePath = null, string cloneParameters = null, System.Action configure = null) -> NGitLab.Mock.Config.GitLabConfig static NGitLab.Mock.Config.GitLabHelpers.WithRelease(this NGitLab.Mock.Config.GitLabProject project, string author, string tagName, System.DateTime? createdAt = null, System.DateTime? releasedAt = null) -> NGitLab.Mock.Config.GitLabProject +static NGitLab.Mock.Config.GitLabHelpers.WithSubModule(this NGitLab.Mock.Config.GitLabCommit commit, string projectName) -> NGitLab.Mock.Config.GitLabCommit static NGitLab.Mock.Config.GitLabHelpers.WithSystemComment(this NGitLab.Mock.Config.GitLabIssue issue, string message = null, string innerHtml = null, int id = 0, string author = null, System.DateTime? createdAt = null, System.DateTime? updatedAt = null) -> NGitLab.Mock.Config.GitLabIssue static NGitLab.Mock.Config.GitLabHelpers.WithSystemComment(this NGitLab.Mock.Config.GitLabMergeRequest mergeRequest, string message = null, string innerHtml = null, int id = 0, string author = null, System.DateTime? createdAt = null, System.DateTime? updatedAt = null) -> NGitLab.Mock.Config.GitLabMergeRequest static NGitLab.Mock.Config.GitLabHelpers.WithUser(this NGitLab.Mock.Config.GitLabConfig config, string username, string name = null, string email = null, string avatarUrl = null, bool isAdmin = false, bool isDefault = false, System.Action configure = null) -> NGitLab.Mock.Config.GitLabConfig diff --git a/NGitLab.Mock/Repository.cs b/NGitLab.Mock/Repository.cs index 9808a9c2..a6c9372c 100644 --- a/NGitLab.Mock/Repository.cs +++ b/NGitLab.Mock/Repository.cs @@ -157,7 +157,7 @@ public IReadOnlyCollection GetAllBranches() public Commit Commit(User user, string message) { - return Commit(user, message, targetBranch: null, new[] { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) }); + return Commit(user, message, targetBranch: null, new[] { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) }, Enumerable.Empty()); } public Commit Commit(User user, string message, IEnumerable files) @@ -166,6 +166,11 @@ public Commit Commit(User user, string message, IEnumerable files) } public Commit Commit(User user, string message, string targetBranch, IEnumerable files) + { + return Commit(user, message, targetBranch, files, Enumerable.Empty()); + } + + public Commit Commit(User user, string message, string targetBranch, IEnumerable files, IEnumerable submodules) { var repository = GetGitRepository(); if (targetBranch != null) @@ -181,6 +186,11 @@ public Commit Commit(User user, string message, string targetBranch, IEnumerable repository.Index.Add(file.Path); } + foreach (var submodule in submodules) + { + repository.Index.Add(submodule); + } + repository.Index.Write(); var author = new Signature(user.UserName, user.Email, DateTimeOffset.UtcNow); From ac714a52926cc608139a37def7ceef17eb7eeaba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Oct 2023 07:38:57 -0400 Subject: [PATCH 008/122] Bump Polly from 7.2.4 to 8.0.0 (#533) Bumps [Polly](https://github.com/App-vNext/Polly) from 7.2.4 to 8.0.0. - [Release notes](https://github.com/App-vNext/Polly/releases) - [Changelog](https://github.com/App-vNext/Polly/blob/main/CHANGELOG.md) - [Commits](https://github.com/App-vNext/Polly/compare/7.2.4...8.0.0) --- updated-dependencies: - dependency-name: Polly dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index bab4a6bb..f3e4f880 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -20,7 +20,7 @@ - + all From c8b1b5256553e855516fe579e6e2ab249b925b32 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Oct 2023 17:16:34 -0400 Subject: [PATCH 009/122] Bump Meziantou.Analyzer from 2.0.85 to 2.0.91 (#532) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.85 to 2.0.91. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.85...2.0.91) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 1861a9b9..c1c17483 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 705e8804cf04153e0a67d76207093a56624b817b Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Wed, 4 Oct 2023 09:58:16 -0400 Subject: [PATCH 010/122] Migrate NGitLab from net461 to net462 + bump up LangVersion to 11.0 (#534) --- Directory.Build.props | 2 +- NGitLab/DynamicEnum.cs | 10 +++++----- NGitLab/Impl/Json/EnumConverterFactory.cs | 3 +-- NGitLab/Impl/ProjectClient.cs | 2 +- NGitLab/Impl/RepositoryClient.cs | 2 -- NGitLab/Impl/SshKeyClient.cs | 2 +- NGitLab/NGitLab.csproj | 4 ++-- global.json | 4 ++-- 8 files changed, 13 insertions(+), 16 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index c1c17483..e68ea864 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -8,7 +8,7 @@ $(Company), NGitLab contributors - 10.0 + 11.0 true strict true diff --git a/NGitLab/DynamicEnum.cs b/NGitLab/DynamicEnum.cs index df53ef62..09ded2b4 100644 --- a/NGitLab/DynamicEnum.cs +++ b/NGitLab/DynamicEnum.cs @@ -35,23 +35,23 @@ public DynamicEnum(string stringValue) StringValue = stringValue; } - public bool Equals(TEnum other) + public readonly bool Equals(TEnum other) { return Equals(EnumValue, other); } - public bool Equals(DynamicEnum other) + public readonly bool Equals(DynamicEnum other) { return EqualityComparer.Default.Equals(EnumValue, other.EnumValue) && StringComparer.OrdinalIgnoreCase.Equals(StringValue, other.StringValue); } - public override bool Equals(object obj) + public override readonly bool Equals(object obj) { return obj is DynamicEnum other && Equals(other); } - public override int GetHashCode() + public override readonly int GetHashCode() { return EqualityComparer.Default.GetHashCode(EnumValue); } @@ -64,7 +64,7 @@ public override int GetHashCode() public static bool operator !=(DynamicEnum obj1, TEnum obj2) => !obj1.Equals(obj2); - public override string ToString() + public override readonly string ToString() { return StringValue ?? EnumValue?.ToString() ?? string.Empty; } diff --git a/NGitLab/Impl/Json/EnumConverterFactory.cs b/NGitLab/Impl/Json/EnumConverterFactory.cs index 111b5380..b12e54e4 100644 --- a/NGitLab/Impl/Json/EnumConverterFactory.cs +++ b/NGitLab/Impl/Json/EnumConverterFactory.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Text.Json; using System.Text.Json.Serialization; using NGitLab.Models; @@ -38,7 +37,7 @@ public EnumConverter() foreach (var mapping in _enumType.GetEnumMappings()) { enumValues.Add((TEnum)mapping.EnumValue); - stringValues.Add(mapping.StringValue ?? mapping.EnumValue.ToString(CultureInfo.InvariantCulture)); + stringValues.Add(mapping.StringValue ?? mapping.EnumValue.ToString()); } _stringToEnumValues = new Dictionary(stringValues.Count, StringComparer.OrdinalIgnoreCase); diff --git a/NGitLab/Impl/ProjectClient.cs b/NGitLab/Impl/ProjectClient.cs index bf593737..2292899b 100644 --- a/NGitLab/Impl/ProjectClient.cs +++ b/NGitLab/Impl/ProjectClient.cs @@ -71,7 +71,7 @@ private static string CreateGetUrl(ProjectQuery query) // This is the default, it returns all visible projects. break; default: - throw new ArgumentOutOfRangeException(); + throw new ArgumentOutOfRangeException(nameof(query), $"'{nameof(query.Scope)}' has unknown value '{query.Scope}'"); } url = Utils.AddParameter(url, "archived", query.Archived); diff --git a/NGitLab/Impl/RepositoryClient.cs b/NGitLab/Impl/RepositoryClient.cs index 56a0c0ea..126a65ca 100644 --- a/NGitLab/Impl/RepositoryClient.cs +++ b/NGitLab/Impl/RepositoryClient.cs @@ -13,12 +13,10 @@ public class RepositoryClient : IRepositoryClient private readonly API _api; private readonly string _repoPath; private readonly string _projectPath; - private readonly int _projectId; public RepositoryClient(API api, int projectId) { _api = api; - _projectId = projectId; _projectPath = Project.Url + "/" + projectId.ToStringInvariant(); _repoPath = _projectPath + "/repository"; } diff --git a/NGitLab/Impl/SshKeyClient.cs b/NGitLab/Impl/SshKeyClient.cs index 55e30f45..0da1ee73 100644 --- a/NGitLab/Impl/SshKeyClient.cs +++ b/NGitLab/Impl/SshKeyClient.cs @@ -12,7 +12,7 @@ public class SshKeyClient : ISshKeyClient public SshKeyClient(API api, int? userId) { _api = api; - _url = userId != null ? $"users/{userId}/keys" : "user/keys"; + _url = userId != null ? $"users/{userId.Value.ToStringInvariant()}/keys" : "user/keys"; } public IEnumerable All => _api.Get().GetAll(_url); diff --git a/NGitLab/NGitLab.csproj b/NGitLab/NGitLab.csproj index 00e52c6f..30231e39 100644 --- a/NGitLab/NGitLab.csproj +++ b/NGitLab/NGitLab.csproj @@ -1,13 +1,13 @@ - net461;netstandard2.0 + net462;netstandard2.0 - + diff --git a/global.json b/global.json index 73ee58ca..857e6681 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "6.0.202", - "rollForward": "major" + "version": "7.0.100", + "rollForward": "latestFeature" } } From ccc6a662002a94b1d74c46c717f2156551816a89 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 07:51:29 -0400 Subject: [PATCH 011/122] Bump YamlDotNet from 13.4.0 to 13.5.2 (#536) Bumps [YamlDotNet](https://github.com/aaubry/YamlDotNet) from 13.4.0 to 13.5.2. - [Release notes](https://github.com/aaubry/YamlDotNet/releases) - [Commits](https://github.com/aaubry/YamlDotNet/compare/v13.4.0...v13.5.2) --- updated-dependencies: - dependency-name: YamlDotNet dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Mock/NGitLab.Mock.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Mock/NGitLab.Mock.csproj b/NGitLab.Mock/NGitLab.Mock.csproj index d44f59d7..e4c43379 100644 --- a/NGitLab.Mock/NGitLab.Mock.csproj +++ b/NGitLab.Mock/NGitLab.Mock.csproj @@ -13,7 +13,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + From 20e57d3de99b61478951d7dd6e4b9f749f87c893 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 10 Oct 2023 08:37:56 -0400 Subject: [PATCH 012/122] Bump Meziantou.Analyzer from 2.0.91 to 2.0.92 (#535) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.91 to 2.0.92. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.91...2.0.92) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index e68ea864..e1aefdc3 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 63095322980accf7301ac6901c0fbcc9b5391e80 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Fri, 13 Oct 2023 22:33:21 +0800 Subject: [PATCH 013/122] Support setting multiple assignees for issues (#541) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gérald Barré --- NGitLab/Models/IssueCreate.cs | 3 +++ NGitLab/Models/IssueEdit.cs | 3 +++ NGitLab/PublicAPI.Unshipped.txt | 2 ++ 3 files changed, 8 insertions(+) diff --git a/NGitLab/Models/IssueCreate.cs b/NGitLab/Models/IssueCreate.cs index 92474df2..b737828d 100644 --- a/NGitLab/Models/IssueCreate.cs +++ b/NGitLab/Models/IssueCreate.cs @@ -25,6 +25,9 @@ public class IssueCreate [JsonPropertyName("assignee_id")] public int? AssigneeId; + [JsonPropertyName("assignee_ids")] + public int[] AssigneeIds; + [JsonPropertyName("milestone_id")] public int? MileStoneId; diff --git a/NGitLab/Models/IssueEdit.cs b/NGitLab/Models/IssueEdit.cs index a3ee32c3..78f24bfd 100644 --- a/NGitLab/Models/IssueEdit.cs +++ b/NGitLab/Models/IssueEdit.cs @@ -28,6 +28,9 @@ public class IssueEdit [JsonPropertyName("assignee_id")] public int? AssigneeId; + [JsonPropertyName("assignee_ids")] + public int[] AssigneeIds; + [JsonPropertyName("milestone_id")] public int? MilestoneId; diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index 4f9b3455..d184794c 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -1817,6 +1817,7 @@ NGitLab.Models.IssueClone.WithNotes.get -> bool NGitLab.Models.IssueClone.WithNotes.set -> void NGitLab.Models.IssueCreate NGitLab.Models.IssueCreate.AssigneeId -> int? +NGitLab.Models.IssueCreate.AssigneeIds -> int[] NGitLab.Models.IssueCreate.Confidential -> bool NGitLab.Models.IssueCreate.Description -> string NGitLab.Models.IssueCreate.DueDate -> System.DateTime? @@ -1830,6 +1831,7 @@ NGitLab.Models.IssueCreate.ProjectId.set -> void NGitLab.Models.IssueCreate.Title -> string NGitLab.Models.IssueEdit NGitLab.Models.IssueEdit.AssigneeId -> int? +NGitLab.Models.IssueEdit.AssigneeIds -> int[] NGitLab.Models.IssueEdit.Description -> string NGitLab.Models.IssueEdit.DueDate -> System.DateTime? NGitLab.Models.IssueEdit.EpicId -> int? From 1834ec9fad19541687600c91a68f2ef32de5fc77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 07:17:04 -0400 Subject: [PATCH 014/122] Bump Meziantou.Analyzer from 2.0.92 to 2.0.93 (#545) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.92 to 2.0.93. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.92...2.0.93) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index e1aefdc3..aaf8a3a5 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From ad6594f5f2ee816d78050c8c4c63aa9104202d7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Oct 2023 07:50:48 -0400 Subject: [PATCH 015/122] Bump YamlDotNet from 13.5.2 to 13.7.1 (#544) Bumps [YamlDotNet](https://github.com/aaubry/YamlDotNet) from 13.5.2 to 13.7.1. - [Release notes](https://github.com/aaubry/YamlDotNet/releases) - [Commits](https://github.com/aaubry/YamlDotNet/compare/v13.5.2...v13.7.1) --- updated-dependencies: - dependency-name: YamlDotNet dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Mock/NGitLab.Mock.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Mock/NGitLab.Mock.csproj b/NGitLab.Mock/NGitLab.Mock.csproj index e4c43379..e78713ae 100644 --- a/NGitLab.Mock/NGitLab.Mock.csproj +++ b/NGitLab.Mock/NGitLab.Mock.csproj @@ -13,7 +13,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + From 8ba3bc68520562804f046072baec1f4c66628e23 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Mon, 16 Oct 2023 20:17:41 +0800 Subject: [PATCH 016/122] Add missing attribute `user_notes_count` to merge requests (#542) --- NGitLab/Models/MergeRequest.cs | 3 +++ NGitLab/PublicAPI.Unshipped.txt | 1 + 2 files changed, 4 insertions(+) diff --git a/NGitLab/Models/MergeRequest.cs b/NGitLab/Models/MergeRequest.cs index ff8095f8..93437283 100644 --- a/NGitLab/Models/MergeRequest.cs +++ b/NGitLab/Models/MergeRequest.cs @@ -32,6 +32,9 @@ public class MergeRequest [JsonPropertyName("description")] public string Description; + [JsonPropertyName("user_notes_count")] + public int UserNotesCount; + [JsonPropertyName("downvotes")] public int Downvotes; diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index d184794c..c4bae40a 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -2118,6 +2118,7 @@ NGitLab.Models.MergeRequest.UpdatedAt -> System.DateTime NGitLab.Models.MergeRequest.Upvotes -> int NGitLab.Models.MergeRequest.User.get -> NGitLab.Models.MergeRequestUserInfo NGitLab.Models.MergeRequest.User.set -> void +NGitLab.Models.MergeRequest.UserNotesCount -> int NGitLab.Models.MergeRequest.WebUrl -> string NGitLab.Models.MergeRequest.WorkInProgress -> bool? NGitLab.Models.MergeRequestAccept From 09cdaae330e43fd996fd1a0d7cdb4d29cf21c308 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Tue, 17 Oct 2023 21:18:23 +0800 Subject: [PATCH 017/122] Remove the default `target_project_id` when creating merge request (#540) Co-authored-by: Thomas Cortes <78750681+Toa741@users.noreply.github.com> --- NGitLab/Impl/MergeRequestClient.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/NGitLab/Impl/MergeRequestClient.cs b/NGitLab/Impl/MergeRequestClient.cs index cd8396f2..8582ce26 100644 --- a/NGitLab/Impl/MergeRequestClient.cs +++ b/NGitLab/Impl/MergeRequestClient.cs @@ -11,13 +11,11 @@ namespace NGitLab.Impl public class MergeRequestClient : IMergeRequestClient { private readonly API _api; - private readonly int _projectId; private readonly string _projectPath; public MergeRequestClient(API api, int projectId) { _api = api; - _projectId = projectId; _projectPath = Project.Url + "/" + projectId.ToStringInvariant(); } @@ -89,8 +87,6 @@ public MergeRequest Create(MergeRequestCreate mergeRequest) if (mergeRequest == null) throw new ArgumentNullException(nameof(mergeRequest)); - mergeRequest.TargetProjectId ??= _projectId; - return _api .Post().With(mergeRequest) .To(_projectPath + "/merge_requests"); From 6368d6a4ec01fcfd7641dd9cfec9e79596469faf Mon Sep 17 00:00:00 2001 From: PM Extra Date: Tue, 17 Oct 2023 21:47:41 +0800 Subject: [PATCH 018/122] Support downloading a single artifact file (#539) --- NGitLab.Mock/Clients/JobClient.cs | 5 +++++ NGitLab.Tests/JobTests.cs | 23 +++++++++++++++++++++++ NGitLab/IJobClient.cs | 2 ++ NGitLab/Impl/JobClient.cs | 12 ++++++++++++ NGitLab/PublicAPI.Unshipped.txt | 2 ++ 5 files changed, 44 insertions(+) diff --git a/NGitLab.Mock/Clients/JobClient.cs b/NGitLab.Mock/Clients/JobClient.cs index 913eb43f..aa97a9c9 100644 --- a/NGitLab.Mock/Clients/JobClient.cs +++ b/NGitLab.Mock/Clients/JobClient.cs @@ -45,6 +45,11 @@ public byte[] GetJobArtifacts(int jobId) throw new NotImplementedException(); } + public byte[] GetJobArtifact(int jobId, string path) + { + throw new NotImplementedException(); + } + public IEnumerable GetJobs(JobScopeMask scope) { return GetJobs(new JobQuery { Scope = scope }); diff --git a/NGitLab.Tests/JobTests.cs b/NGitLab.Tests/JobTests.cs index 247cdf6b..ba783476 100644 --- a/NGitLab.Tests/JobTests.cs +++ b/NGitLab.Tests/JobTests.cs @@ -1,6 +1,7 @@ using System; using System.Globalization; using System.Linq; +using System.Text; using System.Threading.Tasks; using NGitLab.Models; using NGitLab.Tests.Docker; @@ -203,5 +204,27 @@ public async Task Test_get_job_artifacts() Assert.IsNotEmpty(artifacts); } } + + [Test] + [NGitLabRetry] + public async Task Test_get_job_artifact() + { + using var context = await GitLabTestContext.CreateAsync(); + var project = context.CreateProject(); + var jobsClient = context.Client.GetJobs(project.Id); + using (await context.StartRunnerForOneJobAsync(project.Id)) + { + AddGitLabCiFile(context.Client, project); + var jobs = await GitLabTestContext.RetryUntilAsync(() => jobsClient.GetJobs(JobScopeMask.Success), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); + var job = jobs.Single(); + Assert.AreEqual(JobStatus.Success, job.Status); + + var artifact = jobsClient.GetJobArtifact(job.Id, "file0.txt"); + Assert.IsNotEmpty(artifact); + + var content = Encoding.ASCII.GetString(artifact).Trim(); + Assert.AreEqual("test", content); + } + } } } diff --git a/NGitLab/IJobClient.cs b/NGitLab/IJobClient.cs index 6b9c71d8..84c05f89 100644 --- a/NGitLab/IJobClient.cs +++ b/NGitLab/IJobClient.cs @@ -23,6 +23,8 @@ public interface IJobClient byte[] GetJobArtifacts(int jobId); + byte[] GetJobArtifact(int jobId, string path); + string GetTrace(int jobId); Task GetTraceAsync(int jobId, CancellationToken cancellationToken = default); diff --git a/NGitLab/Impl/JobClient.cs b/NGitLab/Impl/JobClient.cs index 92b5034b..334eb784 100644 --- a/NGitLab/Impl/JobClient.cs +++ b/NGitLab/Impl/JobClient.cs @@ -82,6 +82,18 @@ public byte[] GetJobArtifacts(int jobId) return result; } + public byte[] GetJobArtifact(int jobId, string path) + { + byte[] result = null; + _api.Get().Stream($"{_jobsPath}/{jobId.ToStringInvariant()}/artifacts/{path}", s => + { + using var ms = new MemoryStream(); + s.CopyTo(ms); + result = ms.ToArray(); + }); + return result; + } + public string GetTrace(int jobId) { var result = string.Empty; diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index c4bae40a..c191f5bf 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -282,6 +282,7 @@ NGitLab.IIssueClient.TimeStatsAsync(int projectId, int issueIid, System.Threadin NGitLab.IJobClient NGitLab.IJobClient.Get(int jobId) -> NGitLab.Models.Job NGitLab.IJobClient.GetAsync(int jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +NGitLab.IJobClient.GetJobArtifact(int jobId, string path) -> byte[] NGitLab.IJobClient.GetJobArtifacts(int jobId) -> byte[] NGitLab.IJobClient.GetJobs(NGitLab.Models.JobQuery query) -> System.Collections.Generic.IEnumerable NGitLab.IJobClient.GetJobs(NGitLab.Models.JobScopeMask scope) -> System.Collections.Generic.IEnumerable @@ -537,6 +538,7 @@ NGitLab.Impl.IssueClient.TimeStatsAsync(int projectId, int issueIid, System.Thre NGitLab.Impl.JobClient NGitLab.Impl.JobClient.Get(int jobId) -> NGitLab.Models.Job NGitLab.Impl.JobClient.GetAsync(int jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +NGitLab.Impl.JobClient.GetJobArtifact(int jobId, string path) -> byte[] NGitLab.Impl.JobClient.GetJobArtifacts(int jobId) -> byte[] NGitLab.Impl.JobClient.GetJobs(NGitLab.Models.JobQuery query) -> System.Collections.Generic.IEnumerable NGitLab.Impl.JobClient.GetJobs(NGitLab.Models.JobScopeMask scope) -> System.Collections.Generic.IEnumerable From 8b8d882662a7d5e20b645ae444aba0e58191c399 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 07:41:39 -0400 Subject: [PATCH 019/122] Bump Microsoft.Playwright from 1.38.0 to 1.39.0 (#548) Bumps [Microsoft.Playwright](https://github.com/microsoft/playwright-dotnet) from 1.38.0 to 1.39.0. - [Release notes](https://github.com/microsoft/playwright-dotnet/releases) - [Commits](https://github.com/microsoft/playwright-dotnet/compare/v1.38.0...v1.39.0) --- updated-dependencies: - dependency-name: Microsoft.Playwright dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index f3e4f880..a21c7a0a 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -15,7 +15,7 @@ - + From 5346942affd9869eb62a3529d401641c815d2830 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:04:02 +0000 Subject: [PATCH 020/122] Bump Meziantou.Analyzer from 2.0.93 to 2.0.94 (#549) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.93 to 2.0.94. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.93...2.0.94) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index aaf8a3a5..dd2a5ea0 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From dee78df69563ee7847d98f672d8f02c91554b53a Mon Sep 17 00:00:00 2001 From: phdesroUbi <83839027+phdesroUbi@users.noreply.github.com> Date: Tue, 24 Oct 2023 16:53:39 -0400 Subject: [PATCH 021/122] Add ResourceEvents for merge requests (#547) * Add ResourceEvents for merge requests - Closes #546 * added resources uses in mock * comment fixes * modified mock for resourceLabelEvent for MRs [skip ci] * added resourceMilestones to mock and tests * api changes * added comment to tests --- NGitLab.Mock.Tests/MergeRequestsMockTests.cs | 122 ++++++++++++++++++ NGitLab.Mock/Clients/IssueClient.cs | 105 +-------------- NGitLab.Mock/Clients/MergeRequestClient.cs | 80 +++++++++++- NGitLab.Mock/ResourceLabelEventCollection.cs | 58 +++++++++ .../ResourceMilestoneEventCollection.cs | 42 ++++++ NGitLab.Mock/ResourceStateEventCollection.cs | 24 ++++ NGitLab/IMergeRequestClient.cs | 33 +++++ NGitLab/Impl/MergeRequestClient.cs | 20 ++- NGitLab/PublicAPI.Unshipped.txt | 6 + 9 files changed, 379 insertions(+), 111 deletions(-) diff --git a/NGitLab.Mock.Tests/MergeRequestsMockTests.cs b/NGitLab.Mock.Tests/MergeRequestsMockTests.cs index 2e35f717..2f5bf362 100644 --- a/NGitLab.Mock.Tests/MergeRequestsMockTests.cs +++ b/NGitLab.Mock.Tests/MergeRequestsMockTests.cs @@ -290,5 +290,127 @@ public void Test_merge_request_with_head_pipeline() var pipeline = project.Pipelines.Add(branch, JobStatus.Success, user); Assert.AreEqual(pipeline, mr.HeadPipeline, "A pipeline was just created on the source branch"); } + + [Test] + public void Test_merge_request_resource_state_events_found_on_close_and_reopen() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var projectId = server.AllProjects.First().Id; + var mrClient = client.GetMergeRequest(projectId); + var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); + + mrClient.Close(mergeRequest.Iid); + mrClient.Reopen(mergeRequest.Iid); + + var resourceStateEvents = mrClient.ResourceStateEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); + Assert.AreEqual(2, resourceStateEvents.Length); + + var closeStateEvents = resourceStateEvents.Where(e => string.Equals(e.State, "closed", StringComparison.Ordinal)).ToArray(); + Assert.AreEqual(1, closeStateEvents.Length); + + var reopenMilestoneEvents = resourceStateEvents.Where(e => string.Equals(e.State, "reopened", StringComparison.Ordinal)).ToArray(); + Assert.AreEqual(1, reopenMilestoneEvents.Length); + } + + [Test] + public void Test_merge_request_resource_label_events_found() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var projectId = server.AllProjects.First().Id; + var mrClient = client.GetMergeRequest(projectId); + var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() + { + AddLabels = "first,second,third", + }); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() + { + RemoveLabels = "second", + }); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() + { + Labels = "first,second", + }); + + /* We're expecting this sequence + * 1. Add first + * 1. Add second + * 1. Add third + * 2. Remove second + * 3. Add second + * 3. Remove third + */ + var resourceLabelEvents = mrClient.ResourceLabelEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); + Assert.AreEqual(6, resourceLabelEvents.Length); + + var addLabelEvents = resourceLabelEvents.Where(e => e.Action == ResourceLabelEventAction.Add).ToArray(); + Assert.AreEqual(4, addLabelEvents.Length); + + var removeLabelEvents = resourceLabelEvents.Where(e => e.Action == ResourceLabelEventAction.Remove).ToArray(); + Assert.AreEqual(2, removeLabelEvents.Length); + } + + [Test] + public void Test_merge_request_resource_milestone_events_found() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2") + .WithMilestone("Milestone 1") + .WithMilestone("Milestone 2")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var projectId = server.AllProjects.First().Id; + var mrClient = client.GetMergeRequest(projectId); + var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); + var milestones = client.GetMilestone(1).All.ToArray(); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() + { + MilestoneId = milestones[0].Id, + }); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() + { + MilestoneId = milestones[1].Id, + }); + + /* We're expecting this sequence + * 1. Add milestone 1 + * 2. Remove milestone 1 + * 2. Add milestone 2 + */ + var resourceMilestoneEvents = mrClient.ResourceMilestoneEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); + Assert.AreEqual(3, resourceMilestoneEvents.Length); + + var removeMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Remove).ToArray(); + Assert.AreEqual(1, removeMilestoneEvents.Length); + Assert.AreEqual(milestones[0].Id, removeMilestoneEvents[0].Milestone.Id); + + var addMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Add).ToArray(); + Assert.AreEqual(2, addMilestoneEvents.Length); + Assert.AreEqual(milestones[0].Id, addMilestoneEvents[0].Milestone.Id); + Assert.AreEqual(milestones[1].Id, addMilestoneEvents[1].Milestone.Id); + } } } diff --git a/NGitLab.Mock/Clients/IssueClient.cs b/NGitLab.Mock/Clients/IssueClient.cs index bc1a342b..394097fc 100644 --- a/NGitLab.Mock/Clients/IssueClient.cs +++ b/NGitLab.Mock/Clients/IssueClient.cs @@ -84,7 +84,7 @@ public Models.Issue Edit(IssueEdit issueEdit) if (issueEdit.MilestoneId.HasValue) { issueToModify.Milestone = GetMilestone(projectId, issueEdit.MilestoneId.Value); - CreateResourceMilestoneEvents(issueToModify.Id, prevMilestone, issueToModify.Milestone); + Server.ResourceMilestoneEvents.CreateResourceMilestoneEvents(Context.User, issueToModify.Id, prevMilestone, issueToModify.Milestone, "Issue"); } issueToModify.Title = issueEdit.Title; @@ -107,7 +107,7 @@ public Models.Issue Edit(IssueEdit issueEdit) if (labelsEdit is not null) { - CreateResourceLabelEvents(issueToModify.Labels, labelsEdit, issueToModify.Id); + Server.ResourceLabelEvents.CreateResourceLabelEvents(Context.User, issueToModify.Labels, labelsEdit, issueToModify.Id, "issue"); issueToModify.Labels = labelsEdit; } @@ -451,106 +451,5 @@ private IEnumerable FilterByQuery(IEnumerable issues, IssueQuery q return issues; } - - private void CreateResourceLabelEvents(string[] previousLabels, string[] newLabels, int resourceId) - { - var currentUser = Context.User; - - foreach (var label in previousLabels) - { - if (!newLabels.Any(l => string.Equals(l, label, StringComparison.OrdinalIgnoreCase))) - { - Server.ResourceLabelEvents.Add(new ResourceLabelEvent() - { - Action = ResourceLabelEventAction.Remove, - Label = new Label() { Name = label }, - ResourceId = resourceId, - CreatedAt = DateTime.UtcNow, - Id = Server.GetNewResourceLabelEventId(), - User = new Author() - { - Id = currentUser.Id, - Email = currentUser.Email, - AvatarUrl = currentUser.AvatarUrl, - Name = currentUser.Name, - State = currentUser.State.ToString(), - Username = currentUser.UserName, - CreatedAt = currentUser.CreatedAt, - WebUrl = currentUser.WebUrl, - }, - ResourceType = "issue", - }); - } - } - - foreach (var label in newLabels) - { - if (!previousLabels.Any(l => string.Equals(l, label, StringComparison.OrdinalIgnoreCase))) - { - Server.ResourceLabelEvents.Add(new ResourceLabelEvent() - { - Action = ResourceLabelEventAction.Add, - Label = new Label() { Name = label }, - ResourceId = resourceId, - CreatedAt = DateTime.UtcNow, - Id = Server.GetNewResourceLabelEventId(), - User = new Author() - { - Id = currentUser.Id, - Email = currentUser.Email, - AvatarUrl = currentUser.AvatarUrl, - Name = currentUser.Name, - State = currentUser.State.ToString(), - Username = currentUser.UserName, - CreatedAt = currentUser.CreatedAt, - WebUrl = currentUser.WebUrl, - }, - ResourceType = "issue", - }); - } - } - } - - private void CreateResourceMilestoneEvents(int resourceId, Milestone previousMilestone, Milestone newMilestone) - { - if (previousMilestone is null) - { - CreateResourceMilestoneEvent(resourceId, newMilestone, ResourceMilestoneEventAction.Add); - } - else if (newMilestone is not null && previousMilestone is not null) - { - if (newMilestone.Id != previousMilestone.Id) - { - CreateResourceMilestoneEvent(resourceId, previousMilestone, ResourceMilestoneEventAction.Remove); - } - - CreateResourceMilestoneEvent(resourceId, newMilestone, ResourceMilestoneEventAction.Add); - } - } - - private void CreateResourceMilestoneEvent(int resourceId, Milestone milestone, ResourceMilestoneEventAction action) - { - var currentUser = Context.User; - Server.ResourceMilestoneEvents.Add(new ResourceMilestoneEvent() - { - Action = action, - Milestone = milestone, - ResourceId = resourceId, - CreatedAt = DateTime.UtcNow, - Id = Server.GetNewResourceLabelEventId(), - User = new Author() - { - Id = currentUser.Id, - Email = currentUser.Email, - AvatarUrl = currentUser.AvatarUrl, - Name = currentUser.Name, - State = currentUser.State.ToString(), - Username = currentUser.UserName, - CreatedAt = currentUser.CreatedAt, - WebUrl = currentUser.WebUrl, - }, - ResourceType = "issue", - }); - } } } diff --git a/NGitLab.Mock/Clients/MergeRequestClient.cs b/NGitLab.Mock/Clients/MergeRequestClient.cs index b7354542..201bd7ad 100644 --- a/NGitLab.Mock/Clients/MergeRequestClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestClient.cs @@ -5,6 +5,7 @@ using System.Net; using System.Threading; using System.Threading.Tasks; +using NGitLab.Mock.Internals; using NGitLab.Models; namespace NGitLab.Mock.Clients @@ -262,6 +263,8 @@ public Models.MergeRequest Close(int mergeRequestIid) mergeRequest.ClosedAt = DateTimeOffset.UtcNow; mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; + + Server.ResourceStateEvents.CreateResourceStateEvent(Context.User, "closed", mergeRequest.Id, "MergeRequest"); return mergeRequest.ToMergeRequestClient(); } } @@ -326,22 +329,43 @@ public Models.MergeRequest Create(MergeRequestCreate mergeRequestCreate) mergeRequest.Description = mergeRequestCreate.Description; mergeRequest.ShouldRemoveSourceBranch = mergeRequestCreate.RemoveSourceBranch; mergeRequest.Squash = mergeRequestCreate.Squash; - SetLabels(mergeRequest, mergeRequestCreate.Labels); + SetLabels(mergeRequest, mergeRequestCreate.Labels, labelsToAdd: null, labelsToRemove: null); return mergeRequest.ToMergeRequestClient(); } } - private static void SetLabels(MergeRequest mergeRequest, string labels) + private void SetLabels(MergeRequest mergeRequest, string labels, string labelsToAdd, string labelsToRemove) { - if (labels != null) + if (labels is not null || labelsToAdd is not null || labelsToRemove is not null) { + var newLabels = mergeRequest.Labels.ToArray(); + if (labels is not null) + { + newLabels = labels.Split(',').Distinct(StringComparer.Ordinal).ToArray(); + } + + if (labelsToAdd is not null) + { + newLabels = newLabels.Concat(labelsToAdd.Split(',')).Distinct(StringComparer.Ordinal).ToArray(); + } + + if (labelsToRemove is not null) + { + newLabels = newLabels.Except(labelsToRemove.Split(','), StringComparer.Ordinal).Distinct(StringComparer.Ordinal).ToArray(); + } + + if (newLabels is not null) + { + Server.ResourceLabelEvents.CreateResourceLabelEvents(Context.User, mergeRequest.Labels.ToArray(), newLabels, mergeRequest.Id, "MergeRequest"); + } + mergeRequest.Labels.Clear(); - foreach (var label in labels.Split(',')) + foreach (var newLabel in newLabels) { - if (!string.IsNullOrEmpty(label)) + if (!string.IsNullOrEmpty(newLabel)) { - mergeRequest.Labels.Add(label); + mergeRequest.Labels.Add(newLabel); } } } @@ -571,6 +595,8 @@ public Models.MergeRequest Reopen(int mergeRequestIid) mergeRequest.ClosedAt = null; mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; + + Server.ResourceStateEvents.CreateResourceStateEvent(Context.User, "reopened", mergeRequest.Id, "MergeRequest"); return mergeRequest.ToMergeRequestClient(); } } @@ -621,6 +647,13 @@ public Models.MergeRequest Update(int mergeRequestIid, MergeRequestUpdate mergeR } } + if (mergeRequestUpdate.MilestoneId != null) + { + var prevMilestone = mergeRequest.Milestone; + mergeRequest.Milestone = GetMilestone(project.Id, mergeRequestUpdate.MilestoneId.Value); + Server.ResourceMilestoneEvents.CreateResourceMilestoneEvents(Context.User, mergeRequest.Id, prevMilestone, mergeRequest.Milestone, "MergeRequest"); + } + if (mergeRequestUpdate.ReviewerIds != null) { foreach (var reviewerId in mergeRequestUpdate.ReviewerIds) @@ -658,7 +691,7 @@ public Models.MergeRequest Update(int mergeRequestIid, MergeRequestUpdate mergeR mergeRequest.Title = mergeRequestUpdate.Title; } - SetLabels(mergeRequest, mergeRequestUpdate.Labels); + SetLabels(mergeRequest, mergeRequestUpdate.Labels, mergeRequestUpdate.AddLabels, mergeRequestUpdate.RemoveLabels); mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; return mergeRequest.ToMergeRequestClient(); @@ -681,5 +714,38 @@ public IMergeRequestDiscussionClient Discussions(int mergeRequestIid) return new MergeRequestDiscussionClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); } + + public GitLabCollectionResponse ResourceLabelEventsAsync(int projectId, int mergeRequestIid) + { + using (Context.BeginOperationScope()) + { + var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); + var resourceLabelEvents = Server.ResourceLabelEvents.Get(mergeRequest.Id); + + return GitLabCollectionResponse.Create(resourceLabelEvents.Select(rle => rle.ToClientResourceLabelEvent())); + } + } + + public GitLabCollectionResponse ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid) + { + using (Context.BeginOperationScope()) + { + var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); + var resourceMilestoneEvents = Server.ResourceMilestoneEvents.Get(mergeRequest.Id); + + return GitLabCollectionResponse.Create(resourceMilestoneEvents.Select(rme => rme.ToClientResourceMilestoneEvent())); + } + } + + public GitLabCollectionResponse ResourceStateEventsAsync(int projectId, int mergeRequestIid) + { + using (Context.BeginOperationScope()) + { + var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); + var resourceStateEvents = Server.ResourceStateEvents.Get(mergeRequest.Id); + + return GitLabCollectionResponse.Create(resourceStateEvents.Select(rle => rle.ToClientResourceStateEvent())); + } + } } } diff --git a/NGitLab.Mock/ResourceLabelEventCollection.cs b/NGitLab.Mock/ResourceLabelEventCollection.cs index d48057f6..bb073045 100644 --- a/NGitLab.Mock/ResourceLabelEventCollection.cs +++ b/NGitLab.Mock/ResourceLabelEventCollection.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NGitLab.Models; namespace NGitLab.Mock { @@ -40,5 +41,62 @@ private int GetNewId() { return this.Select(rle => rle.Id).DefaultIfEmpty().Max() + 1; } + + internal void CreateResourceLabelEvents(User currentUser, string[] previousLabels, string[] newLabels, int resourceId, string resourceType) + { + foreach (var label in previousLabels) + { + if (!newLabels.Any(l => string.Equals(l, label, StringComparison.OrdinalIgnoreCase))) + { + Add(new ResourceLabelEvent() + { + Action = ResourceLabelEventAction.Remove, + Label = new Label() { Name = label }, + ResourceId = resourceId, + CreatedAt = DateTime.UtcNow, + Id = Server.GetNewResourceLabelEventId(), + User = new Author() + { + Id = currentUser.Id, + Email = currentUser.Email, + AvatarUrl = currentUser.AvatarUrl, + Name = currentUser.Name, + State = currentUser.State.ToString(), + Username = currentUser.UserName, + CreatedAt = currentUser.CreatedAt, + WebUrl = currentUser.WebUrl, + }, + ResourceType = resourceType, + }); + } + } + + foreach (var label in newLabels) + { + if (!previousLabels.Any(l => string.Equals(l, label, StringComparison.OrdinalIgnoreCase))) + { + Add(new ResourceLabelEvent() + { + Action = ResourceLabelEventAction.Add, + Label = new Label() { Name = label }, + ResourceId = resourceId, + CreatedAt = DateTime.UtcNow, + Id = Server.GetNewResourceLabelEventId(), + User = new Author() + { + Id = currentUser.Id, + Email = currentUser.Email, + AvatarUrl = currentUser.AvatarUrl, + Name = currentUser.Name, + State = currentUser.State.ToString(), + Username = currentUser.UserName, + CreatedAt = currentUser.CreatedAt, + WebUrl = currentUser.WebUrl, + }, + ResourceType = resourceType, + }); + } + } + } } } diff --git a/NGitLab.Mock/ResourceMilestoneEventCollection.cs b/NGitLab.Mock/ResourceMilestoneEventCollection.cs index 1418547f..f75fd78a 100644 --- a/NGitLab.Mock/ResourceMilestoneEventCollection.cs +++ b/NGitLab.Mock/ResourceMilestoneEventCollection.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NGitLab.Models; namespace NGitLab.Mock { @@ -40,5 +41,46 @@ private int GetNewId() { return this.Select(rle => rle.Id).DefaultIfEmpty().Max() + 1; } + + internal void CreateResourceMilestoneEvents(User currentUser, int resourceId, Milestone previousMilestone, Milestone newMilestone, string resourceType) + { + if (previousMilestone is null) + { + CreateResourceMilestoneEvent(currentUser, resourceId, newMilestone, ResourceMilestoneEventAction.Add, resourceType); + } + else if (newMilestone is not null && previousMilestone is not null) + { + if (newMilestone.Id != previousMilestone.Id) + { + CreateResourceMilestoneEvent(currentUser, resourceId, previousMilestone, ResourceMilestoneEventAction.Remove, resourceType); + } + + CreateResourceMilestoneEvent(currentUser, resourceId, newMilestone, ResourceMilestoneEventAction.Add, resourceType); + } + } + + internal void CreateResourceMilestoneEvent(User currentUser, int resourceId, Milestone milestone, ResourceMilestoneEventAction action, string resourceType) + { + Add(new ResourceMilestoneEvent() + { + Action = action, + Milestone = milestone, + ResourceId = resourceId, + CreatedAt = DateTime.UtcNow, + Id = Server.GetNewResourceLabelEventId(), + User = new Author() + { + Id = currentUser.Id, + Email = currentUser.Email, + AvatarUrl = currentUser.AvatarUrl, + Name = currentUser.Name, + State = currentUser.State.ToString(), + Username = currentUser.UserName, + CreatedAt = currentUser.CreatedAt, + WebUrl = currentUser.WebUrl, + }, + ResourceType = resourceType, + }); + } } } diff --git a/NGitLab.Mock/ResourceStateEventCollection.cs b/NGitLab.Mock/ResourceStateEventCollection.cs index 34557005..0123650d 100644 --- a/NGitLab.Mock/ResourceStateEventCollection.cs +++ b/NGitLab.Mock/ResourceStateEventCollection.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NGitLab.Models; namespace NGitLab.Mock { @@ -40,5 +41,28 @@ private int GetNewId() { return this.Select(rle => rle.Id).DefaultIfEmpty().Max() + 1; } + + internal void CreateResourceStateEvent(User currentUser, string state, int id, string resourceType) + { + Add(new ResourceStateEvent() + { + ResourceId = id, + CreatedAt = DateTime.UtcNow, + Id = Server.GetNewResourceLabelEventId(), + State = state, + User = new Author() + { + Id = currentUser.Id, + Email = currentUser.Email, + AvatarUrl = currentUser.AvatarUrl, + Name = currentUser.Name, + State = currentUser.State.ToString(), + Username = currentUser.UserName, + CreatedAt = currentUser.CreatedAt, + WebUrl = currentUser.WebUrl, + }, + ResourceType = resourceType, + }); + } } } diff --git a/NGitLab/IMergeRequestClient.cs b/NGitLab/IMergeRequestClient.cs index ae59bd36..4628a480 100644 --- a/NGitLab/IMergeRequestClient.cs +++ b/NGitLab/IMergeRequestClient.cs @@ -58,5 +58,38 @@ public interface IMergeRequestClient IMergeRequestApprovalClient ApprovalClient(int mergeRequestIid); IEnumerable ClosesIssues(int mergeRequestIid); + + /// + /// Gets the resource label events. + /// + /// url like GET /projects/:id/merge_requests/:merge_request_iid/resource_label_events + /// + /// + /// The project id. + /// The id of the merge request in the project's scope. + /// A collection of the resource label events linked to this merge request. + GitLabCollectionResponse ResourceLabelEventsAsync(int projectId, int mergeRequestIid); + + /// + /// Gets the resource milestone events. + /// + /// url like GET /projects/:id/merge_requests/:merge_request_iid/resource_milestone_events + /// + /// + /// The project id. + /// The id of the merge request in the project's scope. + /// A collection of the resource milestone events linked to this merge request. + GitLabCollectionResponse ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid); + + /// + /// Gets the resource state events. + /// + /// url like GET /projects/:id/merge_requests/:merge_request_iid/resource_state_events + /// + /// + /// The project id. + /// The id of the merge request in the project's scope. + /// A collection of the resource state events linked to this merge request. + GitLabCollectionResponse ResourceStateEventsAsync(int projectId, int mergeRequestIid); } } diff --git a/NGitLab/Impl/MergeRequestClient.cs b/NGitLab/Impl/MergeRequestClient.cs index 8582ce26..01f9ee25 100644 --- a/NGitLab/Impl/MergeRequestClient.cs +++ b/NGitLab/Impl/MergeRequestClient.cs @@ -10,8 +10,11 @@ namespace NGitLab.Impl { public class MergeRequestClient : IMergeRequestClient { - private readonly API _api; + private const string ResourceLabelEventUrl = "/projects/{0}/merge_requests/{1}/resource_label_events"; + private const string ResourceMilestoneEventUrl = "/projects/{0}/merge_requests/{1}/resource_milestone_events"; + private const string ResourceStateEventUrl = "/projects/{0}/merge_requests/{1}/resource_state_events"; private readonly string _projectPath; + private readonly API _api; public MergeRequestClient(API api, int projectId) { @@ -161,5 +164,20 @@ public GitLabCollectionResponse GetVersionsAsync(int mergeR public IMergeRequestApprovalClient ApprovalClient(int mergeRequestIid) => new MergeRequestApprovalClient(_api, _projectPath, mergeRequestIid); public IMergeRequestChangeClient Changes(int mergeRequestIid) => new MergeRequestChangeClient(_api, _projectPath, mergeRequestIid); + + public GitLabCollectionResponse ResourceLabelEventsAsync(int projectId, int mergeRequestIid) + { + return _api.Get().GetAllAsync(string.Format(CultureInfo.InvariantCulture, ResourceLabelEventUrl, projectId, mergeRequestIid)); + } + + public GitLabCollectionResponse ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid) + { + return _api.Get().GetAllAsync(string.Format(CultureInfo.InvariantCulture, ResourceMilestoneEventUrl, projectId, mergeRequestIid)); + } + + public GitLabCollectionResponse ResourceStateEventsAsync(int projectId, int mergeRequestIid) + { + return _api.Get().GetAllAsync(string.Format(CultureInfo.InvariantCulture, ResourceStateEventUrl, projectId, mergeRequestIid)); + } } } diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index c191f5bf..c209dfac 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -353,6 +353,9 @@ NGitLab.IMergeRequestClient.GetVersionsAsync(int mergeRequestIid) -> NGitLab.Git NGitLab.IMergeRequestClient.Rebase(int mergeRequestIid) -> NGitLab.Models.RebaseResult NGitLab.IMergeRequestClient.RebaseAsync(int mergeRequestIid, NGitLab.Models.MergeRequestRebase options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.IMergeRequestClient.Reopen(int mergeRequestIid) -> NGitLab.Models.MergeRequest +NGitLab.IMergeRequestClient.ResourceLabelEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse +NGitLab.IMergeRequestClient.ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse +NGitLab.IMergeRequestClient.ResourceStateEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse NGitLab.IMergeRequestClient.this[int iid].get -> NGitLab.Models.MergeRequest NGitLab.IMergeRequestClient.Update(int mergeRequestIid, NGitLab.Models.MergeRequestUpdate mergeRequest) -> NGitLab.Models.MergeRequest NGitLab.IMergeRequestCommentClient @@ -614,6 +617,9 @@ NGitLab.Impl.MergeRequestClient.MergeRequestClient(NGitLab.Impl.API api, int pro NGitLab.Impl.MergeRequestClient.Rebase(int mergeRequestIid) -> NGitLab.Models.RebaseResult NGitLab.Impl.MergeRequestClient.RebaseAsync(int mergeRequestIid, NGitLab.Models.MergeRequestRebase options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.MergeRequestClient.Reopen(int mergeRequestIid) -> NGitLab.Models.MergeRequest +NGitLab.Impl.MergeRequestClient.ResourceLabelEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse +NGitLab.Impl.MergeRequestClient.ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse +NGitLab.Impl.MergeRequestClient.ResourceStateEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse NGitLab.Impl.MergeRequestClient.this[int iid].get -> NGitLab.Models.MergeRequest NGitLab.Impl.MergeRequestClient.Update(int mergeRequestIid, NGitLab.Models.MergeRequestUpdate mergeRequest) -> NGitLab.Models.MergeRequest NGitLab.Impl.MergeRequestCommentClient From 1ba8140668a8f8eea947a5efb7a939249d35ac8b Mon Sep 17 00:00:00 2001 From: Pascal Richter <85873523+DelphinRP@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:45:00 +0200 Subject: [PATCH 022/122] Add TimeStatsAsync to MergeRequestClient (#543) * Add TimeStatsAsync to MergeRequestClient * Remove projectId parameter from MergeRequestClient TimeStatsAsync method and use _projectPath * fix comment --- NGitLab.Mock/Clients/MergeRequestClient.cs | 5 +++++ NGitLab/IMergeRequestClient.cs | 7 +++++++ NGitLab/Impl/MergeRequestClient.cs | 5 +++++ NGitLab/PublicAPI.Unshipped.txt | 2 ++ 4 files changed, 19 insertions(+) diff --git a/NGitLab.Mock/Clients/MergeRequestClient.cs b/NGitLab.Mock/Clients/MergeRequestClient.cs index 201bd7ad..c06a397e 100644 --- a/NGitLab.Mock/Clients/MergeRequestClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestClient.cs @@ -708,6 +708,11 @@ public GitLabCollectionResponse GetVersionsAsync(int mergeR throw new NotImplementedException(); } + public Task TimeStatsAsync(int mergeRequestIid, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + public IMergeRequestDiscussionClient Discussions(int mergeRequestIid) { AssertProjectId(); diff --git a/NGitLab/IMergeRequestClient.cs b/NGitLab/IMergeRequestClient.cs index 4628a480..54544cb8 100644 --- a/NGitLab/IMergeRequestClient.cs +++ b/NGitLab/IMergeRequestClient.cs @@ -59,6 +59,13 @@ public interface IMergeRequestClient IEnumerable ClosesIssues(int mergeRequestIid); + /// + /// Get time tracking statistics + /// + /// The id of the merge request in the project's scope. + /// The time tracking statistics of the merge request. + Task TimeStatsAsync(int mergeRequestIid, CancellationToken cancellationToken = default); + /// /// Gets the resource label events. /// diff --git a/NGitLab/Impl/MergeRequestClient.cs b/NGitLab/Impl/MergeRequestClient.cs index 01f9ee25..fab19d07 100644 --- a/NGitLab/Impl/MergeRequestClient.cs +++ b/NGitLab/Impl/MergeRequestClient.cs @@ -155,6 +155,11 @@ public GitLabCollectionResponse GetVersionsAsync(int mergeR return _api.Get().GetAllAsync(_projectPath + "/merge_requests/" + mergeRequestIid.ToString(CultureInfo.InvariantCulture) + "/versions"); } + public Task TimeStatsAsync(int mergeRequestIid, CancellationToken cancellationToken = default) + { + return _api.Get().ToAsync(_projectPath + "/merge_requests/" + mergeRequestIid.ToString(CultureInfo.InvariantCulture) + "/time_stats", cancellationToken); + } + public IMergeRequestCommentClient Comments(int mergeRequestIid) => new MergeRequestCommentClient(_api, _projectPath, mergeRequestIid); public IMergeRequestDiscussionClient Discussions(int mergeRequestIid) => new MergeRequestDiscussionClient(_api, _projectPath, mergeRequestIid); diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index c209dfac..5ff74a54 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -357,6 +357,7 @@ NGitLab.IMergeRequestClient.ResourceLabelEventsAsync(int projectId, int mergeReq NGitLab.IMergeRequestClient.ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse NGitLab.IMergeRequestClient.ResourceStateEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse NGitLab.IMergeRequestClient.this[int iid].get -> NGitLab.Models.MergeRequest +NGitLab.IMergeRequestClient.TimeStatsAsync(int mergeRequestIid, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.IMergeRequestClient.Update(int mergeRequestIid, NGitLab.Models.MergeRequestUpdate mergeRequest) -> NGitLab.Models.MergeRequest NGitLab.IMergeRequestCommentClient NGitLab.IMergeRequestCommentClient.Add(NGitLab.Models.MergeRequestComment comment) -> NGitLab.Models.MergeRequestComment @@ -621,6 +622,7 @@ NGitLab.Impl.MergeRequestClient.ResourceLabelEventsAsync(int projectId, int merg NGitLab.Impl.MergeRequestClient.ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse NGitLab.Impl.MergeRequestClient.ResourceStateEventsAsync(int projectId, int mergeRequestIid) -> NGitLab.GitLabCollectionResponse NGitLab.Impl.MergeRequestClient.this[int iid].get -> NGitLab.Models.MergeRequest +NGitLab.Impl.MergeRequestClient.TimeStatsAsync(int mergeRequestIid, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.MergeRequestClient.Update(int mergeRequestIid, NGitLab.Models.MergeRequestUpdate mergeRequest) -> NGitLab.Models.MergeRequest NGitLab.Impl.MergeRequestCommentClient NGitLab.Impl.MergeRequestCommentClient.Add(NGitLab.Models.MergeRequestComment comment) -> NGitLab.Models.MergeRequestComment From 749c590c93471d17ec698c85c72eb1fe8df4842a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 07:31:27 -0400 Subject: [PATCH 023/122] Bump Meziantou.Analyzer from 2.0.94 to 2.0.103 (#551) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.94 to 2.0.103. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.94...2.0.103) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index dd2a5ea0..e292508f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 44157b8406edbcdd5b2f056d20a50535193b0ec1 Mon Sep 17 00:00:00 2001 From: PM Extra Date: Fri, 3 Nov 2023 22:45:48 +0800 Subject: [PATCH 024/122] Support for using URL-encoded paths as group or project ids (#550) * Support long and string id for projects and groups, then obsolete int * Correct MilestoneClient * Replace record types with struct + interface * Fix typo `IIdOrPathAddressable` --------- Co-authored-by: Thomas Cortes <78750681+Toa741@users.noreply.github.com> --- NGitLab.Mock/Clients/ClientBase.cs | 2 +- NGitLab.Mock/Clients/ClusterClient.cs | 4 +- NGitLab.Mock/Clients/CommitClient.cs | 4 +- NGitLab.Mock/Clients/CommitStatusClient.cs | 4 +- NGitLab.Mock/Clients/EnvironmentClient.cs | 4 +- NGitLab.Mock/Clients/EventClient.cs | 4 +- NGitLab.Mock/Clients/GitLabClient.cs | 95 +++++++--- NGitLab.Mock/Clients/GroupBadgeClient.cs | 4 +- NGitLab.Mock/Clients/GroupClient.cs | 2 +- NGitLab.Mock/Clients/GroupSearchClient.cs | 7 +- NGitLab.Mock/Clients/GroupVariableClient.cs | 4 +- NGitLab.Mock/Clients/JobClient.cs | 4 +- NGitLab.Mock/Clients/MergeRequestClient.cs | 4 +- NGitLab.Mock/Clients/MilestoneClient.cs | 9 +- NGitLab.Mock/Clients/PipelineClient.cs | 4 +- NGitLab.Mock/Clients/ProjectBadgeClient.cs | 4 +- .../Clients/ProjectIssueNoteClient.cs | 4 +- .../ProjectLevelApprovalRulesClient.cs | 4 +- NGitLab.Mock/Clients/ProjectSearchClient.cs | 7 +- NGitLab.Mock/Clients/ProjectVariableClient.cs | 4 +- NGitLab.Mock/Clients/ProtectedBranchClient.cs | 4 +- NGitLab.Mock/Clients/ReleaseClient.cs | 4 +- NGitLab.Mock/Clients/RepositoryClient.cs | 4 +- NGitLab.Mock/Clients/TriggerClient.cs | 4 +- NGitLab.Mock/Clients/WikiClient.cs | 4 +- NGitLab.Mock/GroupExtensions.cs | 28 ++- NGitLab.Mock/ProjectExtensions.cs | 33 ++-- NGitLab.Mock/PublicAPI.Unshipped.txt | 6 +- NGitLab/GitLabClient.cs | 170 ++++++++++-------- NGitLab/IGitLabClient.cs | 78 +++++++- NGitLab/Impl/ClusterClient.cs | 12 +- NGitLab/Impl/CommitClient.cs | 12 +- NGitLab/Impl/CommitStatusClient.cs | 16 +- NGitLab/Impl/EnvironmentClient.cs | 8 +- NGitLab/Impl/GroupBadgeClient.cs | 7 +- NGitLab/Impl/GroupVariableClient.cs | 7 +- NGitLab/Impl/JobClient.cs | 8 +- NGitLab/Impl/MergeRequestClient.cs | 8 +- NGitLab/Impl/MilestoneClient.cs | 6 +- NGitLab/Impl/PipelineClient.cs | 10 +- NGitLab/Impl/ProjectBadgeClient.cs | 5 +- NGitLab/Impl/ProjectIssueNoteClient.cs | 13 +- .../Impl/ProjectLevelApprovalRulesClient.cs | 11 +- NGitLab/Impl/ProjectVariableClient.cs | 7 +- NGitLab/Impl/ProtectedBranchClient.cs | 4 +- NGitLab/Impl/ReleaseClient.cs | 6 +- NGitLab/Impl/RepositoryClient.cs | 10 +- NGitLab/Impl/TriggerClient.cs | 11 +- NGitLab/Impl/WikiClient.cs | 9 +- NGitLab/Models/GroupId.cs | 37 ++++ NGitLab/Models/IdOrPathExtensions.cs | 14 ++ NGitLab/Models/IidOrPathAddressable.cs | 11 ++ NGitLab/Models/ProjectId.cs | 37 ++++ NGitLab/PublicAPI.Unshipped.txt | 82 ++++++++- 54 files changed, 622 insertions(+), 242 deletions(-) create mode 100644 NGitLab/Models/GroupId.cs create mode 100644 NGitLab/Models/IdOrPathExtensions.cs create mode 100644 NGitLab/Models/IidOrPathAddressable.cs create mode 100644 NGitLab/Models/ProjectId.cs diff --git a/NGitLab.Mock/Clients/ClientBase.cs b/NGitLab.Mock/Clients/ClientBase.cs index da9e6b2e..ab9868c7 100644 --- a/NGitLab.Mock/Clients/ClientBase.cs +++ b/NGitLab.Mock/Clients/ClientBase.cs @@ -29,7 +29,7 @@ protected Group GetGroup(object id, GroupPermission permissions) var group = id switch { - int idInt => Server.AllGroups.FindGroupById(idInt), + int idInt => Server.AllGroups.FindById(idInt), string idStr => Server.AllGroups.FindGroup(idStr), _ => throw new ArgumentException($"Id of type '{id.GetType()}' is not supported"), }; diff --git a/NGitLab.Mock/Clients/ClusterClient.cs b/NGitLab.Mock/Clients/ClusterClient.cs index 183e477c..f45d36e4 100644 --- a/NGitLab.Mock/Clients/ClusterClient.cs +++ b/NGitLab.Mock/Clients/ClusterClient.cs @@ -8,10 +8,10 @@ internal sealed class ClusterClient : ClientBase, IClusterClient { private readonly int _projectId; - public ClusterClient(ClientContext context, int projectId) + public ClusterClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public IEnumerable All => throw new NotImplementedException(); diff --git a/NGitLab.Mock/Clients/CommitClient.cs b/NGitLab.Mock/Clients/CommitClient.cs index 62d473a0..c5acccbf 100644 --- a/NGitLab.Mock/Clients/CommitClient.cs +++ b/NGitLab.Mock/Clients/CommitClient.cs @@ -9,10 +9,10 @@ internal sealed class CommitClient : ClientBase, ICommitClient { private readonly int _projectId; - public CommitClient(ClientContext context, int projectId) + public CommitClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public Commit Create(CommitCreate commit) diff --git a/NGitLab.Mock/Clients/CommitStatusClient.cs b/NGitLab.Mock/Clients/CommitStatusClient.cs index 0f70a8f6..d124b2ee 100644 --- a/NGitLab.Mock/Clients/CommitStatusClient.cs +++ b/NGitLab.Mock/Clients/CommitStatusClient.cs @@ -9,10 +9,10 @@ internal sealed class CommitStatusClient : ClientBase, ICommitStatusClient { private readonly int _projectId; - public CommitStatusClient(ClientContext context, int projectId) + public CommitStatusClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public CommitStatusCreate AddOrUpdate(CommitStatusCreate status) diff --git a/NGitLab.Mock/Clients/EnvironmentClient.cs b/NGitLab.Mock/Clients/EnvironmentClient.cs index 86a5f7fa..593e2b1b 100644 --- a/NGitLab.Mock/Clients/EnvironmentClient.cs +++ b/NGitLab.Mock/Clients/EnvironmentClient.cs @@ -10,10 +10,10 @@ internal sealed class EnvironmentClient : ClientBase, IEnvironmentClient { private readonly int _projectId; - public EnvironmentClient(ClientContext context, int projectId) + public EnvironmentClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public IEnumerable All => throw new NotImplementedException(); diff --git a/NGitLab.Mock/Clients/EventClient.cs b/NGitLab.Mock/Clients/EventClient.cs index 5c755ddc..4b48d1d4 100644 --- a/NGitLab.Mock/Clients/EventClient.cs +++ b/NGitLab.Mock/Clients/EventClient.cs @@ -14,11 +14,11 @@ public EventClient(ClientContext context) { } - public EventClient(ClientContext context, int? userId = null, int? projectId = null) + public EventClient(ClientContext context, int? userId = null, ProjectId? projectId = null) : base(context) { _userId = userId; - _projectId = projectId; + _projectId = projectId.HasValue ? Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id : null; } IEnumerable IEventClient.Get(EventQuery query) diff --git a/NGitLab.Mock/Clients/GitLabClient.cs b/NGitLab.Mock/Clients/GitLabClient.cs index b5363a23..2ae10d62 100644 --- a/NGitLab.Mock/Clients/GitLabClient.cs +++ b/NGitLab.Mock/Clients/GitLabClient.cs @@ -1,4 +1,5 @@ using NGitLab.Impl; +using NGitLab.Models; namespace NGitLab.Mock.Clients { @@ -19,7 +20,9 @@ public GitLabClient(ClientContext context) public IMembersClient Members => new MembersClient(Context); - public ICommitClient GetCommits(int projectId) => new CommitClient(Context, projectId); + public ICommitClient GetCommits(int projectId) => GetCommits((long)projectId); + + public ICommitClient GetCommits(ProjectId projectId) => new CommitClient(Context, projectId); public IIssueClient Issues => new IssueClient(Context); @@ -55,50 +58,94 @@ public IGraphQLClient GraphQL public IEventClient GetEvents() => new EventClient(Context); - public IEventClient GetUserEvents(int userId) => new EventClient(Context, userId: userId); + public IEventClient GetUserEvents(int userId) => new EventClient(Context, userId); + + public IEventClient GetProjectEvents(int projectId) => GetProjectEvents((long)projectId); + + public IEventClient GetProjectEvents(ProjectId projectId) => new EventClient(Context, null, projectId); + + public ICommitStatusClient GetCommitStatus(int projectId) => GetCommitStatus((long)projectId); + + public ICommitStatusClient GetCommitStatus(ProjectId projectId) => new CommitStatusClient(Context, projectId); + + public IEnvironmentClient GetEnvironmentClient(int projectId) => GetEnvironmentClient((long)projectId); + + public IEnvironmentClient GetEnvironmentClient(ProjectId projectId) => new EnvironmentClient(Context, projectId); + + public IClusterClient GetClusterClient(int projectId) => GetClusterClient((long)projectId); + + public IClusterClient GetClusterClient(ProjectId projectId) => new ClusterClient(Context, projectId); + + public IGroupBadgeClient GetGroupBadgeClient(int groupId) => GetGroupBadgeClient((long)groupId); + + public IGroupBadgeClient GetGroupBadgeClient(GroupId groupId) => new GroupBadgeClient(Context, groupId); + + public IGroupVariableClient GetGroupVariableClient(int groupId) => GetGroupVariableClient((long)groupId); + + public IGroupVariableClient GetGroupVariableClient(GroupId groupId) => new GroupVariableClient(Context, groupId); + + public IJobClient GetJobs(int projectId) => GetJobs((long)projectId); + + public IJobClient GetJobs(ProjectId projectId) => new JobClient(Context, projectId); + + public IMergeRequestClient GetMergeRequest(int projectId) => GetMergeRequest((long)projectId); + + public IMergeRequestClient GetMergeRequest(ProjectId projectId) => new MergeRequestClient(Context, projectId); + + public IMilestoneClient GetMilestone(int projectId) => GetMilestone((long)projectId); + + public IMilestoneClient GetMilestone(ProjectId projectId) => new MilestoneClient(Context, projectId, MilestoneScope.Projects); + + public IMilestoneClient GetGroupMilestone(int groupId) => GetGroupMilestone((long)groupId); + + public IMilestoneClient GetGroupMilestone(GroupId groupId) => new MilestoneClient(Context, groupId, MilestoneScope.Groups); + + public IReleaseClient GetReleases(int projectId) => GetReleases((long)projectId); + + public IReleaseClient GetReleases(ProjectId projectId) => new ReleaseClient(Context, projectId); - public IEventClient GetProjectEvents(int projectId) => new EventClient(Context, projectId: projectId); + public IPipelineClient GetPipelines(int projectId) => GetPipelines((long)projectId); - public ICommitStatusClient GetCommitStatus(int projectId) => new CommitStatusClient(Context, projectId); + public IPipelineClient GetPipelines(ProjectId projectId) => new PipelineClient(Context, jobClient: GetJobs(projectId), projectId: projectId); - public IEnvironmentClient GetEnvironmentClient(int projectId) => new EnvironmentClient(Context, projectId); + public IProjectBadgeClient GetProjectBadgeClient(int projectId) => GetProjectBadgeClient((long)projectId); - public IClusterClient GetClusterClient(int projectId) => new ClusterClient(Context, projectId); + public IProjectBadgeClient GetProjectBadgeClient(ProjectId projectId) => new ProjectBadgeClient(Context, projectId); - public IGroupBadgeClient GetGroupBadgeClient(int groupId) => new GroupBadgeClient(Context, groupId); + public IProjectIssueNoteClient GetProjectIssueNoteClient(int projectId) => GetProjectIssueNoteClient((long)projectId); - public IGroupVariableClient GetGroupVariableClient(int groupId) => new GroupVariableClient(Context, groupId); + public IProjectIssueNoteClient GetProjectIssueNoteClient(ProjectId projectId) => new ProjectIssueNoteClient(Context, projectId); - public IJobClient GetJobs(int projectId) => new JobClient(Context, projectId); + public IProjectVariableClient GetProjectVariableClient(int projectId) => GetProjectVariableClient((long)projectId); - public IMergeRequestClient GetMergeRequest(int projectId) => new MergeRequestClient(Context, projectId); + public IProjectVariableClient GetProjectVariableClient(ProjectId projectId) => new ProjectVariableClient(Context, projectId); - public IMilestoneClient GetMilestone(int projectId) => new MilestoneClient(Context, projectId, MilestoneScope.Projects); + public IRepositoryClient GetRepository(int projectId) => GetRepository((long)projectId); - public IMilestoneClient GetGroupMilestone(int groupId) => new MilestoneClient(Context, groupId, MilestoneScope.Groups); + public IRepositoryClient GetRepository(ProjectId projectId) => new RepositoryClient(Context, projectId); - public IReleaseClient GetReleases(int projectId) => new ReleaseClient(Context, projectId); + public ITriggerClient GetTriggers(int projectId) => GetTriggers((long)projectId); - public IPipelineClient GetPipelines(int projectId) => new PipelineClient(Context, jobClient: GetJobs(projectId), projectId: projectId); + public ITriggerClient GetTriggers(ProjectId projectId) => new TriggerClient(Context, projectId); - public IProjectBadgeClient GetProjectBadgeClient(int projectId) => new ProjectBadgeClient(Context, projectId); + public IWikiClient GetWikiClient(int projectId) => GetWikiClient((long)projectId); - public IProjectIssueNoteClient GetProjectIssueNoteClient(int projectId) => new ProjectIssueNoteClient(Context, projectId); + public IWikiClient GetWikiClient(ProjectId projectId) => new WikiClient(Context, projectId); - public IProjectVariableClient GetProjectVariableClient(int projectId) => new ProjectVariableClient(Context, projectId); + public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId) => GetProjectLevelApprovalRulesClient((long)projectId); - public IRepositoryClient GetRepository(int projectId) => new RepositoryClient(Context, projectId); + public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(ProjectId projectId) => new ProjectLevelApprovalRulesClient(Context, projectId); - public ITriggerClient GetTriggers(int projectId) => new TriggerClient(Context, projectId); + public IProtectedBranchClient GetProtectedBranchClient(int projectId) => GetProtectedBranchClient((long)projectId); - public IWikiClient GetWikiClient(int projectId) => new WikiClient(Context, projectId); + public IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId) => new ProtectedBranchClient(Context, projectId); - public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId) => new ProjectLevelApprovalRulesClient(Context, projectId); + public ISearchClient GetGroupSearchClient(int groupId) => GetGroupSearchClient((long)groupId); - public IProtectedBranchClient GetProtectedBranchClient(int projectId) => new ProtectedBranchClient(Context, projectId); + public ISearchClient GetGroupSearchClient(GroupId groupId) => new GroupSearchClient(Context, groupId); - public ISearchClient GetGroupSearchClient(int groupId) => new GroupSearchClient(Context, groupId); + public ISearchClient GetProjectSearchClient(int projectId) => GetProjectSearchClient((long)projectId); - public ISearchClient GetProjectSearchClient(int projectId) => new ProjectSearchClient(Context, projectId); + public ISearchClient GetProjectSearchClient(ProjectId projectId) => new ProjectSearchClient(Context, projectId); } } diff --git a/NGitLab.Mock/Clients/GroupBadgeClient.cs b/NGitLab.Mock/Clients/GroupBadgeClient.cs index ee1d461c..89a426bd 100644 --- a/NGitLab.Mock/Clients/GroupBadgeClient.cs +++ b/NGitLab.Mock/Clients/GroupBadgeClient.cs @@ -8,10 +8,10 @@ internal sealed class GroupBadgeClient : ClientBase, IGroupBadgeClient { private readonly int _groupId; - public GroupBadgeClient(ClientContext context, int groupId) + public GroupBadgeClient(ClientContext context, GroupId groupId) : base(context) { - _groupId = groupId; + _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; } public Models.Badge this[int id] diff --git a/NGitLab.Mock/Clients/GroupClient.cs b/NGitLab.Mock/Clients/GroupClient.cs index 78ebff51..40eec7d8 100644 --- a/NGitLab.Mock/Clients/GroupClient.cs +++ b/NGitLab.Mock/Clients/GroupClient.cs @@ -235,7 +235,7 @@ public Models.Group Update(int id, GroupUpdate groupUpdate) { using (Context.BeginOperationScope()) { - var group = Server.AllGroups.FindGroupById(id); + var group = Server.AllGroups.FindById(id); if (group == null || !group.CanUserViewGroup(Context.User)) throw new GitLabNotFoundException(); diff --git a/NGitLab.Mock/Clients/GroupSearchClient.cs b/NGitLab.Mock/Clients/GroupSearchClient.cs index a092214d..b9742dba 100644 --- a/NGitLab.Mock/Clients/GroupSearchClient.cs +++ b/NGitLab.Mock/Clients/GroupSearchClient.cs @@ -3,15 +3,16 @@ namespace NGitLab.Mock.Clients { - internal sealed class GroupSearchClient : ISearchClient + internal sealed class GroupSearchClient : ClientBase, ISearchClient { private readonly ClientContext _context; private readonly int _groupId; - public GroupSearchClient(ClientContext context, int groupId) + public GroupSearchClient(ClientContext context, GroupId groupId) + : base(context) { _context = context; - _groupId = groupId; + _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; } public GitLabCollectionResponse GetBlobsAsync(SearchQuery query) diff --git a/NGitLab.Mock/Clients/GroupVariableClient.cs b/NGitLab.Mock/Clients/GroupVariableClient.cs index 6a0b51b1..b681a38c 100644 --- a/NGitLab.Mock/Clients/GroupVariableClient.cs +++ b/NGitLab.Mock/Clients/GroupVariableClient.cs @@ -8,10 +8,10 @@ internal sealed class GroupVariableClient : ClientBase, IGroupVariableClient { private readonly int _groupId; - public GroupVariableClient(ClientContext context, int groupId) + public GroupVariableClient(ClientContext context, GroupId groupId) : base(context) { - _groupId = groupId; + _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; } public Variable this[string key] => throw new NotImplementedException(); diff --git a/NGitLab.Mock/Clients/JobClient.cs b/NGitLab.Mock/Clients/JobClient.cs index aa97a9c9..ca4e5b76 100644 --- a/NGitLab.Mock/Clients/JobClient.cs +++ b/NGitLab.Mock/Clients/JobClient.cs @@ -13,10 +13,10 @@ internal sealed class JobClient : ClientBase, IJobClient { private readonly int _projectId; - public JobClient(ClientContext context, int projectId) + public JobClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public Models.Job Get(int jobId) diff --git a/NGitLab.Mock/Clients/MergeRequestClient.cs b/NGitLab.Mock/Clients/MergeRequestClient.cs index c06a397e..33d7abf4 100644 --- a/NGitLab.Mock/Clients/MergeRequestClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestClient.cs @@ -19,10 +19,10 @@ public MergeRequestClient(ClientContext context) { } - public MergeRequestClient(ClientContext context, int projectId) + public MergeRequestClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } private void AssertProjectId() diff --git a/NGitLab.Mock/Clients/MilestoneClient.cs b/NGitLab.Mock/Clients/MilestoneClient.cs index 0e688f6d..d8b0cf04 100644 --- a/NGitLab.Mock/Clients/MilestoneClient.cs +++ b/NGitLab.Mock/Clients/MilestoneClient.cs @@ -12,10 +12,15 @@ internal sealed class MilestoneClient : ClientBase, IMilestoneClient { private readonly int _resourceId; - public MilestoneClient(ClientContext context, int id, MilestoneScope scope) + public MilestoneClient(ClientContext context, IIdOrPathAddressable id, MilestoneScope scope) : base(context) { - _resourceId = id; + _resourceId = scope switch + { + MilestoneScope.Groups => Server.AllGroups.FindGroup(id.ValueAsUriParameter()).Id, + MilestoneScope.Projects => Server.AllProjects.FindProject(id.ValueAsUriParameter()).Id, + _ => throw new NotSupportedException($"{scope} milestone is not supported yet."), + }; Scope = scope; } diff --git a/NGitLab.Mock/Clients/PipelineClient.cs b/NGitLab.Mock/Clients/PipelineClient.cs index 97c028c6..68a0e517 100644 --- a/NGitLab.Mock/Clients/PipelineClient.cs +++ b/NGitLab.Mock/Clients/PipelineClient.cs @@ -14,11 +14,11 @@ internal sealed class PipelineClient : ClientBase, IPipelineClient private readonly int _projectId; private readonly IJobClient _jobClient; - public PipelineClient(ClientContext context, IJobClient jobClient, int projectId) + public PipelineClient(ClientContext context, IJobClient jobClient, ProjectId projectId) : base(context) { _jobClient = jobClient; - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public Models.Pipeline this[int id] diff --git a/NGitLab.Mock/Clients/ProjectBadgeClient.cs b/NGitLab.Mock/Clients/ProjectBadgeClient.cs index 4eb23a6a..101a6c93 100644 --- a/NGitLab.Mock/Clients/ProjectBadgeClient.cs +++ b/NGitLab.Mock/Clients/ProjectBadgeClient.cs @@ -9,10 +9,10 @@ internal sealed class ProjectBadgeClient : ClientBase, IProjectBadgeClient { private readonly int _projectId; - public ProjectBadgeClient(ClientContext context, int projectId) + public ProjectBadgeClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public Models.Badge this[int id] diff --git a/NGitLab.Mock/Clients/ProjectIssueNoteClient.cs b/NGitLab.Mock/Clients/ProjectIssueNoteClient.cs index 7cd6da56..dd9e7a57 100644 --- a/NGitLab.Mock/Clients/ProjectIssueNoteClient.cs +++ b/NGitLab.Mock/Clients/ProjectIssueNoteClient.cs @@ -8,10 +8,10 @@ internal sealed class ProjectIssueNoteClient : ClientBase, IProjectIssueNoteClie { private readonly int _projectId; - public ProjectIssueNoteClient(ClientContext context, int projectId) + public ProjectIssueNoteClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public Models.ProjectIssueNote Create(ProjectIssueNoteCreate create) diff --git a/NGitLab.Mock/Clients/ProjectLevelApprovalRulesClient.cs b/NGitLab.Mock/Clients/ProjectLevelApprovalRulesClient.cs index 172a027a..c8b50c6a 100644 --- a/NGitLab.Mock/Clients/ProjectLevelApprovalRulesClient.cs +++ b/NGitLab.Mock/Clients/ProjectLevelApprovalRulesClient.cs @@ -8,10 +8,10 @@ internal sealed class ProjectLevelApprovalRulesClient : ClientBase, IProjectLeve { private readonly int _projectId; - public ProjectLevelApprovalRulesClient(ClientContext context, int projectId) + public ProjectLevelApprovalRulesClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public List GetProjectLevelApprovalRules() diff --git a/NGitLab.Mock/Clients/ProjectSearchClient.cs b/NGitLab.Mock/Clients/ProjectSearchClient.cs index 06af83f7..8eea7e93 100644 --- a/NGitLab.Mock/Clients/ProjectSearchClient.cs +++ b/NGitLab.Mock/Clients/ProjectSearchClient.cs @@ -3,15 +3,16 @@ namespace NGitLab.Mock.Clients { - internal sealed class ProjectSearchClient : ISearchClient + internal sealed class ProjectSearchClient : ClientBase, ISearchClient { private readonly ClientContext _context; private readonly int _projectId; - public ProjectSearchClient(ClientContext context, int projectId) + public ProjectSearchClient(ClientContext context, ProjectId projectId) + : base(context) { _context = context; - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public GitLabCollectionResponse GetBlobsAsync(SearchQuery query) diff --git a/NGitLab.Mock/Clients/ProjectVariableClient.cs b/NGitLab.Mock/Clients/ProjectVariableClient.cs index a911d077..082f6432 100644 --- a/NGitLab.Mock/Clients/ProjectVariableClient.cs +++ b/NGitLab.Mock/Clients/ProjectVariableClient.cs @@ -8,10 +8,10 @@ internal sealed class ProjectVariableClient : ClientBase, IProjectVariableClient { private readonly int _projectId; - public ProjectVariableClient(ClientContext context, int projectId) + public ProjectVariableClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public Variable this[string key] => throw new NotImplementedException(); diff --git a/NGitLab.Mock/Clients/ProtectedBranchClient.cs b/NGitLab.Mock/Clients/ProtectedBranchClient.cs index 491a9b54..66d4761f 100644 --- a/NGitLab.Mock/Clients/ProtectedBranchClient.cs +++ b/NGitLab.Mock/Clients/ProtectedBranchClient.cs @@ -8,10 +8,10 @@ internal sealed class ProtectedBranchClient : ClientBase, IProtectedBranchClient { private readonly int _projectId; - public ProtectedBranchClient(ClientContext context, int projectId) + public ProtectedBranchClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public Models.ProtectedBranch GetProtectedBranch(string branchName) diff --git a/NGitLab.Mock/Clients/ReleaseClient.cs b/NGitLab.Mock/Clients/ReleaseClient.cs index 6bf6c2f5..c26595f3 100644 --- a/NGitLab.Mock/Clients/ReleaseClient.cs +++ b/NGitLab.Mock/Clients/ReleaseClient.cs @@ -13,10 +13,10 @@ internal sealed class ReleaseClient : ClientBase, IReleaseClient { private readonly int _projectId; - public ReleaseClient(ClientContext context, int projectId) + public ReleaseClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public IEnumerable All diff --git a/NGitLab.Mock/Clients/RepositoryClient.cs b/NGitLab.Mock/Clients/RepositoryClient.cs index 2d28c937..2e07eb19 100644 --- a/NGitLab.Mock/Clients/RepositoryClient.cs +++ b/NGitLab.Mock/Clients/RepositoryClient.cs @@ -11,10 +11,10 @@ internal sealed class RepositoryClient : ClientBase, IRepositoryClient { private readonly int _projectId; - public RepositoryClient(ClientContext context, int projectId) + public RepositoryClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public ITagClient Tags => new TagClient(Context, _projectId); diff --git a/NGitLab.Mock/Clients/TriggerClient.cs b/NGitLab.Mock/Clients/TriggerClient.cs index 560b686d..054631e9 100644 --- a/NGitLab.Mock/Clients/TriggerClient.cs +++ b/NGitLab.Mock/Clients/TriggerClient.cs @@ -8,10 +8,10 @@ internal sealed class TriggerClient : ClientBase, ITriggerClient { private readonly int _projectId; - public TriggerClient(ClientContext context, int projectId) + public TriggerClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public Trigger this[int id] => throw new NotImplementedException(); diff --git a/NGitLab.Mock/Clients/WikiClient.cs b/NGitLab.Mock/Clients/WikiClient.cs index 35231d0f..10d3bd66 100644 --- a/NGitLab.Mock/Clients/WikiClient.cs +++ b/NGitLab.Mock/Clients/WikiClient.cs @@ -8,10 +8,10 @@ internal sealed class WikiClient : ClientBase, IWikiClient { private readonly int _projectId; - public WikiClient(ClientContext context, int projectId) + public WikiClient(ClientContext context, ProjectId projectId) : base(context) { - _projectId = projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } public WikiPage this[string slug] => throw new NotImplementedException(); diff --git a/NGitLab.Mock/GroupExtensions.cs b/NGitLab.Mock/GroupExtensions.cs index a7ac63fb..7045406a 100644 --- a/NGitLab.Mock/GroupExtensions.cs +++ b/NGitLab.Mock/GroupExtensions.cs @@ -1,34 +1,26 @@ using System; using System.Collections.Generic; -using System.Globalization; +using System.Linq; namespace NGitLab.Mock { public static class GroupExtensions { - public static Group FindGroupById(this IEnumerable groups, int id) + public static Group FindById(this IEnumerable groups, long id) { - foreach (var group in groups) - { - if (group.Id == id) - return group; - } + return groups.FirstOrDefault(group => group.Id == id); + } - return null; + public static Group FindByNamespacedPath(this IEnumerable groups, string pathWithNamespace) + { + return groups.FirstOrDefault(group => string.Equals(group.PathWithNameSpace, pathWithNamespace, StringComparison.Ordinal)); } public static Group FindGroup(this IEnumerable groups, string idOrPathWithNamespace) { - foreach (var group in groups) - { - if (string.Equals(group.PathWithNameSpace, idOrPathWithNamespace, StringComparison.Ordinal)) - return group; - - if (string.Equals(group.Id.ToString(CultureInfo.InvariantCulture), idOrPathWithNamespace, StringComparison.Ordinal)) - return group; - } - - return null; + return long.TryParse(idOrPathWithNamespace, out var id) + ? FindById(groups, id) + : FindByNamespacedPath(groups, idOrPathWithNamespace); } } } diff --git a/NGitLab.Mock/ProjectExtensions.cs b/NGitLab.Mock/ProjectExtensions.cs index 61930219..e1e92233 100644 --- a/NGitLab.Mock/ProjectExtensions.cs +++ b/NGitLab.Mock/ProjectExtensions.cs @@ -1,37 +1,26 @@ using System; using System.Collections.Generic; -using System.Globalization; +using System.Linq; namespace NGitLab.Mock { public static class ProjectExtensions { - public static Project FindProject(this IEnumerable projects, string idOrPathWithNamespace) + public static Project FindById(this IEnumerable projects, long id) { - foreach (var project in projects) - { - if (string.Equals(project.Id.ToString(CultureInfo.InvariantCulture), idOrPathWithNamespace, StringComparison.Ordinal)) - return project; - } - - foreach (var project in projects) - { - if (string.Equals(project.PathWithNamespace, idOrPathWithNamespace, StringComparison.OrdinalIgnoreCase)) - return project; - } - - return null; + return projects.FirstOrDefault(project => project.Id == id); } - public static Project FindById(this IEnumerable projects, int id) + public static Project FindByNamespacedPath(this IEnumerable projects, string pathWithNamespace) { - foreach (var project in projects) - { - if (project.Id == id) - return project; - } + return projects.FirstOrDefault(project => string.Equals(project.PathWithNamespace, pathWithNamespace, StringComparison.OrdinalIgnoreCase)); + } - return null; + public static Project FindProject(this IEnumerable projects, string idOrPathWithNamespace) + { + return long.TryParse(idOrPathWithNamespace, out var id) + ? FindById(projects, id) + : FindByNamespacedPath(projects, idOrPathWithNamespace); } } } diff --git a/NGitLab.Mock/PublicAPI.Unshipped.txt b/NGitLab.Mock/PublicAPI.Unshipped.txt index 2aa6ffc9..159a3e56 100644 --- a/NGitLab.Mock/PublicAPI.Unshipped.txt +++ b/NGitLab.Mock/PublicAPI.Unshipped.txt @@ -1263,9 +1263,11 @@ static NGitLab.Mock.Config.GitLabHelpers.WithProject(this NGitLab.Mock.Config.Gi static NGitLab.Mock.Config.GitLabHelpers.WithTag(this NGitLab.Mock.Config.GitLabCommit commit, string name) -> NGitLab.Mock.Config.GitLabCommit static NGitLab.Mock.Config.GitLabHelpers.WithUser(this NGitLab.Mock.Config.GitLabConfig config, string username, System.Action configure) -> NGitLab.Mock.Config.GitLabConfig static NGitLab.Mock.GitLabClientMockExtensions.WithGraphQLClient(this NGitLab.IGitLabClient client, NGitLab.IGraphQLClient graphQLClient) -> NGitLab.IGitLabClient +static NGitLab.Mock.GroupExtensions.FindById(this System.Collections.Generic.IEnumerable groups, long id) -> NGitLab.Mock.Group +static NGitLab.Mock.GroupExtensions.FindByNamespacedPath(this System.Collections.Generic.IEnumerable groups, string pathWithNamespace) -> NGitLab.Mock.Group static NGitLab.Mock.GroupExtensions.FindGroup(this System.Collections.Generic.IEnumerable groups, string idOrPathWithNamespace) -> NGitLab.Mock.Group -static NGitLab.Mock.GroupExtensions.FindGroupById(this System.Collections.Generic.IEnumerable groups, int id) -> NGitLab.Mock.Group -static NGitLab.Mock.ProjectExtensions.FindById(this System.Collections.Generic.IEnumerable projects, int id) -> NGitLab.Mock.Project +static NGitLab.Mock.ProjectExtensions.FindById(this System.Collections.Generic.IEnumerable projects, long id) -> NGitLab.Mock.Project +static NGitLab.Mock.ProjectExtensions.FindByNamespacedPath(this System.Collections.Generic.IEnumerable projects, string pathWithNamespace) -> NGitLab.Mock.Project static NGitLab.Mock.ProjectExtensions.FindProject(this System.Collections.Generic.IEnumerable projects, string idOrPathWithNamespace) -> NGitLab.Mock.Project static NGitLab.Mock.StringExtensions.Contains(this string source, string toCheck, System.StringComparison comparison) -> bool static NGitLab.Mock.TemporaryDirectory.Create() -> NGitLab.Mock.TemporaryDirectory diff --git a/NGitLab/GitLabClient.cs b/NGitLab/GitLabClient.cs index 9bb61b5e..9fd164fa 100644 --- a/NGitLab/GitLabClient.cs +++ b/NGitLab/GitLabClient.cs @@ -1,6 +1,7 @@ using System; using NGitLab.Extensions; using NGitLab.Impl; +using NGitLab.Models; namespace NGitLab { @@ -95,133 +96,154 @@ private GitLabClient(GitLabCredentials credentials, RequestOptions options) [Obsolete("Use GitLabClient constructor instead")] public static GitLabClient Connect(string hostUrl, string apiToken) - { - return new GitLabClient(hostUrl, apiToken); - } + => new(hostUrl, apiToken); [Obsolete("Use GitLabClient constructor instead")] public static GitLabClient Connect(string hostUrl, string username, string password) - { - return new GitLabClient(hostUrl, username, password); - } + => new(hostUrl, username, password); public IEventClient GetEvents() - { - return new EventClient(_api, "events"); - } + => new EventClient(_api, "events"); public IEventClient GetUserEvents(int userId) - { - return new EventClient(_api, $"users/{userId.ToStringInvariant()}/events"); - } + => new EventClient(_api, $"users/{userId.ToStringInvariant()}/events"); public IEventClient GetProjectEvents(int projectId) - { - return new EventClient(_api, $"projects/{projectId.ToStringInvariant()}/events"); - } + => GetProjectEvents((long)projectId); + + public IEventClient GetProjectEvents(ProjectId projectId) + => new EventClient(_api, $"projects/{projectId.ValueAsUriParameter()}/events"); public IRepositoryClient GetRepository(int projectId) - { - return new RepositoryClient(_api, projectId); - } + => GetRepository((long)projectId); + + public IRepositoryClient GetRepository(ProjectId projectId) + => new RepositoryClient(_api, projectId); public ICommitClient GetCommits(int projectId) - { - return new CommitClient(_api, projectId); - } + => GetCommits((long)projectId); + + public ICommitClient GetCommits(ProjectId projectId) + => new CommitClient(_api, projectId); public ICommitStatusClient GetCommitStatus(int projectId) - { - return new CommitStatusClient(_api, projectId); - } + => GetCommitStatus((long)projectId); + + public ICommitStatusClient GetCommitStatus(ProjectId projectId) + => new CommitStatusClient(_api, projectId); public IPipelineClient GetPipelines(int projectId) - { - return new PipelineClient(_api, projectId); - } + => GetPipelines((long)projectId); + + public IPipelineClient GetPipelines(ProjectId projectId) + => new PipelineClient(_api, projectId); public ITriggerClient GetTriggers(int projectId) - { - return new TriggerClient(_api, projectId); - } + => GetTriggers((long)projectId); + + public ITriggerClient GetTriggers(ProjectId projectId) + => new TriggerClient(_api, projectId); public IJobClient GetJobs(int projectId) - { - return new JobClient(_api, projectId); - } + => GetJobs((long)projectId); + + public IJobClient GetJobs(ProjectId projectId) + => new JobClient(_api, projectId); public IMergeRequestClient GetMergeRequest(int projectId) - { - return new MergeRequestClient(_api, projectId); - } + => GetMergeRequest((long)projectId); + + public IMergeRequestClient GetMergeRequest(ProjectId projectId) + => new MergeRequestClient(_api, projectId); public IMilestoneClient GetMilestone(int projectId) - { - return new MilestoneClient(_api, MilestoneScope.Projects, projectId); - } + => GetMilestone((long)projectId); + + public IMilestoneClient GetMilestone(ProjectId projectId) + => new MilestoneClient(_api, MilestoneScope.Projects, projectId); public IMilestoneClient GetGroupMilestone(int groupId) - { - return new MilestoneClient(_api, MilestoneScope.Groups, groupId); - } + => GetGroupMilestone((long)groupId); + + public IMilestoneClient GetGroupMilestone(GroupId groupId) + => new MilestoneClient(_api, MilestoneScope.Groups, groupId); public IReleaseClient GetReleases(int projectId) - { - return new ReleaseClient(_api, projectId); - } + => GetReleases((long)projectId); + + public IReleaseClient GetReleases(ProjectId projectId) + => new ReleaseClient(_api, projectId); public IProjectIssueNoteClient GetProjectIssueNoteClient(int projectId) - { - return new ProjectIssueNoteClient(_api, projectId); - } + => GetProjectIssueNoteClient((long)projectId); + + public IProjectIssueNoteClient GetProjectIssueNoteClient(ProjectId projectId) + => new ProjectIssueNoteClient(_api, projectId); public IEnvironmentClient GetEnvironmentClient(int projectId) - { - return new EnvironmentClient(_api, projectId); - } + => GetEnvironmentClient((long)projectId); + + public IEnvironmentClient GetEnvironmentClient(ProjectId projectId) + => new EnvironmentClient(_api, projectId); public IClusterClient GetClusterClient(int projectId) - { - return new ClusterClient(_api, projectId); - } + => GetClusterClient((long)projectId); + + public IClusterClient GetClusterClient(ProjectId projectId) + => new ClusterClient(_api, projectId); public IWikiClient GetWikiClient(int projectId) - { - return new WikiClient(_api, projectId); - } + => GetWikiClient((long)projectId); + + public IWikiClient GetWikiClient(ProjectId projectId) + => new WikiClient(_api, projectId); public IProjectBadgeClient GetProjectBadgeClient(int projectId) - { - return new ProjectBadgeClient(_api, projectId); - } + => GetProjectBadgeClient((long)projectId); + + public IProjectBadgeClient GetProjectBadgeClient(ProjectId projectId) + => new ProjectBadgeClient(_api, projectId); public IGroupBadgeClient GetGroupBadgeClient(int groupId) - { - return new GroupBadgeClient(_api, groupId); - } + => GetGroupBadgeClient((long)groupId); + + public IGroupBadgeClient GetGroupBadgeClient(GroupId groupId) + => new GroupBadgeClient(_api, groupId); public IProjectVariableClient GetProjectVariableClient(int projectId) - { - return new ProjectVariableClient(_api, projectId); - } + => GetProjectVariableClient((long)projectId); + + public IProjectVariableClient GetProjectVariableClient(ProjectId projectId) + => new ProjectVariableClient(_api, projectId); public IGroupVariableClient GetGroupVariableClient(int groupId) - { - return new GroupVariableClient(_api, groupId); - } + => GetGroupVariableClient((long)groupId); + + public IGroupVariableClient GetGroupVariableClient(GroupId groupId) + => new GroupVariableClient(_api, groupId); public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId) - { - return new ProjectLevelApprovalRulesClient(_api, projectId); - } + => GetProjectLevelApprovalRulesClient((long)projectId); + + public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(ProjectId projectId) + => new ProjectLevelApprovalRulesClient(_api, projectId); public IProtectedBranchClient GetProtectedBranchClient(int projectId) + => GetProtectedBranchClient((long)projectId); + + public IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId) => new ProtectedBranchClient(_api, projectId); public ISearchClient GetGroupSearchClient(int groupId) - => new SearchClient(_api, $"/groups/{groupId.ToStringInvariant()}/search"); + => GetGroupSearchClient((long)groupId); + + public ISearchClient GetGroupSearchClient(GroupId groupId) + => new SearchClient(_api, $"/groups/{groupId.ValueAsUriParameter()}/search"); public ISearchClient GetProjectSearchClient(int projectId) - => new SearchClient(_api, $"/projects/{projectId.ToStringInvariant()}/search"); + => GetProjectSearchClient((long)projectId); + + public ISearchClient GetProjectSearchClient(ProjectId projectId) + => new SearchClient(_api, $"/projects/{projectId.ValueAsUriParameter()}/search"); } } diff --git a/NGitLab/IGitLabClient.cs b/NGitLab/IGitLabClient.cs index fd60a0da..abdfd87c 100644 --- a/NGitLab/IGitLabClient.cs +++ b/NGitLab/IGitLabClient.cs @@ -1,4 +1,7 @@ -namespace NGitLab +using System; +using NGitLab.Models; + +namespace NGitLab { public interface IGitLabClient { @@ -33,29 +36,64 @@ public interface IGitLabClient /// /// Returns the events that occurred in the specified project. /// - /// + [Obsolete("Use long or namespaced path string as projectId instead.")] IEventClient GetProjectEvents(int projectId); + /// + /// Returns the events that occurred in the specified project. + /// + IEventClient GetProjectEvents(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IRepositoryClient GetRepository(int projectId); + IRepositoryClient GetRepository(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] ICommitClient GetCommits(int projectId); + ICommitClient GetCommits(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] ICommitStatusClient GetCommitStatus(int projectId); + ICommitStatusClient GetCommitStatus(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IPipelineClient GetPipelines(int projectId); + IPipelineClient GetPipelines(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] ITriggerClient GetTriggers(int projectId); + ITriggerClient GetTriggers(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IJobClient GetJobs(int projectId); + IJobClient GetJobs(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IMergeRequestClient GetMergeRequest(int projectId); + IMergeRequestClient GetMergeRequest(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IMilestoneClient GetMilestone(int projectId); + IMilestoneClient GetMilestone(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as groupId instead.")] IMilestoneClient GetGroupMilestone(int groupId); + IMilestoneClient GetGroupMilestone(GroupId groupId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IReleaseClient GetReleases(int projectId); + IReleaseClient GetReleases(ProjectId projectId); + IMembersClient Members { get; } IVersionClient Version { get; } @@ -74,28 +112,64 @@ public interface IGitLabClient ISearchClient AdvancedSearch { get; } + [Obsolete("Use long or namespaced path string as projectId instead.")] IProjectIssueNoteClient GetProjectIssueNoteClient(int projectId); + IProjectIssueNoteClient GetProjectIssueNoteClient(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IEnvironmentClient GetEnvironmentClient(int projectId); + IEnvironmentClient GetEnvironmentClient(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IClusterClient GetClusterClient(int projectId); + IClusterClient GetClusterClient(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IWikiClient GetWikiClient(int projectId); + IWikiClient GetWikiClient(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IProjectBadgeClient GetProjectBadgeClient(int projectId); + IProjectBadgeClient GetProjectBadgeClient(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as groupId instead.")] IGroupBadgeClient GetGroupBadgeClient(int groupId); + IGroupBadgeClient GetGroupBadgeClient(GroupId groupId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IProjectVariableClient GetProjectVariableClient(int projectId); + IProjectVariableClient GetProjectVariableClient(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as groupId instead.")] IGroupVariableClient GetGroupVariableClient(int groupId); + IGroupVariableClient GetGroupVariableClient(GroupId groupId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId); + IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] IProtectedBranchClient GetProtectedBranchClient(int projectId); + IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId); + + [Obsolete("Use long or namespaced path string as groupId instead.")] public ISearchClient GetGroupSearchClient(int groupId); + public ISearchClient GetGroupSearchClient(GroupId groupId); + + [Obsolete("Use long or namespaced path string as projectId instead.")] public ISearchClient GetProjectSearchClient(int projectId); + + public ISearchClient GetProjectSearchClient(ProjectId projectId); } } diff --git a/NGitLab/Impl/ClusterClient.cs b/NGitLab/Impl/ClusterClient.cs index 641a2b33..a74293ed 100644 --- a/NGitLab/Impl/ClusterClient.cs +++ b/NGitLab/Impl/ClusterClient.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; -using NGitLab.Extensions; +using System; +using System.Collections.Generic; using NGitLab.Models; namespace NGitLab.Impl @@ -9,10 +9,16 @@ public class ClusterClient : IClusterClient private readonly API _api; private readonly string _environmentsPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public ClusterClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public ClusterClient(API api, ProjectId projectId) { _api = api; - _environmentsPath = $"{Project.Url}/{projectId.ToStringInvariant()}/clusters"; + _environmentsPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}/clusters"; } public IEnumerable All => _api.Get().GetAll(_environmentsPath); diff --git a/NGitLab/Impl/CommitClient.cs b/NGitLab/Impl/CommitClient.cs index f6ece503..3ab98bfa 100644 --- a/NGitLab/Impl/CommitClient.cs +++ b/NGitLab/Impl/CommitClient.cs @@ -1,6 +1,5 @@ using System; using System.Net; -using NGitLab.Extensions; using NGitLab.Models; namespace NGitLab.Impl @@ -10,12 +9,17 @@ public class CommitClient : ICommitClient private readonly API _api; private readonly string _repoPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public CommitClient(API api, int projectId) + : this(api, (long)projectId) { - _api = api; + } - var projectPath = Project.Url + "/" + projectId.ToStringInvariant(); - _repoPath = projectPath + "/repository"; + public CommitClient(API api, ProjectId projectId) + { + _api = api; + var projectPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}"; + _repoPath = $"{projectPath}/repository"; } public Commit GetCommit(string @ref) diff --git a/NGitLab/Impl/CommitStatusClient.cs b/NGitLab/Impl/CommitStatusClient.cs index 5b33b111..7f18360e 100644 --- a/NGitLab/Impl/CommitStatusClient.cs +++ b/NGitLab/Impl/CommitStatusClient.cs @@ -1,5 +1,5 @@ -using System.Collections.Generic; -using NGitLab.Extensions; +using System; +using System.Collections.Generic; using NGitLab.Models; namespace NGitLab.Impl @@ -10,13 +10,19 @@ public class CommitStatusClient : ICommitStatusClient private readonly string _statusCreatePath; private readonly string _statusPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public CommitStatusClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public CommitStatusClient(API api, ProjectId projectId) { _api = api; - var projectPath = Project.Url + "/" + projectId.ToStringInvariant(); - _statusCreatePath = projectPath + "/statuses"; - _statusPath = projectPath + "/repository/commits"; + var projectPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}"; + _statusCreatePath = $"{projectPath}/statuses"; + _statusPath = $"{projectPath}/repository/commits"; } public IEnumerable AllBySha(string commitSha) => _api.Get().GetAll($"{_statusPath}/{commitSha}/statuses"); diff --git a/NGitLab/Impl/EnvironmentClient.cs b/NGitLab/Impl/EnvironmentClient.cs index 02ebe797..22c517b8 100644 --- a/NGitLab/Impl/EnvironmentClient.cs +++ b/NGitLab/Impl/EnvironmentClient.cs @@ -12,10 +12,16 @@ public class EnvironmentClient : IEnvironmentClient private readonly API _api; private readonly string _environmentsPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public EnvironmentClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public EnvironmentClient(API api, ProjectId projectId) { _api = api; - _environmentsPath = $"{Project.Url}/{projectId.ToStringInvariant()}/environments"; + _environmentsPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}/environments"; } public IEnumerable All => _api.Get().GetAll(_environmentsPath); diff --git a/NGitLab/Impl/GroupBadgeClient.cs b/NGitLab/Impl/GroupBadgeClient.cs index 0fad6140..0cc11340 100644 --- a/NGitLab/Impl/GroupBadgeClient.cs +++ b/NGitLab/Impl/GroupBadgeClient.cs @@ -1,12 +1,11 @@ -using NGitLab.Extensions; -using NGitLab.Models; +using NGitLab.Models; namespace NGitLab.Impl { internal sealed class GroupBadgeClient : BadgeClient, IGroupBadgeClient { - public GroupBadgeClient(API api, int projectId) - : base(api, Group.Url + "/" + projectId.ToStringInvariant()) + public GroupBadgeClient(API api, GroupId groupId) + : base(api, $"{Group.Url}/{groupId.ValueAsUriParameter()}") { } } diff --git a/NGitLab/Impl/GroupVariableClient.cs b/NGitLab/Impl/GroupVariableClient.cs index 4e1ac2cb..58ef94a5 100644 --- a/NGitLab/Impl/GroupVariableClient.cs +++ b/NGitLab/Impl/GroupVariableClient.cs @@ -1,12 +1,11 @@ -using NGitLab.Extensions; -using NGitLab.Models; +using NGitLab.Models; namespace NGitLab.Impl { internal sealed class GroupVariableClient : VariableClient, IGroupVariableClient { - public GroupVariableClient(API api, int groupId) - : base(api, Group.Url + $"/{groupId.ToStringInvariant()}") + public GroupVariableClient(API api, GroupId groupId) + : base(api, $"{Group.Url}/{groupId.ValueAsUriParameter()}") { } } diff --git a/NGitLab/Impl/JobClient.cs b/NGitLab/Impl/JobClient.cs index 334eb784..473b4a2d 100644 --- a/NGitLab/Impl/JobClient.cs +++ b/NGitLab/Impl/JobClient.cs @@ -13,10 +13,16 @@ public class JobClient : IJobClient private readonly API _api; private readonly string _jobsPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public JobClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public JobClient(API api, ProjectId projectId) { _api = api; - _jobsPath = $"{Project.Url}/{projectId.ToStringInvariant()}/jobs"; + _jobsPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}/jobs"; } public IEnumerable GetJobs(JobScopeMask scope) diff --git a/NGitLab/Impl/MergeRequestClient.cs b/NGitLab/Impl/MergeRequestClient.cs index fab19d07..d8796266 100644 --- a/NGitLab/Impl/MergeRequestClient.cs +++ b/NGitLab/Impl/MergeRequestClient.cs @@ -16,10 +16,16 @@ public class MergeRequestClient : IMergeRequestClient private readonly string _projectPath; private readonly API _api; + [Obsolete("Use long or namespaced path string as projectId instead.")] public MergeRequestClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public MergeRequestClient(API api, ProjectId projectId) { _api = api; - _projectPath = Project.Url + "/" + projectId.ToStringInvariant(); + _projectPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}"; } public MergeRequestClient(API api) diff --git a/NGitLab/Impl/MilestoneClient.cs b/NGitLab/Impl/MilestoneClient.cs index 5e0c00e6..4a4dcb84 100644 --- a/NGitLab/Impl/MilestoneClient.cs +++ b/NGitLab/Impl/MilestoneClient.cs @@ -12,16 +12,16 @@ public class MilestoneClient : IMilestoneClient private readonly API _api; private readonly string _milestonePath; - internal MilestoneClient(API api, MilestoneScope scope, int id) + internal MilestoneClient(API api, MilestoneScope scope, IIdOrPathAddressable id) { _api = api; - _milestonePath = $"/{scope.ToString().ToLowerInvariant()}/{id.ToStringInvariant()}/milestones"; + _milestonePath = $"/{scope.ToString().ToLowerInvariant()}/{id.ValueAsUriParameter()}/milestones"; Scope = scope; } [Obsolete("Use GitLabClient.GetMilestone() or GitLabClient.GetGroupMilestone() instead.")] public MilestoneClient(API api, int projectId) - : this(api, MilestoneScope.Projects, projectId) + : this(api, MilestoneScope.Projects, (ProjectId)projectId) { } diff --git a/NGitLab/Impl/PipelineClient.cs b/NGitLab/Impl/PipelineClient.cs index 6f9305ac..31ba7d7a 100644 --- a/NGitLab/Impl/PipelineClient.cs +++ b/NGitLab/Impl/PipelineClient.cs @@ -15,11 +15,17 @@ public class PipelineClient : IPipelineClient private readonly string _projectPath; private readonly string _pipelinesPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public PipelineClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public PipelineClient(API api, ProjectId projectId) { _api = api; - _projectPath = $"{Project.Url}/{projectId.ToStringInvariant()}"; - _pipelinesPath = $"{Project.Url}/{projectId.ToStringInvariant()}/pipelines"; + _projectPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}"; + _pipelinesPath = $"{_projectPath}/pipelines"; } public IEnumerable All => _api.Get().GetAll(_pipelinesPath); diff --git a/NGitLab/Impl/ProjectBadgeClient.cs b/NGitLab/Impl/ProjectBadgeClient.cs index 2104b309..2712d88c 100644 --- a/NGitLab/Impl/ProjectBadgeClient.cs +++ b/NGitLab/Impl/ProjectBadgeClient.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; using System.Linq; -using NGitLab.Extensions; using NGitLab.Models; namespace NGitLab.Impl { internal sealed class ProjectBadgeClient : BadgeClient, IProjectBadgeClient { - public ProjectBadgeClient(API api, int projectId) - : base(api, Project.Url + $"/{projectId.ToStringInvariant()}") + public ProjectBadgeClient(API api, ProjectId projectId) + : base(api, $"{Project.Url}/{projectId.ValueAsUriParameter()}") { } diff --git a/NGitLab/Impl/ProjectIssueNoteClient.cs b/NGitLab/Impl/ProjectIssueNoteClient.cs index be938958..1ac9c255 100644 --- a/NGitLab/Impl/ProjectIssueNoteClient.cs +++ b/NGitLab/Impl/ProjectIssueNoteClient.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using NGitLab.Models; namespace NGitLab.Impl @@ -9,12 +10,18 @@ public class ProjectIssueNoteClient : IProjectIssueNoteClient private const string SingleNoteIssueUrl = "/projects/{0}/issues/{1}/notes/{2}"; private readonly API _api; - private readonly int _projectId; + private readonly string _projectId; + [Obsolete("Use long or namespaced path string as projectId instead.")] public ProjectIssueNoteClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public ProjectIssueNoteClient(API api, ProjectId projectId) { _api = api; - _projectId = projectId; + _projectId = projectId.ValueAsUriParameter(); } public IEnumerable ForIssue(int issueId) diff --git a/NGitLab/Impl/ProjectLevelApprovalRulesClient.cs b/NGitLab/Impl/ProjectLevelApprovalRulesClient.cs index cc2379b3..e8a747da 100644 --- a/NGitLab/Impl/ProjectLevelApprovalRulesClient.cs +++ b/NGitLab/Impl/ProjectLevelApprovalRulesClient.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using NGitLab.Extensions; using NGitLab.Models; @@ -9,10 +10,16 @@ public class ProjectLevelApprovalRulesClient : IProjectLevelApprovalRulesClient private readonly API _api; private readonly string _approvalRulesUrl; + [Obsolete("Use long or namespaced path string as projectId instead.")] public ProjectLevelApprovalRulesClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public ProjectLevelApprovalRulesClient(API api, ProjectId projectId) { _api = api; - _approvalRulesUrl = $"{Project.Url}/{projectId.ToStringInvariant()}/approval_rules"; + _approvalRulesUrl = $"{Project.Url}/{projectId.ValueAsUriParameter()}/approval_rules"; } public List GetProjectLevelApprovalRules() diff --git a/NGitLab/Impl/ProjectVariableClient.cs b/NGitLab/Impl/ProjectVariableClient.cs index 882b705f..a896ec12 100644 --- a/NGitLab/Impl/ProjectVariableClient.cs +++ b/NGitLab/Impl/ProjectVariableClient.cs @@ -1,12 +1,11 @@ -using NGitLab.Extensions; -using NGitLab.Models; +using NGitLab.Models; namespace NGitLab.Impl { internal sealed class ProjectVariableClient : VariableClient, IProjectVariableClient { - public ProjectVariableClient(API api, int projectId) - : base(api, Project.Url + $"/{projectId.ToStringInvariant()}") + public ProjectVariableClient(API api, ProjectId projectId) + : base(api, $"{Project.Url}/{projectId.ValueAsUriParameter()}") { } } diff --git a/NGitLab/Impl/ProtectedBranchClient.cs b/NGitLab/Impl/ProtectedBranchClient.cs index 2cf1ffb8..e6cc5263 100644 --- a/NGitLab/Impl/ProtectedBranchClient.cs +++ b/NGitLab/Impl/ProtectedBranchClient.cs @@ -9,10 +9,10 @@ internal sealed class ProtectedBranchClient : IProtectedBranchClient private readonly API _api; private readonly string _protectedBranchesUrl; - public ProtectedBranchClient(API api, int projectId) + public ProtectedBranchClient(API api, ProjectId projectId) { _api = api; - _protectedBranchesUrl = $"{Project.Url}/{projectId.ToStringInvariant()}/protected_branches"; + _protectedBranchesUrl = $"{Project.Url}/{projectId.ValueAsUriParameter()}/protected_branches"; } public ProtectedBranch ProtectBranch(BranchProtect branchProtect) diff --git a/NGitLab/Impl/ReleaseClient.cs b/NGitLab/Impl/ReleaseClient.cs index 09c96bba..32572cbf 100644 --- a/NGitLab/Impl/ReleaseClient.cs +++ b/NGitLab/Impl/ReleaseClient.cs @@ -14,11 +14,11 @@ internal sealed class ReleaseClient : IReleaseClient private readonly API _api; private readonly string _releasesPath; - public ReleaseClient(API api, int projectId) + public ReleaseClient(API api, ProjectId projectId) { _api = api; - var projectPath = Project.Url + "/" + projectId.ToStringInvariant(); - _releasesPath = projectPath + "/releases"; + var projectPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}"; + _releasesPath = $"{projectPath}/releases"; } public IEnumerable All => _api.Get().GetAll(_releasesPath); diff --git a/NGitLab/Impl/RepositoryClient.cs b/NGitLab/Impl/RepositoryClient.cs index 126a65ca..aa615a1e 100644 --- a/NGitLab/Impl/RepositoryClient.cs +++ b/NGitLab/Impl/RepositoryClient.cs @@ -14,11 +14,17 @@ public class RepositoryClient : IRepositoryClient private readonly string _repoPath; private readonly string _projectPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public RepositoryClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public RepositoryClient(API api, ProjectId projectId) { _api = api; - _projectPath = Project.Url + "/" + projectId.ToStringInvariant(); - _repoPath = _projectPath + "/repository"; + _projectPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}"; + _repoPath = $"{_projectPath}/repository"; } public ITagClient Tags => new TagClient(_api, _repoPath); diff --git a/NGitLab/Impl/TriggerClient.cs b/NGitLab/Impl/TriggerClient.cs index e808389b..e868fc1a 100644 --- a/NGitLab/Impl/TriggerClient.cs +++ b/NGitLab/Impl/TriggerClient.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using NGitLab.Extensions; using NGitLab.Models; @@ -9,10 +10,16 @@ public class TriggerClient : ITriggerClient private readonly API _api; private readonly string _triggersPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public TriggerClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public TriggerClient(API api, ProjectId projectId) { _api = api; - _triggersPath = $"{Project.Url}/{projectId.ToStringInvariant()}/triggers"; + _triggersPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}/triggers"; } public Trigger this[int id] => _api.Get().To(_triggersPath + "/" + id.ToStringInvariant()); diff --git a/NGitLab/Impl/WikiClient.cs b/NGitLab/Impl/WikiClient.cs index c603d87a..441f6c85 100644 --- a/NGitLab/Impl/WikiClient.cs +++ b/NGitLab/Impl/WikiClient.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Net; -using NGitLab.Extensions; using NGitLab.Models; namespace NGitLab.Impl @@ -11,10 +10,16 @@ public class WikiClient : IWikiClient private readonly API _api; private readonly string _projectPath; + [Obsolete("Use long or namespaced path string as projectId instead.")] public WikiClient(API api, int projectId) + : this(api, (long)projectId) + { + } + + public WikiClient(API api, ProjectId projectId) { _api = api; - _projectPath = Project.Url + "/" + projectId.ToStringInvariant(); + _projectPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}"; } public IEnumerable All => _api.Get().GetAll(_projectPath + "/wikis"); diff --git a/NGitLab/Models/GroupId.cs b/NGitLab/Models/GroupId.cs new file mode 100644 index 00000000..800daefd --- /dev/null +++ b/NGitLab/Models/GroupId.cs @@ -0,0 +1,37 @@ +using System; + +namespace NGitLab.Models +{ + public readonly struct GroupId : IIdOrPathAddressable + { + private readonly long _id; + private readonly string _path; + + long IIdOrPathAddressable.Id => _id; + + string IIdOrPathAddressable.Path => _path; + + public GroupId(long id) + { + _id = id; + } + + public GroupId(string path) + { + _path = path ?? throw new ArgumentNullException(nameof(path)); + } + + public GroupId(Group group) + { + _id = group?.Id ?? throw new ArgumentNullException(nameof(group)); + } + + public static implicit operator GroupId(long id) => new(id); + + public static implicit operator GroupId(string path) => new(path); + + public static implicit operator GroupId(Group group) => new(group); + + public override string ToString() => this.ValueAsString(); + } +} diff --git a/NGitLab/Models/IdOrPathExtensions.cs b/NGitLab/Models/IdOrPathExtensions.cs new file mode 100644 index 00000000..55fec516 --- /dev/null +++ b/NGitLab/Models/IdOrPathExtensions.cs @@ -0,0 +1,14 @@ +using System; +using NGitLab.Extensions; + +namespace NGitLab.Models +{ + public static class IdOrPathExtensions + { + public static string ValueAsString(this IIdOrPathAddressable idOrPath) + => idOrPath.Path ?? idOrPath.Id.ToStringInvariant(); + + public static string ValueAsUriParameter(this IIdOrPathAddressable idOrPath) + => idOrPath.Path is null ? idOrPath.Id.ToStringInvariant() : Uri.EscapeDataString(idOrPath.Path); + } +} diff --git a/NGitLab/Models/IidOrPathAddressable.cs b/NGitLab/Models/IidOrPathAddressable.cs new file mode 100644 index 00000000..4d5cec8f --- /dev/null +++ b/NGitLab/Models/IidOrPathAddressable.cs @@ -0,0 +1,11 @@ +#nullable enable + +namespace NGitLab.Models +{ + public interface IIdOrPathAddressable + { + internal long Id { get; } + + internal string? Path { get; } + } +} diff --git a/NGitLab/Models/ProjectId.cs b/NGitLab/Models/ProjectId.cs new file mode 100644 index 00000000..61b44443 --- /dev/null +++ b/NGitLab/Models/ProjectId.cs @@ -0,0 +1,37 @@ +using System; + +namespace NGitLab.Models +{ + public readonly struct ProjectId : IIdOrPathAddressable + { + private readonly long _id; + private readonly string _path; + + long IIdOrPathAddressable.Id => _id; + + string IIdOrPathAddressable.Path => _path; + + public ProjectId(long id) + { + _id = id; + } + + public ProjectId(string path) + { + _path = path ?? throw new ArgumentNullException(nameof(path)); + } + + public ProjectId(Project project) + { + _id = project?.Id ?? throw new ArgumentNullException(nameof(project)); + } + + public static implicit operator ProjectId(long id) => new(id); + + public static implicit operator ProjectId(string path) => new(path); + + public static implicit operator ProjectId(Project project) => new(project); + + public override string ToString() => this.ValueAsString(); + } +} diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index 5ff74a54..367915e9 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -1,4 +1,4 @@ -abstract NGitLab.GitLabCollectionResponse.GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerator +abstract NGitLab.GitLabCollectionResponse.GetAsyncEnumerator(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Collections.Generic.IAsyncEnumerator abstract NGitLab.GitLabCollectionResponse.GetEnumerator() -> System.Collections.Generic.IEnumerator const NGitLab.Impl.GroupsClient.Url = "/groups" -> string const NGitLab.Impl.LabelClient.GroupLabelUrl = "/groups/{0}/labels" -> string @@ -44,30 +44,53 @@ NGitLab.GitLabClient.AdvancedSearch.get -> NGitLab.ISearchClient NGitLab.GitLabClient.Deployments.get -> NGitLab.IDeploymentClient NGitLab.GitLabClient.Epics.get -> NGitLab.IEpicClient NGitLab.GitLabClient.GetClusterClient(int projectId) -> NGitLab.IClusterClient +NGitLab.GitLabClient.GetClusterClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IClusterClient NGitLab.GitLabClient.GetCommits(int projectId) -> NGitLab.ICommitClient +NGitLab.GitLabClient.GetCommits(NGitLab.Models.ProjectId projectId) -> NGitLab.ICommitClient NGitLab.GitLabClient.GetCommitStatus(int projectId) -> NGitLab.ICommitStatusClient +NGitLab.GitLabClient.GetCommitStatus(NGitLab.Models.ProjectId projectId) -> NGitLab.ICommitStatusClient NGitLab.GitLabClient.GetEnvironmentClient(int projectId) -> NGitLab.IEnvironmentClient +NGitLab.GitLabClient.GetEnvironmentClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IEnvironmentClient NGitLab.GitLabClient.GetEvents() -> NGitLab.IEventClient NGitLab.GitLabClient.GetGroupBadgeClient(int groupId) -> NGitLab.IGroupBadgeClient +NGitLab.GitLabClient.GetGroupBadgeClient(NGitLab.Models.GroupId groupId) -> NGitLab.IGroupBadgeClient NGitLab.GitLabClient.GetGroupMilestone(int groupId) -> NGitLab.IMilestoneClient +NGitLab.GitLabClient.GetGroupMilestone(NGitLab.Models.GroupId groupId) -> NGitLab.IMilestoneClient NGitLab.GitLabClient.GetGroupSearchClient(int groupId) -> NGitLab.ISearchClient +NGitLab.GitLabClient.GetGroupSearchClient(NGitLab.Models.GroupId groupId) -> NGitLab.ISearchClient NGitLab.GitLabClient.GetGroupVariableClient(int groupId) -> NGitLab.IGroupVariableClient +NGitLab.GitLabClient.GetGroupVariableClient(NGitLab.Models.GroupId groupId) -> NGitLab.IGroupVariableClient NGitLab.GitLabClient.GetJobs(int projectId) -> NGitLab.IJobClient +NGitLab.GitLabClient.GetJobs(NGitLab.Models.ProjectId projectId) -> NGitLab.IJobClient NGitLab.GitLabClient.GetMergeRequest(int projectId) -> NGitLab.IMergeRequestClient +NGitLab.GitLabClient.GetMergeRequest(NGitLab.Models.ProjectId projectId) -> NGitLab.IMergeRequestClient NGitLab.GitLabClient.GetMilestone(int projectId) -> NGitLab.IMilestoneClient +NGitLab.GitLabClient.GetMilestone(NGitLab.Models.ProjectId projectId) -> NGitLab.IMilestoneClient NGitLab.GitLabClient.GetPipelines(int projectId) -> NGitLab.IPipelineClient +NGitLab.GitLabClient.GetPipelines(NGitLab.Models.ProjectId projectId) -> NGitLab.IPipelineClient NGitLab.GitLabClient.GetProjectBadgeClient(int projectId) -> NGitLab.IProjectBadgeClient +NGitLab.GitLabClient.GetProjectBadgeClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectBadgeClient NGitLab.GitLabClient.GetProjectEvents(int projectId) -> NGitLab.IEventClient +NGitLab.GitLabClient.GetProjectEvents(NGitLab.Models.ProjectId projectId) -> NGitLab.IEventClient NGitLab.GitLabClient.GetProjectIssueNoteClient(int projectId) -> NGitLab.IProjectIssueNoteClient +NGitLab.GitLabClient.GetProjectIssueNoteClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectIssueNoteClient NGitLab.GitLabClient.GetProjectLevelApprovalRulesClient(int projectId) -> NGitLab.IProjectLevelApprovalRulesClient +NGitLab.GitLabClient.GetProjectLevelApprovalRulesClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectLevelApprovalRulesClient NGitLab.GitLabClient.GetProjectSearchClient(int projectId) -> NGitLab.ISearchClient +NGitLab.GitLabClient.GetProjectSearchClient(NGitLab.Models.ProjectId projectId) -> NGitLab.ISearchClient NGitLab.GitLabClient.GetProjectVariableClient(int projectId) -> NGitLab.IProjectVariableClient +NGitLab.GitLabClient.GetProjectVariableClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectVariableClient NGitLab.GitLabClient.GetProtectedBranchClient(int projectId) -> NGitLab.IProtectedBranchClient +NGitLab.GitLabClient.GetProtectedBranchClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProtectedBranchClient NGitLab.GitLabClient.GetReleases(int projectId) -> NGitLab.IReleaseClient +NGitLab.GitLabClient.GetReleases(NGitLab.Models.ProjectId projectId) -> NGitLab.IReleaseClient NGitLab.GitLabClient.GetRepository(int projectId) -> NGitLab.IRepositoryClient +NGitLab.GitLabClient.GetRepository(NGitLab.Models.ProjectId projectId) -> NGitLab.IRepositoryClient NGitLab.GitLabClient.GetTriggers(int projectId) -> NGitLab.ITriggerClient +NGitLab.GitLabClient.GetTriggers(NGitLab.Models.ProjectId projectId) -> NGitLab.ITriggerClient NGitLab.GitLabClient.GetUserEvents(int userId) -> NGitLab.IEventClient NGitLab.GitLabClient.GetWikiClient(int projectId) -> NGitLab.IWikiClient +NGitLab.GitLabClient.GetWikiClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IWikiClient NGitLab.GitLabClient.GitLabClient(string hostUrl, string apiToken) -> void NGitLab.GitLabClient.GitLabClient(string hostUrl, string apiToken, NGitLab.RequestOptions options) -> void NGitLab.GitLabClient.GitLabClient(string hostUrl, string userName, string password) -> void @@ -161,30 +184,53 @@ NGitLab.IGitLabClient.AdvancedSearch.get -> NGitLab.ISearchClient NGitLab.IGitLabClient.Deployments.get -> NGitLab.IDeploymentClient NGitLab.IGitLabClient.Epics.get -> NGitLab.IEpicClient NGitLab.IGitLabClient.GetClusterClient(int projectId) -> NGitLab.IClusterClient +NGitLab.IGitLabClient.GetClusterClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IClusterClient NGitLab.IGitLabClient.GetCommits(int projectId) -> NGitLab.ICommitClient +NGitLab.IGitLabClient.GetCommits(NGitLab.Models.ProjectId projectId) -> NGitLab.ICommitClient NGitLab.IGitLabClient.GetCommitStatus(int projectId) -> NGitLab.ICommitStatusClient +NGitLab.IGitLabClient.GetCommitStatus(NGitLab.Models.ProjectId projectId) -> NGitLab.ICommitStatusClient NGitLab.IGitLabClient.GetEnvironmentClient(int projectId) -> NGitLab.IEnvironmentClient +NGitLab.IGitLabClient.GetEnvironmentClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IEnvironmentClient NGitLab.IGitLabClient.GetEvents() -> NGitLab.IEventClient NGitLab.IGitLabClient.GetGroupBadgeClient(int groupId) -> NGitLab.IGroupBadgeClient +NGitLab.IGitLabClient.GetGroupBadgeClient(NGitLab.Models.GroupId groupId) -> NGitLab.IGroupBadgeClient NGitLab.IGitLabClient.GetGroupMilestone(int groupId) -> NGitLab.IMilestoneClient +NGitLab.IGitLabClient.GetGroupMilestone(NGitLab.Models.GroupId groupId) -> NGitLab.IMilestoneClient NGitLab.IGitLabClient.GetGroupSearchClient(int groupId) -> NGitLab.ISearchClient +NGitLab.IGitLabClient.GetGroupSearchClient(NGitLab.Models.GroupId groupId) -> NGitLab.ISearchClient NGitLab.IGitLabClient.GetGroupVariableClient(int groupId) -> NGitLab.IGroupVariableClient +NGitLab.IGitLabClient.GetGroupVariableClient(NGitLab.Models.GroupId groupId) -> NGitLab.IGroupVariableClient NGitLab.IGitLabClient.GetJobs(int projectId) -> NGitLab.IJobClient +NGitLab.IGitLabClient.GetJobs(NGitLab.Models.ProjectId projectId) -> NGitLab.IJobClient NGitLab.IGitLabClient.GetMergeRequest(int projectId) -> NGitLab.IMergeRequestClient +NGitLab.IGitLabClient.GetMergeRequest(NGitLab.Models.ProjectId projectId) -> NGitLab.IMergeRequestClient NGitLab.IGitLabClient.GetMilestone(int projectId) -> NGitLab.IMilestoneClient +NGitLab.IGitLabClient.GetMilestone(NGitLab.Models.ProjectId projectId) -> NGitLab.IMilestoneClient NGitLab.IGitLabClient.GetPipelines(int projectId) -> NGitLab.IPipelineClient +NGitLab.IGitLabClient.GetPipelines(NGitLab.Models.ProjectId projectId) -> NGitLab.IPipelineClient NGitLab.IGitLabClient.GetProjectBadgeClient(int projectId) -> NGitLab.IProjectBadgeClient +NGitLab.IGitLabClient.GetProjectBadgeClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectBadgeClient NGitLab.IGitLabClient.GetProjectEvents(int projectId) -> NGitLab.IEventClient +NGitLab.IGitLabClient.GetProjectEvents(NGitLab.Models.ProjectId projectId) -> NGitLab.IEventClient NGitLab.IGitLabClient.GetProjectIssueNoteClient(int projectId) -> NGitLab.IProjectIssueNoteClient +NGitLab.IGitLabClient.GetProjectIssueNoteClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectIssueNoteClient NGitLab.IGitLabClient.GetProjectLevelApprovalRulesClient(int projectId) -> NGitLab.IProjectLevelApprovalRulesClient +NGitLab.IGitLabClient.GetProjectLevelApprovalRulesClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectLevelApprovalRulesClient NGitLab.IGitLabClient.GetProjectSearchClient(int projectId) -> NGitLab.ISearchClient +NGitLab.IGitLabClient.GetProjectSearchClient(NGitLab.Models.ProjectId projectId) -> NGitLab.ISearchClient NGitLab.IGitLabClient.GetProjectVariableClient(int projectId) -> NGitLab.IProjectVariableClient +NGitLab.IGitLabClient.GetProjectVariableClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectVariableClient NGitLab.IGitLabClient.GetProtectedBranchClient(int projectId) -> NGitLab.IProtectedBranchClient +NGitLab.IGitLabClient.GetProtectedBranchClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProtectedBranchClient NGitLab.IGitLabClient.GetReleases(int projectId) -> NGitLab.IReleaseClient +NGitLab.IGitLabClient.GetReleases(NGitLab.Models.ProjectId projectId) -> NGitLab.IReleaseClient NGitLab.IGitLabClient.GetRepository(int projectId) -> NGitLab.IRepositoryClient +NGitLab.IGitLabClient.GetRepository(NGitLab.Models.ProjectId projectId) -> NGitLab.IRepositoryClient NGitLab.IGitLabClient.GetTriggers(int projectId) -> NGitLab.ITriggerClient +NGitLab.IGitLabClient.GetTriggers(NGitLab.Models.ProjectId projectId) -> NGitLab.ITriggerClient NGitLab.IGitLabClient.GetUserEvents(int userId) -> NGitLab.IEventClient NGitLab.IGitLabClient.GetWikiClient(int projectId) -> NGitLab.IWikiClient +NGitLab.IGitLabClient.GetWikiClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IWikiClient NGitLab.IGitLabClient.GraphQL.get -> NGitLab.IGraphQLClient NGitLab.IGitLabClient.Groups.get -> NGitLab.IGroupsClient NGitLab.IGitLabClient.Issues.get -> NGitLab.IIssueClient @@ -413,9 +459,11 @@ NGitLab.Impl.BranchClient.Unprotect(string name) -> NGitLab.Models.Branch NGitLab.Impl.ClusterClient NGitLab.Impl.ClusterClient.All.get -> System.Collections.Generic.IEnumerable NGitLab.Impl.ClusterClient.ClusterClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.ClusterClient.ClusterClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.CommitClient NGitLab.Impl.CommitClient.CherryPick(NGitLab.Models.CommitCherryPick cherryPick) -> NGitLab.Models.Commit NGitLab.Impl.CommitClient.CommitClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.CommitClient.CommitClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.CommitClient.Create(NGitLab.Models.CommitCreate commit) -> NGitLab.Models.Commit NGitLab.Impl.CommitClient.GetCommit(string ref) -> NGitLab.Models.Commit NGitLab.Impl.CommitClient.GetJobStatus(string branchName) -> NGitLab.JobStatus @@ -424,6 +472,7 @@ NGitLab.Impl.CommitStatusClient NGitLab.Impl.CommitStatusClient.AddOrUpdate(NGitLab.Models.CommitStatusCreate status) -> NGitLab.Models.CommitStatusCreate NGitLab.Impl.CommitStatusClient.AllBySha(string commitSha) -> System.Collections.Generic.IEnumerable NGitLab.Impl.CommitStatusClient.CommitStatusClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.CommitStatusClient.CommitStatusClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.DeploymentClient NGitLab.Impl.DeploymentClient.DeploymentClient(NGitLab.Impl.API api) -> void NGitLab.Impl.DeploymentClient.Get(int projectId, NGitLab.Models.DeploymentQuery query) -> System.Collections.Generic.IEnumerable @@ -440,6 +489,7 @@ NGitLab.Impl.EnvironmentClient.Create(string name, string externalUrl) -> NGitLa NGitLab.Impl.EnvironmentClient.Delete(int environmentId) -> void NGitLab.Impl.EnvironmentClient.Edit(int environmentId, string name, string externalUrl) -> NGitLab.Models.EnvironmentInfo NGitLab.Impl.EnvironmentClient.EnvironmentClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.EnvironmentClient.EnvironmentClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.EnvironmentClient.GetById(int environmentId) -> NGitLab.Models.EnvironmentInfo NGitLab.Impl.EnvironmentClient.GetByIdAsync(int environmentId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.EnvironmentClient.GetEnvironmentsAsync(NGitLab.Models.EnvironmentQuery query) -> NGitLab.GitLabCollectionResponse @@ -550,6 +600,7 @@ NGitLab.Impl.JobClient.GetJobsAsync(NGitLab.Models.JobQuery query) -> NGitLab.Gi NGitLab.Impl.JobClient.GetTrace(int jobId) -> string NGitLab.Impl.JobClient.GetTraceAsync(int jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.JobClient.JobClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.JobClient.JobClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.JobClient.RunAction(int jobId, NGitLab.Models.JobAction action) -> NGitLab.Models.Job NGitLab.Impl.JobClient.RunActionAsync(int jobId, NGitLab.Models.JobAction action, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.LabelClient @@ -615,6 +666,7 @@ NGitLab.Impl.MergeRequestClient.GetPipelines(int mergeRequestIid) -> System.Coll NGitLab.Impl.MergeRequestClient.GetVersionsAsync(int mergeRequestIid) -> NGitLab.GitLabCollectionResponse NGitLab.Impl.MergeRequestClient.MergeRequestClient(NGitLab.Impl.API api) -> void NGitLab.Impl.MergeRequestClient.MergeRequestClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.MergeRequestClient.MergeRequestClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.MergeRequestClient.Rebase(int mergeRequestIid) -> NGitLab.Models.RebaseResult NGitLab.Impl.MergeRequestClient.RebaseAsync(int mergeRequestIid, NGitLab.Models.MergeRequestRebase options, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.MergeRequestClient.Reopen(int mergeRequestIid) -> NGitLab.Models.MergeRequest @@ -695,6 +747,7 @@ NGitLab.Impl.PipelineClient.GetTestReportsSummary(int pipelineId) -> NGitLab.Mod NGitLab.Impl.PipelineClient.GetVariables(int pipelineId) -> System.Collections.Generic.IEnumerable NGitLab.Impl.PipelineClient.GetVariablesAsync(int pipelineId) -> NGitLab.GitLabCollectionResponse NGitLab.Impl.PipelineClient.PipelineClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.PipelineClient.PipelineClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.PipelineClient.RetryAsync(int pipelineId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.PipelineClient.Search(NGitLab.Models.PipelineQuery query) -> System.Collections.Generic.IEnumerable NGitLab.Impl.PipelineClient.SearchAsync(NGitLab.Models.PipelineQuery query) -> NGitLab.GitLabCollectionResponse @@ -735,11 +788,13 @@ NGitLab.Impl.ProjectIssueNoteClient.Edit(NGitLab.Models.ProjectIssueNoteEdit edi NGitLab.Impl.ProjectIssueNoteClient.ForIssue(int issueId) -> System.Collections.Generic.IEnumerable NGitLab.Impl.ProjectIssueNoteClient.Get(int issueId, int noteId) -> NGitLab.Models.ProjectIssueNote NGitLab.Impl.ProjectIssueNoteClient.ProjectIssueNoteClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.ProjectIssueNoteClient.ProjectIssueNoteClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.ProjectLevelApprovalRulesClient NGitLab.Impl.ProjectLevelApprovalRulesClient.CreateProjectLevelRule(NGitLab.Models.ApprovalRuleCreate approvalRuleCreate) -> NGitLab.Models.ApprovalRule NGitLab.Impl.ProjectLevelApprovalRulesClient.DeleteProjectLevelRule(int approvalRuleIdToDelete) -> void NGitLab.Impl.ProjectLevelApprovalRulesClient.GetProjectLevelApprovalRules() -> System.Collections.Generic.List NGitLab.Impl.ProjectLevelApprovalRulesClient.ProjectLevelApprovalRulesClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.ProjectLevelApprovalRulesClient.ProjectLevelApprovalRulesClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.ProjectLevelApprovalRulesClient.UpdateProjectLevelApprovalRule(int approvalRuleIdToUpdate, NGitLab.Models.ApprovalRuleUpdate approvalRuleUpdate) -> NGitLab.Models.ApprovalRule NGitLab.Impl.RepositoryClient NGitLab.Impl.RepositoryClient.Branches.get -> NGitLab.IBranchClient @@ -759,6 +814,7 @@ NGitLab.Impl.RepositoryClient.GetTree(string path, string ref, bool recursive) - NGitLab.Impl.RepositoryClient.GetTreeAsync(NGitLab.Models.RepositoryGetTreeOptions options) -> NGitLab.GitLabCollectionResponse NGitLab.Impl.RepositoryClient.ProjectHooks.get -> NGitLab.IProjectHooksClient NGitLab.Impl.RepositoryClient.RepositoryClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.RepositoryClient.RepositoryClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.RepositoryClient.Tags.get -> NGitLab.ITagClient NGitLab.Impl.RepositoryClient.Tree.get -> System.Collections.Generic.IEnumerable NGitLab.Impl.RunnerClient @@ -815,6 +871,7 @@ NGitLab.Impl.TriggerClient.All.get -> System.Collections.Generic.IEnumerable NGitLab.Models.Trigger NGitLab.Impl.TriggerClient.this[int id].get -> NGitLab.Models.Trigger NGitLab.Impl.TriggerClient.TriggerClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.TriggerClient.TriggerClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.UserClient NGitLab.Impl.UserClient.Activate(int userId) -> void NGitLab.Impl.UserClient.All.get -> System.Collections.Generic.IEnumerable @@ -844,6 +901,7 @@ NGitLab.Impl.WikiClient.Delete(string slug) -> void NGitLab.Impl.WikiClient.this[string slug].get -> NGitLab.Models.WikiPage NGitLab.Impl.WikiClient.Update(string slug, NGitLab.Models.WikiPageUpdate wikiPage) -> NGitLab.Models.WikiPage NGitLab.Impl.WikiClient.WikiClient(NGitLab.Impl.API api, int projectId) -> void +NGitLab.Impl.WikiClient.WikiClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.INamespacesClient NGitLab.INamespacesClient.Accessible.get -> System.Collections.Generic.IEnumerable NGitLab.INamespacesClient.Search(string search) -> System.Collections.Generic.IEnumerable @@ -1696,6 +1754,11 @@ NGitLab.Models.GroupCreate.RequestAccessEnabled -> bool NGitLab.Models.GroupCreate.SharedRunnersMinutesLimit.get -> int? NGitLab.Models.GroupCreate.SharedRunnersMinutesLimit.set -> void NGitLab.Models.GroupCreate.Visibility -> NGitLab.Models.VisibilityLevel +NGitLab.Models.GroupId +NGitLab.Models.GroupId.GroupId() -> void +NGitLab.Models.GroupId.GroupId(long id) -> void +NGitLab.Models.GroupId.GroupId(NGitLab.Models.Group group) -> void +NGitLab.Models.GroupId.GroupId(string path) -> void NGitLab.Models.GroupLabelCreate NGitLab.Models.GroupLabelCreate.Color.get -> string NGitLab.Models.GroupLabelCreate.Color.set -> void @@ -1790,6 +1853,8 @@ NGitLab.Models.Identity.ExternUid -> string NGitLab.Models.Identity.Identity() -> void NGitLab.Models.Identity.Provider -> string NGitLab.Models.Identity.SamlProviderId -> int? +NGitLab.Models.IdOrPathExtensions +NGitLab.Models.IIdOrPathAddressable NGitLab.Models.Issue NGitLab.Models.Issue.Assignee -> NGitLab.Models.Assignee NGitLab.Models.Issue.Assignees -> NGitLab.Models.Assignee[] @@ -2677,6 +2742,11 @@ NGitLab.Models.ProjectHookUpsert.PushEvents -> bool NGitLab.Models.ProjectHookUpsert.TagPushEvents -> bool NGitLab.Models.ProjectHookUpsert.Token -> string NGitLab.Models.ProjectHookUpsert.Url -> System.Uri +NGitLab.Models.ProjectId +NGitLab.Models.ProjectId.ProjectId() -> void +NGitLab.Models.ProjectId.ProjectId(long id) -> void +NGitLab.Models.ProjectId.ProjectId(NGitLab.Models.Project project) -> void +NGitLab.Models.ProjectId.ProjectId(string path) -> void NGitLab.Models.ProjectIssueNote NGitLab.Models.ProjectIssueNote.Attachment -> string NGitLab.Models.ProjectIssueNote.Author -> NGitLab.Models.Author @@ -3659,7 +3729,9 @@ override NGitLab.Models.Blame.GetHashCode() -> int override NGitLab.Models.BlameCommit.Equals(object obj) -> bool override NGitLab.Models.BlameCommit.GetHashCode() -> int override NGitLab.Models.Event.ToString() -> string +override NGitLab.Models.GroupId.ToString() -> string override NGitLab.Models.MergeRequest.ToString() -> string +override NGitLab.Models.ProjectId.ToString() -> string override NGitLab.Models.QueryAssigneeId.ToString() -> string override NGitLab.Sha1.Equals(object obj) -> bool override NGitLab.Sha1.GetHashCode() -> int @@ -3672,6 +3744,14 @@ static NGitLab.GitLabClient.Connect(string hostUrl, string apiToken) -> NGitLab. static NGitLab.GitLabClient.Connect(string hostUrl, string username, string password) -> NGitLab.GitLabClient static NGitLab.Models.FileData.Base64Decode(string base64EncodedData) -> string static NGitLab.Models.FileUpsert.Base64Encode(string plainText) -> string +static NGitLab.Models.GroupId.implicit operator NGitLab.Models.GroupId(long id) -> NGitLab.Models.GroupId +static NGitLab.Models.GroupId.implicit operator NGitLab.Models.GroupId(NGitLab.Models.Group group) -> NGitLab.Models.GroupId +static NGitLab.Models.GroupId.implicit operator NGitLab.Models.GroupId(string path) -> NGitLab.Models.GroupId +static NGitLab.Models.IdOrPathExtensions.ValueAsString(this NGitLab.Models.IIdOrPathAddressable idOrPath) -> string +static NGitLab.Models.IdOrPathExtensions.ValueAsUriParameter(this NGitLab.Models.IIdOrPathAddressable idOrPath) -> string +static NGitLab.Models.ProjectId.implicit operator NGitLab.Models.ProjectId(long id) -> NGitLab.Models.ProjectId +static NGitLab.Models.ProjectId.implicit operator NGitLab.Models.ProjectId(NGitLab.Models.Project project) -> NGitLab.Models.ProjectId +static NGitLab.Models.ProjectId.implicit operator NGitLab.Models.ProjectId(string path) -> NGitLab.Models.ProjectId static NGitLab.Models.QueryAssigneeId.Any.get -> NGitLab.Models.QueryAssigneeId static NGitLab.Models.QueryAssigneeId.implicit operator NGitLab.Models.QueryAssigneeId(int id) -> NGitLab.Models.QueryAssigneeId static NGitLab.Models.QueryAssigneeId.None.get -> NGitLab.Models.QueryAssigneeId From 99b0710bb70b3c63c75956f1135714ec493e6fe5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 07:49:42 -0500 Subject: [PATCH 025/122] Bump Polly from 8.0.0 to 8.1.0 (#556) Bumps [Polly](https://github.com/App-vNext/Polly) from 8.0.0 to 8.1.0. - [Release notes](https://github.com/App-vNext/Polly/releases) - [Changelog](https://github.com/App-vNext/Polly/blob/main/CHANGELOG.md) - [Commits](https://github.com/App-vNext/Polly/compare/8.0.0...8.1.0) --- updated-dependencies: - dependency-name: Polly dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index a21c7a0a..30c20369 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -20,7 +20,7 @@ - + all From 3c1289b6ed59001007966f13006748cdf03dc785 Mon Sep 17 00:00:00 2001 From: phdesroUbi <83839027+phdesroUbi@users.noreply.github.com> Date: Mon, 6 Nov 2023 15:25:03 -0500 Subject: [PATCH 026/122] Draft status missing in MergeRequest class (#553) * Draft status missing in MergeRequest class - Closes #552 * added obsolete to work in progress for mergeRequest * further changes for draft --- NGitLab.Mock/Clients/MergeRequestClient.cs | 2 +- NGitLab.Mock/MergeRequest.cs | 5 +++++ NGitLab.Mock/PublicAPI.Unshipped.txt | 1 + NGitLab/Models/MergeRequest.cs | 4 ++++ NGitLab/PublicAPI.Unshipped.txt | 1 + 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/NGitLab.Mock/Clients/MergeRequestClient.cs b/NGitLab.Mock/Clients/MergeRequestClient.cs index 33d7abf4..48072735 100644 --- a/NGitLab.Mock/Clients/MergeRequestClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestClient.cs @@ -532,7 +532,7 @@ public void Delete(int mergeRequestIid) if (query.Wip != null) { - mergeRequests = mergeRequests.Where(mr => (bool)query.Wip ? mr.WorkInProgress : !mr.WorkInProgress); + mergeRequests = mergeRequests.Where(mr => (bool)query.Wip ? mr.Draft : !mr.Draft); } } diff --git a/NGitLab.Mock/MergeRequest.cs b/NGitLab.Mock/MergeRequest.cs index d48238bc..602d085e 100644 --- a/NGitLab.Mock/MergeRequest.cs +++ b/NGitLab.Mock/MergeRequest.cs @@ -153,10 +153,14 @@ public Pipeline HeadPipeline public NoteCollection Comments { get; } + [Obsolete("Deprecated by GitLab. Use Draft instead")] public bool WorkInProgress => Title is not null && (Title.StartsWith("WIP:", StringComparison.OrdinalIgnoreCase) || Title.StartsWith("Draft:", StringComparison.OrdinalIgnoreCase)); + public bool Draft => Title is not null && + Title.StartsWith("Draft:", StringComparison.OrdinalIgnoreCase); + public IList Approvers { get; } = new List(); public MergeRequestChangeCollection Changes @@ -286,6 +290,7 @@ internal Models.MergeRequest ToMergeRequestClient() MergedAt = MergedAt?.UtcDateTime, ClosedAt = ClosedAt?.UtcDateTime, Description = Description, + Draft = Draft, Id = Id, Iid = Iid, ProjectId = Project.Id, diff --git a/NGitLab.Mock/PublicAPI.Unshipped.txt b/NGitLab.Mock/PublicAPI.Unshipped.txt index 159a3e56..3fd2fb2b 100644 --- a/NGitLab.Mock/PublicAPI.Unshipped.txt +++ b/NGitLab.Mock/PublicAPI.Unshipped.txt @@ -607,6 +607,7 @@ NGitLab.Mock.MergeRequest.CreatedAt.set -> void NGitLab.Mock.MergeRequest.Description.get -> string NGitLab.Mock.MergeRequest.Description.set -> void NGitLab.Mock.MergeRequest.DivergedCommitsCount.get -> int? +NGitLab.Mock.MergeRequest.Draft.get -> bool NGitLab.Mock.MergeRequest.ForceRemoveSourceBranch.get -> bool NGitLab.Mock.MergeRequest.ForceRemoveSourceBranch.set -> void NGitLab.Mock.MergeRequest.GetDiscussions() -> System.Collections.Generic.IEnumerable diff --git a/NGitLab/Models/MergeRequest.cs b/NGitLab/Models/MergeRequest.cs index 93437283..52c45d10 100644 --- a/NGitLab/Models/MergeRequest.cs +++ b/NGitLab/Models/MergeRequest.cs @@ -38,6 +38,9 @@ public class MergeRequest [JsonPropertyName("downvotes")] public int Downvotes; + [JsonPropertyName("draft")] + public bool Draft; + [JsonPropertyName("upvotes")] public int Upvotes; @@ -59,6 +62,7 @@ public class MergeRequest [JsonPropertyName("target_project_id")] public int TargetProjectId; + [Obsolete("Deprecated by GitLab. Use Draft instead")] [JsonPropertyName("work_in_progress")] public bool? WorkInProgress; diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index 367915e9..5e4b1d61 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -2162,6 +2162,7 @@ NGitLab.Models.MergeRequest.DiffRefs -> NGitLab.Models.DiffRefs NGitLab.Models.MergeRequest.DivergedCommitsCount.get -> int? NGitLab.Models.MergeRequest.DivergedCommitsCount.set -> void NGitLab.Models.MergeRequest.Downvotes -> int +NGitLab.Models.MergeRequest.Draft -> bool NGitLab.Models.MergeRequest.ForceRemoveSourceBranch -> bool NGitLab.Models.MergeRequest.HasConflicts.get -> bool NGitLab.Models.MergeRequest.HasConflicts.set -> void From 7293f61ca38b20914274c5700e2acb861d3c28ab Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 07:16:26 -0500 Subject: [PATCH 027/122] Bump Meziantou.Analyzer from 2.0.103 to 2.0.109 (#558) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.103 to 2.0.109. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.103...2.0.109) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index e292508f..7d315705 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From aac3dca215d67b0536d60280e9757b4e6d12ae99 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 09:12:06 -0500 Subject: [PATCH 028/122] Bump NUnit from 3.13.3 to 3.14.0 (#554) Bumps [NUnit](https://github.com/nunit/nunit) from 3.13.3 to 3.14.0. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/v3.13.3...v3.14.0) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj | 2 +- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj index cb56d584..f771e5a2 100644 --- a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj +++ b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index 30c20369..6c51a711 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -17,7 +17,7 @@ - + From 1900a946a5482669d4709331586f5206ac6c92b5 Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Mon, 13 Nov 2023 10:31:54 -0500 Subject: [PATCH 029/122] Replace recent [Obsolete] additions with [EditorBrowsable] (#559) * Replace recent [Obsolete] additions with [EditorBrowsable] Replace [Obsolete("Use long or namespaced path string as projectId instead.")] with [EditorBrowsable(EditorBrowsableState.Never)] * update --- NGitLab/IGitLabClient.cs | 48 +++++++++---------- NGitLab/Impl/ClusterClient.cs | 6 +-- NGitLab/Impl/CommitClient.cs | 3 +- NGitLab/Impl/CommitStatusClient.cs | 6 +-- NGitLab/Impl/EnvironmentClient.cs | 3 +- NGitLab/Impl/JobClient.cs | 3 +- NGitLab/Impl/MergeRequestClient.cs | 3 +- NGitLab/Impl/PipelineClient.cs | 3 +- NGitLab/Impl/ProjectIssueNoteClient.cs | 6 +-- .../Impl/ProjectLevelApprovalRulesClient.cs | 6 +-- NGitLab/Impl/ProtectedBranchClient.cs | 1 - NGitLab/Impl/ReleaseClient.cs | 1 - NGitLab/Impl/RepositoryClient.cs | 3 +- NGitLab/Impl/TriggerClient.cs | 6 +-- NGitLab/Impl/WikiClient.cs | 3 +- 15 files changed, 53 insertions(+), 48 deletions(-) diff --git a/NGitLab/IGitLabClient.cs b/NGitLab/IGitLabClient.cs index abdfd87c..b4456e7f 100644 --- a/NGitLab/IGitLabClient.cs +++ b/NGitLab/IGitLabClient.cs @@ -1,4 +1,4 @@ -using System; +using System.ComponentModel; using NGitLab.Models; namespace NGitLab @@ -36,7 +36,7 @@ public interface IGitLabClient /// /// Returns the events that occurred in the specified project. /// - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IEventClient GetProjectEvents(int projectId); /// @@ -44,52 +44,52 @@ public interface IGitLabClient /// IEventClient GetProjectEvents(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IRepositoryClient GetRepository(int projectId); IRepositoryClient GetRepository(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] ICommitClient GetCommits(int projectId); ICommitClient GetCommits(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] ICommitStatusClient GetCommitStatus(int projectId); ICommitStatusClient GetCommitStatus(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IPipelineClient GetPipelines(int projectId); IPipelineClient GetPipelines(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] ITriggerClient GetTriggers(int projectId); ITriggerClient GetTriggers(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IJobClient GetJobs(int projectId); IJobClient GetJobs(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IMergeRequestClient GetMergeRequest(int projectId); IMergeRequestClient GetMergeRequest(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IMilestoneClient GetMilestone(int projectId); IMilestoneClient GetMilestone(ProjectId projectId); - [Obsolete("Use long or namespaced path string as groupId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IMilestoneClient GetGroupMilestone(int groupId); IMilestoneClient GetGroupMilestone(GroupId groupId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IReleaseClient GetReleases(int projectId); IReleaseClient GetReleases(ProjectId projectId); @@ -112,62 +112,62 @@ public interface IGitLabClient ISearchClient AdvancedSearch { get; } - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IProjectIssueNoteClient GetProjectIssueNoteClient(int projectId); IProjectIssueNoteClient GetProjectIssueNoteClient(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IEnvironmentClient GetEnvironmentClient(int projectId); IEnvironmentClient GetEnvironmentClient(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IClusterClient GetClusterClient(int projectId); IClusterClient GetClusterClient(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IWikiClient GetWikiClient(int projectId); IWikiClient GetWikiClient(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IProjectBadgeClient GetProjectBadgeClient(int projectId); IProjectBadgeClient GetProjectBadgeClient(ProjectId projectId); - [Obsolete("Use long or namespaced path string as groupId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IGroupBadgeClient GetGroupBadgeClient(int groupId); IGroupBadgeClient GetGroupBadgeClient(GroupId groupId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IProjectVariableClient GetProjectVariableClient(int projectId); IProjectVariableClient GetProjectVariableClient(ProjectId projectId); - [Obsolete("Use long or namespaced path string as groupId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IGroupVariableClient GetGroupVariableClient(int groupId); IGroupVariableClient GetGroupVariableClient(GroupId groupId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId); IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(ProjectId projectId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] IProtectedBranchClient GetProtectedBranchClient(int projectId); IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId); - [Obsolete("Use long or namespaced path string as groupId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public ISearchClient GetGroupSearchClient(int groupId); public ISearchClient GetGroupSearchClient(GroupId groupId); - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public ISearchClient GetProjectSearchClient(int projectId); public ISearchClient GetProjectSearchClient(ProjectId projectId); diff --git a/NGitLab/Impl/ClusterClient.cs b/NGitLab/Impl/ClusterClient.cs index a74293ed..91639ead 100644 --- a/NGitLab/Impl/ClusterClient.cs +++ b/NGitLab/Impl/ClusterClient.cs @@ -1,5 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.ComponentModel; using NGitLab.Models; namespace NGitLab.Impl @@ -9,7 +9,7 @@ public class ClusterClient : IClusterClient private readonly API _api; private readonly string _environmentsPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public ClusterClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/CommitClient.cs b/NGitLab/Impl/CommitClient.cs index 3ab98bfa..e782dd2b 100644 --- a/NGitLab/Impl/CommitClient.cs +++ b/NGitLab/Impl/CommitClient.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Net; using NGitLab.Models; @@ -9,7 +10,7 @@ public class CommitClient : ICommitClient private readonly API _api; private readonly string _repoPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public CommitClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/CommitStatusClient.cs b/NGitLab/Impl/CommitStatusClient.cs index 7f18360e..1f76b4ae 100644 --- a/NGitLab/Impl/CommitStatusClient.cs +++ b/NGitLab/Impl/CommitStatusClient.cs @@ -1,5 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.ComponentModel; using NGitLab.Models; namespace NGitLab.Impl @@ -10,7 +10,7 @@ public class CommitStatusClient : ICommitStatusClient private readonly string _statusCreatePath; private readonly string _statusPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public CommitStatusClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/EnvironmentClient.cs b/NGitLab/Impl/EnvironmentClient.cs index 22c517b8..b5a99966 100644 --- a/NGitLab/Impl/EnvironmentClient.cs +++ b/NGitLab/Impl/EnvironmentClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Threading; using System.Threading.Tasks; using NGitLab.Extensions; @@ -12,7 +13,7 @@ public class EnvironmentClient : IEnvironmentClient private readonly API _api; private readonly string _environmentsPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public EnvironmentClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/JobClient.cs b/NGitLab/Impl/JobClient.cs index 473b4a2d..208b541f 100644 --- a/NGitLab/Impl/JobClient.cs +++ b/NGitLab/Impl/JobClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -13,7 +14,7 @@ public class JobClient : IJobClient private readonly API _api; private readonly string _jobsPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public JobClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/MergeRequestClient.cs b/NGitLab/Impl/MergeRequestClient.cs index d8796266..b6e61d41 100644 --- a/NGitLab/Impl/MergeRequestClient.cs +++ b/NGitLab/Impl/MergeRequestClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Globalization; using System.Threading; using System.Threading.Tasks; @@ -16,7 +17,7 @@ public class MergeRequestClient : IMergeRequestClient private readonly string _projectPath; private readonly API _api; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public MergeRequestClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/PipelineClient.cs b/NGitLab/Impl/PipelineClient.cs index 31ba7d7a..a512cdf1 100644 --- a/NGitLab/Impl/PipelineClient.cs +++ b/NGitLab/Impl/PipelineClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading; @@ -15,7 +16,7 @@ public class PipelineClient : IPipelineClient private readonly string _projectPath; private readonly string _pipelinesPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public PipelineClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/ProjectIssueNoteClient.cs b/NGitLab/Impl/ProjectIssueNoteClient.cs index 1ac9c255..386e3fbf 100644 --- a/NGitLab/Impl/ProjectIssueNoteClient.cs +++ b/NGitLab/Impl/ProjectIssueNoteClient.cs @@ -1,5 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.ComponentModel; using NGitLab.Models; namespace NGitLab.Impl @@ -12,7 +12,7 @@ public class ProjectIssueNoteClient : IProjectIssueNoteClient private readonly API _api; private readonly string _projectId; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public ProjectIssueNoteClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/ProjectLevelApprovalRulesClient.cs b/NGitLab/Impl/ProjectLevelApprovalRulesClient.cs index e8a747da..9150f147 100644 --- a/NGitLab/Impl/ProjectLevelApprovalRulesClient.cs +++ b/NGitLab/Impl/ProjectLevelApprovalRulesClient.cs @@ -1,5 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.ComponentModel; using NGitLab.Extensions; using NGitLab.Models; @@ -10,7 +10,7 @@ public class ProjectLevelApprovalRulesClient : IProjectLevelApprovalRulesClient private readonly API _api; private readonly string _approvalRulesUrl; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public ProjectLevelApprovalRulesClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/ProtectedBranchClient.cs b/NGitLab/Impl/ProtectedBranchClient.cs index e6cc5263..da794ce9 100644 --- a/NGitLab/Impl/ProtectedBranchClient.cs +++ b/NGitLab/Impl/ProtectedBranchClient.cs @@ -1,5 +1,4 @@ using System; -using NGitLab.Extensions; using NGitLab.Models; namespace NGitLab.Impl diff --git a/NGitLab/Impl/ReleaseClient.cs b/NGitLab/Impl/ReleaseClient.cs index 32572cbf..3278c4b7 100644 --- a/NGitLab/Impl/ReleaseClient.cs +++ b/NGitLab/Impl/ReleaseClient.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using NGitLab.Extensions; using NGitLab.Models; namespace NGitLab.Impl diff --git a/NGitLab/Impl/RepositoryClient.cs b/NGitLab/Impl/RepositoryClient.cs index aa615a1e..158450bb 100644 --- a/NGitLab/Impl/RepositoryClient.cs +++ b/NGitLab/Impl/RepositoryClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Globalization; using System.IO; using System.Linq; @@ -14,7 +15,7 @@ public class RepositoryClient : IRepositoryClient private readonly string _repoPath; private readonly string _projectPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public RepositoryClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/TriggerClient.cs b/NGitLab/Impl/TriggerClient.cs index e868fc1a..de4634f0 100644 --- a/NGitLab/Impl/TriggerClient.cs +++ b/NGitLab/Impl/TriggerClient.cs @@ -1,5 +1,5 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; +using System.ComponentModel; using NGitLab.Extensions; using NGitLab.Models; @@ -10,7 +10,7 @@ public class TriggerClient : ITriggerClient private readonly API _api; private readonly string _triggersPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public TriggerClient(API api, int projectId) : this(api, (long)projectId) { diff --git a/NGitLab/Impl/WikiClient.cs b/NGitLab/Impl/WikiClient.cs index 441f6c85..6c8f4b5d 100644 --- a/NGitLab/Impl/WikiClient.cs +++ b/NGitLab/Impl/WikiClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Net; using NGitLab.Models; @@ -10,7 +11,7 @@ public class WikiClient : IWikiClient private readonly API _api; private readonly string _projectPath; - [Obsolete("Use long or namespaced path string as projectId instead.")] + [EditorBrowsable(EditorBrowsableState.Never)] public WikiClient(API api, int projectId) : this(api, (long)projectId) { From f8b5eef1985afaabcc80df0d2fb347c265feb6dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Nov 2023 11:06:04 -0500 Subject: [PATCH 030/122] Bump Microsoft.NET.Test.Sdk from 17.7.2 to 17.8.0 (#557) Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.7.2 to 17.8.0. - [Release notes](https://github.com/microsoft/vstest/releases) - [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md) - [Commits](https://github.com/microsoft/vstest/compare/v17.7.2...v17.8.0) --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Thomas Cortes <78750681+Toa741@users.noreply.github.com> --- NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj | 2 +- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj index f771e5a2..93d9897c 100644 --- a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj +++ b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj @@ -7,7 +7,7 @@ - + diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index 6c51a711..aef0c3d3 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -14,7 +14,7 @@ - + From a48aa409d2bd120d8a1aa03f096218449874c487 Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Mon, 13 Nov 2023 14:36:52 -0500 Subject: [PATCH 031/122] NGitLab.Mock.Repository.GetCommits() should support a revision range argument (#560) --- NGitLab.Mock.Tests/CommitsMockTests.cs | 26 ++++++++++++++++++++++++++ NGitLab.Mock/Repository.cs | 13 ++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/NGitLab.Mock.Tests/CommitsMockTests.cs b/NGitLab.Mock.Tests/CommitsMockTests.cs index b071754b..f6a587d3 100644 --- a/NGitLab.Mock.Tests/CommitsMockTests.cs +++ b/NGitLab.Mock.Tests/CommitsMockTests.cs @@ -79,6 +79,32 @@ public void Test_two_branches_can_be_created_from_same_commit() Assert.AreEqual(commitFromBranch1.Parents[0], commitFromBranch2.Parents[0]); } + [Test] + public void Test_GetCommitsBetweenTwoRefs() + { + // Arrange + 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") + .WithCommit("Yet another commit for branch_1")) + .BuildServer(); + + var client = server.CreateClient(); + var repository = client.GetRepository(1); + + // Act + var intermediateCommits = repository.GetCommits("main..branch_1"); + + // Assert + CollectionAssert.AreEqual(new[] + { + "Yet another commit for branch_1", + "Commit for branch_1", + }, intermediateCommits.Select(c => c.Title)); + } + [Test] public void Test_commits_can_be_cherry_pick() { diff --git a/NGitLab.Mock/Repository.cs b/NGitLab.Mock/Repository.cs index a6c9372c..91011798 100644 --- a/NGitLab.Mock/Repository.cs +++ b/NGitLab.Mock/Repository.cs @@ -403,7 +403,18 @@ public IEnumerable GetCommits(string @ref) if (!string.IsNullOrEmpty(@ref)) { - filter.IncludeReachableFrom = @ref; + // @ref can represent a revision range: + // https://docs.gitlab.com/ee/api/commits.html#list-repository-commits + var range = @ref.Split(new[] { ".." }, StringSplitOptions.None); + if (range.Length == 2) + { + filter.ExcludeReachableFrom = range[0]; + filter.IncludeReachableFrom = range[1]; + } + else + { + filter.IncludeReachableFrom = @ref; + } } try From d7c4ec114633edd81c2752588506f0702bb880ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Nov 2023 16:04:43 +0000 Subject: [PATCH 032/122] Bump LibGit2Sharp from 0.27.2 to 0.28.0 (#555) Bumps [LibGit2Sharp](https://github.com/libgit2/libgit2sharp) from 0.27.2 to 0.28.0. - [Release notes](https://github.com/libgit2/libgit2sharp/releases) - [Changelog](https://github.com/libgit2/libgit2sharp/blob/master/CHANGES.md) - [Commits](https://github.com/libgit2/libgit2sharp/compare/0.27.2...0.28.0) --- updated-dependencies: - dependency-name: LibGit2Sharp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Mock/NGitLab.Mock.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Mock/NGitLab.Mock.csproj b/NGitLab.Mock/NGitLab.Mock.csproj index e78713ae..01ddcbe4 100644 --- a/NGitLab.Mock/NGitLab.Mock.csproj +++ b/NGitLab.Mock/NGitLab.Mock.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 97a0852a645ca92b0eb29bb4629c0fe491b3828d Mon Sep 17 00:00:00 2001 From: Adrien J Date: Thu, 16 Nov 2023 13:30:03 -0500 Subject: [PATCH 033/122] Add runner registration/delete mock (#562) --- NGitLab.Mock/Clients/RunnerClient.cs | 33 +++++++++++++++++++++------- NGitLab.Mock/GitLabServer.cs | 17 ++++++++++++++ NGitLab.Mock/Project.cs | 12 ++++++++++ NGitLab.Mock/ProjectCollection.cs | 2 ++ NGitLab.Mock/PublicAPI.Unshipped.txt | 4 ++++ NGitLab.Mock/RunnerCollection.cs | 9 ++++++++ 6 files changed, 69 insertions(+), 8 deletions(-) diff --git a/NGitLab.Mock/Clients/RunnerClient.cs b/NGitLab.Mock/Clients/RunnerClient.cs index 492d9619..d5a38cad 100644 --- a/NGitLab.Mock/Clients/RunnerClient.cs +++ b/NGitLab.Mock/Clients/RunnerClient.cs @@ -57,14 +57,26 @@ public Models.Runner this[int id] } } - public void Delete(Models.Runner runner) - { - throw new NotImplementedException(); - } + public void Delete(Models.Runner runner) => Delete(runner.Id); public void Delete(int runnerId) { - throw new NotImplementedException(); + using (Context.BeginOperationScope()) + { + var projects = Server.AllProjects.Where(p => p.EnabledRunners.Any(r => r.Id == runnerId)); + if (!projects.Any()) + { + throw new GitLabBadRequestException("Runner is not found in any project"); + } + + if (projects.Skip(1).Any()) + { + throw new GitLabBadRequestException("Runner is enabled in multiple projects"); + } + + var project = GetProject(projects.Single().Id, ProjectPermission.Edit); + project.RemoveRunner(runnerId); + } } public Models.Runner Update(int runnerId, RunnerUpdate runnerUpdate) @@ -130,7 +142,7 @@ public Models.Runner EnableRunner(int projectId, RunnerId runnerId) if (project.EnabledRunners.Contains(runnerReference)) { - throw new GitLabException("Bad Request. Runner has already been taken"); + throw new GitLabBadRequestException("Runner has already been taken"); } project.EnabledRunners.Add(runnerReference); @@ -174,9 +186,14 @@ private Runner GetServerRunner(int id) return GetOwnedRunners().FirstOrDefault(runner => runner.Id == id) ?? throw new GitLabNotFoundException(); } - Models.Runner IRunnerClient.Register(RunnerRegister request) + public Models.Runner Register(RunnerRegister request) { - throw new NotImplementedException(); + using (Context.BeginOperationScope()) + { + var project = Server.AllProjects.SingleOrDefault(p => string.Equals(p.RunnersToken, request.Token, StringComparison.Ordinal)); + var runner = project.AddRunner(null, request.Description, request.Active ?? false, request.Locked ?? true, false, request.RunUntagged ?? false); + return runner.ToClientRunner(Context.User); + } } } } diff --git a/NGitLab.Mock/GitLabServer.cs b/NGitLab.Mock/GitLabServer.cs index 292b1455..b6e32c1e 100644 --- a/NGitLab.Mock/GitLabServer.cs +++ b/NGitLab.Mock/GitLabServer.cs @@ -27,6 +27,8 @@ public sealed class GitLabServer : GitLabObject, IDisposable private int _lastResourceLabelEventId = 10000; private int _lastResourceMilestoneEventId = 10000; private int _lastResourceStateEventId = 10000; + private int _lastTokenId = 10000; + private int _lastRegistrationTokenId = 10000; public event EventHandler ClientOperation; @@ -130,11 +132,26 @@ public void Dispose() internal int GetNewResourceStateEventId() => Interlocked.Increment(ref _lastResourceStateEventId); + internal string GetNewRunnerToken() => MakeToken(Convert.ToString(Interlocked.Increment(ref _lastTokenId))); + + internal string GetNewRegistrationToken() => MakeRegistrationToken(Convert.ToString(Interlocked.Increment(ref _lastRegistrationTokenId))); + internal string MakeUrl(string relativeUrl) { return new Uri(Url, relativeUrl).AbsoluteUri; } + internal static string MakeToken(string id, string prefix = "") + { + return prefix + id.PadLeft(20, '0'); + } + + internal static string MakeRegistrationToken(string id) + { + // Prefix is hardcoded: https://gitlab.com/gitlab-org/gitlab/-/issues/388379 + return MakeToken(id, "GR1348941"); + } + internal void RaiseOnClientOperation() { ClientOperation?.Invoke(this, EventArgs.Empty); diff --git a/NGitLab.Mock/Project.cs b/NGitLab.Mock/Project.cs index 86f99ba9..79158da6 100644 --- a/NGitLab.Mock/Project.cs +++ b/NGitLab.Mock/Project.cs @@ -149,6 +149,8 @@ public string[] Tags public ProtectedBranchCollection ProtectedBranches { get; } + public string RunnersToken { get; internal set; } + public void Remove() { Group.Projects.Remove(this); @@ -345,6 +347,11 @@ public MergeRequest CreateMergeRequest(User user, string title, string descripti return mr; } + public bool RemoveRunner(int runnerId) + { + return RegisteredRunners.Remove(runnerId); + } + public Runner AddRunner(string name, string description, bool active, bool locked, bool isShared, bool runUntagged, int id) { var runner = new Runner @@ -374,6 +381,11 @@ public Runner AddRunner(string name, string description, bool active, bool locke return AddRunner(name, description, active, locked, isShared, runUntagged: false, default); } + public Runner AddRunner(string name, string description, bool active, bool locked, bool isShared, bool runUntagged) + { + return AddRunner(name, description, active, locked, isShared, runUntagged, default); + } + public Project Fork(User user) { return Fork(user.Namespace, user, Name); diff --git a/NGitLab.Mock/ProjectCollection.cs b/NGitLab.Mock/ProjectCollection.cs index dd8a8fdf..eaf30022 100644 --- a/NGitLab.Mock/ProjectCollection.cs +++ b/NGitLab.Mock/ProjectCollection.cs @@ -32,6 +32,8 @@ public override void Add(Project project) project.Id = Server.GetNewProjectId(); } + project.RunnersToken ??= Server.GetNewRegistrationToken(); + base.Add(project); } } diff --git a/NGitLab.Mock/PublicAPI.Unshipped.txt b/NGitLab.Mock/PublicAPI.Unshipped.txt index 3fd2fb2b..3de90739 100644 --- a/NGitLab.Mock/PublicAPI.Unshipped.txt +++ b/NGitLab.Mock/PublicAPI.Unshipped.txt @@ -785,6 +785,7 @@ NGitLab.Mock.Project NGitLab.Mock.Project.AccessibleMergeRequests.get -> bool NGitLab.Mock.Project.AccessibleMergeRequests.set -> void NGitLab.Mock.Project.AddRunner(string name, string description, bool active, bool locked, bool isShared) -> NGitLab.Mock.Runner +NGitLab.Mock.Project.AddRunner(string name, string description, bool active, bool locked, bool isShared, bool runUntagged) -> NGitLab.Mock.Runner NGitLab.Mock.Project.AddRunner(string name, string description, bool active, bool locked, bool isShared, bool runUntagged, int id) -> NGitLab.Mock.Runner NGitLab.Mock.Project.AllThreadsMustBeResolvedToMerge.get -> bool NGitLab.Mock.Project.AllThreadsMustBeResolvedToMerge.set -> void @@ -858,9 +859,11 @@ NGitLab.Mock.Project.ProtectedBranches.get -> NGitLab.Mock.ProtectedBranchCollec NGitLab.Mock.Project.RegisteredRunners.get -> NGitLab.Mock.RunnerCollection NGitLab.Mock.Project.Releases.get -> NGitLab.Mock.ReleaseCollection NGitLab.Mock.Project.Remove() -> void +NGitLab.Mock.Project.RemoveRunner(int runnerId) -> bool NGitLab.Mock.Project.Repository.get -> NGitLab.Mock.Repository NGitLab.Mock.Project.RepositoryAccessLevel.get -> NGitLab.Models.RepositoryAccessLevel NGitLab.Mock.Project.RepositoryAccessLevel.set -> void +NGitLab.Mock.Project.RunnersToken.get -> string NGitLab.Mock.Project.SshUrl.get -> string NGitLab.Mock.Project.Statistics.get -> NGitLab.Models.ProjectStatistics NGitLab.Mock.Project.Statistics.set -> void @@ -1085,6 +1088,7 @@ NGitLab.Mock.Runner.Token.set -> void NGitLab.Mock.Runner.Version.get -> string NGitLab.Mock.Runner.Version.set -> void NGitLab.Mock.RunnerCollection +NGitLab.Mock.RunnerCollection.Remove(int id) -> bool NGitLab.Mock.RunnerCollection.RunnerCollection(NGitLab.Mock.Project parent) -> void NGitLab.Mock.RunnerRef NGitLab.Mock.RunnerRef.Id.get -> int diff --git a/NGitLab.Mock/RunnerCollection.cs b/NGitLab.Mock/RunnerCollection.cs index d9549218..08ee104d 100644 --- a/NGitLab.Mock/RunnerCollection.cs +++ b/NGitLab.Mock/RunnerCollection.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; namespace NGitLab.Mock { @@ -22,7 +23,15 @@ public override void Add(Runner item) item.Id = Server.GetNewRunnerId(); } + item.Token ??= Server.GetNewRunnerToken(); + base.Add(item); } + + public bool Remove(int id) + { + var r = this.SingleOrDefault(r => r.Id == id); + return Remove(r); + } } } From 613bee0c34a0c33deaed428f81196643ef7585b3 Mon Sep 17 00:00:00 2001 From: Markus Date: Fri, 17 Nov 2023 14:13:43 +0100 Subject: [PATCH 034/122] Add ability to do a code compare. (#444) * Add ability to do a code compare. * Rename classes, methods, add tests * Update NGitLab.Tests/CompareTests.cs Co-authored-by: Louis Zanella * Update NGitLab.Tests/CompareTests.cs Co-authored-by: Louis Zanella * Update NGitLab/Impl/RepositoryClient.cs Co-authored-by: Louis Zanella * Fix spelling * Fixed tests * removed unnecessary variable --------- Co-authored-by: Markus Stein Co-authored-by: Louis Zanella --- NGitLab.Mock/Clients/RepositoryClient.cs | 5 ++ NGitLab.Tests/CompareTests.cs | 70 ++++++++++++++++++++++++ NGitLab/IRepositoryClient.cs | 5 ++ NGitLab/Impl/RepositoryClient.cs | 5 ++ NGitLab/Models/CompareQuery.cs | 24 ++++++++ NGitLab/Models/CompareResults.cs | 22 ++++++++ NGitLab/PublicAPI.Unshipped.txt | 20 +++++++ 7 files changed, 151 insertions(+) create mode 100644 NGitLab.Tests/CompareTests.cs create mode 100644 NGitLab/Models/CompareQuery.cs create mode 100644 NGitLab/Models/CompareResults.cs diff --git a/NGitLab.Mock/Clients/RepositoryClient.cs b/NGitLab.Mock/Clients/RepositoryClient.cs index 2e07eb19..4eb0fe57 100644 --- a/NGitLab.Mock/Clients/RepositoryClient.cs +++ b/NGitLab.Mock/Clients/RepositoryClient.cs @@ -122,5 +122,10 @@ private static Commit ConvertToNGitLabCommit(LibGit2Sharp.Commit commit, Project { return commit.ToCommitClient(project); } + + public CompareResults Compare(CompareQuery query) + { + throw new NotImplementedException(); + } } } diff --git a/NGitLab.Tests/CompareTests.cs b/NGitLab.Tests/CompareTests.cs new file mode 100644 index 00000000..8ec25680 --- /dev/null +++ b/NGitLab.Tests/CompareTests.cs @@ -0,0 +1,70 @@ +using System.Threading.Tasks; +using NGitLab.Models; +using NGitLab.Tests.Docker; +using NUnit.Framework; + +namespace NGitLab.Tests +{ + public class CompareTests + { + [Test] + [NGitLabRetry] + public async Task Test_compare_equal() + { + using var context = await GitLabTestContext.CreateAsync(); + var project = context.CreateProject(initializeWithCommits: true); + var compareResults = context.Client.GetRepository(project.Id).Compare(new CompareQuery(project.DefaultBranch, project.DefaultBranch)); + + Assert.IsNotNull(compareResults); + Assert.AreEqual(0, compareResults.Commits.Length); + } + + [Test] + [NGitLabRetry] + public async Task Test_compare() + { + using var context = await GitLabTestContext.CreateAsync(); + var project = context.CreateProject(initializeWithCommits: true); + + var devTestBranchCreate = new BranchCreate(); + devTestBranchCreate.Ref = project.DefaultBranch; + devTestBranchCreate.Name = "devtest"; + + context.Client.GetRepository(project.Id).Branches.Create(devTestBranchCreate); + + context.Client.GetRepository(project.Id).Files.Create(new FileUpsert + { + Branch = "devtest", + CommitMessage = "file to be compared", + Path = "compare1.txt", + RawContent = "compare me", + }); + + context.Client.GetRepository(project.Id).Files.Create(new FileUpsert + { + Branch = "devtest", + CommitMessage = "file to be compared, too", + Path = "compare2.txt", + RawContent = "compare me now", + }); + + var compareResults = context.Client.GetRepository(project.Id).Compare(new CompareQuery(project.DefaultBranch, "devtest")); + + Assert.IsNotNull(compareResults); + Assert.AreEqual(2, compareResults.Commits.Length); + } + + [Test] + [NGitLabRetry] + public async Task Test_compare_invalid() + { + using var context = await GitLabTestContext.CreateAsync(); + var project = context.CreateProject(initializeWithCommits: true); + + Assert.Catch< GitLabException>(() => + { + context.Client.GetRepository(project.Id).Compare(new CompareQuery(project.DefaultBranch, "testblub")); + }, "404 Ref Not Found", null); + } + } +} diff --git a/NGitLab/IRepositoryClient.cs b/NGitLab/IRepositoryClient.cs index 5facb508..7035ee10 100644 --- a/NGitLab/IRepositoryClient.cs +++ b/NGitLab/IRepositoryClient.cs @@ -48,5 +48,10 @@ public interface IRepositoryClient IBranchClient Branches { get; } IProjectHooksClient ProjectHooks { get; } + + /// + /// Compare two branches/tags/commit hashes + /// + CompareResults Compare(CompareQuery query); } } diff --git a/NGitLab/Impl/RepositoryClient.cs b/NGitLab/Impl/RepositoryClient.cs index 158450bb..05222a9f 100644 --- a/NGitLab/Impl/RepositoryClient.cs +++ b/NGitLab/Impl/RepositoryClient.cs @@ -112,6 +112,11 @@ public IEnumerable GetCommits(GetCommitsRequest request) return allCommits.Take(request.MaxResults); } + public CompareResults Compare(CompareQuery query) + { + return _api.Get().To(_repoPath + $@"/compare?from={query.Source}&to={query.Target}"); + } + public Commit GetCommit(Sha1 sha) => _api.Get().To(_repoPath + "/commits/" + sha); public IEnumerable GetCommitDiff(Sha1 sha) => _api.Get().GetAll(_repoPath + "/commits/" + sha + "/diff"); diff --git a/NGitLab/Models/CompareQuery.cs b/NGitLab/Models/CompareQuery.cs new file mode 100644 index 00000000..e2104a3b --- /dev/null +++ b/NGitLab/Models/CompareQuery.cs @@ -0,0 +1,24 @@ +namespace NGitLab.Models +{ + /// + /// Query details for comparison of branches/tags/commit hashes + /// + public class CompareQuery + { + /// + /// The source for comparison, can be a branch, tag or a commit hash. + /// + public string Source { get; set; } + + /// + /// The target for comparison, can be a branch, tag or a commit hash. + /// + public string Target { get; set; } + + public CompareQuery(string source, string target) + { + Source = source; + Target = target; + } + } +} diff --git a/NGitLab/Models/CompareResults.cs b/NGitLab/Models/CompareResults.cs new file mode 100644 index 00000000..2ea3598a --- /dev/null +++ b/NGitLab/Models/CompareResults.cs @@ -0,0 +1,22 @@ +using System.Text.Json.Serialization; + +namespace NGitLab.Models +{ + public class CompareResults + { + [JsonPropertyName("commit")] + public Commit Commit { get; set; } + + [JsonPropertyName("commits")] + public Commit[] Commits { get; set; } + + [JsonPropertyName("diffs")] + public Diff[] Diff { get; set; } + + [JsonPropertyName("compare_timeout")] + public bool CompareTimeout { get; set; } + + [JsonPropertyName("compare_same_ref")] + public bool CompareSameRefs { get; set; } + } +} diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index 5e4b1d61..09c522ea 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -799,6 +799,7 @@ NGitLab.Impl.ProjectLevelApprovalRulesClient.UpdateProjectLevelApprovalRule(int NGitLab.Impl.RepositoryClient NGitLab.Impl.RepositoryClient.Branches.get -> NGitLab.IBranchClient NGitLab.Impl.RepositoryClient.Commits.get -> System.Collections.Generic.IEnumerable +NGitLab.Impl.RepositoryClient.Compare(NGitLab.Models.CompareQuery query) -> NGitLab.Models.CompareResults NGitLab.Impl.RepositoryClient.Contributors.get -> NGitLab.IContributorClient NGitLab.Impl.RepositoryClient.Files.get -> NGitLab.IFilesClient NGitLab.Impl.RepositoryClient.GetArchive(System.Action parser) -> void @@ -1004,6 +1005,7 @@ NGitLab.IReleaseLinkClient.Update(int id, NGitLab.Models.ReleaseLinkUpdate data) NGitLab.IRepositoryClient NGitLab.IRepositoryClient.Branches.get -> NGitLab.IBranchClient NGitLab.IRepositoryClient.Commits.get -> System.Collections.Generic.IEnumerable +NGitLab.IRepositoryClient.Compare(NGitLab.Models.CompareQuery query) -> NGitLab.Models.CompareResults NGitLab.IRepositoryClient.Contributors.get -> NGitLab.IContributorClient NGitLab.IRepositoryClient.Files.get -> NGitLab.IFilesClient NGitLab.IRepositoryClient.GetArchive(System.Action parser) -> void @@ -1394,6 +1396,24 @@ NGitLab.Models.CommitStatusCreate.Ref -> string NGitLab.Models.CommitStatusCreate.State -> string NGitLab.Models.CommitStatusCreate.Status -> string NGitLab.Models.CommitStatusCreate.TargetUrl -> string +NGitLab.Models.CompareQuery +NGitLab.Models.CompareQuery.CompareQuery(string source, string target) -> void +NGitLab.Models.CompareQuery.Source.get -> string +NGitLab.Models.CompareQuery.Source.set -> void +NGitLab.Models.CompareQuery.Target.get -> string +NGitLab.Models.CompareQuery.Target.set -> void +NGitLab.Models.CompareResults +NGitLab.Models.CompareResults.Commit.get -> NGitLab.Models.Commit +NGitLab.Models.CompareResults.Commit.set -> void +NGitLab.Models.CompareResults.Commits.get -> NGitLab.Models.Commit[] +NGitLab.Models.CompareResults.Commits.set -> void +NGitLab.Models.CompareResults.CompareResults() -> void +NGitLab.Models.CompareResults.CompareSameRefs.get -> bool +NGitLab.Models.CompareResults.CompareSameRefs.set -> void +NGitLab.Models.CompareResults.CompareTimeout.get -> bool +NGitLab.Models.CompareResults.CompareTimeout.set -> void +NGitLab.Models.CompareResults.Diff.get -> NGitLab.Models.Diff[] +NGitLab.Models.CompareResults.Diff.set -> void NGitLab.Models.Contributor NGitLab.Models.Contributor.Addition -> int NGitLab.Models.Contributor.Commits -> int From e1e9356b5cfeddc8689d200233ce4293af50855e Mon Sep 17 00:00:00 2001 From: Adrien J Date: Fri, 17 Nov 2023 14:36:59 -0500 Subject: [PATCH 035/122] Add runner token to clientproject (#565) --- NGitLab.Mock/Project.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/NGitLab.Mock/Project.cs b/NGitLab.Mock/Project.cs index 79158da6..ef78ece7 100644 --- a/NGitLab.Mock/Project.cs +++ b/NGitLab.Mock/Project.cs @@ -459,6 +459,7 @@ public Models.Project ToClientProject(User currentUser) WebUrl = WebUrl, BuildTimeout = (int)BuildTimeout.TotalMinutes, RepositoryAccessLevel = RepositoryAccessLevel, + RunnersToken = RunnersToken, LfsEnabled = LfsEnabled, Archived = Archived, ApprovalsBeforeMerge = ApprovalsBeforeMerge, From 315777456f6a29bcf8034a8840eb386ddfd521a1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 07:44:51 -0500 Subject: [PATCH 036/122] Bump Microsoft.CodeAnalysis.NetAnalyzers from 7.0.4 to 8.0.0 (#572) Bumps [Microsoft.CodeAnalysis.NetAnalyzers](https://github.com/dotnet/roslyn-analyzers) from 7.0.4 to 8.0.0. - [Release notes](https://github.com/dotnet/roslyn-analyzers/releases) - [Changelog](https://github.com/dotnet/roslyn-analyzers/blob/main/PostReleaseActivities.md) - [Commits](https://github.com/dotnet/roslyn-analyzers/commits) --- updated-dependencies: - dependency-name: Microsoft.CodeAnalysis.NetAnalyzers dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 7d315705..40961977 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -37,7 +37,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 3418e61a47e3ae6eb0a2a8eb9e381002e1ce0c33 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 08:05:24 -0500 Subject: [PATCH 037/122] Bump Microsoft.Extensions.Http from 7.0.0 to 8.0.0 (#569) Bumps [Microsoft.Extensions.Http](https://github.com/dotnet/runtime) from 7.0.0 to 8.0.0. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v7.0.0...v8.0.0) --- updated-dependencies: - dependency-name: Microsoft.Extensions.Http dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index aef0c3d3..6885586d 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -13,7 +13,7 @@ - + From e145b8855cb17c8a6610474328eefc2296915410 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 08:23:36 -0500 Subject: [PATCH 038/122] Bump NuGet.Versioning from 6.7.0 to 6.8.0 (#566) Bumps [NuGet.Versioning](https://github.com/NuGet/NuGet.Client) from 6.7.0 to 6.8.0. - [Release notes](https://github.com/NuGet/NuGet.Client/releases) - [Commits](https://github.com/NuGet/NuGet.Client/commits) --- updated-dependencies: - dependency-name: NuGet.Versioning dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index 6885586d..f7aa4158 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -16,7 +16,7 @@ - + From 8e8f9f29c8ef3ba5f84bfc18fef162e1bf7e72ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:21:11 -0500 Subject: [PATCH 039/122] Bump Microsoft.Bcl.AsyncInterfaces from 7.0.0 to 8.0.0 (#567) Bumps [Microsoft.Bcl.AsyncInterfaces](https://github.com/dotnet/runtime) from 7.0.0 to 8.0.0. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v7.0.0...v8.0.0) --- updated-dependencies: - dependency-name: Microsoft.Bcl.AsyncInterfaces dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab/NGitLab.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab/NGitLab.csproj b/NGitLab/NGitLab.csproj index 30231e39..2d0fe991 100644 --- a/NGitLab/NGitLab.csproj +++ b/NGitLab/NGitLab.csproj @@ -17,7 +17,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 95ea5e1b3c7b99cba274e5ffa18c70b30aacfd9a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 09:47:17 -0500 Subject: [PATCH 040/122] Bump System.Text.Json from 7.0.3 to 8.0.0 (#573) Bumps [System.Text.Json](https://github.com/dotnet/runtime) from 7.0.3 to 8.0.0. - [Release notes](https://github.com/dotnet/runtime/releases) - [Commits](https://github.com/dotnet/runtime/compare/v7.0.3...v8.0.0) --- updated-dependencies: - dependency-name: System.Text.Json dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- NGitLab/NGitLab.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index f7aa4158..fd90d434 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -21,7 +21,7 @@ - + all runtime; build; native; contentfiles; analyzers diff --git a/NGitLab/NGitLab.csproj b/NGitLab/NGitLab.csproj index 2d0fe991..8dec9884 100644 --- a/NGitLab/NGitLab.csproj +++ b/NGitLab/NGitLab.csproj @@ -22,6 +22,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + \ No newline at end of file From 83707f3e7c43f83e982b5f915b91ff24c87596fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 11:20:50 -0500 Subject: [PATCH 041/122] Bump Meziantou.Analyzer from 2.0.109 to 2.0.110 (#571) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.109 to 2.0.110. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.109...2.0.110) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 40961977..d4a8cf3f 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 13c15a78f1c5f496f971c7cc270da03f70731cd7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 12:53:14 -0500 Subject: [PATCH 042/122] Bump Meziantou.Framework.Versioning from 1.3.2 to 1.3.3 (#568) Bumps [Meziantou.Framework.Versioning](https://github.com/meziantou/Meziantou.Framework) from 1.3.2 to 1.3.3. - [Commits](https://github.com/meziantou/Meziantou.Framework/commits) --- updated-dependencies: - dependency-name: Meziantou.Framework.Versioning dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index fd90d434..a9c1a91b 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -11,7 +11,7 @@ - + From 918f10a7481f7bed235c420c31b635f506817b4c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Nov 2023 13:11:40 -0500 Subject: [PATCH 043/122] Bump Polly from 8.1.0 to 8.2.0 (#574) Bumps [Polly](https://github.com/App-vNext/Polly) from 8.1.0 to 8.2.0. - [Release notes](https://github.com/App-vNext/Polly/releases) - [Changelog](https://github.com/App-vNext/Polly/blob/main/CHANGELOG.md) - [Commits](https://github.com/App-vNext/Polly/compare/8.1.0...8.2.0) --- updated-dependencies: - dependency-name: Polly dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index a9c1a91b..9234180f 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -20,7 +20,7 @@ - + all From e02fe369645ea70a264f9043516031a7b8642c4d Mon Sep 17 00:00:00 2001 From: Markus Date: Tue, 21 Nov 2023 13:59:17 +0100 Subject: [PATCH 044/122] Add ability to get job artifact by Ref (#564) * Add ability to do a code compare. * Rename classes, methods, add tests * Update NGitLab.Tests/CompareTests.cs Co-authored-by: Louis Zanella * Update NGitLab.Tests/CompareTests.cs Co-authored-by: Louis Zanella * Update NGitLab/Impl/RepositoryClient.cs Co-authored-by: Louis Zanella * Fix spelling * Fixed tests * removed unnecessary variable * Added ability to get job artifact by Ref see: https://docs.gitlab.com/ee/api/job_artifacts.html#download-a-single-artifact-file-from-specific-tag-or-branch Fixes #563 * Fix missing method and PublicAPI * Update NGitLab/Models/JobArtifactQuery.cs Co-authored-by: Louis Zanella * Change to property * Fix blank --------- Co-authored-by: Markus Stein Co-authored-by: Louis Zanella --- NGitLab.Mock/Clients/JobClient.cs | 5 +++++ NGitLab.Tests/CompareTests.cs | 2 +- NGitLab.Tests/JobTests.cs | 27 +++++++++++++++++++++++++++ NGitLab/IJobClient.cs | 2 ++ NGitLab/Impl/JobClient.cs | 12 ++++++++++++ NGitLab/Models/JobArtifactQuery.cs | 16 ++++++++++++++++ NGitLab/PublicAPI.Unshipped.txt | 10 ++++++++++ 7 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 NGitLab/Models/JobArtifactQuery.cs diff --git a/NGitLab.Mock/Clients/JobClient.cs b/NGitLab.Mock/Clients/JobClient.cs index ca4e5b76..41682f1f 100644 --- a/NGitLab.Mock/Clients/JobClient.cs +++ b/NGitLab.Mock/Clients/JobClient.cs @@ -50,6 +50,11 @@ public byte[] GetJobArtifact(int jobId, string path) throw new NotImplementedException(); } + public byte[] GetJobArtifact(JobArtifactQuery query) + { + throw new NotImplementedException(); + } + public IEnumerable GetJobs(JobScopeMask scope) { return GetJobs(new JobQuery { Scope = scope }); diff --git a/NGitLab.Tests/CompareTests.cs b/NGitLab.Tests/CompareTests.cs index 8ec25680..a4fd83f6 100644 --- a/NGitLab.Tests/CompareTests.cs +++ b/NGitLab.Tests/CompareTests.cs @@ -61,7 +61,7 @@ public async Task Test_compare_invalid() using var context = await GitLabTestContext.CreateAsync(); var project = context.CreateProject(initializeWithCommits: true); - Assert.Catch< GitLabException>(() => + Assert.Catch(() => { context.Client.GetRepository(project.Id).Compare(new CompareQuery(project.DefaultBranch, "testblub")); }, "404 Ref Not Found", null); diff --git a/NGitLab.Tests/JobTests.cs b/NGitLab.Tests/JobTests.cs index ba783476..dea8c2d7 100644 --- a/NGitLab.Tests/JobTests.cs +++ b/NGitLab.Tests/JobTests.cs @@ -226,5 +226,32 @@ public async Task Test_get_job_artifact() Assert.AreEqual("test", content); } } + + [Test] + [NGitLabRetry] + public async Task Test_get_job_artifact_query() + { + using var context = await GitLabTestContext.CreateAsync(); + var project = context.CreateProject(); + var jobsClient = context.Client.GetJobs(project.Id); + using (await context.StartRunnerForOneJobAsync(project.Id)) + { + AddGitLabCiFile(context.Client, project); + var jobs = await GitLabTestContext.RetryUntilAsync(() => jobsClient.GetJobs(JobScopeMask.Success), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); + var job = jobs.Single(); + Assert.AreEqual(JobStatus.Success, job.Status); + + var query = new JobArtifactQuery(); + query.RefName = project.DefaultBranch; + query.JobName = job.Name; + query.ArtifactPath = "file0.txt"; + + var artifact = jobsClient.GetJobArtifact(query); + Assert.IsNotEmpty(artifact); + + var content = Encoding.ASCII.GetString(artifact).Trim(); + Assert.AreEqual("test", content); + } + } } } diff --git a/NGitLab/IJobClient.cs b/NGitLab/IJobClient.cs index 84c05f89..15e045a7 100644 --- a/NGitLab/IJobClient.cs +++ b/NGitLab/IJobClient.cs @@ -25,6 +25,8 @@ public interface IJobClient byte[] GetJobArtifact(int jobId, string path); + byte[] GetJobArtifact(JobArtifactQuery query); + string GetTrace(int jobId); Task GetTraceAsync(int jobId, CancellationToken cancellationToken = default); diff --git a/NGitLab/Impl/JobClient.cs b/NGitLab/Impl/JobClient.cs index 208b541f..1f92b068 100644 --- a/NGitLab/Impl/JobClient.cs +++ b/NGitLab/Impl/JobClient.cs @@ -101,6 +101,18 @@ public byte[] GetJobArtifact(int jobId, string path) return result; } + public byte[] GetJobArtifact(JobArtifactQuery query) + { + byte[] result = null; + _api.Get().Stream($"{_jobsPath}/artifacts/{query.RefName}/raw/{query.ArtifactPath}?job={query.JobName}", s => + { + using var ms = new MemoryStream(); + s.CopyTo(ms); + result = ms.ToArray(); + }); + return result; + } + public string GetTrace(int jobId) { var result = string.Empty; diff --git a/NGitLab/Models/JobArtifactQuery.cs b/NGitLab/Models/JobArtifactQuery.cs new file mode 100644 index 00000000..e46e35e3 --- /dev/null +++ b/NGitLab/Models/JobArtifactQuery.cs @@ -0,0 +1,16 @@ +using System.Text.Json.Serialization; + +namespace NGitLab.Models +{ + public sealed class JobArtifactQuery + { + [JsonPropertyName("ref_name")] + public string RefName { get; set; } + + [JsonPropertyName("artifact_path")] + public string ArtifactPath { get; set; } + + [JsonPropertyName("job")] + public string JobName { get; set; } + } +} diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index 09c522ea..58dbe115 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -329,6 +329,7 @@ NGitLab.IJobClient NGitLab.IJobClient.Get(int jobId) -> NGitLab.Models.Job NGitLab.IJobClient.GetAsync(int jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.IJobClient.GetJobArtifact(int jobId, string path) -> byte[] +NGitLab.IJobClient.GetJobArtifact(NGitLab.Models.JobArtifactQuery query) -> byte[] NGitLab.IJobClient.GetJobArtifacts(int jobId) -> byte[] NGitLab.IJobClient.GetJobs(NGitLab.Models.JobQuery query) -> System.Collections.Generic.IEnumerable NGitLab.IJobClient.GetJobs(NGitLab.Models.JobScopeMask scope) -> System.Collections.Generic.IEnumerable @@ -593,6 +594,7 @@ NGitLab.Impl.JobClient NGitLab.Impl.JobClient.Get(int jobId) -> NGitLab.Models.Job NGitLab.Impl.JobClient.GetAsync(int jobId, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.JobClient.GetJobArtifact(int jobId, string path) -> byte[] +NGitLab.Impl.JobClient.GetJobArtifact(NGitLab.Models.JobArtifactQuery query) -> byte[] NGitLab.Impl.JobClient.GetJobArtifacts(int jobId) -> byte[] NGitLab.Impl.JobClient.GetJobs(NGitLab.Models.JobQuery query) -> System.Collections.Generic.IEnumerable NGitLab.Impl.JobClient.GetJobs(NGitLab.Models.JobScopeMask scope) -> System.Collections.Generic.IEnumerable @@ -2031,6 +2033,14 @@ NGitLab.Models.JobAction.Cancel = 0 -> NGitLab.Models.JobAction NGitLab.Models.JobAction.Erase = 2 -> NGitLab.Models.JobAction NGitLab.Models.JobAction.Play = 3 -> NGitLab.Models.JobAction NGitLab.Models.JobAction.Retry = 1 -> NGitLab.Models.JobAction +NGitLab.Models.JobArtifactQuery +NGitLab.Models.JobArtifactQuery.ArtifactPath.get -> string +NGitLab.Models.JobArtifactQuery.ArtifactPath.set -> void +NGitLab.Models.JobArtifactQuery.JobArtifactQuery() -> void +NGitLab.Models.JobArtifactQuery.JobName.get -> string +NGitLab.Models.JobArtifactQuery.JobName.set -> void +NGitLab.Models.JobArtifactQuery.RefName.get -> string +NGitLab.Models.JobArtifactQuery.RefName.set -> void NGitLab.Models.JobBasic NGitLab.Models.JobBasic.Commit.get -> NGitLab.Models.Commit NGitLab.Models.JobBasic.JobBasic() -> void From 203ffb8d58a163f0932789b06da8af89fff45af3 Mon Sep 17 00:00:00 2001 From: AceBlackGloss Date: Tue, 21 Nov 2023 21:17:09 +0800 Subject: [PATCH 045/122] Add missing attribute `target` and `protected` to tag (#576) --- NGitLab/Models/Tag.cs | 6 ++++++ NGitLab/PublicAPI.Unshipped.txt | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/NGitLab/Models/Tag.cs b/NGitLab/Models/Tag.cs index db7ed753..60091545 100644 --- a/NGitLab/Models/Tag.cs +++ b/NGitLab/Models/Tag.cs @@ -15,5 +15,11 @@ public class Tag [JsonPropertyName("release")] public ReleaseInfo Release; + + [JsonPropertyName("target")] + public Sha1 Target { get; set; } + + [JsonPropertyName("protected")] + public bool Protected { get; set; } } } diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index 58dbe115..eaa79438 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -3419,8 +3419,12 @@ NGitLab.Models.Tag NGitLab.Models.Tag.Commit -> NGitLab.Models.CommitInfo NGitLab.Models.Tag.Message -> string NGitLab.Models.Tag.Name -> string +NGitLab.Models.Tag.Protected.get -> bool +NGitLab.Models.Tag.Protected.set -> void NGitLab.Models.Tag.Release -> NGitLab.Models.ReleaseInfo NGitLab.Models.Tag.Tag() -> void +NGitLab.Models.Tag.Target.get -> NGitLab.Sha1 +NGitLab.Models.Tag.Target.set -> void NGitLab.Models.TagCreate NGitLab.Models.TagCreate.Message -> string NGitLab.Models.TagCreate.Name -> string From 900721f26b9a7792fb0e81ed60cfa9cc6b7a449e Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Thu, 23 Nov 2023 12:29:43 -0500 Subject: [PATCH 046/122] Put Microsoft NuGet packages into their own dependabot group (#575) --- .github/dependabot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d081b290..3341b6e8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -32,3 +32,8 @@ updates: interval: weekly rebase-strategy: auto open-pull-requests-limit: 20 + groups: + ms-dependencies: + patterns: + - "Microsoft.*" + - "System.*" From 4df78073f1e645419d3f1ec0245b27c9f5cb117f Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Thu, 23 Nov 2023 13:13:23 -0500 Subject: [PATCH 047/122] Exclude "Microsoft.Playwright" from 'ms-dependencies' group (#579) --- .github/dependabot.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 3341b6e8..477f3434 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -37,3 +37,5 @@ updates: patterns: - "Microsoft.*" - "System.*" + exclude-patterns: + - "Microsoft.Playwright" From 55348e5e21c3a59b7200f242e57aa9d0df43a8fd Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Thu, 23 Nov 2023 13:44:37 -0500 Subject: [PATCH 048/122] Bump up to .NET 8 (#581) --- NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj | 2 +- NGitLab.Tests/NGitLab.Tests.csproj | 4 ++-- global.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj index 93d9897c..8c3877aa 100644 --- a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj +++ b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj @@ -1,6 +1,6 @@ - net6.0;net472 + net8.0;net472 false diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index 9234180f..e9870e9f 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -1,6 +1,6 @@ - net6.0 + net8.0 false @@ -27,4 +27,4 @@ runtime; build; native; contentfiles; analyzers - \ No newline at end of file + diff --git a/global.json b/global.json index 857e6681..368a14e3 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.100", - "rollForward": "latestFeature" + "version": "8.0.100", + "rollForward": "latestMajor" } } From b740463ce743d1dcc47a39531fd3c3821c8a21bb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 23 Nov 2023 19:07:08 +0000 Subject: [PATCH 049/122] Bump the ms-dependencies group with 1 update (#580) Bumps the ms-dependencies group with 1 update: [Microsoft.AspNetCore.WebUtilities](https://github.com/dotnet/aspnetcore). - [Release notes](https://github.com/dotnet/aspnetcore/releases) - [Changelog](https://github.com/dotnet/aspnetcore/blob/main/docs/ReleasePlanning.md) - [Commits](https://github.com/dotnet/aspnetcore/compare/2.2.0...v8.0.0) --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.WebUtilities dependency-type: direct:production update-type: version-update:semver-major dependency-group: ms-dependencies ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index e9870e9f..a0cfd353 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -12,7 +12,7 @@ - + From 81e264c0fd1a6bb28edb3a2f308e863b25bb8356 Mon Sep 17 00:00:00 2001 From: AceBlackGloss Date: Fri, 24 Nov 2023 23:40:55 +0800 Subject: [PATCH 050/122] Add protected tags client (#577) * Add protected tags client * Fix protect branch error * Revert "Fix protect branch error" This reverts commit 7698ef01919f3ff983dadb3e16dce9b191b60431. * Remove `Id` from `AccessLevelInfo` * Apply suggestions --- NGitLab.Mock/Clients/GitLabClient.cs | 5 +++ NGitLab.Tests/ProtectedTagTests.cs | 61 ++++++++++++++++++++++++++++ NGitLab/GitLabClient.cs | 3 ++ NGitLab/IGitLabClient.cs | 2 + NGitLab/IProtectedTagClient.cs | 26 ++++++++++++ NGitLab/Impl/ProtectedTagClient.cs | 60 +++++++++++++++++++++++++++ NGitLab/Models/AccessControl.cs | 26 ++++++++++++ NGitLab/Models/ProtectedTag.cs | 13 ++++++ NGitLab/Models/TagProtect.cs | 21 ++++++++++ NGitLab/PublicAPI.Unshipped.txt | 49 ++++++++++++++++++++++ 10 files changed, 266 insertions(+) create mode 100644 NGitLab.Tests/ProtectedTagTests.cs create mode 100644 NGitLab/IProtectedTagClient.cs create mode 100644 NGitLab/Impl/ProtectedTagClient.cs create mode 100644 NGitLab/Models/AccessControl.cs create mode 100644 NGitLab/Models/ProtectedTag.cs create mode 100644 NGitLab/Models/TagProtect.cs diff --git a/NGitLab.Mock/Clients/GitLabClient.cs b/NGitLab.Mock/Clients/GitLabClient.cs index 2ae10d62..4bcb1bf9 100644 --- a/NGitLab.Mock/Clients/GitLabClient.cs +++ b/NGitLab.Mock/Clients/GitLabClient.cs @@ -140,6 +140,11 @@ public IGraphQLClient GraphQL public IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId) => new ProtectedBranchClient(Context, projectId); + public IProtectedTagClient GetProtectedTagClient(ProjectId projectId) + { + throw new System.NotImplementedException(); + } + public ISearchClient GetGroupSearchClient(int groupId) => GetGroupSearchClient((long)groupId); public ISearchClient GetGroupSearchClient(GroupId groupId) => new GroupSearchClient(Context, groupId); diff --git a/NGitLab.Tests/ProtectedTagTests.cs b/NGitLab.Tests/ProtectedTagTests.cs new file mode 100644 index 00000000..ef1f8a6c --- /dev/null +++ b/NGitLab.Tests/ProtectedTagTests.cs @@ -0,0 +1,61 @@ +using System.Linq; +using System.Threading.Tasks; +using NGitLab.Models; +using NGitLab.Tests.Docker; +using NUnit.Framework; + +namespace NGitLab.Tests +{ + public class ProtectedTagTests + { + [Test] + [NGitLabRetry] + public async Task ProtectTag_Test() + { + using var context = await GitLabTestContext.CreateAsync(); + var project = context.CreateProject(initializeWithCommits: true); + var tagClient = context.Client.GetRepository(project.Id).Tags; + + var tag = tagClient.Create(new TagCreate { Name = "protectedTag", Ref = project.DefaultBranch }); + Assert.False(tag.Protected); + + var protectedTagClient = context.Client.GetProtectedTagClient(project.Id); + var protectedTags = protectedTagClient.GetProtectedTagsAsync(); + Assert.False(protectedTags.Any()); + + await ProtectedTagTest(tag.Name, tag.Name, protectedTagClient, tagClient); + await ProtectedTagTest("*", tag.Name, protectedTagClient, tagClient); + } + + private static async Task ProtectedTagTest(string tagProtectName, string tagName, IProtectedTagClient protectedTagClient, ITagClient tagClient) + { + var tagProtect = new TagProtect(tagProtectName) + { + AllowedToCreate = new AccessControl[] { new AccessLevelControl { AccessLevel = AccessLevel.Maintainer }, }, + CreateAccessLevel = AccessLevel.NoAccess, + }; + var protectedTag = await protectedTagClient.ProtectTagAsync(tagProtect).ConfigureAwait(false); + Assert.AreEqual(protectedTag.Name, tagProtect.Name); + var accessLevels = protectedTag.CreateAccessLevels.Select(level => level.AccessLevel).ToArray(); + Assert.Contains(AccessLevel.NoAccess, accessLevels); + Assert.Contains(AccessLevel.Maintainer, accessLevels); + + var getProtectedTag = await protectedTagClient.GetProtectedTagAsync(tagProtectName).ConfigureAwait(false); + Assert.AreEqual(protectedTag.Name, getProtectedTag.Name); + accessLevels = getProtectedTag.CreateAccessLevels.Select(level => level.AccessLevel).ToArray(); + Assert.Contains(AccessLevel.NoAccess, accessLevels); + Assert.Contains(AccessLevel.Maintainer, accessLevels); + + var tag = await tagClient.GetByNameAsync(tagName).ConfigureAwait(false); + Assert.True(tag.Protected); + + await protectedTagClient.UnprotectTagAsync(tagProtectName).ConfigureAwait(false); + + var protectedTags = protectedTagClient.GetProtectedTagsAsync(); + Assert.False(protectedTags.Any()); + + tag = await tagClient.GetByNameAsync(tag.Name).ConfigureAwait(false); + Assert.False(tag.Protected); + } + } +} diff --git a/NGitLab/GitLabClient.cs b/NGitLab/GitLabClient.cs index 9fd164fa..0bd104e5 100644 --- a/NGitLab/GitLabClient.cs +++ b/NGitLab/GitLabClient.cs @@ -234,6 +234,9 @@ public IProtectedBranchClient GetProtectedBranchClient(int projectId) public IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId) => new ProtectedBranchClient(_api, projectId); + public IProtectedTagClient GetProtectedTagClient(ProjectId projectId) + => new ProtectedTagClient(_api, projectId); + public ISearchClient GetGroupSearchClient(int groupId) => GetGroupSearchClient((long)groupId); diff --git a/NGitLab/IGitLabClient.cs b/NGitLab/IGitLabClient.cs index b4456e7f..4f8b2581 100644 --- a/NGitLab/IGitLabClient.cs +++ b/NGitLab/IGitLabClient.cs @@ -162,6 +162,8 @@ public interface IGitLabClient IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId); + IProtectedTagClient GetProtectedTagClient(ProjectId projectId); + [EditorBrowsable(EditorBrowsableState.Never)] public ISearchClient GetGroupSearchClient(int groupId); diff --git a/NGitLab/IProtectedTagClient.cs b/NGitLab/IProtectedTagClient.cs new file mode 100644 index 00000000..d81e55d9 --- /dev/null +++ b/NGitLab/IProtectedTagClient.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using NGitLab.Models; + +namespace NGitLab +{ + public interface IProtectedTagClient + { + ProtectedTag ProtectTag(TagProtect protect); + + Task ProtectTagAsync(TagProtect protect, CancellationToken cancellationToken = default); + + void UnprotectTag(string name); + + Task UnprotectTagAsync(string name, CancellationToken cancellationToken = default); + + ProtectedTag GetProtectedTag(string name); + + Task GetProtectedTagAsync(string name, CancellationToken cancellationToken = default); + + IEnumerable GetProtectedTags(); + + GitLabCollectionResponse GetProtectedTagsAsync(); + } +} diff --git a/NGitLab/Impl/ProtectedTagClient.cs b/NGitLab/Impl/ProtectedTagClient.cs new file mode 100644 index 00000000..42aa461c --- /dev/null +++ b/NGitLab/Impl/ProtectedTagClient.cs @@ -0,0 +1,60 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using NGitLab.Models; + +namespace NGitLab.Impl +{ + public class ProtectedTagClient : IProtectedTagClient + { + private readonly API _api; + private readonly string _protectedTagsPath; + + public ProtectedTagClient(API api, ProjectId projectId) + { + _api = api; + _protectedTagsPath = $"{Project.Url}/{projectId.ValueAsUriParameter()}/protected_tags"; + } + + public ProtectedTag ProtectTag(TagProtect protect) + { + return _api.Post().With(protect).To(_protectedTagsPath); + } + + public async Task ProtectTagAsync(TagProtect protect, CancellationToken cancellationToken = default) + { + return await _api.Post().With(protect).ToAsync(_protectedTagsPath, cancellationToken).ConfigureAwait(false); + } + + public void UnprotectTag(string name) + { + _api.Delete().Execute($"{_protectedTagsPath}/{Uri.EscapeDataString(name)}"); + } + + public async Task UnprotectTagAsync(string name, CancellationToken cancellationToken = default) + { + await _api.Delete().ExecuteAsync($"{_protectedTagsPath}/{Uri.EscapeDataString(name)}", cancellationToken).ConfigureAwait(false); + } + + public ProtectedTag GetProtectedTag(string name) + { + return _api.Get().To($"{_protectedTagsPath}/{Uri.EscapeDataString(name)}"); + } + + public async Task GetProtectedTagAsync(string name, CancellationToken cancellationToken = default) + { + return await _api.Get().ToAsync($"{_protectedTagsPath}/{Uri.EscapeDataString(name)}", cancellationToken).ConfigureAwait(false); + } + + public IEnumerable GetProtectedTags() + { + return _api.Get().GetAll(_protectedTagsPath); + } + + public GitLabCollectionResponse GetProtectedTagsAsync() + { + return _api.Get().GetAllAsync(_protectedTagsPath); + } + } +} diff --git a/NGitLab/Models/AccessControl.cs b/NGitLab/Models/AccessControl.cs new file mode 100644 index 00000000..6313c543 --- /dev/null +++ b/NGitLab/Models/AccessControl.cs @@ -0,0 +1,26 @@ +using System.Text.Json.Serialization; + +namespace NGitLab.Models +{ + public abstract class AccessControl + { + } + + public class UserIdControl : AccessControl + { + [JsonPropertyName("user_id")] + public long UserId { get; set; } + } + + public class GroupIdControl : AccessControl + { + [JsonPropertyName("group_id")] + public long GroupId { get; set; } + } + + public class AccessLevelControl : AccessControl + { + [JsonPropertyName("access_level")] + public AccessLevel AccessLevel { get; set; } + } +} diff --git a/NGitLab/Models/ProtectedTag.cs b/NGitLab/Models/ProtectedTag.cs new file mode 100644 index 00000000..396bf9d8 --- /dev/null +++ b/NGitLab/Models/ProtectedTag.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace NGitLab.Models +{ + public class ProtectedTag + { + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("create_access_levels")] + public AccessLevelInfo[] CreateAccessLevels { get; set; } + } +} diff --git a/NGitLab/Models/TagProtect.cs b/NGitLab/Models/TagProtect.cs new file mode 100644 index 00000000..f5cc014d --- /dev/null +++ b/NGitLab/Models/TagProtect.cs @@ -0,0 +1,21 @@ +using System.Text.Json.Serialization; + +namespace NGitLab.Models +{ + public class TagProtect + { + public TagProtect(string name) + { + Name = name; + } + + [JsonPropertyName("name")] + public string Name { get; set; } + + [JsonPropertyName("allowed_to_create")] + public AccessControl[] AllowedToCreate { get; set; } + + [JsonPropertyName("create_access_level")] + public AccessLevel? CreateAccessLevel { get; set; } + } +} diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index eaa79438..0df41368 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -82,6 +82,7 @@ NGitLab.GitLabClient.GetProjectVariableClient(int projectId) -> NGitLab.IProject NGitLab.GitLabClient.GetProjectVariableClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectVariableClient NGitLab.GitLabClient.GetProtectedBranchClient(int projectId) -> NGitLab.IProtectedBranchClient NGitLab.GitLabClient.GetProtectedBranchClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProtectedBranchClient +NGitLab.GitLabClient.GetProtectedTagClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProtectedTagClient NGitLab.GitLabClient.GetReleases(int projectId) -> NGitLab.IReleaseClient NGitLab.GitLabClient.GetReleases(NGitLab.Models.ProjectId projectId) -> NGitLab.IReleaseClient NGitLab.GitLabClient.GetRepository(int projectId) -> NGitLab.IRepositoryClient @@ -222,6 +223,7 @@ NGitLab.IGitLabClient.GetProjectVariableClient(int projectId) -> NGitLab.IProjec NGitLab.IGitLabClient.GetProjectVariableClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProjectVariableClient NGitLab.IGitLabClient.GetProtectedBranchClient(int projectId) -> NGitLab.IProtectedBranchClient NGitLab.IGitLabClient.GetProtectedBranchClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProtectedBranchClient +NGitLab.IGitLabClient.GetProtectedTagClient(NGitLab.Models.ProjectId projectId) -> NGitLab.IProtectedTagClient NGitLab.IGitLabClient.GetReleases(int projectId) -> NGitLab.IReleaseClient NGitLab.IGitLabClient.GetReleases(NGitLab.Models.ProjectId projectId) -> NGitLab.IReleaseClient NGitLab.IGitLabClient.GetRepository(int projectId) -> NGitLab.IRepositoryClient @@ -798,6 +800,16 @@ NGitLab.Impl.ProjectLevelApprovalRulesClient.GetProjectLevelApprovalRules() -> S NGitLab.Impl.ProjectLevelApprovalRulesClient.ProjectLevelApprovalRulesClient(NGitLab.Impl.API api, int projectId) -> void NGitLab.Impl.ProjectLevelApprovalRulesClient.ProjectLevelApprovalRulesClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void NGitLab.Impl.ProjectLevelApprovalRulesClient.UpdateProjectLevelApprovalRule(int approvalRuleIdToUpdate, NGitLab.Models.ApprovalRuleUpdate approvalRuleUpdate) -> NGitLab.Models.ApprovalRule +NGitLab.Impl.ProtectedTagClient +NGitLab.Impl.ProtectedTagClient.GetProtectedTag(string name) -> NGitLab.Models.ProtectedTag +NGitLab.Impl.ProtectedTagClient.GetProtectedTagAsync(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +NGitLab.Impl.ProtectedTagClient.GetProtectedTags() -> System.Collections.Generic.IEnumerable +NGitLab.Impl.ProtectedTagClient.GetProtectedTagsAsync() -> NGitLab.GitLabCollectionResponse +NGitLab.Impl.ProtectedTagClient.ProtectedTagClient(NGitLab.Impl.API api, NGitLab.Models.ProjectId projectId) -> void +NGitLab.Impl.ProtectedTagClient.ProtectTag(NGitLab.Models.TagProtect protect) -> NGitLab.Models.ProtectedTag +NGitLab.Impl.ProtectedTagClient.ProtectTagAsync(NGitLab.Models.TagProtect protect, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +NGitLab.Impl.ProtectedTagClient.UnprotectTag(string name) -> void +NGitLab.Impl.ProtectedTagClient.UnprotectTagAsync(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.Impl.RepositoryClient NGitLab.Impl.RepositoryClient.Branches.get -> NGitLab.IBranchClient NGitLab.Impl.RepositoryClient.Commits.get -> System.Collections.Generic.IEnumerable @@ -989,6 +1001,15 @@ NGitLab.IProtectedBranchClient.GetProtectedBranch(string branchName) -> NGitLab. NGitLab.IProtectedBranchClient.GetProtectedBranches(string search = null) -> NGitLab.Models.ProtectedBranch[] NGitLab.IProtectedBranchClient.ProtectBranch(NGitLab.Models.BranchProtect branchProtect) -> NGitLab.Models.ProtectedBranch NGitLab.IProtectedBranchClient.UnprotectBranch(string branchName) -> void +NGitLab.IProtectedTagClient +NGitLab.IProtectedTagClient.GetProtectedTag(string name) -> NGitLab.Models.ProtectedTag +NGitLab.IProtectedTagClient.GetProtectedTagAsync(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +NGitLab.IProtectedTagClient.GetProtectedTags() -> System.Collections.Generic.IEnumerable +NGitLab.IProtectedTagClient.GetProtectedTagsAsync() -> NGitLab.GitLabCollectionResponse +NGitLab.IProtectedTagClient.ProtectTag(NGitLab.Models.TagProtect protect) -> NGitLab.Models.ProtectedTag +NGitLab.IProtectedTagClient.ProtectTagAsync(NGitLab.Models.TagProtect protect, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task +NGitLab.IProtectedTagClient.UnprotectTag(string name) -> void +NGitLab.IProtectedTagClient.UnprotectTagAsync(string name, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task NGitLab.IReleaseClient NGitLab.IReleaseClient.All.get -> System.Collections.Generic.IEnumerable NGitLab.IReleaseClient.Create(NGitLab.Models.ReleaseCreate data) -> NGitLab.Models.ReleaseInfo @@ -1118,6 +1139,8 @@ NGitLab.JobStatus.WaitingForResource = 11 -> NGitLab.JobStatus NGitLab.MergeRequestChangeClient NGitLab.MergeRequestChangeClient.MergeRequestChange.get -> NGitLab.Models.MergeRequestChange NGitLab.MergeRequestChangeClient.MergeRequestChangeClient(NGitLab.Impl.API api, string projectPath, int mergeRequestIid) -> void +NGitLab.Models.AccessControl +NGitLab.Models.AccessControl.AccessControl() -> void NGitLab.Models.AccessLevel NGitLab.Models.AccessLevel.Admin = 60 -> NGitLab.Models.AccessLevel NGitLab.Models.AccessLevel.Developer = 30 -> NGitLab.Models.AccessLevel @@ -1127,6 +1150,10 @@ NGitLab.Models.AccessLevel.Master = 40 -> NGitLab.Models.AccessLevel NGitLab.Models.AccessLevel.NoAccess = 0 -> NGitLab.Models.AccessLevel NGitLab.Models.AccessLevel.Owner = 50 -> NGitLab.Models.AccessLevel NGitLab.Models.AccessLevel.Reporter = 20 -> NGitLab.Models.AccessLevel +NGitLab.Models.AccessLevelControl +NGitLab.Models.AccessLevelControl.AccessLevel.get -> NGitLab.Models.AccessLevel +NGitLab.Models.AccessLevelControl.AccessLevel.set -> void +NGitLab.Models.AccessLevelControl.AccessLevelControl() -> void NGitLab.Models.AccessLevelInfo NGitLab.Models.AccessLevelInfo.AccessLevel.get -> NGitLab.Models.AccessLevel NGitLab.Models.AccessLevelInfo.AccessLevel.set -> void @@ -1781,6 +1808,10 @@ NGitLab.Models.GroupId.GroupId() -> void NGitLab.Models.GroupId.GroupId(long id) -> void NGitLab.Models.GroupId.GroupId(NGitLab.Models.Group group) -> void NGitLab.Models.GroupId.GroupId(string path) -> void +NGitLab.Models.GroupIdControl +NGitLab.Models.GroupIdControl.GroupId.get -> long +NGitLab.Models.GroupIdControl.GroupId.set -> void +NGitLab.Models.GroupIdControl.GroupIdControl() -> void NGitLab.Models.GroupLabelCreate NGitLab.Models.GroupLabelCreate.Color.get -> string NGitLab.Models.GroupLabelCreate.Color.set -> void @@ -2958,6 +2989,12 @@ NGitLab.Models.ProtectedBranch.Name.set -> void NGitLab.Models.ProtectedBranch.ProtectedBranch() -> void NGitLab.Models.ProtectedBranch.PushAccessLevels.get -> NGitLab.Models.AccessLevelInfo[] NGitLab.Models.ProtectedBranch.PushAccessLevels.set -> void +NGitLab.Models.ProtectedTag +NGitLab.Models.ProtectedTag.CreateAccessLevels.get -> NGitLab.Models.AccessLevelInfo[] +NGitLab.Models.ProtectedTag.CreateAccessLevels.set -> void +NGitLab.Models.ProtectedTag.Name.get -> string +NGitLab.Models.ProtectedTag.Name.set -> void +NGitLab.Models.ProtectedTag.ProtectedTag() -> void NGitLab.Models.PushData NGitLab.Models.PushData.Action.get -> NGitLab.Models.PushDataAction NGitLab.Models.PushData.Action.set -> void @@ -3431,6 +3468,14 @@ NGitLab.Models.TagCreate.Name -> string NGitLab.Models.TagCreate.Ref -> string NGitLab.Models.TagCreate.ReleaseDescription -> string NGitLab.Models.TagCreate.TagCreate() -> void +NGitLab.Models.TagProtect +NGitLab.Models.TagProtect.AllowedToCreate.get -> NGitLab.Models.AccessControl[] +NGitLab.Models.TagProtect.AllowedToCreate.set -> void +NGitLab.Models.TagProtect.CreateAccessLevel.get -> NGitLab.Models.AccessLevel? +NGitLab.Models.TagProtect.CreateAccessLevel.set -> void +NGitLab.Models.TagProtect.Name.get -> string +NGitLab.Models.TagProtect.Name.set -> void +NGitLab.Models.TagProtect.TagProtect(string name) -> void NGitLab.Models.TagQuery NGitLab.Models.TagQuery.OrderBy.get -> string NGitLab.Models.TagQuery.OrderBy.set -> void @@ -3592,6 +3637,10 @@ NGitLab.Models.User.UsingLicenseSeat -> bool NGitLab.Models.User.WebsiteURL -> string NGitLab.Models.User.WebURL -> string NGitLab.Models.User.WorkInformation -> string +NGitLab.Models.UserIdControl +NGitLab.Models.UserIdControl.UserId.get -> long +NGitLab.Models.UserIdControl.UserId.set -> void +NGitLab.Models.UserIdControl.UserIdControl() -> void NGitLab.Models.UserToken NGitLab.Models.UserToken.Active.get -> bool NGitLab.Models.UserToken.Active.set -> void From 5e99e33c1d9ba8038a97a7a4ae9134f2a284c554 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 07:17:02 -0500 Subject: [PATCH 051/122] Bump Microsoft.Playwright from 1.39.0 to 1.40.0 (#585) Bumps [Microsoft.Playwright](https://github.com/microsoft/playwright-dotnet) from 1.39.0 to 1.40.0. - [Release notes](https://github.com/microsoft/playwright-dotnet/releases) - [Commits](https://github.com/microsoft/playwright-dotnet/compare/v1.39.0...v1.40.0) --- updated-dependencies: - dependency-name: Microsoft.Playwright dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index a0cfd353..d0639d17 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -15,7 +15,7 @@ - + From f154d3933a1fc280a3f1264264e331735978b64d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 08:12:27 -0500 Subject: [PATCH 052/122] Bump Meziantou.Analyzer from 2.0.110 to 2.0.112 (#583) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.110 to 2.0.112. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.110...2.0.112) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index d4a8cf3f..b243e508 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From bbc6deb99aa18e39b6f699f230c200c6d1f11fed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Nov 2023 09:15:48 -0500 Subject: [PATCH 053/122] Bump NUnit from 3.14.0 to 4.0.0 (#584) * Bump NUnit from 3.14.0 to 4.0.0 Bumps [NUnit](https://github.com/nunit/nunit) from 3.14.0 to 4.0.0. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/v3.14.0...v4.0.0) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Fix --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Louis Zanella --- NGitLab.Mock.Tests/GlobalUsings.cs | 5 +++++ NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj | 2 +- NGitLab.Tests/GlobalUsings.cs | 5 +++++ NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 4 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 NGitLab.Mock.Tests/GlobalUsings.cs create mode 100644 NGitLab.Tests/GlobalUsings.cs diff --git a/NGitLab.Mock.Tests/GlobalUsings.cs b/NGitLab.Mock.Tests/GlobalUsings.cs new file mode 100644 index 00000000..bb334208 --- /dev/null +++ b/NGitLab.Mock.Tests/GlobalUsings.cs @@ -0,0 +1,5 @@ +// This is needed for quick migration from NUnit 3.x -> 4.x +// https://docs.nunit.org/articles/nunit/release-notes/Nunit4.0-MigrationGuide.html#use-global-using-aliases +global using Assert = NUnit.Framework.Legacy.ClassicAssert; +global using CollectionAssert = NUnit.Framework.Legacy.CollectionAssert; +global using StringAssert = NUnit.Framework.Legacy.StringAssert; diff --git a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj index 8c3877aa..eb868ba1 100644 --- a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj +++ b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/NGitLab.Tests/GlobalUsings.cs b/NGitLab.Tests/GlobalUsings.cs new file mode 100644 index 00000000..bb334208 --- /dev/null +++ b/NGitLab.Tests/GlobalUsings.cs @@ -0,0 +1,5 @@ +// This is needed for quick migration from NUnit 3.x -> 4.x +// https://docs.nunit.org/articles/nunit/release-notes/Nunit4.0-MigrationGuide.html#use-global-using-aliases +global using Assert = NUnit.Framework.Legacy.ClassicAssert; +global using CollectionAssert = NUnit.Framework.Legacy.CollectionAssert; +global using StringAssert = NUnit.Framework.Legacy.StringAssert; diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index d0639d17..e74f2ae4 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -17,7 +17,7 @@ - + From c72c21d580b546a915dd84c05bcd21b752c330ca Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Mon, 27 Nov 2023 10:54:01 -0500 Subject: [PATCH 054/122] Extend Mock to further support so-called LintCI (#582) * Extend Mock to further support so-called LintCI * Make mock behavior similar to GitLab's when ref is not found * Add tests --- NGitLab.Mock.Tests/LintCITests.cs | 42 ++++++++++++++++++++++++++++ NGitLab.Mock/Clients/LintClient.cs | 30 +++++++++++++++----- NGitLab.Mock/LintCI.cs | 17 +++++++++++ NGitLab.Mock/LintCICollection.cs | 9 ++++++ NGitLab.Mock/Project.cs | 3 ++ NGitLab.Mock/PublicAPI.Unshipped.txt | 8 ++++++ 6 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 NGitLab.Mock.Tests/LintCITests.cs create mode 100644 NGitLab.Mock/LintCI.cs create mode 100644 NGitLab.Mock/LintCICollection.cs diff --git a/NGitLab.Mock.Tests/LintCITests.cs b/NGitLab.Mock.Tests/LintCITests.cs new file mode 100644 index 00000000..c2c14326 --- /dev/null +++ b/NGitLab.Mock.Tests/LintCITests.cs @@ -0,0 +1,42 @@ +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using NGitLab.Models; +using NUnit.Framework; + +namespace NGitLab.Mock.Tests; + +public class LintCITests +{ + [TestCase(null, "Pipeline filtered out by workflow rules.")] + [TestCase("main", "Pipeline filtered out by workflow rules.")] + [TestCase("dummy", "Reference not found")] + public async Task Test_GetLintCIByRef(string @ref, string expectedError) + { + // Arrange + using var server = new GitLabServer(); + + var user = server.Users.AddNew("user1"); + var client = server.CreateClient(user); + + var group = new Group("SomeGroup"); + server.Groups.Add(group); + + var project = new Project("Project") { Visibility = VisibilityLevel.Internal }; + group.Projects.Add(project); + + // Simulate what GitLab would return if CI was configured not to run pipelines in "main" branch + project.LintCIs.Add(new LintCI(project.DefaultBranch, valid: false, "Pipeline filtered out by workflow rules.")); + + // Act + var result = await client.Lint.ValidateProjectCIConfigurationAsync(project.Id.ToString(CultureInfo.InvariantCulture), new LintCIOptions + { + DryRun = true, + Ref = @ref, + }); + + // Assert + Assert.IsFalse(result.Valid); + Assert.AreEqual(expectedError, result.Errors.Single()); + } +} diff --git a/NGitLab.Mock/Clients/LintClient.cs b/NGitLab.Mock/Clients/LintClient.cs index 300c7781..cefee115 100644 --- a/NGitLab.Mock/Clients/LintClient.cs +++ b/NGitLab.Mock/Clients/LintClient.cs @@ -1,27 +1,43 @@ using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using NGitLab.Models; namespace NGitLab.Mock.Clients { - internal class LintClient : ILintClient + internal class LintClient : ClientBase, ILintClient { - private readonly ClientContext _context; - public LintClient(ClientContext context) + : base(context) { - _context = context; } - public Task ValidateCIYamlContentAsync(string projectId, string yamlContent, LintCIOptions options, CancellationToken cancellationToken = default) + public Task ValidateCIYamlContentAsync(string projectId, string yamlContent, LintCIOptions options, CancellationToken cancellationToken = default) { throw new NotImplementedException(); } - public Task ValidateProjectCIConfigurationAsync(string projectId, LintCIOptions options, CancellationToken cancellationToken = default) + public async Task ValidateProjectCIConfigurationAsync(string projectId, LintCIOptions options, CancellationToken cancellationToken = default) { - throw new NotImplementedException(); + await Task.Yield(); + + using (Context.BeginOperationScope()) + { + var project = GetProject(projectId, ProjectPermission.View); + var @ref = string.IsNullOrEmpty(options.Ref) ? project.DefaultBranch : options.Ref; + + var lintCi = project.LintCIs.FirstOrDefault(ci => + { + return string.Equals(ci.Ref, @ref, StringComparison.Ordinal); + }) ?? new LintCI(@ref, valid: false, "Reference not found"); + + return new Models.LintCI + { + Valid = lintCi.Valid, + Errors = lintCi.Errors, + }; + } } } } diff --git a/NGitLab.Mock/LintCI.cs b/NGitLab.Mock/LintCI.cs new file mode 100644 index 00000000..36d08e5e --- /dev/null +++ b/NGitLab.Mock/LintCI.cs @@ -0,0 +1,17 @@ +namespace NGitLab.Mock; + +public sealed class LintCI : GitLabObject +{ + public LintCI(string @ref, bool valid, params string[] errors) + { + Ref = @ref; + Valid = valid; + Errors = errors; + } + + public string Ref { get; } + + public bool Valid { get; } + + public string[] Errors { get; } +} diff --git a/NGitLab.Mock/LintCICollection.cs b/NGitLab.Mock/LintCICollection.cs new file mode 100644 index 00000000..ab999877 --- /dev/null +++ b/NGitLab.Mock/LintCICollection.cs @@ -0,0 +1,9 @@ +namespace NGitLab.Mock; + +public sealed class LintCICollection : Collection +{ + public LintCICollection(GitLabObject container) + : base(container) + { + } +} diff --git a/NGitLab.Mock/Project.cs b/NGitLab.Mock/Project.cs index ef78ece7..5d4829e1 100644 --- a/NGitLab.Mock/Project.cs +++ b/NGitLab.Mock/Project.cs @@ -17,6 +17,7 @@ public Project(string name) Name = name ?? throw new ArgumentNullException(nameof(name)); Permissions = new PermissionCollection(this); + LintCIs = new LintCICollection(this); Hooks = new ProjectHookCollection(this); Repository = new Repository(this); RegisteredRunners = new RunnerCollection(this); @@ -103,6 +104,8 @@ public string[] Tags public PermissionCollection Permissions { get; } + public LintCICollection LintCIs { get; } + public Repository Repository { get; } public MergeRequestCollection MergeRequests { get; } diff --git a/NGitLab.Mock/PublicAPI.Unshipped.txt b/NGitLab.Mock/PublicAPI.Unshipped.txt index 3de90739..5953b669 100644 --- a/NGitLab.Mock/PublicAPI.Unshipped.txt +++ b/NGitLab.Mock/PublicAPI.Unshipped.txt @@ -587,6 +587,13 @@ NGitLab.Mock.LabelsCollection.Add(string name = null, string color = null, strin NGitLab.Mock.LabelsCollection.GetById(int id) -> NGitLab.Mock.Label NGitLab.Mock.LabelsCollection.GetByName(string name) -> NGitLab.Mock.Label NGitLab.Mock.LabelsCollection.LabelsCollection(NGitLab.Mock.GitLabObject parent) -> void +NGitLab.Mock.LintCI +NGitLab.Mock.LintCI.Errors.get -> string[] +NGitLab.Mock.LintCI.LintCI(string ref, bool valid, params string[] errors) -> void +NGitLab.Mock.LintCI.Ref.get -> string +NGitLab.Mock.LintCI.Valid.get -> bool +NGitLab.Mock.LintCICollection +NGitLab.Mock.LintCICollection.LintCICollection(NGitLab.Mock.GitLabObject container) -> void NGitLab.Mock.MergeRequest NGitLab.Mock.MergeRequest.Accept(NGitLab.Mock.User user) -> void NGitLab.Mock.MergeRequest.Approvers.get -> System.Collections.Generic.IList @@ -833,6 +840,7 @@ NGitLab.Mock.Project.Jobs.get -> NGitLab.Mock.JobCollection NGitLab.Mock.Project.Labels.get -> NGitLab.Mock.LabelsCollection NGitLab.Mock.Project.LfsEnabled.get -> bool NGitLab.Mock.Project.LfsEnabled.set -> void +NGitLab.Mock.Project.LintCIs.get -> NGitLab.Mock.LintCICollection NGitLab.Mock.Project.MergeMethod.get -> string NGitLab.Mock.Project.MergeMethod.set -> void NGitLab.Mock.Project.MergeRequests.get -> NGitLab.Mock.MergeRequestCollection From 03593a7f7e7f43c919514da013972c1f5a8302a4 Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Tue, 28 Nov 2023 14:23:03 -0500 Subject: [PATCH 055/122] Make comparison of string SHA1s in mock case-insensitive (#586) --- NGitLab.Mock/Clients/LibGit2SharpExtensions.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs b/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs index 6b86a8c8..82c6ce1d 100644 --- a/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs +++ b/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs @@ -9,7 +9,8 @@ public static class LibGit2SharpExtensions { public static Commit ToCommitClient(this LibGit2Sharp.Commit commit, Project project) { - var commitInfo = project.CommitInfos.SingleOrDefault(c => string.Equals(c.Sha, commit.Sha, StringComparison.Ordinal)); + var commitSha = new Sha1(commit.Sha); + var commitInfo = project.CommitInfos.SingleOrDefault(c => commitSha.Equals(new Sha1(c.Sha))); return new Commit { AuthoredDate = commit.Author.When.UtcDateTime, From 77089be2937792bbd1dd4a03a76dac5d484eb6ed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 07:18:15 -0500 Subject: [PATCH 056/122] Bump Meziantou.Analyzer from 2.0.112 to 2.0.118 (#588) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.112 to 2.0.118. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.112...2.0.118) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index b243e508..52584627 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 357e208431142fe680ef13e7439fa40cd1751a05 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 4 Dec 2023 08:46:22 -0500 Subject: [PATCH 057/122] Bump LibGit2Sharp from 0.28.0 to 0.29.0 (#589) Bumps [LibGit2Sharp](https://github.com/libgit2/libgit2sharp) from 0.28.0 to 0.29.0. - [Release notes](https://github.com/libgit2/libgit2sharp/releases) - [Changelog](https://github.com/libgit2/libgit2sharp/blob/master/CHANGES.md) - [Commits](https://github.com/libgit2/libgit2sharp/compare/0.28.0...0.29.0) --- updated-dependencies: - dependency-name: LibGit2Sharp dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Mock/NGitLab.Mock.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Mock/NGitLab.Mock.csproj b/NGitLab.Mock/NGitLab.Mock.csproj index 01ddcbe4..1aee352a 100644 --- a/NGitLab.Mock/NGitLab.Mock.csproj +++ b/NGitLab.Mock/NGitLab.Mock.csproj @@ -8,7 +8,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From ee644feb4ea5f5fbc8b39dc7e0f1311293e2d892 Mon Sep 17 00:00:00 2001 From: LaurentM-Ubi <81652553+LaurentM-Ubi@users.noreply.github.com> Date: Tue, 5 Dec 2023 17:34:48 +0100 Subject: [PATCH 058/122] Return empty list of environment in Mock EnvironmentClient (#590) --- NGitLab.Mock/Clients/EnvironmentClient.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NGitLab.Mock/Clients/EnvironmentClient.cs b/NGitLab.Mock/Clients/EnvironmentClient.cs index 593e2b1b..d79c15dc 100644 --- a/NGitLab.Mock/Clients/EnvironmentClient.cs +++ b/NGitLab.Mock/Clients/EnvironmentClient.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using NGitLab.Mock.Internals; using NGitLab.Models; namespace NGitLab.Mock.Clients @@ -40,7 +41,7 @@ public EnvironmentInfo Stop(int environmentId) public GitLabCollectionResponse GetEnvironmentsAsync(EnvironmentQuery query) { - throw new NotImplementedException(); + return GitLabCollectionResponse.Create(Array.Empty()); } public EnvironmentInfo GetById(int environmentId) From 14060164234b2293ccc1e715b36bcebe564a813c Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Wed, 6 Dec 2023 07:58:27 -0500 Subject: [PATCH 059/122] Add support for project's "releases_access_level" + a bit more (#591) * Add support for project's "releases_access_level" + a bit more * review * update --- .github/workflows/ci.yml | 2 +- NGitLab.Tests/Docker/GitLabDockerContainer.cs | 5 ++--- NGitLab.Tests/Docker/GitLabTestContext.cs | 8 ++++---- NGitLab.Tests/ReleaseClientTests.cs | 1 + NGitLab/Models/Project.cs | 3 +++ NGitLab/Models/ReleasesAccessLevel.cs | 8 ++++++++ NGitLab/PublicAPI.Unshipped.txt | 6 ++++++ 7 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 NGitLab/Models/ReleasesAccessLevel.cs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 621af2e4..ac3d557f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -51,8 +51,8 @@ jobs: # Keep in sync with the version in GitLabDockerContainer.cs # Available tags: https://hub.docker.com/r/gitlab/gitlab-ee/tags gitlab: [ - 'gitlab/gitlab-ee:15.4.6-ee.0', 'gitlab/gitlab-ee:15.11.9-ee.0', + 'gitlab/gitlab-ee:15.11.13-ee.0', ] configuration: [ Release ] fail-fast: false diff --git a/NGitLab.Tests/Docker/GitLabDockerContainer.cs b/NGitLab.Tests/Docker/GitLabDockerContainer.cs index faa595f7..50f81d8a 100644 --- a/NGitLab.Tests/Docker/GitLabDockerContainer.cs +++ b/NGitLab.Tests/Docker/GitLabDockerContainer.cs @@ -8,7 +8,6 @@ using System.Linq; using System.Net; using System.Net.Http; -using System.Runtime.InteropServices; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -27,7 +26,7 @@ public class GitLabDockerContainer public const string ImageName = "gitlab/gitlab-ee"; // https://hub.docker.com/r/gitlab/gitlab-ee/tags/ - public const string GitLabDockerVersion = "15.4.6-ee.0"; // Keep in sync with .github/workflows/ci.yml + public const string GitLabDockerVersion = "15.11.9-ee.0"; // Keep in sync with .github/workflows/ci.yml private static string s_creationErrorMessage; private static readonly SemaphoreSlim s_setupLock = new(initialCount: 1, maxCount: 1); @@ -156,7 +155,7 @@ private async Task SpawnDockerContainerAsync() // Spawn the container // https://docs.gitlab.com/omnibus/settings/configuration.html - using var conf = new DockerClientConfiguration(new Uri(RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "npipe://./pipe/docker_engine" : "unix:///var/run/docker.sock")); + using var conf = new DockerClientConfiguration(new Uri(OperatingSystem.IsWindows() ? "npipe://./pipe/docker_engine" : "unix:///var/run/docker.sock")); using var client = conf.CreateClient(); await ValidateDockerIsEnabled(client); diff --git a/NGitLab.Tests/Docker/GitLabTestContext.cs b/NGitLab.Tests/Docker/GitLabTestContext.cs index 421c64cd..3d4b8585 100644 --- a/NGitLab.Tests/Docker/GitLabTestContext.cs +++ b/NGitLab.Tests/Docker/GitLabTestContext.cs @@ -300,11 +300,11 @@ public async Task StartRunnerForOneJobAsync(int projectId) if (!File.Exists(path)) { Uri url; - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { url = new Uri($"https://gitlab-runner-downloads.s3.amazonaws.com/v{version}/binaries/gitlab-runner-windows-amd64.exe"); } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + else if (OperatingSystem.IsLinux()) { url = new Uri($"https://gitlab-runner-downloads.s3.amazonaws.com/v{version}/binaries/gitlab-runner-linux-amd64"); } @@ -335,7 +335,7 @@ public async Task StartRunnerForOneJobAsync(int projectId) } TestContext.WriteLine("Test runner downloaded"); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + if (OperatingSystem.IsLinux()) { using var chmodProcess = Process.Start("chmod", "+x \"" + path + "\""); chmodProcess.WaitForExit(); @@ -379,7 +379,7 @@ public async Task StartRunnerForOneJobAsync(int projectId) "run-single", "--url", DockerContainer.GitLabUrl.ToString(), "--executor", "shell", - "--shell", RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "powershell" : "pwsh", + "--shell", OperatingSystem.IsWindows() ? "powershell" : "pwsh", "--builds-dir", buildDir, "--wait-timeout", "240", // in seconds "--token", runner.Token, diff --git a/NGitLab.Tests/ReleaseClientTests.cs b/NGitLab.Tests/ReleaseClientTests.cs index 1d8811d2..693d7fe8 100644 --- a/NGitLab.Tests/ReleaseClientTests.cs +++ b/NGitLab.Tests/ReleaseClientTests.cs @@ -30,6 +30,7 @@ public async Task Test_release_api() Description = "test", }); + Assert.AreEqual(ReleasesAccessLevel.Enabled, project.ReleasesAccessLevel); Assert.That(release.TagName, Is.EqualTo("0.7")); Assert.That(release.Name, Is.EqualTo("0.7")); Assert.That(release.Description, Is.EqualTo("test")); diff --git a/NGitLab/Models/Project.cs b/NGitLab/Models/Project.cs index 4a64c029..740693e7 100644 --- a/NGitLab/Models/Project.cs +++ b/NGitLab/Models/Project.cs @@ -212,5 +212,8 @@ public class Project [JsonPropertyName("permissions")] public ProjectPermissions Permissions; + + [JsonPropertyName("releases_access_level")] + public ReleasesAccessLevel ReleasesAccessLevel { get; set; } } } diff --git a/NGitLab/Models/ReleasesAccessLevel.cs b/NGitLab/Models/ReleasesAccessLevel.cs new file mode 100644 index 00000000..ccc1fbad --- /dev/null +++ b/NGitLab/Models/ReleasesAccessLevel.cs @@ -0,0 +1,8 @@ +namespace NGitLab.Models; + +public enum ReleasesAccessLevel +{ + Disabled, + Private, + Enabled, +} diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index 0df41368..d050bf0b 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -2731,6 +2731,8 @@ NGitLab.Models.Project.PrintingMergeRequestsLinkEnabled -> bool NGitLab.Models.Project.Project() -> void NGitLab.Models.Project.Public -> bool NGitLab.Models.Project.PublicJobs -> bool +NGitLab.Models.Project.ReleasesAccessLevel.get -> NGitLab.Models.ReleasesAccessLevel +NGitLab.Models.Project.ReleasesAccessLevel.set -> void NGitLab.Models.Project.RepositoryAccessLevel -> NGitLab.Models.RepositoryAccessLevel NGitLab.Models.Project.RepositoryStorage -> string NGitLab.Models.Project.RequestAccessEnabled -> bool @@ -3146,6 +3148,10 @@ NGitLab.Models.ReleaseQuery.PerPage.set -> void NGitLab.Models.ReleaseQuery.ReleaseQuery() -> void NGitLab.Models.ReleaseQuery.Sort.get -> string NGitLab.Models.ReleaseQuery.Sort.set -> void +NGitLab.Models.ReleasesAccessLevel +NGitLab.Models.ReleasesAccessLevel.Disabled = 0 -> NGitLab.Models.ReleasesAccessLevel +NGitLab.Models.ReleasesAccessLevel.Enabled = 2 -> NGitLab.Models.ReleasesAccessLevel +NGitLab.Models.ReleasesAccessLevel.Private = 1 -> NGitLab.Models.ReleasesAccessLevel NGitLab.Models.ReleaseUpdate NGitLab.Models.ReleaseUpdate.Description.get -> string NGitLab.Models.ReleaseUpdate.Description.set -> void From 8704e7fe20d662ff744ae0256dd045c3ac577943 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 07:22:50 -0500 Subject: [PATCH 060/122] Bump actions/setup-dotnet from 3 to 4 (#592) Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3 to 4. - [Release notes](https://github.com/actions/setup-dotnet/releases) - [Commits](https://github.com/actions/setup-dotnet/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/setup-dotnet dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ac3d557f..65f7ee1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,7 +27,7 @@ jobs: with: fetch-depth: 0 # Get all the history so MinGit can compute the version - name: Setup .NET Core (latest) - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - run: dotnet pack NGitLab.sln --configuration Release --output ${{ env.NuGetDirectory }} /bl - uses: actions/upload-artifact@v3 with: @@ -67,7 +67,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup .NET Core (latest) - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - run: | $value = "${{ matrix.gitlab }}-${{ matrix.configuration }}".Replace(':', '-').Replace('/', '-') "artifact_name=test-results-$value" >> $env:GITHUB_OUTPUT @@ -101,7 +101,7 @@ jobs: name: nuget path: ${{ env.NuGetDirectory }} - name: Setup .NET Core - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 - run: | Write-Host "Current ref: $env:GITHUB_REF" Write-Host "Searching nupkg in folder: ${{ env.NuGetDirectory }}" From 9d77aa8e5ad6336bdc2e41baf484efc917dbcb1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 11 Dec 2023 12:45:12 +0000 Subject: [PATCH 061/122] Bump NUnit from 4.0.0 to 4.0.1 (#593) Bumps [NUnit](https://github.com/nunit/nunit) from 4.0.0 to 4.0.1. - [Release notes](https://github.com/nunit/nunit/releases) - [Changelog](https://github.com/nunit/nunit/blob/master/CHANGES.md) - [Commits](https://github.com/nunit/nunit/compare/v4.0.0...v4.0.1) --- updated-dependencies: - dependency-name: NUnit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj | 2 +- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj index eb868ba1..d07af6f3 100644 --- a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj +++ b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj @@ -8,7 +8,7 @@ - + diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index e74f2ae4..bb9efcec 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -17,7 +17,7 @@ - + From 8ab7396758afd48ddfb60d19ade3d4f86ae6c5f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 07:56:39 -0500 Subject: [PATCH 062/122] Bump Meziantou.Analyzer from 2.0.118 to 2.0.123 (#598) Bumps [Meziantou.Analyzer](https://github.com/meziantou/Meziantou.Analyzer) from 2.0.118 to 2.0.123. - [Release notes](https://github.com/meziantou/Meziantou.Analyzer/releases) - [Commits](https://github.com/meziantou/Meziantou.Analyzer/compare/2.0.118...2.0.123) --- updated-dependencies: - dependency-name: Meziantou.Analyzer dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Build.props b/Directory.Build.props index 52584627..866f38c4 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -42,7 +42,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 0b94429a9014b434bfae50a051cae5092872bb77 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 08:20:00 -0500 Subject: [PATCH 063/122] Bump Meziantou.Framework.Versioning from 1.3.3 to 1.3.4 (#595) Bumps [Meziantou.Framework.Versioning](https://github.com/meziantou/Meziantou.Framework) from 1.3.3 to 1.3.4. - [Commits](https://github.com/meziantou/Meziantou.Framework/commits) --- updated-dependencies: - dependency-name: Meziantou.Framework.Versioning dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- NGitLab.Tests/NGitLab.Tests.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index bb9efcec..f2ea6c6d 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -11,7 +11,7 @@ - + From c292927381520d3cd073ca5b69ac06f30414d7f0 Mon Sep 17 00:00:00 2001 From: AceBlackGloss Date: Mon, 18 Dec 2023 22:30:23 +0800 Subject: [PATCH 064/122] Fix adding the wrong scope parameter. (#599) --- NGitLab.Tests/PipelineTests.cs | 20 ++++++++++++++++++++ NGitLab/Impl/PipelineClient.cs | 4 ++-- NGitLab/Impl/Utils.cs | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/NGitLab.Tests/PipelineTests.cs b/NGitLab.Tests/PipelineTests.cs index 80c004f9..8991ce29 100644 --- a/NGitLab.Tests/PipelineTests.cs +++ b/NGitLab.Tests/PipelineTests.cs @@ -74,6 +74,26 @@ public async Task Test_can_list_all_jobs_from_project() Assert.That(allJobs.Any()); } + [Test] + [NGitLabRetry] + public async Task Test_can_list_jobs_from_pipeline() + { + using var context = await GitLabTestContext.CreateAsync(); + var project = context.CreateProject(); + var pipelineClient = context.Client.GetPipelines(project.Id); + JobTests.AddGitLabCiFile(context.Client, project); + + var pipelines = await GitLabTestContext.RetryUntilAsync(() => pipelineClient.All, p => p.Any(), TimeSpan.FromSeconds(120)); + var pipeline = pipelines.First(); + + var pipelineJobQuery = new PipelineJobQuery + { + PipelineId = pipeline.Id, Scope = new[] { "success", "pending" }, + }; + var allJobs = await GitLabTestContext.RetryUntilAsync(() => pipelineClient.GetJobsAsync(pipelineJobQuery).ToList(), p => p.Any(), TimeSpan.FromSeconds(120)); + Assert.That(allJobs.Any()); + } + [Test] [NGitLabRetry] public async Task Test_search_for_pipeline() diff --git a/NGitLab/Impl/PipelineClient.cs b/NGitLab/Impl/PipelineClient.cs index a512cdf1..720e8fcb 100644 --- a/NGitLab/Impl/PipelineClient.cs +++ b/NGitLab/Impl/PipelineClient.cs @@ -84,7 +84,7 @@ public GitLabCollectionResponse GetJobsAsync(PipelineJobQuery query) private string CreateGetJobsUrl(PipelineJobQuery query) { var url = $"{_pipelinesPath}/{query.PipelineId.ToStringInvariant()}/jobs"; - url = Utils.AddParameter(url, "scope", query.Scope); + url = Utils.AddArrayParameter(url, "scope", query.Scope); url = Utils.AddParameter(url, "include_retried", query.IncludeRetried); return url; } @@ -213,7 +213,7 @@ public GitLabCollectionResponse GetBridgesAsync(PipelineBridgeQuery quer private string CreateGetBridgesUrl(PipelineBridgeQuery query) { var url = $"{_pipelinesPath}/{query.PipelineId.ToStringInvariant()}/bridges"; - url = Utils.AddParameter(url, "scope", query.Scope); + url = Utils.AddArrayParameter(url, "scope", query.Scope); return url; } diff --git a/NGitLab/Impl/Utils.cs b/NGitLab/Impl/Utils.cs index 17b4a513..6ed245bb 100644 --- a/NGitLab/Impl/Utils.cs +++ b/NGitLab/Impl/Utils.cs @@ -29,6 +29,21 @@ public static string AddParameter(string url, string parameterName, int[] values return Equals(values, null) ? url : AddParameterInternal(url, parameterName, string.Join(",", values)); } + public static string AddArrayParameter(string url, string parameterName, string[] values) + { + if (Equals(values, null)) + { + return url; + } + + foreach (var value in values) + { + url = AddParameterInternal(url, $"{parameterName}[]", value); + } + + return url; + } + public static string AddOrderBy(string url, string orderBy = null, bool supportKeysetPagination = true) { if (supportKeysetPagination && (string.IsNullOrEmpty(orderBy) || string.Equals(orderBy, "id", StringComparison.Ordinal))) From cc093dff84d4df85fba73a4a48b1c7201ff44247 Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Mon, 18 Dec 2023 09:50:59 -0500 Subject: [PATCH 065/122] Configure GitHub Actions' updates to be grouped into a single PR (#600) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gérald Barré --- .github/dependabot.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 477f3434..2c7b765c 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,7 +1,7 @@ # To get started with Dependabot version updates, you'll need to specify which # package ecosystems to update and where the package manifests are located. # Please see the documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file version: 2 updates: @@ -18,6 +18,10 @@ updates: interval: weekly rebase-strategy: auto open-pull-requests-limit: 20 + groups: + github-actions: + patterns: + - "*" - package-ecosystem: "npm" directory: "/" From 658a3fb95511cd6f19cc7381b52e79bf03b88775 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 18 Dec 2023 15:29:10 +0000 Subject: [PATCH 066/122] Bump the github-actions group with 2 updates (#601) Bumps the github-actions group with 2 updates: [actions/upload-artifact](https://github.com/actions/upload-artifact) and [actions/download-artifact](https://github.com/actions/download-artifact). Updates `actions/upload-artifact` from 3 to 4 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) Updates `actions/download-artifact` from 3 to 4 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major dependency-group: github-actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 65f7ee1d..260f7f0a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,13 +29,13 @@ jobs: - name: Setup .NET Core (latest) uses: actions/setup-dotnet@v4 - run: dotnet pack NGitLab.sln --configuration Release --output ${{ env.NuGetDirectory }} /bl - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: nuget if-no-files-found: error retention-days: 7 path: ${{ env.NuGetDirectory }}/**/* - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: binlogs if-no-files-found: error @@ -75,7 +75,7 @@ jobs: id: set-artifact-name - run: dotnet test --configuration ${{ matrix.configuration }} --logger trx --results-directory "${{ env.TestResultsDirectory }}" --collect:"XPlat Code Coverage" /p:RunAnalyzers=false name: Run tests - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 if: always() with: name: ${{ steps.set-artifact-name.outputs.artifact_name }} @@ -96,7 +96,7 @@ jobs: runs-on: 'ubuntu-20.04' needs: [ create_nuget, build_and_test ] steps: - - uses: actions/download-artifact@v3 + - uses: actions/download-artifact@v4 with: name: nuget path: ${{ env.NuGetDirectory }} From 4278a311f0d7a78e811803c94dc5dccb0a0bc107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Myka=C3=ABl=20Lemieux-Lafontaine?= <132388133+mlemieuxlafontaine-ubi@users.noreply.github.com> Date: Mon, 18 Dec 2023 15:53:40 -0500 Subject: [PATCH 067/122] Add Merge Error field on Merge Request Model (#602) Add Missing MergeRequest field Adds the "merge_error" field, that gets field when rebasing / merging through the API fails for any reason --- NGitLab/Models/MergeRequest.cs | 3 +++ NGitLab/PublicAPI.Unshipped.txt | 2 ++ 2 files changed, 5 insertions(+) diff --git a/NGitLab/Models/MergeRequest.cs b/NGitLab/Models/MergeRequest.cs index 52c45d10..f3dae0ad 100644 --- a/NGitLab/Models/MergeRequest.cs +++ b/NGitLab/Models/MergeRequest.cs @@ -147,5 +147,8 @@ public class MergeRequest [JsonPropertyName("detailed_merge_status")] public DynamicEnum DetailedMergeStatus { get; set; } + [JsonPropertyName("merge_error")] + public string MergeError { get; set; } + public override string ToString() => $"!{Id.ToStringInvariant()}: {Title}"; } diff --git a/NGitLab/PublicAPI.Unshipped.txt b/NGitLab/PublicAPI.Unshipped.txt index d050bf0b..cef8008b 100644 --- a/NGitLab/PublicAPI.Unshipped.txt +++ b/NGitLab/PublicAPI.Unshipped.txt @@ -2234,6 +2234,8 @@ NGitLab.Models.MergeRequest.Labels -> string[] NGitLab.Models.MergeRequest.MergeCommitSha -> string NGitLab.Models.MergeRequest.MergedAt -> System.DateTime? NGitLab.Models.MergeRequest.MergedBy -> NGitLab.Models.User +NGitLab.Models.MergeRequest.MergeError.get -> string +NGitLab.Models.MergeRequest.MergeError.set -> void NGitLab.Models.MergeRequest.MergeRequest() -> void NGitLab.Models.MergeRequest.MergeStatus -> string NGitLab.Models.MergeRequest.MergeWhenPipelineSucceeds -> bool From f8031d8455f2e4bd11f79cb242a347aaacd5caa3 Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Wed, 20 Dec 2023 15:08:04 -0500 Subject: [PATCH 068/122] Improve NUnit tests (#603) * Improve NUnit tests - Add package reference to `NUnit.Analyzers` - Use analyzer fixers to convert asserts to constraint models - Remove the no longer necessary `GlobalUsings.cs` * tweaks --- .editorconfig | 3 + NGitLab.Mock.Tests/BranchesMockTests.cs | 10 +- NGitLab.Mock.Tests/CommitsMockTests.cs | 24 ++-- NGitLab.Mock.Tests/ConfigTests.cs | 68 +++++----- NGitLab.Mock.Tests/GlobalUsings.cs | 5 - NGitLab.Mock.Tests/GroupsMockTests.cs | 8 +- NGitLab.Mock.Tests/IssuesMockTests.cs | 24 ++-- NGitLab.Mock.Tests/LabelsMockTests.cs | 30 ++-- NGitLab.Mock.Tests/LintCITests.cs | 4 +- NGitLab.Mock.Tests/MembersMockTests.cs | 8 +- NGitLab.Mock.Tests/MergeRequestsMockTests.cs | 90 ++++++------ NGitLab.Mock.Tests/MilestonesMockTests.cs | 28 ++-- NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj | 4 + NGitLab.Mock.Tests/PipelineTests.cs | 22 +-- NGitLab.Mock.Tests/ProjectsMockTests.cs | 48 +++---- NGitLab.Mock.Tests/ReleasesMockTests.cs | 18 +-- NGitLab.Mock.Tests/TagTests.cs | 4 +- NGitLab.Tests/BranchClientTests.cs | 44 +++--- NGitLab.Tests/CommitStatusTests.cs | 48 +++---- NGitLab.Tests/CommitsTests.cs | 14 +- NGitLab.Tests/CompareTests.cs | 8 +- NGitLab.Tests/ContributorsTests.cs | 8 +- NGitLab.Tests/Docker/GitLabTestContext.cs | 8 +- NGitLab.Tests/EnvironmentsTests.cs | 96 ++++++------- NGitLab.Tests/FilesTests.cs | 73 +++++----- NGitLab.Tests/GitLabChangeDiffCounterTests.cs | 4 +- NGitLab.Tests/GitLabCredentialsTests.cs | 2 +- NGitLab.Tests/GlobalUsings.cs | 5 - NGitLab.Tests/GraphQLTests.cs | 4 +- NGitLab.Tests/GroupBadgeClientTests.cs | 16 +-- NGitLab.Tests/GroupVariableClientTests.cs | 16 +-- NGitLab.Tests/GroupsTests.cs | 128 +++++++++--------- NGitLab.Tests/HttpRequestorTests.cs | 16 +-- NGitLab.Tests/Impl/DynamicEnumTests.cs | 8 +- NGitLab.Tests/Impl/JsonConverterTests.cs | 32 ++--- NGitLab.Tests/IssueTests.cs | 64 ++++----- NGitLab.Tests/JobTests.cs | 46 +++---- NGitLab.Tests/JsonTests.cs | 6 +- NGitLab.Tests/LintClientTests.cs | 24 ++-- NGitLab.Tests/MembersClientTests.cs | 20 +-- .../MergeRequestChangesClientTests.cs | 14 +- .../MergeRequest/MergeRequestClientTests.cs | 74 +++++----- .../MergeRequestCommentsClientTests.cs | 6 +- .../MergeRequestDiscussionsClientTests.cs | 6 +- .../Milestone/MilestoneClientTests.cs | 20 +-- NGitLab.Tests/NGitLab.Tests.csproj | 4 + NGitLab.Tests/NamespacesTests.cs | 12 +- NGitLab.Tests/PipelineTests.cs | 54 ++++---- NGitLab.Tests/ProjectBadgeClientTests.cs | 18 +-- .../ProjectLevelApprovalRulesClientTests.cs | 20 +-- NGitLab.Tests/ProjectVariableClientTests.cs | 16 +-- NGitLab.Tests/ProjectsTests.cs | 74 +++++----- NGitLab.Tests/ProtectedBranchTests.cs | 14 +- NGitLab.Tests/ProtectedTagTests.cs | 22 +-- NGitLab.Tests/ReleaseClientTests.cs | 16 +-- .../RepositoryClient/BranchClientTests.cs | 16 +-- .../ProjectHooksClientTests.cs | 42 +++--- .../RepositoryClient/RepositoryClientTests.cs | 60 ++++---- NGitLab.Tests/RunnerTests.cs | 42 ++---- NGitLab.Tests/Sha1Tests.cs | 6 +- NGitLab.Tests/SnippetsTest.cs | 24 ++-- NGitLab.Tests/TagTests.cs | 14 +- NGitLab.Tests/TriggerTests.cs | 6 +- NGitLab.Tests/UsersTests.cs | 26 ++-- 64 files changed, 835 insertions(+), 859 deletions(-) delete mode 100644 NGitLab.Mock.Tests/GlobalUsings.cs delete mode 100644 NGitLab.Tests/GlobalUsings.cs diff --git a/.editorconfig b/.editorconfig index dc8e66ff..69fc9750 100644 --- a/.editorconfig +++ b/.editorconfig @@ -260,6 +260,9 @@ dotnet_diagnostic.SA1101.severity = none # SA1116: Split parameters should start on line after declaration dotnet_diagnostic.SA1116.severity = silent +# SA1118: Parameter should not span multiple lines +dotnet_diagnostic.SA1118.severity = suggestion + # SA1122: Use string.Empty for empty strings dotnet_diagnostic.SA1122.severity = none diff --git a/NGitLab.Mock.Tests/BranchesMockTests.cs b/NGitLab.Mock.Tests/BranchesMockTests.cs index 18c4d03f..f9a2d962 100644 --- a/NGitLab.Mock.Tests/BranchesMockTests.cs +++ b/NGitLab.Mock.Tests/BranchesMockTests.cs @@ -21,22 +21,22 @@ public void Test_search_branches() var branches = branchClient.Search("main").ToList(); var expectedBranch = branches.Single(); - Assert.AreEqual("main", expectedBranch.Name); + Assert.That(expectedBranch.Name, Is.EqualTo("main")); branches = branchClient.Search("^main$").ToList(); expectedBranch = branches.Single(); - Assert.AreEqual("main", expectedBranch.Name); + Assert.That(expectedBranch.Name, Is.EqualTo("main")); branches = branchClient.Search("^branch").ToList(); expectedBranch = branches.Single(); - Assert.AreEqual("branch_1", expectedBranch.Name); + Assert.That(expectedBranch.Name, Is.EqualTo("branch_1")); branches = branchClient.Search("1$").ToList(); expectedBranch = branches.Single(); - Assert.AreEqual("branch_1", expectedBranch.Name); + Assert.That(expectedBranch.Name, Is.EqualTo("branch_1")); branches = branchClient.Search("foobar").ToList(); - Assert.IsEmpty(branches); + Assert.That(branches, Is.Empty); } } } diff --git a/NGitLab.Mock.Tests/CommitsMockTests.cs b/NGitLab.Mock.Tests/CommitsMockTests.cs index f6a587d3..f7dcd0b7 100644 --- a/NGitLab.Mock.Tests/CommitsMockTests.cs +++ b/NGitLab.Mock.Tests/CommitsMockTests.cs @@ -20,7 +20,7 @@ public void Test_commits_added_can_be_found() var client = server.CreateClient(); var commit = client.GetCommits(1).GetCommit("branch-01"); - Assert.AreEqual("Create branch", commit.Message.TrimEnd('\r', '\n')); + Assert.That(commit.Message.TrimEnd('\r', '\n'), Is.EqualTo("Create branch")); } [Test] @@ -36,7 +36,7 @@ public void Test_commits_with_tags_can_be_found() var client = server.CreateClient(); var commit = client.GetCommits(1).GetCommit("1.0.0"); - Assert.AreEqual("Changes with tag", commit.Message.TrimEnd('\r', '\n')); + Assert.That(commit.Message.TrimEnd('\r', '\n'), Is.EqualTo("Changes with tag")); } [Test] @@ -53,7 +53,7 @@ public void Test_tags_from_commit_can_be_found() var tags = client.GetRepository(1).Tags.All.ToArray(); Assert.That(tags, Has.One.Items); - Assert.AreEqual("1.0.0", tags[0].Name); + Assert.That(tags[0].Name, Is.EqualTo("1.0.0")); } [Test] @@ -72,11 +72,11 @@ public void Test_two_branches_can_be_created_from_same_commit() var commitFromBranch1 = repository.GetCommits("branch_1").FirstOrDefault(); var commitFromBranch2 = repository.GetCommits("branch_2").FirstOrDefault(); - Assert.NotNull(commitFromBranch1); - Assert.NotNull(commitFromBranch2); - Assert.IsNotEmpty(commitFromBranch1.Parents); - Assert.IsNotEmpty(commitFromBranch2.Parents); - Assert.AreEqual(commitFromBranch1.Parents[0], commitFromBranch2.Parents[0]); + Assert.That(commitFromBranch1, Is.Not.Null); + Assert.That(commitFromBranch2, Is.Not.Null); + Assert.That(commitFromBranch1.Parents, Is.Not.Empty); + Assert.That(commitFromBranch2.Parents, Is.Not.Empty); + Assert.That(commitFromBranch2.Parents[0], Is.EqualTo(commitFromBranch1.Parents[0])); } [Test] @@ -98,11 +98,11 @@ public void Test_GetCommitsBetweenTwoRefs() var intermediateCommits = repository.GetCommits("main..branch_1"); // Assert - CollectionAssert.AreEqual(new[] + Assert.That(intermediateCommits.Select(c => c.Title), Is.EqualTo(new[] { "Yet another commit for branch_1", "Commit for branch_1", - }, intermediateCommits.Select(c => c.Title)); + }).AsCollection); } [Test] @@ -118,14 +118,14 @@ public void Test_commits_can_be_cherry_pick() var client = server.CreateClient(); var repository = client.GetRepository(1); var commitFromBranch1 = repository.GetCommits("branch_1").FirstOrDefault(); - Assert.NotNull(commitFromBranch1); + Assert.That(commitFromBranch1, Is.Not.Null); var cherryPicked = client.GetCommits(1).CherryPick(new CommitCherryPick { Sha = commitFromBranch1.Id, Branch = "main", }); - Assert.NotNull(cherryPicked); + Assert.That(cherryPicked, Is.Not.Null); } } } diff --git a/NGitLab.Mock.Tests/ConfigTests.cs b/NGitLab.Mock.Tests/ConfigTests.cs index 1316f8e1..6e02f336 100644 --- a/NGitLab.Mock.Tests/ConfigTests.cs +++ b/NGitLab.Mock.Tests/ConfigTests.cs @@ -40,33 +40,33 @@ public void Test_server_can_be_saved_in_config() project.Permissions.Add(new Permission(user, AccessLevel.Owner)); var config = server.ToConfig(); - Assert.IsNotNull(config); + Assert.That(config, Is.Not.Null); Assert.That(config.Users, Has.One.Items); - Assert.AreEqual("user1", config.Users[0].Username); + Assert.That(config.Users[0].Username, Is.EqualTo("user1")); Assert.That(config.Groups, Has.One.Items); - Assert.AreEqual("unit-tests", config.Groups[0].Name); + Assert.That(config.Groups[0].Name, Is.EqualTo("unit-tests")); Assert.That(config.Projects, Has.One.Items); - Assert.AreEqual("test-project", config.Projects[0].Name); - Assert.AreEqual("unit-tests", config.Projects[0].Namespace); - Assert.AreEqual("Test project", config.Projects[0].Description); - Assert.AreEqual("default", config.Projects[0].DefaultBranch); - Assert.AreEqual(VisibilityLevel.Public, config.Projects[0].Visibility); + Assert.That(config.Projects[0].Name, Is.EqualTo("test-project")); + Assert.That(config.Projects[0].Namespace, Is.EqualTo("unit-tests")); + Assert.That(config.Projects[0].Description, Is.EqualTo("Test project")); + Assert.That(config.Projects[0].DefaultBranch, Is.EqualTo("default")); + Assert.That(config.Projects[0].Visibility, Is.EqualTo(VisibilityLevel.Public)); Assert.That(config.Projects[0].Labels, Has.One.Items); - Assert.AreEqual("label1", config.Projects[0].Labels[0].Name); + Assert.That(config.Projects[0].Labels[0].Name, Is.EqualTo("label1")); Assert.That(config.Projects[0].Issues, Has.One.Items); - Assert.AreEqual("Issue #1", config.Projects[0].Issues[0].Title); - Assert.AreEqual("My issue", config.Projects[0].Issues[0].Description); - Assert.AreEqual("user1", config.Projects[0].Issues[0].Author); + Assert.That(config.Projects[0].Issues[0].Title, Is.EqualTo("Issue #1")); + Assert.That(config.Projects[0].Issues[0].Description, Is.EqualTo("My issue")); + Assert.That(config.Projects[0].Issues[0].Author, Is.EqualTo("user1")); Assert.That(config.Projects[0].Issues[0].Labels, Has.One.Items); - Assert.AreEqual("label1", config.Projects[0].Issues[0].Labels[0]); + Assert.That(config.Projects[0].Issues[0].Labels[0], Is.EqualTo("label1")); Assert.That(config.Projects[0].MergeRequests, Has.One.Items); - Assert.AreEqual("Merge request #1", config.Projects[0].MergeRequests[0].Title); - Assert.AreEqual("My merge request", config.Projects[0].MergeRequests[0].Description); - Assert.AreEqual("user1", config.Projects[0].MergeRequests[0].Author); + Assert.That(config.Projects[0].MergeRequests[0].Title, Is.EqualTo("Merge request #1")); + Assert.That(config.Projects[0].MergeRequests[0].Description, Is.EqualTo("My merge request")); + Assert.That(config.Projects[0].MergeRequests[0].Author, Is.EqualTo("user1")); Assert.That(config.Projects[0].Permissions, Has.One.Items); - Assert.AreEqual("user1", config.Projects[0].Permissions[0].User); - Assert.AreEqual(AccessLevel.Owner, config.Projects[0].Permissions[0].Level); + Assert.That(config.Projects[0].Permissions[0].User, Is.EqualTo("user1")); + Assert.That(config.Projects[0].Permissions[0].Level, Is.EqualTo(AccessLevel.Owner)); } [Test] @@ -84,30 +84,30 @@ public void Test_config_can_be_serialized() .WithProject("project-2"); var content = config.Serialize(); - Assert.IsNotEmpty(content); + Assert.That(content, Is.Not.Empty); var config2 = GitLabConfig.Deserialize(content); - Assert.IsNotNull(config2); + Assert.That(config2, Is.Not.Null); Assert.That(config2.Users, Has.One.Items); - Assert.AreEqual("user1", config2.Users[0].Username); + Assert.That(config2.Users[0].Username, Is.EqualTo("user1")); Assert.That(config2.Projects, Has.Exactly(2).Items); - Assert.AreEqual("project-1", config2.Projects[0].Name); - Assert.AreEqual("Project #1", config2.Projects[0].Description); - Assert.AreEqual(VisibilityLevel.Public, config2.Projects[0].Visibility); + Assert.That(config2.Projects[0].Name, Is.EqualTo("project-1")); + Assert.That(config2.Projects[0].Description, Is.EqualTo("Project #1")); + Assert.That(config2.Projects[0].Visibility, Is.EqualTo(VisibilityLevel.Public)); Assert.That(config2.Projects[0].Commits, Has.Exactly(2).Items); - Assert.AreEqual("Initial commit", config2.Projects[0].Commits[0].Message); - Assert.AreEqual("Create branch", config2.Projects[0].Commits[1].Message); + Assert.That(config2.Projects[0].Commits[0].Message, Is.EqualTo("Initial commit")); + Assert.That(config2.Projects[0].Commits[1].Message, Is.EqualTo("Create branch")); Assert.That(config2.Projects[0].Issues, Has.One.Items); - Assert.AreEqual("Issue #1", config2.Projects[0].Issues[0].Title); + Assert.That(config2.Projects[0].Issues[0].Title, Is.EqualTo("Issue #1")); Assert.That(config2.Projects[0].MergeRequests, Has.One.Items); - Assert.AreEqual("Merge request #1", config2.Projects[0].MergeRequests[0].Title); + Assert.That(config2.Projects[0].MergeRequests[0].Title, Is.EqualTo("Merge request #1")); Assert.That(config2.Projects[0].Permissions, Has.One.Items); - Assert.AreEqual("user1", config2.Projects[0].Permissions[0].User); - Assert.AreEqual("project-2", config2.Projects[1].Name); + Assert.That(config2.Projects[0].Permissions[0].User, Is.EqualTo("user1")); + Assert.That(config2.Projects[1].Name, Is.EqualTo("project-2")); using var server = config2.BuildServer(); - Assert.IsNotNull(server); + Assert.That(server, Is.Not.Null); } [Test] @@ -125,15 +125,15 @@ public void Test_job_ids_are_unique() .WithPipeline("C1", p => p.WithJob().WithJob())); using var server = config.BuildServer(); - Assert.IsNotNull(server); + Assert.That(server, Is.Not.Null); var project1 = server.AllProjects.FirstOrDefault(); - Assert.IsNotNull(project1); + Assert.That(project1, Is.Not.Null); project1.Jobs.Should().BeEquivalentTo(new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } }); var project2 = server.AllProjects.LastOrDefault(); - Assert.IsNotNull(project2); + Assert.That(project2, Is.Not.Null); project2.Jobs.Should().BeEquivalentTo(new[] { new { Id = 4 }, new { Id = 5 } }); } diff --git a/NGitLab.Mock.Tests/GlobalUsings.cs b/NGitLab.Mock.Tests/GlobalUsings.cs deleted file mode 100644 index bb334208..00000000 --- a/NGitLab.Mock.Tests/GlobalUsings.cs +++ /dev/null @@ -1,5 +0,0 @@ -// This is needed for quick migration from NUnit 3.x -> 4.x -// https://docs.nunit.org/articles/nunit/release-notes/Nunit4.0-MigrationGuide.html#use-global-using-aliases -global using Assert = NUnit.Framework.Legacy.ClassicAssert; -global using CollectionAssert = NUnit.Framework.Legacy.CollectionAssert; -global using StringAssert = NUnit.Framework.Legacy.StringAssert; diff --git a/NGitLab.Mock.Tests/GroupsMockTests.cs b/NGitLab.Mock.Tests/GroupsMockTests.cs index d2f08c5d..a8af88f7 100644 --- a/NGitLab.Mock.Tests/GroupsMockTests.cs +++ b/NGitLab.Mock.Tests/GroupsMockTests.cs @@ -21,7 +21,7 @@ public async Task Test_group_get_by_id() var client = server.CreateClient("user1"); var group = await client.Groups.GetByIdAsync(1); - Assert.AreEqual("G1", group.Name, "Subgroups found are invalid"); + Assert.That(group.Name, Is.EqualTo("G1"), "Subgroups found are invalid"); } [Test] @@ -38,7 +38,7 @@ public async Task Test_group_get_by_fullpath() var client = server.CreateClient("user1"); var group = await client.Groups.GetByFullPathAsync("name3"); - Assert.AreEqual("name3", group.FullPath, "Subgroups found are invalid"); + Assert.That(group.FullPath, Is.EqualTo("name3"), "Subgroups found are invalid"); } [Test] @@ -57,7 +57,7 @@ public void Test_get_subgroups_by_id() var client = server.CreateClient("user1"); var group = client.Groups.GetSubgroupsByIdAsync(12, new Models.SubgroupQuery { }); - Assert.AreEqual(2, group.Count(), "Subgroups found are invalid"); + Assert.That(group.Count(), Is.EqualTo(2), "Subgroups found are invalid"); } [Test] @@ -76,7 +76,7 @@ public void Test_get_subgroups_by_fullpath() var client = server.CreateClient("user1"); var group = client.Groups.GetSubgroupsByFullPathAsync("parentgroup1", new Models.SubgroupQuery { }); - Assert.AreEqual(2, group.Count(), "Subgroups found are invalid"); + Assert.That(group.Count(), Is.EqualTo(2), "Subgroups found are invalid"); } } } diff --git a/NGitLab.Mock.Tests/IssuesMockTests.cs b/NGitLab.Mock.Tests/IssuesMockTests.cs index 6525987c..a7b90f3b 100644 --- a/NGitLab.Mock.Tests/IssuesMockTests.cs +++ b/NGitLab.Mock.Tests/IssuesMockTests.cs @@ -21,8 +21,8 @@ public void Test_issues_created_by_me_can_be_listed() var client = server.CreateClient("user1"); var issues = client.Issues.Get(new IssueQuery { Scope = "created_by_me" }).ToArray(); - Assert.AreEqual(1, issues.Length, "Issues count is invalid"); - Assert.AreEqual("Issue 1", issues[0].Title, "Issue found is invalid"); + Assert.That(issues, Has.Length.EqualTo(1), "Issues count is invalid"); + Assert.That(issues[0].Title, Is.EqualTo("Issue 1"), "Issue found is invalid"); } [Test] @@ -39,8 +39,8 @@ public void Test_issues_assigned_to_me_can_be_listed() var client = server.CreateClient("user1"); var issues = client.Issues.Get(new IssueQuery { Scope = "assigned_to_me" }).ToArray(); - Assert.AreEqual(1, issues.Length, "Issues count is invalid"); - Assert.AreEqual("Issue 2", issues[0].Title, "Issue found is invalid"); + Assert.That(issues, Has.Length.EqualTo(1), "Issues count is invalid"); + Assert.That(issues[0].Title, Is.EqualTo("Issue 2"), "Issue found is invalid"); } [Test] @@ -68,8 +68,8 @@ public void Test_issue_by_id_can_be_found() var client = server.CreateClient(); var issue = client.Issues.GetById(10001); - Assert.AreEqual(5, issue.IssueId); - Assert.AreEqual("Issue title", issue.Title); + Assert.That(issue.IssueId, Is.EqualTo(5)); + Assert.That(issue.Title, Is.EqualTo("Issue title")); } [Test] @@ -102,16 +102,16 @@ public void Test_issue_resource_milestone_events_can_be_found() }); var resourceMilestoneEvents = issuesClient.ResourceMilestoneEvents(projectId: 1, issueIid: 5).ToList(); - Assert.AreEqual(3, resourceMilestoneEvents.Count); + Assert.That(resourceMilestoneEvents, Has.Count.EqualTo(3)); var removeMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Remove).ToArray(); - Assert.AreEqual(1, removeMilestoneEvents.Length); - Assert.AreEqual(1, removeMilestoneEvents[0].Milestone.Id); + Assert.That(removeMilestoneEvents, Has.Length.EqualTo(1)); + Assert.That(removeMilestoneEvents[0].Milestone.Id, Is.EqualTo(1)); var addMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Add).ToArray(); - Assert.AreEqual(2, addMilestoneEvents.Length); - Assert.AreEqual(1, addMilestoneEvents[0].Milestone.Id); - Assert.AreEqual(2, addMilestoneEvents[1].Milestone.Id); + Assert.That(addMilestoneEvents, Has.Length.EqualTo(2)); + Assert.That(addMilestoneEvents[0].Milestone.Id, Is.EqualTo(1)); + Assert.That(addMilestoneEvents[1].Milestone.Id, Is.EqualTo(2)); } } } diff --git a/NGitLab.Mock.Tests/LabelsMockTests.cs b/NGitLab.Mock.Tests/LabelsMockTests.cs index 52b760fe..305c8b94 100644 --- a/NGitLab.Mock.Tests/LabelsMockTests.cs +++ b/NGitLab.Mock.Tests/LabelsMockTests.cs @@ -21,9 +21,9 @@ public void Test_labels_can_be_found_from_project() var client = server.CreateClient(); var labels = client.Labels.ForProject(1).ToArray(); - Assert.AreEqual(2, labels.Length, "Labels count is invalid"); - Assert.IsTrue(labels.Any(x => string.Equals(x.Name, "test1", StringComparison.Ordinal)), "Label test1 not found"); - Assert.IsTrue(labels.Any(x => string.Equals(x.Name, "test2", StringComparison.Ordinal)), "Label test2 not found"); + Assert.That(labels, Has.Length.EqualTo(2), "Labels count is invalid"); + Assert.That(labels.Any(x => string.Equals(x.Name, "test1", StringComparison.Ordinal)), Is.True, "Label test1 not found"); + Assert.That(labels.Any(x => string.Equals(x.Name, "test2", StringComparison.Ordinal)), Is.True, "Label test2 not found"); } [Test] @@ -38,8 +38,8 @@ public void Test_labels_can_be_added_to_project() client.Labels.Create(new LabelCreate { Id = 1, Name = "test1" }); var labels = client.Labels.ForProject(1).ToArray(); - Assert.AreEqual(1, labels.Length, "Labels count is invalid"); - Assert.AreEqual("test1", labels[0].Name, "Label not found"); + Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); + Assert.That(labels[0].Name, Is.EqualTo("test1"), "Label not found"); } [Test] @@ -55,8 +55,8 @@ public void Test_labels_can_be_edited_from_project() client.Labels.Edit(new LabelEdit { Id = 1, Name = "test1", NewName = "test2" }); var labels = client.Labels.ForProject(1).ToArray(); - Assert.AreEqual(1, labels.Length, "Labels count is invalid"); - Assert.AreEqual("test2", labels[0].Name, "Label not found"); + Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); + Assert.That(labels[0].Name, Is.EqualTo("test2"), "Label not found"); } [Test] @@ -72,7 +72,7 @@ public void Test_labels_can_be_deleted_from_project() client.Labels.Delete(new LabelDelete { Id = 1, Name = "test1" }); var labels = client.Labels.ForProject(1).ToArray(); - Assert.AreEqual(0, labels.Length, "Labels count is invalid"); + Assert.That(labels, Is.Empty, "Labels count is invalid"); } [Test] @@ -88,9 +88,9 @@ public void Test_labels_can_be_found_from_group() var client = server.CreateClient(); var labels = client.Labels.ForGroup(2).ToArray(); - Assert.AreEqual(2, labels.Length, "Labels count is invalid"); - Assert.IsTrue(labels.Any(x => string.Equals(x.Name, "test1", StringComparison.Ordinal)), "Label test1 not found"); - Assert.IsTrue(labels.Any(x => string.Equals(x.Name, "test2", StringComparison.Ordinal)), "Label test2 not found"); + Assert.That(labels, Has.Length.EqualTo(2), "Labels count is invalid"); + Assert.That(labels.Any(x => string.Equals(x.Name, "test1", StringComparison.Ordinal)), Is.True, "Label test1 not found"); + Assert.That(labels.Any(x => string.Equals(x.Name, "test2", StringComparison.Ordinal)), Is.True, "Label test2 not found"); } [Test] @@ -105,8 +105,8 @@ public void Test_labels_can_be_added_to_group() client.Labels.CreateGroupLabel(new LabelCreate { Id = 2, Name = "test1" }); var labels = client.Labels.ForGroup(2).ToArray(); - Assert.AreEqual(1, labels.Length, "Labels count is invalid"); - Assert.AreEqual("test1", labels[0].Name, "Label not found"); + Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); + Assert.That(labels[0].Name, Is.EqualTo("test1"), "Label not found"); } [Test] @@ -122,8 +122,8 @@ public void Test_labels_can_be_edited_from_group() client.Labels.EditGroupLabel(new LabelEdit { Id = 2, Name = "test1", NewName = "test2" }); var labels = client.Labels.ForGroup(2).ToArray(); - Assert.AreEqual(1, labels.Length, "Labels count is invalid"); - Assert.AreEqual("test2", labels[0].Name, "Label not found"); + Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); + Assert.That(labels[0].Name, Is.EqualTo("test2"), "Label not found"); } } } diff --git a/NGitLab.Mock.Tests/LintCITests.cs b/NGitLab.Mock.Tests/LintCITests.cs index c2c14326..00f558e0 100644 --- a/NGitLab.Mock.Tests/LintCITests.cs +++ b/NGitLab.Mock.Tests/LintCITests.cs @@ -36,7 +36,7 @@ public async Task Test_GetLintCIByRef(string @ref, string expectedError) }); // Assert - Assert.IsFalse(result.Valid); - Assert.AreEqual(expectedError, result.Errors.Single()); + Assert.That(result.Valid, Is.False); + Assert.That(result.Errors.Single(), Is.EqualTo(expectedError)); } } diff --git a/NGitLab.Mock.Tests/MembersMockTests.cs b/NGitLab.Mock.Tests/MembersMockTests.cs index f973c2e0..961ae7d8 100644 --- a/NGitLab.Mock.Tests/MembersMockTests.cs +++ b/NGitLab.Mock.Tests/MembersMockTests.cs @@ -21,7 +21,7 @@ public void Test_members_group_all_direct([Values] bool isDefault) ? client.Members.OfGroup("2") : client.Members.OfGroup("2", includeInheritedMembers: false); - Assert.AreEqual(1, members.Count(), "Membership found are invalid"); + Assert.That(members.Count(), Is.EqualTo(1), "Membership found are invalid"); } [Test] @@ -38,7 +38,7 @@ public void Test_members_group_all_inherited() var client = server.CreateClient("user1"); var members = client.Members.OfGroup("2", includeInheritedMembers: true); - Assert.AreEqual(2, members.Count(), "Membership found are invalid"); + Assert.That(members.Count(), Is.EqualTo(2), "Membership found are invalid"); } [Test] @@ -60,7 +60,7 @@ public void Test_members_project_all_direct([Values] bool isDefault) ? client.Members.OfProject("1") : client.Members.OfProject("1", includeInheritedMembers: false); - Assert.AreEqual(1, members.Count(), "Membership found are invalid"); + Assert.That(members.Count(), Is.EqualTo(1), "Membership found are invalid"); } [Test] @@ -80,7 +80,7 @@ public void Test_members_project_all_inherited() var client = server.CreateClient("user1"); var members = client.Members.OfProject("1", includeInheritedMembers: true); - Assert.AreEqual(3, members.Count(), "Membership found are invalid"); + Assert.That(members.Count(), Is.EqualTo(3), "Membership found are invalid"); } } } diff --git a/NGitLab.Mock.Tests/MergeRequestsMockTests.cs b/NGitLab.Mock.Tests/MergeRequestsMockTests.cs index 2f5bf362..7750c48a 100644 --- a/NGitLab.Mock.Tests/MergeRequestsMockTests.cs +++ b/NGitLab.Mock.Tests/MergeRequestsMockTests.cs @@ -23,8 +23,8 @@ public void Test_merge_requests_created_by_me_can_be_listed() var client = server.CreateClient("user1"); var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "created_by_me" }).ToArray(); - Assert.AreEqual(1, mergeRequests.Length, "Merge requests count is invalid"); - Assert.AreEqual("Merge request 1", mergeRequests[0].Title, "Merge request found is invalid"); + Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); + Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 1"), "Merge request found is invalid"); } [Test] @@ -41,8 +41,8 @@ public void Test_merge_requests_assigned_to_me_can_be_listed() var client = server.CreateClient("user1"); var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "assigned_to_me" }).ToArray(); - Assert.AreEqual(1, mergeRequests.Length, "Merge requests count is invalid"); - Assert.AreEqual("Merge request 2", mergeRequests[0].Title, "Merge request found is invalid"); + Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); + Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); } [Test] @@ -59,8 +59,8 @@ public void Test_merge_requests_approvable_by_me_can_be_listed() var client = server.CreateClient("user1"); var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { ApproverIds = new[] { 1 } }).ToArray(); - Assert.AreEqual(1, mergeRequests.Length, "Merge requests count is invalid"); - Assert.AreEqual("Merge request 2", mergeRequests[0].Title, "Merge request found is invalid"); + Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); + Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); } [Test] @@ -83,8 +83,8 @@ public void Test_merge_requests_can_be_listed_when_assignee_not_set() var client = gitLabServer.CreateClient(user1); var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "assigned_to_me" }).ToArray(); - Assert.AreEqual(1, mergeRequests.Length, "Merge requests count is invalid"); - Assert.AreEqual("Merge request 2", mergeRequests[0].Title, "Merge request found is invalid"); + Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); + Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); } [Test] @@ -103,8 +103,8 @@ public void Test_merge_requests_assignee_should_update_assignees_and_vice_versa( Assignees = new[] { new UserRef(user1), new UserRef(user2) }, }; - Assert.AreEqual(1, mergeRequestSingle.Assignees.Count, "Merge request assignees count invalid"); - Assert.AreEqual("user1", mergeRequestTwo.Assignee.UserName, "Merge request assignee is invalid"); + Assert.That(mergeRequestSingle.Assignees, Has.Count.EqualTo(1), "Merge request assignees count invalid"); + Assert.That(mergeRequestTwo.Assignee.UserName, Is.EqualTo("user1"), "Merge request assignee is invalid"); } [TestCase(false)] @@ -148,16 +148,16 @@ public void Test_merge_request_with_no_rebase_required_can_be_accepted(bool sour }); // Assert - Assert.IsFalse(modelMr.HasConflicts); - Assert.AreEqual(0, modelMr.DivergedCommitsCount); - Assert.IsNotNull(modelMr.DiffRefs?.BaseSha); - Assert.AreEqual(modelMr.DiffRefs.BaseSha, modelMr.DiffRefs.StartSha); - Assert.AreEqual("merged", modelMr.State); + Assert.That(modelMr.HasConflicts, Is.False); + Assert.That(modelMr.DivergedCommitsCount, Is.EqualTo(0)); + Assert.That(modelMr.DiffRefs?.BaseSha, Is.Not.Null); + Assert.That(modelMr.DiffRefs.StartSha, Is.EqualTo(modelMr.DiffRefs.BaseSha)); + Assert.That(modelMr.State, Is.EqualTo("merged")); - Assert.IsFalse(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), + Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.False, "Since the merge succeeded and 'ShouldRemoveSourceBranch' was set, 'to-be-merged' branch should be gone"); - Assert.IsFalse(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), + Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.False, "Since the merge succeeded and 'ShouldRemoveSourceBranch' was set, 'to-be-merged' branch should be gone"); } @@ -202,17 +202,17 @@ public void Test_merge_request_with_non_conflicting_rebase_needed_and_merge_meth MergeWhenPipelineSucceeds = mr.HeadPipeline != null, ShouldRemoveSourceBranch = true, })); - Assert.AreEqual(HttpStatusCode.MethodNotAllowed, exception.StatusCode); - Assert.IsTrue(exception.Message.Equals("The MR cannot be merged with method 'ff': the source branch must first be rebased", StringComparison.Ordinal)); + Assert.That(exception.StatusCode, Is.EqualTo(HttpStatusCode.MethodNotAllowed)); + Assert.That(exception.Message.Equals("The MR cannot be merged with method 'ff': the source branch must first be rebased", StringComparison.Ordinal), Is.True); - Assert.IsFalse(mr.HasConflicts); - Assert.AreEqual(1, mr.DivergedCommitsCount); - Assert.AreNotEqual(mr.BaseSha, mr.StartSha); + Assert.That(mr.HasConflicts, Is.False); + Assert.That(mr.DivergedCommitsCount, Is.EqualTo(1)); + Assert.That(mr.StartSha, Is.Not.EqualTo(mr.BaseSha)); - Assert.IsTrue(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), + Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, "Since the merge failed, 'to-be-merged' branch should still be there"); - Assert.IsTrue(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), + Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, "Since the merge failed, 'to-be-merged' branch should still be there"); } @@ -258,17 +258,17 @@ public void Test_merge_request_with_conflicts_cannot_be_accepted(bool sourceProj MergeWhenPipelineSucceeds = mr.HeadPipeline != null, ShouldRemoveSourceBranch = true, })); - Assert.AreEqual(HttpStatusCode.NotAcceptable, exception.StatusCode); - Assert.IsTrue(exception.Message.Equals("The merge request has some conflicts and cannot be merged", StringComparison.Ordinal)); + Assert.That(exception.StatusCode, Is.EqualTo(HttpStatusCode.NotAcceptable)); + Assert.That(exception.Message.Equals("The merge request has some conflicts and cannot be merged", StringComparison.Ordinal), Is.True); - Assert.IsTrue(mr.HasConflicts); - Assert.AreEqual(1, mr.DivergedCommitsCount); - Assert.AreNotEqual(mr.BaseSha, mr.StartSha); + Assert.That(mr.HasConflicts, Is.True); + Assert.That(mr.DivergedCommitsCount, Is.EqualTo(1)); + Assert.That(mr.StartSha, Is.Not.EqualTo(mr.BaseSha)); - Assert.IsTrue(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), + Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, "Since the merge failed, 'to-be-merged' branch should still be there"); - Assert.IsTrue(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), + Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, "Since the merge failed, 'to-be-merged' branch should still be there"); } @@ -285,10 +285,10 @@ public void Test_merge_request_with_head_pipeline() commit = project.Repository.Commit(user, "another test"); var mr = project.CreateMergeRequest(user, "A great title", "A great description", project.DefaultBranch, branch); - Assert.IsNull(mr.HeadPipeline, "No pipeline created yet on the source branch"); + Assert.That(mr.HeadPipeline, Is.Null, "No pipeline created yet on the source branch"); var pipeline = project.Pipelines.Add(branch, JobStatus.Success, user); - Assert.AreEqual(pipeline, mr.HeadPipeline, "A pipeline was just created on the source branch"); + Assert.That(mr.HeadPipeline, Is.EqualTo(pipeline), "A pipeline was just created on the source branch"); } [Test] @@ -310,13 +310,13 @@ public void Test_merge_request_resource_state_events_found_on_close_and_reopen() mrClient.Reopen(mergeRequest.Iid); var resourceStateEvents = mrClient.ResourceStateEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); - Assert.AreEqual(2, resourceStateEvents.Length); + Assert.That(resourceStateEvents, Has.Length.EqualTo(2)); var closeStateEvents = resourceStateEvents.Where(e => string.Equals(e.State, "closed", StringComparison.Ordinal)).ToArray(); - Assert.AreEqual(1, closeStateEvents.Length); + Assert.That(closeStateEvents, Has.Length.EqualTo(1)); var reopenMilestoneEvents = resourceStateEvents.Where(e => string.Equals(e.State, "reopened", StringComparison.Ordinal)).ToArray(); - Assert.AreEqual(1, reopenMilestoneEvents.Length); + Assert.That(reopenMilestoneEvents, Has.Length.EqualTo(1)); } [Test] @@ -358,13 +358,13 @@ public void Test_merge_request_resource_label_events_found() * 3. Remove third */ var resourceLabelEvents = mrClient.ResourceLabelEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); - Assert.AreEqual(6, resourceLabelEvents.Length); + Assert.That(resourceLabelEvents, Has.Length.EqualTo(6)); var addLabelEvents = resourceLabelEvents.Where(e => e.Action == ResourceLabelEventAction.Add).ToArray(); - Assert.AreEqual(4, addLabelEvents.Length); + Assert.That(addLabelEvents, Has.Length.EqualTo(4)); var removeLabelEvents = resourceLabelEvents.Where(e => e.Action == ResourceLabelEventAction.Remove).ToArray(); - Assert.AreEqual(2, removeLabelEvents.Length); + Assert.That(removeLabelEvents, Has.Length.EqualTo(2)); } [Test] @@ -401,16 +401,16 @@ public void Test_merge_request_resource_milestone_events_found() * 2. Add milestone 2 */ var resourceMilestoneEvents = mrClient.ResourceMilestoneEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); - Assert.AreEqual(3, resourceMilestoneEvents.Length); + Assert.That(resourceMilestoneEvents, Has.Length.EqualTo(3)); var removeMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Remove).ToArray(); - Assert.AreEqual(1, removeMilestoneEvents.Length); - Assert.AreEqual(milestones[0].Id, removeMilestoneEvents[0].Milestone.Id); + Assert.That(removeMilestoneEvents, Has.Length.EqualTo(1)); + Assert.That(removeMilestoneEvents[0].Milestone.Id, Is.EqualTo(milestones[0].Id)); var addMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Add).ToArray(); - Assert.AreEqual(2, addMilestoneEvents.Length); - Assert.AreEqual(milestones[0].Id, addMilestoneEvents[0].Milestone.Id); - Assert.AreEqual(milestones[1].Id, addMilestoneEvents[1].Milestone.Id); + Assert.That(addMilestoneEvents, Has.Length.EqualTo(2)); + Assert.That(addMilestoneEvents[0].Milestone.Id, Is.EqualTo(milestones[0].Id)); + Assert.That(addMilestoneEvents[1].Milestone.Id, Is.EqualTo(milestones[1].Id)); } } } diff --git a/NGitLab.Mock.Tests/MilestonesMockTests.cs b/NGitLab.Mock.Tests/MilestonesMockTests.cs index 074dd2a7..83212ae2 100644 --- a/NGitLab.Mock.Tests/MilestonesMockTests.cs +++ b/NGitLab.Mock.Tests/MilestonesMockTests.cs @@ -21,9 +21,9 @@ public void Test_milestones_can_be_found_from_project() var client = server.CreateClient(); var milestones = client.GetMilestone(1).All.ToArray(); - Assert.AreEqual(2, milestones.Length, "Milestones count is invalid"); - Assert.IsTrue(milestones.Any(x => string.Equals(x.Title, "Milestone 1", StringComparison.Ordinal)), "Milestone 'Milestone 1' not found"); - Assert.IsTrue(milestones.Any(x => string.Equals(x.Title, "Milestone 2", StringComparison.Ordinal)), "Milestone 'Milestone 2' not found"); + Assert.That(milestones, Has.Length.EqualTo(2), "Milestones count is invalid"); + Assert.That(milestones.Any(x => string.Equals(x.Title, "Milestone 1", StringComparison.Ordinal)), Is.True, "Milestone 'Milestone 1' not found"); + Assert.That(milestones.Any(x => string.Equals(x.Title, "Milestone 2", StringComparison.Ordinal)), Is.True, "Milestone 'Milestone 2' not found"); } [Test] @@ -38,8 +38,8 @@ public void Test_milestones_can_be_added_to_project() client.GetMilestone(1).Create(new MilestoneCreate { Title = "Milestone 1" }); var milestones = client.GetMilestone(1).All.ToArray(); - Assert.AreEqual(1, milestones.Length, "Milestones count is invalid"); - Assert.AreEqual("Milestone 1", milestones[0].Title, "Milestone 'Milestone 1' not found"); + Assert.That(milestones, Has.Length.EqualTo(1), "Milestones count is invalid"); + Assert.That(milestones[0].Title, Is.EqualTo("Milestone 1"), "Milestone 'Milestone 1' not found"); } [Test] @@ -55,8 +55,8 @@ public void Test_milestones_can_be_edited_from_project() client.GetMilestone(1).Update(1, new MilestoneUpdate { Title = "Milestone 2" }); var milestones = client.GetMilestone(1).All.ToArray(); - Assert.AreEqual(1, milestones.Length, "Milestones count is invalid"); - Assert.AreEqual("Milestone 2", milestones[0].Title, "Milestone 'Milestone 2' not found"); + Assert.That(milestones, Has.Length.EqualTo(1), "Milestones count is invalid"); + Assert.That(milestones[0].Title, Is.EqualTo("Milestone 2"), "Milestone 'Milestone 2' not found"); } [Test] @@ -72,7 +72,7 @@ public void Test_milestones_can_be_deleted_from_project() client.GetMilestone(1).Delete(1); var milestones = client.GetMilestone(1).All.ToArray(); - Assert.AreEqual(0, milestones.Length, "Milestones count is invalid"); + Assert.That(milestones, Is.Empty, "Milestones count is invalid"); } [Test] @@ -89,15 +89,15 @@ public void Test_milestones_can_be_closed_and_activated_from_project() var activeMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.active).ToArray(); var closedMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.closed).ToArray(); - Assert.AreEqual(0, activeMilestones.Length, "Active milestones count is invalid"); - Assert.AreEqual(1, closedMilestones.Length, "Closed milestones count is invalid"); + Assert.That(activeMilestones, Is.Empty, "Active milestones count is invalid"); + Assert.That(closedMilestones, Has.Length.EqualTo(1), "Closed milestones count is invalid"); client.GetMilestone(1).Activate(1); activeMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.active).ToArray(); closedMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.closed).ToArray(); - Assert.AreEqual(1, activeMilestones.Length, "Active milestones count is invalid"); - Assert.AreEqual(0, closedMilestones.Length, "Closed milestones count is invalid"); + Assert.That(activeMilestones, Has.Length.EqualTo(1), "Active milestones count is invalid"); + Assert.That(closedMilestones, Is.Empty, "Closed milestones count is invalid"); } [Test] @@ -116,7 +116,7 @@ public void Test_projects_merge_request_can_be_found_from_milestone() var client = server.CreateClient(); var mergeRequests = client.GetMilestone(ProjectId).GetMergeRequests(MilestoneId).ToArray(); - Assert.AreEqual(2, mergeRequests.Length, "Merge requests count is invalid"); + Assert.That(mergeRequests, Has.Length.EqualTo(2), "Merge requests count is invalid"); } [Test] @@ -139,7 +139,7 @@ public void Test_groups_merge_request_can_be_found_from_milestone() var client = server.CreateClient(); var mergeRequests = client.GetGroupMilestone(projectId).GetMergeRequests(milestoneId).ToArray(); - Assert.AreEqual(2, mergeRequests.Length, "Merge requests count is invalid"); + Assert.That(mergeRequests, Has.Length.EqualTo(2), "Merge requests count is invalid"); } } } diff --git a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj index d07af6f3..1ba4b07e 100644 --- a/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj +++ b/NGitLab.Mock.Tests/NGitLab.Mock.Tests.csproj @@ -9,6 +9,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/NGitLab.Mock.Tests/PipelineTests.cs b/NGitLab.Mock.Tests/PipelineTests.cs index c602d8e0..53365340 100644 --- a/NGitLab.Mock.Tests/PipelineTests.cs +++ b/NGitLab.Mock.Tests/PipelineTests.cs @@ -20,7 +20,7 @@ public async Task Test_pipelines() job.Trace = "This is a trace\nWith Multiple line"; var client = server.CreateClient(); - Assert.AreEqual(job.Trace, await client.GetJobs(project.Id).GetTraceAsync(job.Id)); + Assert.That(await client.GetJobs(project.Id).GetTraceAsync(job.Id), Is.EqualTo(job.Trace)); } [Test] @@ -47,12 +47,12 @@ public void Test_pipelines_testreport_summary() var client = server.CreateClient(); var summary = client.GetPipelines(project.Id).GetTestReportsSummary(pipeline.Id); - Assert.AreEqual(60, summary.Total.Time); - Assert.AreEqual(1157, summary.Total.Count); - Assert.AreEqual(1157, summary.Total.Success); - Assert.AreEqual(0, summary.Total.Skipped); - Assert.AreEqual(0, summary.Total.Failed); - Assert.AreEqual(0, summary.Total.Error); + Assert.That(summary.Total.Time, Is.EqualTo(60)); + Assert.That(summary.Total.Count, Is.EqualTo(1157)); + Assert.That(summary.Total.Success, Is.EqualTo(1157)); + Assert.That(summary.Total.Skipped, Is.EqualTo(0)); + Assert.That(summary.Total.Failed, Is.EqualTo(0)); + Assert.That(summary.Total.Error, Is.EqualTo(0)); } [TestCase(false)] @@ -69,7 +69,7 @@ public void Test_create_pipeline_with_branch_ref_sets_sha(bool addCommitAfterBra { project.Repository.CreateAndCheckoutBranch(branch); var commit2 = project.Repository.Commit(user, "another test"); - Assert.AreNotEqual(commit.Sha, commit2.Sha); + Assert.That(commit2.Sha, Is.Not.EqualTo(commit.Sha)); commit = commit2; } else @@ -79,7 +79,7 @@ public void Test_create_pipeline_with_branch_ref_sets_sha(bool addCommitAfterBra var pipeline = project.Pipelines.Add(branch, JobStatus.Success, user); - Assert.AreEqual(new Sha1(commit.Sha), pipeline.Sha); + Assert.That(pipeline.Sha, Is.EqualTo(new Sha1(commit.Sha))); } [Test] @@ -95,7 +95,7 @@ public void Test_create_pipeline_with_tag_ref_sets_sha() var pipeline = project.Pipelines.Add(tag, JobStatus.Success, user); - Assert.AreEqual(new Sha1(commit.Sha), pipeline.Sha); + Assert.That(pipeline.Sha, Is.EqualTo(new Sha1(commit.Sha))); } [Test] @@ -108,7 +108,7 @@ public void Test_create_pipeline_with_invalid_ref_does_not_set_sha() var pipeline = project.Pipelines.Add("invalid_ref", JobStatus.Success, user); - Assert.AreEqual(default(Sha1), pipeline.Sha); + Assert.That(pipeline.Sha, Is.EqualTo(default(Sha1))); } } } diff --git a/NGitLab.Mock.Tests/ProjectsMockTests.cs b/NGitLab.Mock.Tests/ProjectsMockTests.cs index 062892d8..c28ceee3 100644 --- a/NGitLab.Mock.Tests/ProjectsMockTests.cs +++ b/NGitLab.Mock.Tests/ProjectsMockTests.cs @@ -20,9 +20,9 @@ public void Test_projects_created_can_be_found() var client = server.CreateClient(); var project = client.Projects["testgroup/Test"]; - Assert.IsNotNull(project); - Assert.AreEqual("Test", project.Name); - Assert.AreEqual("testgroup", project.Namespace.FullPath); + Assert.That(project, Is.Not.Null); + Assert.That(project.Name, Is.EqualTo("Test")); + Assert.That(project.Namespace.FullPath, Is.EqualTo("testgroup")); } [Test] @@ -34,7 +34,7 @@ public void Test_project_can_be_cloned_by_default() .WithProject("Test", clonePath: tempDir.FullPath) .BuildServer(); - Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git"))); + Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); } [Test] @@ -51,11 +51,11 @@ public void Test_project_with_submodules() .WithSubModule("ModuleB"))) .BuildServer(); - Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git"))); - Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/.git"))); - Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/A.txt"))); - Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git"))); - Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt"))); + Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/.git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/A.txt")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt")), Is.True); } [Test] @@ -73,11 +73,11 @@ public void Test_project_with_nested_submodules() => c.WithSubModule("ModuleB"))) .BuildServer(); - Assert.IsTrue(Directory.Exists(tempDir.GetFullPath(".git"))); - Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git"))); - Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt"))); - Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/.git"))); - Assert.IsTrue(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/A.txt"))); + Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/.git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/A.txt")), Is.True); } [Test] @@ -91,10 +91,10 @@ public void Test_projects_created_url_ends_with_namespace_and_name() var client = server.CreateClient(); var project = client.Projects["testgroup/Test"]; - Assert.IsNotNull(project); - StringAssert.EndsWith($"testgroup{Path.DirectorySeparatorChar}test", project.SshUrl); - StringAssert.EndsWith($"testgroup{Path.DirectorySeparatorChar}test", project.HttpUrl); - StringAssert.EndsWith("testgroup/test", project.WebUrl); + Assert.That(project, Is.Not.Null); + Assert.That(project.SshUrl, Does.EndWith($"testgroup{Path.DirectorySeparatorChar}test")); + Assert.That(project.HttpUrl, Does.EndWith($"testgroup{Path.DirectorySeparatorChar}test")); + Assert.That(project.WebUrl, Does.EndWith("testgroup/test")); } [Test] @@ -105,13 +105,13 @@ public void Test_get_languages() var project = user.Namespace.Projects.AddNew(); var client = server.CreateClient(user); - Assert.IsEmpty(client.Projects.GetLanguages(project.Id.ToString(CultureInfo.InvariantCulture))); + Assert.That(client.Projects.GetLanguages(project.Id.ToString(CultureInfo.InvariantCulture)), Is.Empty); project.Repository.Commit(user, "dummy", new[] { File.CreateFromText("test.cs", "dummy"), File.CreateFromText("test.js", "dummy") }); var languages = client.Projects.GetLanguages(project.Id.ToString(CultureInfo.InvariantCulture)); - Assert.AreEqual(2, languages.Count); - Assert.AreEqual(0.5d, languages["C#"]); - Assert.AreEqual(0.5d, languages["JavaScript"]); + Assert.That(languages, Has.Count.EqualTo(2)); + Assert.That(languages["C#"], Is.EqualTo(0.5d)); + Assert.That(languages["JavaScript"], Is.EqualTo(0.5d)); } [Test] @@ -121,10 +121,10 @@ public void Test_empty_repo() var user = server.Users.AddNew(); var project = user.Namespace.Projects.AddNew(); - Assert.IsTrue(project.ToClientProject(user).EmptyRepo); + Assert.That(project.ToClientProject(user).EmptyRepo, Is.True); project.Repository.Commit(user, "dummy"); - Assert.IsFalse(project.ToClientProject(user).EmptyRepo); + Assert.That(project.ToClientProject(user).EmptyRepo, Is.False); } [Test] diff --git a/NGitLab.Mock.Tests/ReleasesMockTests.cs b/NGitLab.Mock.Tests/ReleasesMockTests.cs index 8bf7a803..0ee979e7 100644 --- a/NGitLab.Mock.Tests/ReleasesMockTests.cs +++ b/NGitLab.Mock.Tests/ReleasesMockTests.cs @@ -22,9 +22,9 @@ public void Test_release() var releaseClient = client.GetReleases(project.Id); var singleRelease = releaseClient.All.SingleOrDefault(); - Assert.IsNotNull(singleRelease); - Assert.AreEqual("1.2.3", singleRelease.TagName); - Assert.AreEqual($"{project.WebUrl}/-/releases/1.2.3", singleRelease.Links.Self); + Assert.That(singleRelease, Is.Not.Null); + Assert.That(singleRelease.TagName, Is.EqualTo("1.2.3")); + Assert.That(singleRelease.Links.Self, Is.EqualTo($"{project.WebUrl}/-/releases/1.2.3")); } [Test] @@ -47,8 +47,8 @@ public void Test_release_page() Page = 2, }).SingleOrDefault(); - Assert.IsNotNull(firstRelease); - Assert.AreEqual("1.2.3", firstRelease.TagName); + Assert.That(firstRelease, Is.Not.Null); + Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); } [Test] @@ -70,8 +70,8 @@ public void Test_release_sort() Sort = "asc", }).First(); - Assert.IsNotNull(firstRelease); - Assert.AreEqual("1.2.3", firstRelease.TagName); + Assert.That(firstRelease, Is.Not.Null); + Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); } [Test] @@ -93,8 +93,8 @@ public void Test_release_orderBy() OrderBy = "created_at", }).First(); - Assert.IsNotNull(firstRelease); - Assert.AreEqual("1.2.3", firstRelease.TagName); + Assert.That(firstRelease, Is.Not.Null); + Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); } } } diff --git a/NGitLab.Mock.Tests/TagTests.cs b/NGitLab.Mock.Tests/TagTests.cs index 30e1c985..6720a950 100644 --- a/NGitLab.Mock.Tests/TagTests.cs +++ b/NGitLab.Mock.Tests/TagTests.cs @@ -23,10 +23,10 @@ public async Task GetTagAsync() // Act/Assert var tag = await tagClient.GetByNameAsync("1.0.0"); - Assert.AreEqual("1.0.0", tag.Name); + Assert.That(tag.Name, Is.EqualTo("1.0.0")); var ex = Assert.ThrowsAsync(() => tagClient.GetByNameAsync("1.0.1")); - Assert.AreEqual(HttpStatusCode.NotFound, ex.StatusCode); + Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); } } } diff --git a/NGitLab.Tests/BranchClientTests.cs b/NGitLab.Tests/BranchClientTests.cs index 5609eff4..8a73cf85 100644 --- a/NGitLab.Tests/BranchClientTests.cs +++ b/NGitLab.Tests/BranchClientTests.cs @@ -17,32 +17,32 @@ public async Task Test_CommitInfoIsCorrectlyDeserialized() var branchClient = context.Client.GetRepository(project.Id).Branches; var currentUser = context.Client.Users.Current; - var masterBranch = branchClient[project.DefaultBranch]; - Assert.NotNull(masterBranch); + var defaultBranch = branchClient[project.DefaultBranch]; + Assert.That(defaultBranch, Is.Not.Null); - var commit = masterBranch.Commit; - Assert.NotNull(commit); + var commit = defaultBranch.Commit; + Assert.That(commit, Is.Not.Null); - Assert.AreEqual(40, commit.Id.ToString().Length); - Assert.LessOrEqual(7, commit.ShortId.Length); + Assert.That(commit.Id.ToString(), Has.Length.EqualTo(40)); + Assert.That(commit.ShortId, Has.Length.GreaterThan(7)); var fiveMinutesAgo = DateTime.UtcNow - TimeSpan.FromMinutes(5); - Assert.Less(fiveMinutesAgo, commit.CreatedAt); + Assert.That(commit.CreatedAt, Is.GreaterThan(fiveMinutesAgo)); - Assert.LessOrEqual(1, commit.Parents.Length); + Assert.That(commit.Parents, Has.Length.EqualTo(1)); - Assert.AreEqual("add test file 2", commit.Title); - Assert.AreEqual("add test file 2", commit.Message); + Assert.That(commit.Title, Is.EqualTo("add test file 2")); + Assert.That(commit.Message, Is.EqualTo("add test file 2")); - Assert.AreEqual(currentUser.Name, commit.AuthorName); - Assert.AreEqual(currentUser.Email, commit.AuthorEmail); - Assert.Less(fiveMinutesAgo, commit.AuthoredDate); + Assert.That(commit.AuthorName, Is.EqualTo(currentUser.Name)); + Assert.That(commit.AuthorEmail, Is.EqualTo(currentUser.Email)); + Assert.That(fiveMinutesAgo, Is.LessThan(commit.AuthoredDate)); - Assert.AreEqual(currentUser.Name, commit.CommitterName); - Assert.AreEqual(currentUser.Email, commit.CommitterEmail); - Assert.Less(fiveMinutesAgo, commit.CommittedDate); + Assert.That(commit.CommitterName, Is.EqualTo(currentUser.Name)); + Assert.That(commit.CommitterEmail, Is.EqualTo(currentUser.Email)); + Assert.That(fiveMinutesAgo, Is.LessThan(commit.CommittedDate)); - Assert.IsTrue(Uri.TryCreate(commit.WebUrl, UriKind.Absolute, out _)); + Assert.That(Uri.TryCreate(commit.WebUrl, UriKind.Absolute, out _), Is.True); } [Test] @@ -57,7 +57,7 @@ public async Task Test_search_branches() var branches = branchClient.Search(defaultBranch); var expectedBranch = branches.Single(); - Assert.AreEqual(defaultBranch, expectedBranch.Name); + Assert.That(expectedBranch.Name, Is.EqualTo(defaultBranch)); // This case only worked with GitLab 15.7 and later // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104451 @@ -69,18 +69,18 @@ public async Task Test_search_branches() branches = branchClient.Search($"^{defaultBranch[..^1]}"); expectedBranch = branches.Single(); - Assert.AreEqual(defaultBranch, expectedBranch.Name); + Assert.That(expectedBranch.Name, Is.EqualTo(defaultBranch)); branches = branchClient.Search($"{defaultBranch[1..]}$"); expectedBranch = branches.Single(); - Assert.AreEqual(defaultBranch, expectedBranch.Name); + Assert.That(expectedBranch.Name, Is.EqualTo(defaultBranch)); branches = branchClient.Search(defaultBranch[1..^1]); expectedBranch = branches.Single(); - Assert.AreEqual(defaultBranch, expectedBranch.Name); + Assert.That(expectedBranch.Name, Is.EqualTo(defaultBranch)); branches = branchClient.Search("foobar"); - Assert.IsEmpty(branches); + Assert.That(branches, Is.Empty); } } } diff --git a/NGitLab.Tests/CommitStatusTests.cs b/NGitLab.Tests/CommitStatusTests.cs index e7e895b1..dcd24cac 100644 --- a/NGitLab.Tests/CommitStatusTests.cs +++ b/NGitLab.Tests/CommitStatusTests.cs @@ -56,13 +56,13 @@ public CommitStatusCreate AddOrUpdateCommitStatus(string state = "success", int? var createdCommitStatus = CommitStatusClient.AddOrUpdate(commitStatus); - Assert.AreEqual(commitStatus.Ref, createdCommitStatus.Ref); - Assert.AreEqual(commitStatus.Coverage, createdCommitStatus.Coverage); - Assert.AreEqual(commitStatus.Description, createdCommitStatus.Description); - Assert.AreEqual(commitStatus.State, createdCommitStatus.Status); - Assert.AreEqual(commitStatus.Name, createdCommitStatus.Name); - Assert.AreEqual(commitStatus.TargetUrl, createdCommitStatus.TargetUrl); - Assert.IsTrue(string.Equals(commitStatus.CommitSha, createdCommitStatus.CommitSha, StringComparison.OrdinalIgnoreCase)); + Assert.That(createdCommitStatus.Ref, Is.EqualTo(commitStatus.Ref)); + Assert.That(createdCommitStatus.Coverage, Is.EqualTo(commitStatus.Coverage)); + Assert.That(createdCommitStatus.Description, Is.EqualTo(commitStatus.Description)); + Assert.That(createdCommitStatus.Status, Is.EqualTo(commitStatus.State)); + Assert.That(createdCommitStatus.Name, Is.EqualTo(commitStatus.Name)); + Assert.That(createdCommitStatus.TargetUrl, Is.EqualTo(commitStatus.TargetUrl)); + Assert.That(string.Equals(commitStatus.CommitSha, createdCommitStatus.CommitSha, StringComparison.OrdinalIgnoreCase), Is.True); return createdCommitStatus; } @@ -90,7 +90,7 @@ public async Task Test_get_commit_status() var createdCommitStatus = context.AddOrUpdateCommitStatus(); var commitStatus = context.CommitStatusClient.AllBySha(context.Commit.Id.ToString().ToLowerInvariant()).ToList(); - Assert.IsNotNull(commitStatus.FirstOrDefault()?.Status); + Assert.That(commitStatus.FirstOrDefault()?.Status, Is.Not.Null); } [Test] @@ -100,7 +100,7 @@ public async Task Test_post_commit_status_with_no_coverage() using var context = await CommitStatusTestContext.Create(); var commitStatus = context.AddOrUpdateCommitStatus(coverage: null); - Assert.AreEqual(commitStatus.Coverage, null); + Assert.That(commitStatus.Coverage, Is.Null); } [Test] @@ -109,13 +109,13 @@ public async Task Test_post_commit_status_and_update_it_from_pending_to_running_ { using var context = await CommitStatusTestContext.Create(); var commitStatus = context.AddOrUpdateCommitStatus(state: "pending"); - Assert.AreEqual("pending", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("pending")); commitStatus = context.AddOrUpdateCommitStatus(state: "running"); - Assert.AreEqual("running", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("running")); commitStatus = context.AddOrUpdateCommitStatus(state: "success"); - Assert.AreEqual("success", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("success")); } [Test] @@ -124,10 +124,10 @@ public async Task Test_post_commit_status_and_update_it_from_pending_to_failed() { using var context = await CommitStatusTestContext.Create(); var commitStatus = context.AddOrUpdateCommitStatus(state: "pending"); - Assert.AreEqual("pending", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("pending")); commitStatus = context.AddOrUpdateCommitStatus(state: "failed"); - Assert.AreEqual("failed", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("failed")); } [Test] @@ -136,10 +136,10 @@ public async Task Test_post_commit_status_and_update_it_from_pending_to_canceled { using var context = await CommitStatusTestContext.Create(); var commitStatus = context.AddOrUpdateCommitStatus(state: "pending"); - Assert.AreEqual("pending", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("pending")); commitStatus = context.AddOrUpdateCommitStatus(state: "canceled"); - Assert.AreEqual("canceled", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("canceled")); } [Test] @@ -148,10 +148,10 @@ public async Task Test_post_commit_status_and_update_it_from_success_to_pending( { using var context = await CommitStatusTestContext.Create(); var commitStatus = context.AddOrUpdateCommitStatus(state: "success"); - Assert.AreEqual("success", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("success")); commitStatus = context.AddOrUpdateCommitStatus(state: "pending"); - Assert.AreEqual("pending", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("pending")); } [Test] @@ -160,10 +160,10 @@ public async Task Test_post_commit_status_and_update_it_from_success_to_failed() { using var context = await CommitStatusTestContext.Create(); var commitStatus = context.AddOrUpdateCommitStatus(state: "success"); - Assert.AreEqual("success", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("success")); commitStatus = context.AddOrUpdateCommitStatus(state: "failed"); - Assert.AreEqual("failed", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("failed")); } [Test] @@ -172,10 +172,10 @@ public async Task Test_post_commit_status_and_update_it_from_success_to_canceled { using var context = await CommitStatusTestContext.Create(); var commitStatus = context.AddOrUpdateCommitStatus(state: "success"); - Assert.AreEqual("success", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("success")); commitStatus = context.AddOrUpdateCommitStatus(state: "canceled"); - Assert.AreEqual("canceled", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("canceled")); } [Test] @@ -184,10 +184,10 @@ public async Task Test_post_commit_status_and_update_it_from_canceled_to_pending { using var context = await CommitStatusTestContext.Create(); var commitStatus = context.AddOrUpdateCommitStatus(state: "canceled"); - Assert.AreEqual("canceled", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("canceled")); commitStatus = context.AddOrUpdateCommitStatus(state: "pending"); - Assert.AreEqual("pending", commitStatus.Status); + Assert.That(commitStatus.Status, Is.EqualTo("pending")); } } } diff --git a/NGitLab.Tests/CommitsTests.cs b/NGitLab.Tests/CommitsTests.cs index b77dd7d5..d6272ca4 100644 --- a/NGitLab.Tests/CommitsTests.cs +++ b/NGitLab.Tests/CommitsTests.cs @@ -18,8 +18,8 @@ public async Task Test_can_get_commit() var project = context.CreateProject(initializeWithCommits: true); var commit = context.Client.GetCommits(project.Id).GetCommit(project.DefaultBranch); - Assert.IsNotNull(commit.Message); - Assert.IsNotNull(commit.ShortId); + Assert.That(commit.Message, Is.Not.Null); + Assert.That(commit.ShortId, Is.Not.Null); } [Test] @@ -45,9 +45,9 @@ public async Task Test_can_get_stats_in_commit() }); var commit = context.Client.GetCommits(project.Id).GetCommit(project.DefaultBranch); - Assert.AreEqual(4, commit.Stats.Additions); - Assert.AreEqual(1, commit.Stats.Deletions); - Assert.AreEqual(5, commit.Stats.Total); + Assert.That(commit.Stats.Additions, Is.EqualTo(4)); + Assert.That(commit.Stats.Deletions, Is.EqualTo(1)); + Assert.That(commit.Stats.Total, Is.EqualTo(5)); } [Test] @@ -79,7 +79,7 @@ public async Task Test_can_get_merge_request_associated_to_commit() TimeSpan.FromSeconds(10)); var mergeRequest = mergeRequests.Single(); - Assert.AreEqual(mergeRequestTitle, mergeRequest.Title); + Assert.That(mergeRequest.Title, Is.EqualTo(mergeRequestTitle)); } [Test] @@ -115,7 +115,7 @@ public async Task Test_can_cherry_pick_commit() }); var latestCommit = commitClient.GetCommit(project.DefaultBranch); - Assert.AreEqual(cherryPickedCommit.Id, latestCommit.Id); + Assert.That(latestCommit.Id, Is.EqualTo(cherryPickedCommit.Id)); } } } diff --git a/NGitLab.Tests/CompareTests.cs b/NGitLab.Tests/CompareTests.cs index a4fd83f6..538e87f8 100644 --- a/NGitLab.Tests/CompareTests.cs +++ b/NGitLab.Tests/CompareTests.cs @@ -15,8 +15,8 @@ public async Task Test_compare_equal() var project = context.CreateProject(initializeWithCommits: true); var compareResults = context.Client.GetRepository(project.Id).Compare(new CompareQuery(project.DefaultBranch, project.DefaultBranch)); - Assert.IsNotNull(compareResults); - Assert.AreEqual(0, compareResults.Commits.Length); + Assert.That(compareResults, Is.Not.Null); + Assert.That(compareResults.Commits, Is.Empty); } [Test] @@ -50,8 +50,8 @@ public async Task Test_compare() var compareResults = context.Client.GetRepository(project.Id).Compare(new CompareQuery(project.DefaultBranch, "devtest")); - Assert.IsNotNull(compareResults); - Assert.AreEqual(2, compareResults.Commits.Length); + Assert.That(compareResults, Is.Not.Null); + Assert.That(compareResults.Commits, Has.Length.EqualTo(2)); } [Test] diff --git a/NGitLab.Tests/ContributorsTests.cs b/NGitLab.Tests/ContributorsTests.cs index a2f9b9e5..cd217047 100644 --- a/NGitLab.Tests/ContributorsTests.cs +++ b/NGitLab.Tests/ContributorsTests.cs @@ -19,8 +19,8 @@ public async Task Test_can_get_contributors() var currentUser = context.Client.Users.Current; var contributor = contributorsClient.All; - Assert.IsNotNull(contributor); - Assert.IsTrue(contributor.Any(x => string.Equals(x.Email, currentUser.Email, StringComparison.Ordinal))); + Assert.That(contributor, Is.Not.Null); + Assert.That(contributor.Any(x => string.Equals(x.Email, currentUser.Email, StringComparison.Ordinal)), Is.True); } [Test] @@ -63,8 +63,8 @@ public async Task Test_can_get_MultipleContributors() var contributors = await GitLabTestContext.RetryUntilAsync(() => contributorsClient.All.ToList(), c => c.Count >= 2, TimeSpan.FromMinutes(2)); - Assert.IsTrue(contributors.Any(x => string.Equals(x.Email, currentUser.Email, StringComparison.Ordinal))); - Assert.IsTrue(contributors.Any(x => string.Equals(x.Email, userUpsert.Email, StringComparison.Ordinal))); + Assert.That(contributors.Any(x => string.Equals(x.Email, currentUser.Email, StringComparison.Ordinal)), Is.True); + Assert.That(contributors.Any(x => string.Equals(x.Email, userUpsert.Email, StringComparison.Ordinal)), Is.True); context.AdminClient.Users.Delete(user.Id); } diff --git a/NGitLab.Tests/Docker/GitLabTestContext.cs b/NGitLab.Tests/Docker/GitLabTestContext.cs index 3d4b8585..98ffa02e 100644 --- a/NGitLab.Tests/Docker/GitLabTestContext.cs +++ b/NGitLab.Tests/Docker/GitLabTestContext.cs @@ -215,12 +215,12 @@ public Group CreateGroup(Action configure = null) }); var branch = client.GetRepository(project.Id).Branches.All.FirstOrDefault(b => string.Equals(b.Name, project.DefaultBranch, StringComparison.Ordinal)); - Assert.NotNull(branch, $"Branch '{project.DefaultBranch}' should exist"); - Assert.IsTrue(branch.Default, $"Branch '{project.DefaultBranch}' should be the default one"); + Assert.That(branch, Is.Not.Null, $"Branch '{project.DefaultBranch}' should exist"); + Assert.That(branch.Default, Is.True, $"Branch '{project.DefaultBranch}' should be the default one"); branch = client.GetRepository(project.Id).Branches.All.FirstOrDefault(b => string.Equals(b.Name, BranchForMRName, StringComparison.Ordinal)); - Assert.NotNull(branch, $"Branch '{BranchForMRName}' should exist"); - Assert.IsFalse(branch.Protected, $"Branch '{BranchForMRName}' should not be protected"); + Assert.That(branch, Is.Not.Null, $"Branch '{BranchForMRName}' should exist"); + Assert.That(branch.Protected, Is.False, $"Branch '{BranchForMRName}' should not be protected"); s_gitlabRetryPolicy.Execute(() => client.GetRepository(project.Id).Files.Update(new FileUpsert { Branch = BranchForMRName, CommitMessage = "test", Content = "test2", Path = "test.md" })); diff --git a/NGitLab.Tests/EnvironmentsTests.cs b/NGitLab.Tests/EnvironmentsTests.cs index 907f5fdf..159663ea 100644 --- a/NGitLab.Tests/EnvironmentsTests.cs +++ b/NGitLab.Tests/EnvironmentsTests.cs @@ -31,34 +31,34 @@ public async Task CreateAndGetAll() var newEnvNameExternalUrl = "https://www.example.com"; // Validate environments doesn't exist yet - Assert.IsNull(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameNoUrl, StringComparison.Ordinal) || string.Equals(e.Name, newEnvNameWithUrl, StringComparison.Ordinal))); + Assert.That(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameNoUrl, StringComparison.Ordinal) || string.Equals(e.Name, newEnvNameWithUrl, StringComparison.Ordinal)), Is.Null); // Create and check return value var env = envClient.Create(newEnvNameNoUrl, externalUrl: null); - StringAssert.AreEqualIgnoringCase(newEnvNameNoUrl, env.Name); - StringAssert.StartsWith(newEnvSlugNameNoUrlStart, env.Slug); - Assert.NotZero(env.Id); - Assert.IsNull(env.ExternalUrl); + Assert.That(env.Name, Is.EqualTo(newEnvNameNoUrl).IgnoreCase); + Assert.That(env.Slug, Does.StartWith(newEnvSlugNameNoUrlStart)); + Assert.That(env.Id, Is.Not.Zero); + Assert.That(env.ExternalUrl, Is.Null); // Create newEnvNameWithUrl and check return value env = envClient.Create(newEnvNameWithUrl, newEnvNameExternalUrl); - StringAssert.AreEqualIgnoringCase(newEnvNameWithUrl, env.Name); - StringAssert.StartsWith(newEnvSlugNameWithUrlStart, env.Slug); - Assert.NotZero(env.Id); - StringAssert.AreEqualIgnoringCase(newEnvNameExternalUrl, env.ExternalUrl); + Assert.That(env.Name, Is.EqualTo(newEnvNameWithUrl).IgnoreCase); + Assert.That(env.Slug, Does.StartWith(newEnvSlugNameWithUrlStart)); + Assert.That(env.Id, Is.Not.Zero); + Assert.That(env.ExternalUrl, Is.EqualTo(newEnvNameExternalUrl).IgnoreCase); // Validate new environment are present in All env = envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameNoUrl, StringComparison.Ordinal)); - Assert.IsNotNull(env); - StringAssert.StartsWith(newEnvSlugNameNoUrlStart, env.Slug); - Assert.NotZero(env.Id); - Assert.IsNull(env.ExternalUrl); + Assert.That(env, Is.Not.Null); + Assert.That(env.Slug, Does.StartWith(newEnvSlugNameNoUrlStart)); + Assert.That(env.Id, Is.Not.Zero); + Assert.That(env.ExternalUrl, Is.Null); env = envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameWithUrl, StringComparison.Ordinal)); - Assert.IsNotNull(env); - StringAssert.StartsWith(newEnvSlugNameWithUrlStart, env.Slug); - Assert.NotZero(env.Id); - StringAssert.AreEqualIgnoringCase(newEnvNameExternalUrl, env.ExternalUrl); + Assert.That(env, Is.Not.Null); + Assert.That(env.Slug, Does.StartWith(newEnvSlugNameWithUrlStart)); + Assert.That(env.Id, Is.Not.Zero); + Assert.That(env.ExternalUrl, Is.EqualTo(newEnvNameExternalUrl).IgnoreCase); } [Test] @@ -75,28 +75,28 @@ public async Task Edit() var newEnvNameExternalUrlUpdated = "https://www.example.com/updated"; // Validate environments doesn't exist yet - Assert.IsNull(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToEdit, StringComparison.Ordinal) || string.Equals(e.Name, newEnvNameUpdated, StringComparison.Ordinal))); + Assert.That(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToEdit, StringComparison.Ordinal) || string.Equals(e.Name, newEnvNameUpdated, StringComparison.Ordinal)), Is.Null); // Create newEnvNameToEdit var env = envClient.Create(newEnvNameToEdit, externalUrl: null); var initialEnvId = env.Id; // Validate newEnvNameToEdit is present - Assert.IsNotNull(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToEdit, StringComparison.Ordinal))); + Assert.That(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToEdit, StringComparison.Ordinal)), Is.Not.Null); // Edit and check return value env = envClient.Edit(initialEnvId, newEnvNameUpdated, newEnvNameExternalUrlUpdated); - StringAssert.AreEqualIgnoringCase(newEnvNameUpdated, env.Name); - StringAssert.StartsWith(newEnvSlugNameUpdatedStart, env.Slug); - Assert.AreEqual(initialEnvId, env.Id, "Environment Id should not change"); - StringAssert.AreEqualIgnoringCase(newEnvNameExternalUrlUpdated, env.ExternalUrl); + Assert.That(env.Name, Is.EqualTo(newEnvNameUpdated).IgnoreCase); + Assert.That(env.Slug, Does.StartWith(newEnvSlugNameUpdatedStart)); + Assert.That(env.Id, Is.EqualTo(initialEnvId), "Environment Id should not change"); + Assert.That(env.ExternalUrl, Is.EqualTo(newEnvNameExternalUrlUpdated).IgnoreCase); // Validate update is effective env = envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameUpdated, StringComparison.Ordinal)); - Assert.IsNotNull(env); - StringAssert.StartsWith(newEnvSlugNameUpdatedStart, env.Slug); - Assert.AreEqual(initialEnvId, env.Id, "Environment Id should not change"); - StringAssert.AreEqualIgnoringCase(newEnvNameExternalUrlUpdated, env.ExternalUrl); + Assert.That(env, Is.Not.Null); + Assert.That(env.Slug, Does.StartWith(newEnvSlugNameUpdatedStart)); + Assert.That(env.Id, Is.EqualTo(initialEnvId), "Environment Id should not change"); + Assert.That(env.ExternalUrl, Is.EqualTo(newEnvNameExternalUrlUpdated).IgnoreCase); } [Test] @@ -110,7 +110,7 @@ public async Task Delete() var newEnvNameToDelete = "env_test_name_to_delete"; // Validate environment doesn't exist yet - Assert.IsNull(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToDelete, StringComparison.Ordinal))); + Assert.That(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToDelete, StringComparison.Ordinal)), Is.Null); // Create newEnvNameToDelete var env = envClient.Create(newEnvNameToDelete, externalUrl: null); @@ -118,8 +118,8 @@ public async Task Delete() // Validate newEnvNameToDelete is present & available env = envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToDelete, StringComparison.Ordinal)); - Assert.IsNotNull(env); - StringAssert.AreEqualIgnoringCase("available", env.State); + Assert.That(env, Is.Not.Null); + Assert.That(env.State, Is.EqualTo("available").IgnoreCase); // Trying to delete without stopping beforehand will throw... Assert.Throws(() => envClient.Delete(initialEnvId)); @@ -127,13 +127,13 @@ public async Task Delete() // Stop envClient.Stop(initialEnvId); env = envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToDelete, StringComparison.Ordinal)); - StringAssert.AreEqualIgnoringCase("stopped", env.State); + Assert.That(env.State, Is.EqualTo("stopped").IgnoreCase); // Delete envClient.Delete(initialEnvId); // Validate delete is effective - Assert.IsNull(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToDelete, StringComparison.Ordinal))); + Assert.That(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToDelete, StringComparison.Ordinal)), Is.Null); } [Test] @@ -148,24 +148,24 @@ public async Task Stop() var newEnvSlugNameToStopStart = GetSlugNameStart(newEnvNameToStop); // Validate environment doesn't exist yet - Assert.IsNull(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToStop, StringComparison.Ordinal))); + Assert.That(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToStop, StringComparison.Ordinal)), Is.Null); // Create newEnvNameToStop var env = envClient.Create(newEnvNameToStop, externalUrl: null); var initialEnvId = env.Id; // Validate newEnvNameToStop is present - Assert.IsNotNull(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToStop, StringComparison.Ordinal))); + Assert.That(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToStop, StringComparison.Ordinal)), Is.Not.Null); // Stop and check return value env = envClient.Stop(initialEnvId); - StringAssert.AreEqualIgnoringCase(newEnvNameToStop, env.Name); - StringAssert.StartsWith(newEnvSlugNameToStopStart, env.Slug); - Assert.AreEqual(initialEnvId, env.Id, "Environment Id should not change"); - Assert.IsNull(env.ExternalUrl); + Assert.That(env.Name, Is.EqualTo(newEnvNameToStop).IgnoreCase); + Assert.That(env.Slug, Does.StartWith(newEnvSlugNameToStopStart)); + Assert.That(env.Id, Is.EqualTo(initialEnvId), "Environment Id should not change"); + Assert.That(env.ExternalUrl, Is.Null); // Validate environment is still present - Assert.IsNotNull(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToStop, StringComparison.Ordinal))); + Assert.That(envClient.All.FirstOrDefault(e => string.Equals(e.Name, newEnvNameToStop, StringComparison.Ordinal)), Is.Not.Null); } [Test] @@ -188,10 +188,10 @@ public async Task QueryByState() var availableEnvs = envClient.GetEnvironmentsAsync(new EnvironmentQuery { State = "available" }); // Assert - Assert.AreEqual(2, envClient.All.Count()); + Assert.That(envClient.All.Count(), Is.EqualTo(2)); var availableEnvResult = availableEnvs.Single(); - Assert.AreEqual(newEnvNameAvailable, availableEnvResult.Name); - Assert.AreEqual("available", availableEnvResult.State); + Assert.That(availableEnvResult.Name, Is.EqualTo(newEnvNameAvailable)); + Assert.That(availableEnvResult.State, Is.EqualTo("available")); } [Test] @@ -213,9 +213,9 @@ public async Task QueryByName() var prodEnvs = envClient.GetEnvironmentsAsync(new EnvironmentQuery { Name = prodEnvName }); // Assert - Assert.AreEqual(2, envClient.All.Count()); + Assert.That(envClient.All.Count(), Is.EqualTo(2)); var availableEnvResult = prodEnvs.Single(); - Assert.AreEqual(prodEnvName, availableEnvResult.Name); + Assert.That(availableEnvResult.Name, Is.EqualTo(prodEnvName)); } [Test] @@ -240,8 +240,8 @@ public async Task QueryBySearch() var devEnvs = envClient.GetEnvironmentsAsync(new EnvironmentQuery { Search = "dev" }); // Assert - Assert.AreEqual(3, envClient.All.Count()); - Assert.AreEqual(2, devEnvs.Count()); + Assert.That(envClient.All.Count(), Is.EqualTo(3)); + Assert.That(devEnvs.Count(), Is.EqualTo(2)); Assert.That(devEnvs, Is.All.Matches(e => e.Name.Contains("dev", StringComparison.Ordinal))); } @@ -261,8 +261,8 @@ public async Task GetById() var devEnv = await envClient.GetByIdAsync(devEnvironment.Id); // Assert - Assert.NotNull(devEnv); - Assert.AreEqual(devEnvName, devEnv.Name); + Assert.That(devEnv, Is.Not.Null); + Assert.That(devEnv.Name, Is.EqualTo(devEnvName)); } } } diff --git a/NGitLab.Tests/FilesTests.cs b/NGitLab.Tests/FilesTests.cs index c1510d73..b0b8b82d 100644 --- a/NGitLab.Tests/FilesTests.cs +++ b/NGitLab.Tests/FilesTests.cs @@ -29,16 +29,16 @@ public async Task Test_add_update_delete_and_get_file() filesClient.Create(fileUpsert); var file = filesClient.Get(fileName, project.DefaultBranch); - Assert.IsNotNull(file); - Assert.AreEqual(fileName, file.Name); - Assert.AreEqual("test", file.DecodedContent); + Assert.That(file, Is.Not.Null); + Assert.That(file.Name, Is.EqualTo(fileName)); + Assert.That(file.DecodedContent, Is.EqualTo("test")); fileUpsert.RawContent = "test2"; filesClient.Update(fileUpsert); file = filesClient.Get(fileName, project.DefaultBranch); - Assert.IsNotNull(file); - Assert.AreEqual("test2", file.DecodedContent); + Assert.That(file, Is.Not.Null); + Assert.That(file.DecodedContent, Is.EqualTo("test2")); var fileDelete = new FileDelete { @@ -73,19 +73,19 @@ public async Task Test_get_blame_of_latest_commit() var blameArray1 = filesClient.Blame(fileName, project.DefaultBranch); - Assert.AreEqual(1, blameArray1.Length); - Assert.IsNotNull(blameArray1); + Assert.That(blameArray1, Has.Length.EqualTo(1)); + Assert.That(blameArray1, Is.Not.Null); var firstBlameInfo = blameArray1[0]; - Assert.AreEqual(content1, string.Join(Environment.NewLine, firstBlameInfo.Lines)); - Assert.AreEqual(fileUpsert1.CommitMessage, firstBlameInfo.Commit.Message); - Assert.NotNull(firstBlameInfo.Commit.CommittedDate); - Assert.IsNotEmpty(firstBlameInfo.Commit.AuthorEmail); - Assert.IsNotEmpty(firstBlameInfo.Commit.AuthorName); - Assert.IsNotEmpty(firstBlameInfo.Commit.CommitterEmail); - Assert.IsNotEmpty(firstBlameInfo.Commit.CommitterName); - Assert.NotNull(firstBlameInfo.Commit.AuthoredDate); + Assert.That(string.Join(Environment.NewLine, firstBlameInfo.Lines), Is.EqualTo(content1)); + Assert.That(firstBlameInfo.Commit.Message, Is.EqualTo(fileUpsert1.CommitMessage)); + Assert.That(firstBlameInfo.Commit.CommittedDate, Is.Not.EqualTo(default(DateTime))); + Assert.That(firstBlameInfo.Commit.AuthorEmail, Is.Not.Empty); + Assert.That(firstBlameInfo.Commit.AuthorName, Is.Not.Empty); + Assert.That(firstBlameInfo.Commit.CommitterEmail, Is.Not.Empty); + Assert.That(firstBlameInfo.Commit.CommitterName, Is.Not.Empty); + Assert.That(firstBlameInfo.Commit.AuthoredDate, Is.Not.EqualTo(default(DateTime))); var content2 = "second line"; var fileUpsert2 = new FileUpsert @@ -100,19 +100,19 @@ public async Task Test_get_blame_of_latest_commit() var blameArray2 = filesClient.Blame(fileName, project.DefaultBranch); - Assert.AreEqual(2, blameArray2.Length); - Assert.AreEqual(firstBlameInfo, blameArray2[0]); + Assert.That(blameArray2, Has.Length.EqualTo(2)); + Assert.That(blameArray2[0], Is.EqualTo(firstBlameInfo)); var secondBlameInfo = blameArray2[1]; - Assert.AreEqual(content2, string.Join(Environment.NewLine, secondBlameInfo.Lines)); - Assert.AreEqual(fileUpsert2.CommitMessage, secondBlameInfo.Commit.Message); - Assert.NotNull(secondBlameInfo.Commit.CommittedDate); - Assert.IsNotEmpty(secondBlameInfo.Commit.AuthorEmail); - Assert.IsNotEmpty(secondBlameInfo.Commit.AuthorName); - Assert.IsNotEmpty(secondBlameInfo.Commit.CommitterEmail); - Assert.IsNotEmpty(secondBlameInfo.Commit.CommitterName); - Assert.NotNull(secondBlameInfo.Commit.AuthoredDate); + Assert.That(string.Join(Environment.NewLine, secondBlameInfo.Lines), Is.EqualTo(content2)); + Assert.That(secondBlameInfo.Commit.Message, Is.EqualTo(fileUpsert2.CommitMessage)); + Assert.That(secondBlameInfo.Commit.CommittedDate, Is.Not.EqualTo(default(DateTime))); + Assert.That(secondBlameInfo.Commit.AuthorEmail, Is.Not.Empty); + Assert.That(secondBlameInfo.Commit.AuthorName, Is.Not.Empty); + Assert.That(secondBlameInfo.Commit.CommitterEmail, Is.Not.Empty); + Assert.That(secondBlameInfo.Commit.CommitterName, Is.Not.Empty); + Assert.That(secondBlameInfo.Commit.AuthoredDate, Is.Not.EqualTo(default(DateTime))); var fileDelete = new FileDelete { @@ -145,8 +145,8 @@ public async Task Test_get_blame_of_an_old_commit() var initialBlame = filesClient.Blame(fileName, project.DefaultBranch); - Assert.IsNotNull(initialBlame); - Assert.AreEqual(1, initialBlame.Length); + Assert.That(initialBlame, Is.Not.Null); + Assert.That(initialBlame, Has.Length.EqualTo(1)); var initialBlameInfo = initialBlame[0]; @@ -163,8 +163,8 @@ public async Task Test_get_blame_of_an_old_commit() var blameById = filesClient.Blame(fileName, initialBlameInfo.Commit.Id.ToString()); - Assert.AreEqual(1, blameById.Length); - Assert.AreEqual(initialBlameInfo, blameById[0]); + Assert.That(blameById, Has.Length.EqualTo(1)); + Assert.That(blameById[0], Is.EqualTo(initialBlameInfo)); var fileDelete = new FileDelete { @@ -197,18 +197,15 @@ public async Task Test_blame_comparison() var realBlame = filesClient.Blame(fileName, project.DefaultBranch); - Assert.IsNotNull(realBlame); - Assert.AreEqual(1, realBlame.Length); + Assert.That(realBlame, Is.Not.Null); + Assert.That(realBlame, Has.Length.EqualTo(1)); var realBlameInfo = realBlame[0]; var dummyBlameInfo = new Blame(); - Assert.AreNotEqual(dummyBlameInfo, realBlameInfo); - Assert.AreNotEqual(realBlameInfo, null); - Assert.AreNotEqual(null, realBlameInfo); - Assert.AreEqual(realBlameInfo, realBlameInfo); - Assert.AreEqual(dummyBlameInfo, dummyBlameInfo); + Assert.That(realBlameInfo, Is.Not.EqualTo(dummyBlameInfo)); + Assert.That(realBlameInfo, Is.Not.Null); var fileDelete = new FileDelete { @@ -239,8 +236,8 @@ public async Task Test_get_file_with_bom() filesClient.Create(fileUpsert); var file = filesClient.Get(fileName, project.DefaultBranch); - Assert.AreEqual("77u/YQ==", file.Content); - Assert.AreEqual("a", file.DecodedContent); + Assert.That(file.Content, Is.EqualTo("77u/YQ==")); + Assert.That(file.DecodedContent, Is.EqualTo("a")); } } } diff --git a/NGitLab.Tests/GitLabChangeDiffCounterTests.cs b/NGitLab.Tests/GitLabChangeDiffCounterTests.cs index c09a22aa..3db109fa 100644 --- a/NGitLab.Tests/GitLabChangeDiffCounterTests.cs +++ b/NGitLab.Tests/GitLabChangeDiffCounterTests.cs @@ -37,8 +37,8 @@ public void Compute_return_diffs_stats() }; var unitUnderTest = new GitLabChangeDiffCounter(); var diffStats = unitUnderTest.Compute(mrChange); - Assert.AreEqual(53, diffStats.AddedLines); - Assert.AreEqual(2, diffStats.DeletedLines); + Assert.That(diffStats.AddedLines, Is.EqualTo(53)); + Assert.That(diffStats.DeletedLines, Is.EqualTo(2)); } } } diff --git a/NGitLab.Tests/GitLabCredentialsTests.cs b/NGitLab.Tests/GitLabCredentialsTests.cs index 3370651f..5e09033b 100644 --- a/NGitLab.Tests/GitLabCredentialsTests.cs +++ b/NGitLab.Tests/GitLabCredentialsTests.cs @@ -20,7 +20,7 @@ public void Constructor_should_reject_apiv3(string url) public void Constructor_should_complete_api_version_when_not_set(string url, string expectedUrl) { var gitLabCredentials = new GitLabCredentials(url, "my_token"); - Assert.AreEqual(expectedUrl, gitLabCredentials.HostUrl); + Assert.That(gitLabCredentials.HostUrl, Is.EqualTo(expectedUrl)); } } } diff --git a/NGitLab.Tests/GlobalUsings.cs b/NGitLab.Tests/GlobalUsings.cs deleted file mode 100644 index bb334208..00000000 --- a/NGitLab.Tests/GlobalUsings.cs +++ /dev/null @@ -1,5 +0,0 @@ -// This is needed for quick migration from NUnit 3.x -> 4.x -// https://docs.nunit.org/articles/nunit/release-notes/Nunit4.0-MigrationGuide.html#use-global-using-aliases -global using Assert = NUnit.Framework.Legacy.ClassicAssert; -global using CollectionAssert = NUnit.Framework.Legacy.CollectionAssert; -global using StringAssert = NUnit.Framework.Legacy.StringAssert; diff --git a/NGitLab.Tests/GraphQLTests.cs b/NGitLab.Tests/GraphQLTests.cs index 4a3a955e..3c2aa08b 100644 --- a/NGitLab.Tests/GraphQLTests.cs +++ b/NGitLab.Tests/GraphQLTests.cs @@ -26,7 +26,7 @@ public async Task Test_invalid_request() }", })); - StringAssert.Contains("Field 'unknownProperty' doesn't exist on type 'Project'", exception.Message); + Assert.That(exception.Message, Does.Contain("Field 'unknownProperty' doesn't exist on type 'Project'")); } [Test] @@ -51,7 +51,7 @@ public async Task Test_get_project() }, }); - Assert.AreEqual("gid://gitlab/Project/" + project.Id.ToStringInvariant(), response.Project.Id); + Assert.That(response.Project.Id, Is.EqualTo("gid://gitlab/Project/" + project.Id.ToStringInvariant())); } private sealed class ProjectResponse diff --git a/NGitLab.Tests/GroupBadgeClientTests.cs b/NGitLab.Tests/GroupBadgeClientTests.cs index de4dba93..be79fd7b 100644 --- a/NGitLab.Tests/GroupBadgeClientTests.cs +++ b/NGitLab.Tests/GroupBadgeClientTests.cs @@ -23,9 +23,9 @@ public async Task Test_group_badges() LinkUrl = "http://dummy/image.html", }); - Assert.AreEqual(BadgeKind.Group, badge.Kind); - Assert.AreEqual("http://dummy/image.png", badge.ImageUrl); - Assert.AreEqual("http://dummy/image.html", badge.LinkUrl); + Assert.That(badge.Kind, Is.EqualTo(BadgeKind.Group)); + Assert.That(badge.ImageUrl, Is.EqualTo("http://dummy/image.png")); + Assert.That(badge.LinkUrl, Is.EqualTo("http://dummy/image.html")); // Update badge = groupBadgeClient.Update(badge.Id, new BadgeUpdate @@ -34,22 +34,22 @@ public async Task Test_group_badges() LinkUrl = "http://dummy/image_edit.html", }); - Assert.AreEqual(BadgeKind.Group, badge.Kind); - Assert.AreEqual("http://dummy/image_edit.png", badge.ImageUrl); - Assert.AreEqual("http://dummy/image_edit.html", badge.LinkUrl); + Assert.That(badge.Kind, Is.EqualTo(BadgeKind.Group)); + Assert.That(badge.ImageUrl, Is.EqualTo("http://dummy/image_edit.png")); + Assert.That(badge.LinkUrl, Is.EqualTo("http://dummy/image_edit.html")); // Delete groupBadgeClient.Delete(badge.Id); var badges = groupBadgeClient.All.ToList(); - Assert.IsEmpty(badges); + Assert.That(badges, Is.Empty); // All groupBadgeClient.Create(new BadgeCreate { ImageUrl = "http://dummy/image1.png", LinkUrl = "http://dummy/image1.html", }); groupBadgeClient.Create(new BadgeCreate { ImageUrl = "http://dummy/image2.png", LinkUrl = "http://dummy/image2.html", }); groupBadgeClient.Create(new BadgeCreate { ImageUrl = "http://dummy/image3.png", LinkUrl = "http://dummy/image3.html", }); badges = groupBadgeClient.All.ToList(); - Assert.AreEqual(3, badges.Count); + Assert.That(badges, Has.Count.EqualTo(3)); } } } diff --git a/NGitLab.Tests/GroupVariableClientTests.cs b/NGitLab.Tests/GroupVariableClientTests.cs index 038364f0..efc81788 100644 --- a/NGitLab.Tests/GroupVariableClientTests.cs +++ b/NGitLab.Tests/GroupVariableClientTests.cs @@ -24,9 +24,9 @@ public async Task Test_group_variables() Protected = true, }); - Assert.AreEqual("My_Key", variable.Key); - Assert.AreEqual("My value", variable.Value); - Assert.AreEqual(true, variable.Protected); + Assert.That(variable.Key, Is.EqualTo("My_Key")); + Assert.That(variable.Value, Is.EqualTo("My value")); + Assert.That(variable.Protected, Is.EqualTo(true)); // Update variable = groupVariableClient.Update(variable.Key, new VariableUpdate @@ -35,22 +35,22 @@ public async Task Test_group_variables() Protected = false, }); - Assert.AreEqual("My_Key", variable.Key); - Assert.AreEqual("My value edited", variable.Value); - Assert.AreEqual(false, variable.Protected); + Assert.That(variable.Key, Is.EqualTo("My_Key")); + Assert.That(variable.Value, Is.EqualTo("My value edited")); + Assert.That(variable.Protected, Is.EqualTo(false)); // Delete groupVariableClient.Delete(variable.Key); var variables = groupVariableClient.All.ToList(); - Assert.IsEmpty(variables); + Assert.That(variables, Is.Empty); // All groupVariableClient.Create(new VariableCreate { Key = "Variable1", Value = "test" }); groupVariableClient.Create(new VariableCreate { Key = "Variable2", Value = "test" }); groupVariableClient.Create(new VariableCreate { Key = "Variable3", Value = "test" }); variables = groupVariableClient.All.ToList(); - Assert.AreEqual(3, variables.Count); + Assert.That(variables, Has.Count.EqualTo(3)); } } } diff --git a/NGitLab.Tests/GroupsTests.cs b/NGitLab.Tests/GroupsTests.cs index 536e1ae4..8d5de62e 100644 --- a/NGitLab.Tests/GroupsTests.cs +++ b/NGitLab.Tests/GroupsTests.cs @@ -19,7 +19,7 @@ public async Task Test_groups_is_not_empty() var groupClient = context.Client.Groups; var group = context.CreateGroup(); - Assert.IsNotEmpty(groupClient.Accessible); + Assert.That(groupClient.Accessible, Is.Not.Empty); } [Test] @@ -32,9 +32,9 @@ public async Task Test_projects_are_set_in_a_group_by_id() var project = context.Client.Projects.Create(new ProjectCreate { Name = "test", NamespaceId = group.Id.ToString(CultureInfo.InvariantCulture) }); group = groupClient[group.Id]; - Assert.IsNotNull(group); - Assert.IsNotEmpty(group.Projects); - Assert.AreEqual(project.Id, group.Projects[0].Id); + Assert.That(group, Is.Not.Null); + Assert.That(group.Projects, Is.Not.Empty); + Assert.That(group.Projects[0].Id, Is.EqualTo(project.Id)); } [Test] @@ -46,7 +46,7 @@ public async Task Test_get_group_by_fullpath() var group = context.CreateGroup(); group = groupClient[group.FullPath]; - Assert.IsNotNull(group); + Assert.That(group, Is.Not.Null); } [Test] @@ -59,7 +59,7 @@ public async Task Test_create_delete_group() // Search var searchedGroup = groupClient.Search(group.Name).Single(); - Assert.AreEqual(group.Id, searchedGroup.Id); + Assert.That(searchedGroup.Id, Is.EqualTo(group.Id)); // Delete (operation is asynchronous so we have to retry until the project is deleted) // Group can be marked for deletion (https://docs.gitlab.com/ee/user/admin_area/settings/visibility_and_access_controls.html#default-deletion-adjourned-period-premium-only) @@ -91,7 +91,7 @@ public async Task Test_get_by_group_query_nulls_does_not_throws() var groupQueryNull = new GroupQuery(); // Act & Assert - Assert.NotNull(groupClient.Get(groupQueryNull).Take(10).ToList()); + Assert.That(groupClient.Get(groupQueryNull).Take(10).ToList(), Is.Not.Null); } [Test] @@ -113,7 +113,7 @@ public async Task Test_get_by_group_query_groupQuery_SkipGroups_returns_groups() // Assert foreach (var skippedGroup in skippedGroupIds) { - Assert.False(resultSkip.Any(group => group.Id == skippedGroup), $"Group {skippedGroup} found in results"); + Assert.That(resultSkip.Any(group => group.Id == skippedGroup), Is.False, $"Group {skippedGroup} found in results"); } } @@ -136,7 +136,7 @@ public async Task Test_get_by_group_query_groupQuery_Search_returns_groups() var result = groupClient.Get(groupQueryNull).Count(g => string.Equals(g.Name, group1.Name, StringComparison.Ordinal)); // Assert - Assert.AreEqual(1, result); + Assert.That(result, Is.EqualTo(1)); } [Test] @@ -157,7 +157,7 @@ public async Task Test_get_by_group_query_groupQuery_AllAvailable_returns_groups var result = groupClient.Get(groupQueryAllAvailable); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -188,9 +188,9 @@ public async Task Test_get_by_group_query_groupQuery_OrderBy_returns_groups() var resultById = groupClient.Get(groupQueryOrderById); // Assert - Assert.IsTrue(resultByName.Any()); - Assert.IsTrue(resultByPath.Any()); - Assert.IsTrue(resultById.Any()); + Assert.That(resultByName.Any(), Is.True); + Assert.That(resultByPath.Any(), Is.True); + Assert.That(resultById.Any(), Is.True); } [Test] @@ -216,8 +216,8 @@ public async Task Test_get_by_group_query_groupQuery_Sort_returns_groups() var resultDesc = groupClient.Get(groupQueryDesc); // Assert - Assert.IsTrue(resultAsc.Any()); - Assert.IsTrue(resultDesc.Any()); + Assert.That(resultAsc.Any(), Is.True); + Assert.That(resultDesc.Any(), Is.True); } [Test] @@ -237,7 +237,7 @@ public async Task Test_get_by_group_query_groupQuery_Statistics_returns_groups() var result = groupClient.Get(groupQueryWithStats); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -257,7 +257,7 @@ public async Task Test_get_by_group_query_groupQuery_WithCustomAttributes_return var result = groupClient.Get(groupQueryWithCustomAttributes); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -277,7 +277,7 @@ public async Task Test_get_by_group_query_groupQuery_Owned_returns_groups() var result = groupClient.Get(groupQueryOwned); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -317,11 +317,11 @@ public async Task Test_get_by_group_query_groupQuery_MinAccessLevel_returns_grou var result50 = groupClient.Get(groupQuery50); // Assert - Assert.IsTrue(result10.Any()); - Assert.IsTrue(result20.Any()); - Assert.IsTrue(result30.Any()); - Assert.IsTrue(result40.Any()); - Assert.IsTrue(result50.Any()); + Assert.That(result10.Any(), Is.True); + Assert.That(result20.Any(), Is.True); + Assert.That(result30.Any(), Is.True); + Assert.That(result40.Any(), Is.True); + Assert.That(result50.Any(), Is.True); } [Test] @@ -342,12 +342,12 @@ public async Task Test_group_projects_query_returns_archived() }).ToArray(); group = groupClient[group.Id]; - Assert.IsNotNull(group); - Assert.IsNotEmpty(projects); + Assert.That(group, Is.Not.Null); + Assert.That(projects, Is.Not.Empty); var projectResult = projects.Single(); - Assert.AreEqual(project.Id, projectResult.Id); - Assert.True(projectResult.Archived); + Assert.That(projectResult.Id, Is.EqualTo(project.Id)); + Assert.That(projectResult.Archived, Is.True); } [Test] @@ -368,11 +368,11 @@ public async Task Test_group_projects_query_returns_searched_project() }).ToArray(); group = groupClient[group.Id]; - Assert.IsNotNull(group); - Assert.IsNotEmpty(projects); + Assert.That(group, Is.Not.Null); + Assert.That(projects, Is.Not.Empty); var projectResult = projects.Single(); - Assert.AreEqual(project.Id, projectResult.Id); + Assert.That(projectResult.Id, Is.EqualTo(project.Id)); } [Test] @@ -389,7 +389,7 @@ public async Task Test_get_subgroups_by_id() var subGroupThree = context.CreateGroup(configure: group => group.ParentId = parentGroupTwo.Id); var subgroups = groupClient.GetSubgroupsByIdAsync(parentGroupOne.Id); - Assert.AreEqual(2, subgroups.Count()); + Assert.That(subgroups.Count(), Is.EqualTo(2)); } [Test] @@ -406,7 +406,7 @@ public async Task Test_get_subgroups_by_fullpath() var subGroupThree = context.CreateGroup(configure: group => group.ParentId = parentGroupTwo.Id); var subgroups = groupClient.GetSubgroupsByFullPathAsync(parentGroupOne.FullPath); - Assert.AreEqual(2, subgroups.Count()); + Assert.That(subgroups.Count(), Is.EqualTo(2)); } [Test] @@ -430,7 +430,7 @@ public async Task Test_get_subgroups_by_id_SkipGroups_returns_groups() // Assert foreach (var skippedGroup in skippedGroupIds) { - Assert.False(resultSkip.Any(group => group.Id == skippedGroup), $"Group {skippedGroup} found in results"); + Assert.That(resultSkip.Any(group => group.Id == skippedGroup), Is.False, $"Group {skippedGroup} found in results"); } } @@ -455,7 +455,7 @@ public async Task Test_get_subgroups_by_fullpath_SkipGroups_returns_groups() // Assert foreach (var skippedGroup in skippedGroupIds) { - Assert.False(resultSkip.Any(group => group.Id == skippedGroup), $"Group {skippedGroup} found in results"); + Assert.That(resultSkip.Any(group => group.Id == skippedGroup), Is.False, $"Group {skippedGroup} found in results"); } } @@ -481,7 +481,7 @@ public async Task Test_get_subgroups_by_id_groupQuery_Search_returns_groups() var result = groupClient.GetSubgroupsByIdAsync(parentGroup.Id, groupQuery).Count(g => string.Equals(g.Name, subGroupOne.Name, StringComparison.Ordinal)); // Assert - Assert.AreEqual(1, result); + Assert.That(result, Is.EqualTo(1)); } [Test] @@ -506,7 +506,7 @@ public async Task Test_get_subgroups_by_fullpath_groupQuery_Search_returns_group var result = groupClient.GetSubgroupsByFullPathAsync(parentGroup.FullPath, groupQuery).Count(g => string.Equals(g.Name, subGroupOne.Name, StringComparison.Ordinal)); // Assert - Assert.AreEqual(1, result); + Assert.That(result, Is.EqualTo(1)); } [Test] @@ -531,7 +531,7 @@ public async Task Test_get_subgroups_by_id_groupQuery_AllAvailable_returns_group var result = groupClient.GetSubgroupsByIdAsync(parentGroup.Id, groupQueryAllAvailable); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -556,7 +556,7 @@ public async Task Test_get_subgroups_by_fullpath_query_groupQuery_AllAvailable_r var result = groupClient.GetSubgroupsByFullPathAsync(parentGroup.FullPath, groupQueryAllAvailable); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -591,9 +591,9 @@ public async Task Test_get_subgroups_by_id_groupQuery_OrderBy_returns_groups() var resultById = groupClient.GetSubgroupsByIdAsync(parentGroup.Id, groupQueryOrderById); // Assert - Assert.IsTrue(resultByName.Any()); - Assert.IsTrue(resultByPath.Any()); - Assert.IsTrue(resultById.Any()); + Assert.That(resultByName.Any(), Is.True); + Assert.That(resultByPath.Any(), Is.True); + Assert.That(resultById.Any(), Is.True); } [Test] @@ -628,9 +628,9 @@ public async Task Test_get_subgroups_by_fullpath_groupQuery_OrderBy_returns_grou var resultById = groupClient.GetSubgroupsByFullPathAsync(parentGroup.FullPath, groupQueryOrderById); // Assert - Assert.IsTrue(resultByName.Any()); - Assert.IsTrue(resultByPath.Any()); - Assert.IsTrue(resultById.Any()); + Assert.That(resultByName.Any(), Is.True); + Assert.That(resultByPath.Any(), Is.True); + Assert.That(resultById.Any(), Is.True); } [Test] @@ -660,8 +660,8 @@ public async Task Test_get_subgroups_by_id_groupQuery_Sort_returns_groups() var resultDesc = groupClient.GetSubgroupsByIdAsync(parentGroup.Id, groupQueryDesc); // Assert - Assert.IsTrue(resultAsc.Any()); - Assert.IsTrue(resultDesc.Any()); + Assert.That(resultAsc.Any(), Is.True); + Assert.That(resultDesc.Any(), Is.True); } [Test] @@ -691,8 +691,8 @@ public async Task Test_get_subgroups_by_fullpath_groupQuery_Sort_returns_groups( var resultDesc = groupClient.GetSubgroupsByFullPathAsync(parentGroup.FullPath, groupQueryDesc); // Assert - Assert.IsTrue(resultAsc.Any()); - Assert.IsTrue(resultDesc.Any()); + Assert.That(resultAsc.Any(), Is.True); + Assert.That(resultDesc.Any(), Is.True); } [Test] @@ -716,7 +716,7 @@ public async Task Test_get_subgroups_by_id_groupQuery_Statistics_returns_groups( var result = groupClient.GetSubgroupsByIdAsync(parentGroup.Id, groupQueryWithStats); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -740,7 +740,7 @@ public async Task Test_get_subgroups_by_fullpath_groupQuery_Statistics_returns_g var result = groupClient.GetSubgroupsByFullPathAsync(parentGroup.FullPath, groupQueryWithStats); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -764,7 +764,7 @@ public async Task Test_get_subgroups_by_id_groupQuery_WithCustomAttributes_retur var result = groupClient.GetSubgroupsByIdAsync(parentGroup.Id, groupQueryWithCustomAttributes); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -788,7 +788,7 @@ public async Task Test_get_subgroups_by_fullpath_groupQuery_WithCustomAttributes var result = groupClient.GetSubgroupsByFullPathAsync(parentGroup.FullPath, groupQueryWithCustomAttributes); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -812,7 +812,7 @@ public async Task Test_get_subgroups_by_id_groupQuery_Owned_returns_groups() var result = groupClient.GetSubgroupsByIdAsync(parentGroup.Id, groupQueryOwned); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -836,7 +836,7 @@ public async Task Test_get_subgroups_by_fullpath_groupQuery_Owned_returns_groups var result = groupClient.GetSubgroupsByFullPathAsync(parentGroup.FullPath, groupQueryOwned); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -880,11 +880,11 @@ public async Task Test_get_subgroups_by_id_groupQuery_MinAccessLevel_returns_gro var resultOwner = groupClient.GetSubgroupsByIdAsync(parentGroup.Id, groupQueryOwner); // Assert - Assert.IsTrue(resultGuest.Any()); - Assert.IsTrue(resultReporter.Any()); - Assert.IsTrue(resultDeveloper.Any()); - Assert.IsTrue(resultMantainer.Any()); - Assert.IsTrue(resultOwner.Any()); + Assert.That(resultGuest.Any(), Is.True); + Assert.That(resultReporter.Any(), Is.True); + Assert.That(resultDeveloper.Any(), Is.True); + Assert.That(resultMantainer.Any(), Is.True); + Assert.That(resultOwner.Any(), Is.True); } [Test] @@ -928,11 +928,11 @@ public async Task Test_get_subgroups_by_fullpath_groupQuery_MinAccessLevel_retur var resultOwner = groupClient.GetSubgroupsByFullPathAsync(parentGroup.FullPath, groupQueryOwner); // Assert - Assert.IsTrue(resultGuest.Any()); - Assert.IsTrue(resultReporter.Any()); - Assert.IsTrue(resultDeveloper.Any()); - Assert.IsTrue(resultMantainer.Any()); - Assert.IsTrue(resultOwner.Any()); + Assert.That(resultGuest.Any(), Is.True); + Assert.That(resultReporter.Any(), Is.True); + Assert.That(resultDeveloper.Any(), Is.True); + Assert.That(resultMantainer.Any(), Is.True); + Assert.That(resultOwner.Any(), Is.True); } } } diff --git a/NGitLab.Tests/HttpRequestorTests.cs b/NGitLab.Tests/HttpRequestorTests.cs index 83b9a515..0d41022d 100644 --- a/NGitLab.Tests/HttpRequestorTests.cs +++ b/NGitLab.Tests/HttpRequestorTests.cs @@ -19,7 +19,7 @@ public async Task SetUpOnceAsync() // Make sure at least 1 project exists using var context = await GitLabTestContext.CreateAsync(); var project = context.CreateProject(); - Assert.NotNull(project); + Assert.That(project, Is.Not.Null); } [Test] @@ -32,8 +32,8 @@ public async Task Test_calls_are_retried_when_they_fail_in_gitlab() Assert.Throws(() => httpRequestor.Execute("invalidUrl")); Assert.That(requestOptions.ShouldRetryCalled, Is.True); - Assert.That(requestOptions.HandledRequests.Count, Is.EqualTo(2)); - Assert.IsNull(requestOptions.HttpRequestSudoHeader); + Assert.That(requestOptions.HandledRequests, Has.Count.EqualTo(2)); + Assert.That(requestOptions.HttpRequestSudoHeader, Is.Null); } [Test] @@ -47,7 +47,7 @@ public async Task Test_the_timeout_can_be_overridden_in_the_request_options() var httpRequestor = new HttpRequestor(context.DockerContainer.GitLabUrl.ToString(), context.DockerContainer.Credentials.UserToken, MethodType.Get, requestOptions); Assert.Throws(() => httpRequestor.Execute("invalidUrl")); - Assert.AreEqual(TimeSpan.FromMinutes(2).TotalMilliseconds, requestOptions.HandledRequests.Single().Timeout); + Assert.That(requestOptions.HandledRequests.Single().Timeout, Is.EqualTo(TimeSpan.FromMinutes(2).TotalMilliseconds)); } [Test] @@ -59,7 +59,7 @@ public async Task Test_request_options_sudo_transferred_to_request_header() var httpRequestor = new HttpRequestor(context.DockerContainer.GitLabUrl.ToString(), context.DockerContainer.Credentials.UserToken, MethodType.Get, requestOptions); Assert.Throws(() => httpRequestor.Execute("invalidUrl")); - Assert.AreEqual("UserToImpersonate", requestOptions.HttpRequestSudoHeader); + Assert.That(requestOptions.HttpRequestSudoHeader, Is.EqualTo("UserToImpersonate")); } [Test] @@ -90,7 +90,7 @@ public async Task Test_impersonation_via_sudo_and_username() }); // Assert - Assert.AreEqual(commonUserSession.Username, issue.Author.Username); + Assert.That(issue.Author.Username, Is.EqualTo(commonUserSession.Username)); } [Test] @@ -122,7 +122,7 @@ public async Task Test_impersonation_via_sudo_and_user_id() }); // Assert - Assert.AreEqual(commonUserSession.Id, issue.Author.Id); + Assert.That(issue.Author.Id, Is.EqualTo(commonUserSession.Id)); } [Test] @@ -138,7 +138,7 @@ public async Task Test_authorization_header_uses_bearer() // Assert var actualHeaderValue = context.LastRequest.Headers[HttpRequestHeader.Authorization]; - Assert.AreEqual(expectedHeaderValue, actualHeaderValue); + Assert.That(actualHeaderValue, Is.EqualTo(expectedHeaderValue)); } private sealed class MockRequestOptions : RequestOptions diff --git a/NGitLab.Tests/Impl/DynamicEnumTests.cs b/NGitLab.Tests/Impl/DynamicEnumTests.cs index c0fe728a..c21f83a4 100644 --- a/NGitLab.Tests/Impl/DynamicEnumTests.cs +++ b/NGitLab.Tests/Impl/DynamicEnumTests.cs @@ -7,10 +7,10 @@ public class DynamicEnumTests [Test] public void Test_comparison() { - Assert.AreEqual(new DynamicEnum(MockEnum.A), MockEnum.A); - Assert.AreNotEqual(new DynamicEnum(MockEnum.A), MockEnum.B); - Assert.AreEqual(new DynamicEnum("unknown").StringValue, "unknown"); - Assert.AreNotEqual(new DynamicEnum("unknown").StringValue, "other"); + Assert.That(new DynamicEnum(MockEnum.A), Is.EqualTo(MockEnum.A)); + Assert.That(new DynamicEnum(MockEnum.A), Is.Not.EqualTo(MockEnum.B)); + Assert.That(new DynamicEnum("unknown").StringValue, Is.EqualTo("unknown")); + Assert.That(new DynamicEnum("unknown").StringValue, Is.Not.EqualTo("other")); } public enum MockEnum diff --git a/NGitLab.Tests/Impl/JsonConverterTests.cs b/NGitLab.Tests/Impl/JsonConverterTests.cs index 5d239542..e6b8a778 100644 --- a/NGitLab.Tests/Impl/JsonConverterTests.cs +++ b/NGitLab.Tests/Impl/JsonConverterTests.cs @@ -20,12 +20,12 @@ public void Test_DeserializeNullToSupportedValueType_Succeeds() }"; var obj = Serializer.Deserialize(json); - Assert.NotNull(obj); - Assert.AreEqual(false, obj.SomeBool); - Assert.AreEqual(DateTime.MinValue, obj.SomeDateTime); - Assert.AreEqual(0.0, obj.SomeDouble); - Assert.AreEqual(0, obj.SomeInt32); - Assert.AreEqual(0L, obj.SomeInt64); + Assert.That(obj, Is.Not.Null); + Assert.That(obj.SomeBool, Is.EqualTo(false)); + Assert.That(obj.SomeDateTime, Is.EqualTo(DateTime.MinValue)); + Assert.That(obj.SomeDouble, Is.EqualTo(0.0)); + Assert.That(obj.SomeInt32, Is.EqualTo(0)); + Assert.That(obj.SomeInt64, Is.EqualTo(0L)); } [Test] @@ -33,7 +33,7 @@ public void Test_DeserializeNullToUnsupportedValueType_Throws() { var json = @"{ ""a_uint32"": null }"; var ex = Assert.Throws(() => Serializer.Deserialize(json)); - StringAssert.StartsWith("The JSON value could not be converted to System.UInt32.", ex.Message); + Assert.That(ex.Message, Does.StartWith("The JSON value could not be converted to System.UInt32.")); } [Test] @@ -41,8 +41,8 @@ public void Test_DeserializeStringToInt32() { var json = @"{ ""an_int32"": ""1234"" }"; var obj = Serializer.Deserialize(json); - Assert.NotNull(obj); - Assert.AreEqual(1234, obj.SomeInt32); + Assert.That(obj, Is.Not.Null); + Assert.That(obj.SomeInt32, Is.EqualTo(1234)); } [Test] @@ -50,8 +50,8 @@ public void Test_DeserializeStringToInt64_Succeeds() { var json = @"{ ""an_int64"": ""-1234"" }"; var obj = Serializer.Deserialize(json); - Assert.NotNull(obj); - Assert.AreEqual(-1234L, obj.SomeInt64); + Assert.That(obj, Is.Not.Null); + Assert.That(obj.SomeInt64, Is.EqualTo(-1234L)); } [Test] @@ -59,8 +59,8 @@ public void Test_DeserializeStringToDouble_Succeeds() { var json = @"{ ""a_double"": ""-1234.5"" }"; var obj = Serializer.Deserialize(json); - Assert.NotNull(obj); - Assert.AreEqual(-1234.5d, obj.SomeDouble); + Assert.That(obj, Is.Not.Null); + Assert.That(obj.SomeDouble, Is.EqualTo(-1234.5d)); } [TestCase("2022-01-12", DateTimeKind.Unspecified)] @@ -70,9 +70,9 @@ public void Test_DeserializeStringToDateTime_SupportsMultipleFormats(string inpu { var json = $@"{{ ""a_date_time"": ""{input}"" }}"; var obj = Serializer.Deserialize(json); - Assert.NotNull(obj); - Assert.AreEqual(kind, obj.SomeDateTime.Kind); - Assert.AreEqual(new DateTime(2022, 1, 12).Date, obj.SomeDateTime.Date); + Assert.That(obj, Is.Not.Null); + Assert.That(obj.SomeDateTime.Kind, Is.EqualTo(kind)); + Assert.That(obj.SomeDateTime.Date, Is.EqualTo(new DateTime(2022, 1, 12).Date)); } public class MyDataContract diff --git a/NGitLab.Tests/IssueTests.cs b/NGitLab.Tests/IssueTests.cs index cb975f6d..fecb3af5 100644 --- a/NGitLab.Tests/IssueTests.cs +++ b/NGitLab.Tests/IssueTests.cs @@ -24,7 +24,7 @@ public async Task Test_get_issue_with_IssueQuery() State = IssueState.opened, }).Where(i => i.ProjectId == project.Id).ToList(); - Assert.AreEqual(2, issues.Count); + Assert.That(issues, Has.Count.EqualTo(2)); } [Test] @@ -40,8 +40,8 @@ public async Task Test_get_issue_by_id() var issue = adminIssuesClient.GetById(issue1.Id); - Assert.AreEqual(issue1.Id, issue.Id); - Assert.AreEqual(issue1.IssueId, issue.IssueId); + Assert.That(issue.Id, Is.EqualTo(issue1.Id)); + Assert.That(issue.IssueId, Is.EqualTo(issue1.IssueId)); } [Test] @@ -60,8 +60,8 @@ public async Task Test_get_unassigned_issues_with_IssueQuery() State = IssueState.opened, }).Where(i => i.ProjectId == project.Id).ToList(); - Assert.AreEqual(1, issues.Count); - Assert.AreEqual(issue1.Id, issues[0].Id); + Assert.That(issues, Has.Count.EqualTo(1)); + Assert.That(issues[0].Id, Is.EqualTo(issue1.Id)); } [Test] @@ -80,8 +80,8 @@ public async Task Test_get_assigned_issues_with_IssueQuery() State = IssueState.opened, }).Where(i => i.ProjectId == project.Id).ToList(); - Assert.AreEqual(1, issues.Count); - Assert.AreEqual(issue2.Id, issues[0].Id); + Assert.That(issues, Has.Count.EqualTo(1)); + Assert.That(issues[0].Id, Is.EqualTo(issue2.Id)); } [Test] @@ -100,7 +100,7 @@ public async Task Test_get_confidential_issues_with_IssueQuery() Confidential = true, }).Where(i => i.ProjectId == project.Id).ToList(); - Assert.AreEqual(2, issues.Count); + Assert.That(issues, Has.Count.EqualTo(2)); } [Test] @@ -119,7 +119,7 @@ public async Task Test_get_non_confidential_issues_with_IssueQuery() Confidential = false, }).Where(i => i.ProjectId == project.Id).ToList(); - Assert.AreEqual(1, issues.Count); + Assert.That(issues, Has.Count.EqualTo(1)); } [Test] @@ -135,7 +135,7 @@ public async Task Test_get_issues_no_confidential_filter_with_IssueQuery() var issues = issuesClient.Get(new IssueQuery()).Where(i => i.ProjectId == project.Id).ToList(); - Assert.AreEqual(3, issues.Count); + Assert.That(issues, Has.Count.EqualTo(3)); } [Test] @@ -154,8 +154,8 @@ public async Task Test_get_assigned_issues_with_IssueQuery_and_project_id() State = IssueState.opened, }).ToList(); - Assert.AreEqual(1, issues.Count); - Assert.AreEqual(issue2.Id, issues[0].Id); + Assert.That(issues, Has.Count.EqualTo(1)); + Assert.That(issues[0].Id, Is.EqualTo(issue2.Id)); } [Test] @@ -180,10 +180,10 @@ public async Task Test_get_all_project_issues() var issue2 = issuesClient.Create(new IssueCreate { ProjectId = project.Id, Title = "title2", AssigneeId = context.Client.Users.Current.Id }); var issues = issuesClient.ForProject(project.Id).ToList(); - Assert.AreEqual(2, issues.Count); + Assert.That(issues, Has.Count.EqualTo(2)); issues = issuesClient.Get(project.Id, new IssueQuery()).ToList(); - Assert.AreEqual(2, issues.Count); + Assert.That(issues, Has.Count.EqualTo(2)); } [Test] @@ -196,7 +196,7 @@ public async Task Test_get_all_resource_label_events() var issue1 = issuesClient.Create(new IssueCreate { ProjectId = project.Id, Title = "title1" }); var issues = issuesClient.ForProject(project.Id).ToList(); - Assert.AreEqual(1, issues.Count); + Assert.That(issues, Has.Count.EqualTo(1)); var testLabel = "test"; var updatedIssue = issues[0]; @@ -215,15 +215,15 @@ public async Task Test_get_all_resource_label_events() }); var resourceLabelEvents = issuesClient.ResourceLabelEvents(project.Id, updatedIssue.IssueId).ToList(); - Assert.AreEqual(2, resourceLabelEvents.Count); + Assert.That(resourceLabelEvents, Has.Count.EqualTo(2)); var addLabelEvent = resourceLabelEvents.First(e => e.Action == ResourceLabelEventAction.Add); - Assert.AreEqual(testLabel, addLabelEvent.Label.Name); - Assert.AreEqual(ResourceLabelEventAction.Add, addLabelEvent.Action); + Assert.That(addLabelEvent.Label.Name, Is.EqualTo(testLabel)); + Assert.That(addLabelEvent.Action, Is.EqualTo(ResourceLabelEventAction.Add)); var removeLabelEvent = resourceLabelEvents.First(e => e.Action == ResourceLabelEventAction.Remove); - Assert.AreEqual(testLabel, removeLabelEvent.Label.Name); - Assert.AreEqual(ResourceLabelEventAction.Remove, removeLabelEvent.Action); + Assert.That(removeLabelEvent.Label.Name, Is.EqualTo(testLabel)); + Assert.That(removeLabelEvent.Action, Is.EqualTo(ResourceLabelEventAction.Remove)); } [Test] @@ -236,7 +236,7 @@ public async Task Test_get_all_resource_milestone_events() var issue1 = issuesClient.Create(new IssueCreate { ProjectId = project.Id, Title = "title1" }); var issues = issuesClient.ForProject(project.Id).ToList(); - Assert.AreEqual(1, issues.Count); + Assert.That(issues, Has.Count.EqualTo(1)); var milestoneClient = context.Client.GetMilestone(project.Id); var milestone1 = milestoneClient.Create(new MilestoneCreate { Title = "TestMilestone", Description = "Milestone for Testing", StartDate = "2020-01-27T05:07:12.573Z", DueDate = "2020-05-26T05:07:12.573Z" }); @@ -257,17 +257,17 @@ public async Task Test_get_all_resource_milestone_events() }); var resourceLabelEvents = issuesClient.ResourceMilestoneEvents(project.Id, updatedIssue.IssueId).ToList(); - Assert.AreEqual(2, resourceLabelEvents.Count); + Assert.That(resourceLabelEvents, Has.Count.EqualTo(2)); var addMilestoneEvent = resourceLabelEvents.First(e => e.Action == ResourceMilestoneEventAction.Add); - Assert.AreEqual(milestone1.Id, addMilestoneEvent.Milestone.Id); - Assert.AreEqual(milestone1.Title, addMilestoneEvent.Milestone.Title); - Assert.AreEqual(ResourceMilestoneEventAction.Add, addMilestoneEvent.Action); + Assert.That(addMilestoneEvent.Milestone.Id, Is.EqualTo(milestone1.Id)); + Assert.That(addMilestoneEvent.Milestone.Title, Is.EqualTo(milestone1.Title)); + Assert.That(addMilestoneEvent.Action, Is.EqualTo(ResourceMilestoneEventAction.Add)); var removeMilestoneEvent = resourceLabelEvents.First(e => e.Action == ResourceMilestoneEventAction.Remove); - Assert.AreEqual(milestone1.Id, removeMilestoneEvent.Milestone.Id); - Assert.AreEqual(milestone1.Title, addMilestoneEvent.Milestone.Title); - Assert.AreEqual(ResourceMilestoneEventAction.Remove, removeMilestoneEvent.Action); + Assert.That(removeMilestoneEvent.Milestone.Id, Is.EqualTo(milestone1.Id)); + Assert.That(addMilestoneEvent.Milestone.Title, Is.EqualTo(milestone1.Title)); + Assert.That(removeMilestoneEvent.Action, Is.EqualTo(ResourceMilestoneEventAction.Remove)); } [Test] @@ -281,7 +281,7 @@ public async Task Test_get_new_and_updated_issue_with_duedate() var initialDueDate = new DateTime(2022, 1, 1); var issue1 = issuesClient.Create(new IssueCreate { ProjectId = project.Id, Title = "title1", DueDate = initialDueDate }); var issue = issuesClient.Get(project.Id, issue1.IssueId); - Assert.AreEqual(initialDueDate, issue1.DueDate); + Assert.That(issue1.DueDate, Is.EqualTo(initialDueDate)); var updatedDueDate = new DateTime(2022, 2, 1); var updatedIssue = issuesClient.Edit(new IssueEdit @@ -291,7 +291,7 @@ public async Task Test_get_new_and_updated_issue_with_duedate() DueDate = updatedDueDate, }); - Assert.AreEqual(updatedDueDate, updatedIssue.DueDate); + Assert.That(updatedIssue.DueDate, Is.EqualTo(updatedDueDate)); } [Test] @@ -305,11 +305,11 @@ public async Task Test_get_linked_issue() var issue1 = await issuesClient.CreateAsync(new IssueCreate { ProjectId = project.Id, Title = "title1" }); var issue2 = await issuesClient.CreateAsync(new IssueCreate { ProjectId = project.Id, Title = "title2", Description = "related to #1" }); var linked = issuesClient.CreateLinkBetweenIssues(project.Id, issue1.IssueId, project.Id, issue2.IssueId); - Assert.IsTrue(linked, "Expected true for create Link between issues"); + Assert.That(linked, Is.True, "Expected true for create Link between issues"); var issues = issuesClient.LinkedToAsync(project.Id, issue1.IssueId).ToList(); // for now, no API to link issues so not links exist but API should not throw - Assert.AreEqual(1, issues.Count, "Expected 1. Got {0}", issues.Count); + Assert.That(issues, Has.Count.EqualTo(1), $"Expected 1. Got {issues.Count}"); } } } diff --git a/NGitLab.Tests/JobTests.cs b/NGitLab.Tests/JobTests.cs index dea8c2d7..c54c107d 100644 --- a/NGitLab.Tests/JobTests.cs +++ b/NGitLab.Tests/JobTests.cs @@ -56,7 +56,7 @@ public async Task Test_getjobs_all() var project = context.CreateProject(); AddGitLabCiFile(context.Client, project); var jobs = await GitLabTestContext.RetryUntilAsync(() => context.Client.GetJobs(project.Id).GetJobs(JobScopeMask.Pending), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); - Assert.AreEqual(JobStatus.Pending, jobs.First().Status); + Assert.That(jobs.First().Status, Is.EqualTo(JobStatus.Pending)); } [Test] @@ -67,7 +67,7 @@ public async Task Test_getjobs_scope() var project = context.CreateProject(); AddGitLabCiFile(context.Client, project, manualAction: true); var jobs = await GitLabTestContext.RetryUntilAsync(() => context.Client.GetJobs(project.Id).GetJobs(JobScopeMask.Manual), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); - Assert.AreEqual(JobStatus.Manual, jobs.First().Status); + Assert.That(jobs.First().Status, Is.EqualTo(JobStatus.Manual)); } [Test] @@ -91,8 +91,8 @@ public async Task Test_getjobs_multiple_scopes() }), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); - Assert.IsTrue(jobs.First().Status == JobStatus.Canceled); - Assert.IsTrue(jobs.Last().Status == JobStatus.Pending); + Assert.That(jobs.First().Status, Is.EqualTo(JobStatus.Canceled)); + Assert.That(jobs.Last().Status, Is.EqualTo(JobStatus.Pending)); } [Test] @@ -105,14 +105,14 @@ public async Task Test_run_action_play() AddGitLabCiFile(context.Client, project, manualAction: true); var jobs = await GitLabTestContext.RetryUntilAsync(() => jobsClient.GetJobs(JobScopeMask.Manual), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); var job = jobs.Single(); - Assert.AreEqual(JobStatus.Manual, job.Status); + Assert.That(job.Status, Is.EqualTo(JobStatus.Manual)); var playedJob = jobsClient.RunAction(job.Id, JobAction.Play); - Assert.AreEqual(job.Id, playedJob.Id); - Assert.AreEqual(job.Pipeline.Id, playedJob.Pipeline.Id); - Assert.AreEqual(job.Commit.Id, playedJob.Commit.Id); - Assert.AreEqual(JobStatus.Pending, playedJob.Status); + Assert.That(playedJob.Id, Is.EqualTo(job.Id)); + Assert.That(playedJob.Pipeline.Id, Is.EqualTo(job.Pipeline.Id)); + Assert.That(playedJob.Commit.Id, Is.EqualTo(job.Commit.Id)); + Assert.That(playedJob.Status, Is.EqualTo(JobStatus.Pending)); } [Test] @@ -132,9 +132,9 @@ public async Task Test_run_action_retry() var retriedJob = jobsClient.RunAction(job.Id, JobAction.Retry); - Assert.AreNotEqual(job.Id, retriedJob.Id); - Assert.AreEqual(job.Pipeline.Id, retriedJob.Pipeline.Id); - Assert.AreEqual(job.Commit.Id, retriedJob.Commit.Id); + Assert.That(retriedJob.Id, Is.Not.EqualTo(job.Id)); + Assert.That(retriedJob.Pipeline.Id, Is.EqualTo(job.Pipeline.Id)); + Assert.That(retriedJob.Commit.Id, Is.EqualTo(job.Commit.Id)); } [Test] @@ -150,9 +150,9 @@ public async Task Test_get_job_from_id() var job2 = jobsClient.Get(job.Id); - Assert.AreEqual(job.Id, job2.Id); // Same Job - Assert.AreEqual(job.Pipeline.Id, job2.Pipeline.Id); // Same Pipeline - Assert.AreEqual(job.Commit.Id, job2.Commit.Id); // Same Commit + Assert.That(job2.Id, Is.EqualTo(job.Id)); // Same Job + Assert.That(job2.Pipeline.Id, Is.EqualTo(job.Pipeline.Id)); // Same Pipeline + Assert.That(job2.Commit.Id, Is.EqualTo(job.Commit.Id)); // Same Commit } [Test] @@ -197,11 +197,11 @@ public async Task Test_get_job_artifacts() AddGitLabCiFile(context.Client, project); var jobs = await GitLabTestContext.RetryUntilAsync(() => jobsClient.GetJobs(JobScopeMask.Success), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); var job = jobs.Single(); - Assert.AreEqual(JobStatus.Success, job.Status); + Assert.That(job.Status, Is.EqualTo(JobStatus.Success)); var artifacts = jobsClient.GetJobArtifacts(job.Id); - Assert.IsNotEmpty(artifacts); + Assert.That(artifacts, Is.Not.Empty); } } @@ -217,13 +217,13 @@ public async Task Test_get_job_artifact() AddGitLabCiFile(context.Client, project); var jobs = await GitLabTestContext.RetryUntilAsync(() => jobsClient.GetJobs(JobScopeMask.Success), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); var job = jobs.Single(); - Assert.AreEqual(JobStatus.Success, job.Status); + Assert.That(job.Status, Is.EqualTo(JobStatus.Success)); var artifact = jobsClient.GetJobArtifact(job.Id, "file0.txt"); - Assert.IsNotEmpty(artifact); + Assert.That(artifact, Is.Not.Empty); var content = Encoding.ASCII.GetString(artifact).Trim(); - Assert.AreEqual("test", content); + Assert.That(content, Is.EqualTo("test")); } } @@ -239,7 +239,7 @@ public async Task Test_get_job_artifact_query() AddGitLabCiFile(context.Client, project); var jobs = await GitLabTestContext.RetryUntilAsync(() => jobsClient.GetJobs(JobScopeMask.Success), jobs => jobs.Any(), TimeSpan.FromMinutes(2)); var job = jobs.Single(); - Assert.AreEqual(JobStatus.Success, job.Status); + Assert.That(job.Status, Is.EqualTo(JobStatus.Success)); var query = new JobArtifactQuery(); query.RefName = project.DefaultBranch; @@ -247,10 +247,10 @@ public async Task Test_get_job_artifact_query() query.ArtifactPath = "file0.txt"; var artifact = jobsClient.GetJobArtifact(query); - Assert.IsNotEmpty(artifact); + Assert.That(artifact, Is.Not.Empty); var content = Encoding.ASCII.GetString(artifact).Trim(); - Assert.AreEqual("test", content); + Assert.That(content, Is.EqualTo("test")); } } } diff --git a/NGitLab.Tests/JsonTests.cs b/NGitLab.Tests/JsonTests.cs index f0a6aece..8732b27e 100644 --- a/NGitLab.Tests/JsonTests.cs +++ b/NGitLab.Tests/JsonTests.cs @@ -24,7 +24,7 @@ public enum TestEnum public void DeserializeEnumWithEnumMemberAttribute_Ok(string value, TestEnum expectedValue) { var parsedValue = Serializer.Deserialize('"' + value + '"'); - Assert.AreEqual(expectedValue, parsedValue); + Assert.That(parsedValue, Is.EqualTo(expectedValue)); } [TestCase("dfsf")] @@ -41,7 +41,7 @@ public void DeserializeNewerContract_Ok() TestContractV1 oldContractObject = null; Assert.DoesNotThrow(() => oldContractObject = Serializer.Deserialize(newContractJson)); - Assert.NotNull(oldContractObject); + Assert.That(oldContractObject, Is.Not.Null); } [Test] @@ -52,7 +52,7 @@ public void DeserializeOlderContract_Ok() TestContractV2 newContractObject = null; Assert.DoesNotThrow(() => newContractObject = Serializer.Deserialize(oldContractJson)); - Assert.NotNull(newContractObject); + Assert.That(newContractObject, Is.Not.Null); } public class TestContractV1 diff --git a/NGitLab.Tests/LintClientTests.cs b/NGitLab.Tests/LintClientTests.cs index 215a9879..65efa5c8 100644 --- a/NGitLab.Tests/LintClientTests.cs +++ b/NGitLab.Tests/LintClientTests.cs @@ -37,9 +37,9 @@ public async Task LintValidCIYaml() var result = await context.Client.Lint.ValidateCIYamlContentAsync(project.Id.ToString(), ValidCIYaml, new(), CancellationToken.None); - Assert.True(result.Valid); - Assert.False(result.Errors.Any()); - Assert.False(result.Warnings.Any()); + Assert.That(result.Valid, Is.True); + Assert.That(result.Errors.Any(), Is.False); + Assert.That(result.Warnings.Any(), Is.False); } [Test] @@ -52,9 +52,9 @@ public async Task LintInvalidCIYaml() var result = await context.Client.Lint.ValidateCIYamlContentAsync(project.Id.ToString(), InvalidCIYaml, new(), CancellationToken.None); - Assert.False(result.Valid); - Assert.True(result.Errors.Any()); - Assert.False(result.Warnings.Any()); + Assert.That(result.Valid, Is.False); + Assert.That(result.Errors.Any(), Is.True); + Assert.That(result.Warnings.Any(), Is.False); } [Test] @@ -75,9 +75,9 @@ public async Task LintValidCIProjectYaml() var result = await context.Client.Lint.ValidateProjectCIConfigurationAsync(project.Id.ToString(), new(), CancellationToken.None); - Assert.True(result.Valid); - Assert.False(result.Errors.Any()); - Assert.False(result.Warnings.Any()); + Assert.That(result.Valid, Is.True); + Assert.That(result.Errors.Any(), Is.False); + Assert.That(result.Warnings.Any(), Is.False); } [Test] @@ -98,9 +98,9 @@ public async Task LintInvalidProjectCIYaml() var result = await context.Client.Lint.ValidateProjectCIConfigurationAsync(project.Id.ToString(), new(), CancellationToken.None); - Assert.False(result.Valid); - Assert.True(result.Errors.Any()); - Assert.False(result.Warnings.Any()); + Assert.That(result.Valid, Is.False); + Assert.That(result.Errors.Any(), Is.True); + Assert.That(result.Warnings.Any(), Is.False); } } } diff --git a/NGitLab.Tests/MembersClientTests.cs b/NGitLab.Tests/MembersClientTests.cs index 5028d7a4..a6fd4e89 100644 --- a/NGitLab.Tests/MembersClientTests.cs +++ b/NGitLab.Tests/MembersClientTests.cs @@ -30,8 +30,8 @@ public async Task AddMemberToProject() }); var projectUser = context.Client.Members.OfProject(projectId).Single(u => u.Id == user.Id); - Assert.AreEqual(AccessLevel.Developer, (AccessLevel)projectUser.AccessLevel); - Assert.AreEqual(expiresAt, projectUser.ExpiresAt?.ToString("yyyy-MM-dd")); + Assert.That((AccessLevel)projectUser.AccessLevel, Is.EqualTo(AccessLevel.Developer)); + Assert.That(projectUser.ExpiresAt?.ToString("yyyy-MM-dd"), Is.EqualTo(expiresAt)); } [Test] @@ -50,7 +50,7 @@ public async Task UpsertAccessLevelMemberOfProject() UserId = user.Id.ToString(CultureInfo.InvariantCulture), }); var projectUser = context.Client.Members.OfProject(projectId).Single(u => u.Id == user.Id); - Assert.AreEqual(AccessLevel.Developer, (AccessLevel)projectUser.AccessLevel); + Assert.That((AccessLevel)projectUser.AccessLevel, Is.EqualTo(AccessLevel.Developer)); // Update context.Client.Members.UpdateMemberOfProject(projectId, new ProjectMemberUpdate @@ -59,7 +59,7 @@ public async Task UpsertAccessLevelMemberOfProject() UserId = user.Id.ToString(CultureInfo.InvariantCulture), }); projectUser = context.Client.Members.OfProject(projectId).Single(u => u.Id == user.Id); - Assert.AreEqual(AccessLevel.Maintainer, (AccessLevel)projectUser.AccessLevel); + Assert.That((AccessLevel)projectUser.AccessLevel, Is.EqualTo(AccessLevel.Maintainer)); } [Test] @@ -79,7 +79,7 @@ public async Task GetAccessLevelMemberOfProject() // Get var projectUser = context.Client.Members.GetMemberOfProject(projectId, user.Id.ToString(CultureInfo.InvariantCulture)); - Assert.AreEqual(AccessLevel.Developer, (AccessLevel)projectUser.AccessLevel); + Assert.That((AccessLevel)projectUser.AccessLevel, Is.EqualTo(AccessLevel.Developer)); } [Test] @@ -100,8 +100,8 @@ public async Task AddMemberToGroup() }); var groupUser = context.Client.Members.OfGroup(groupId).Single(u => u.Id == user.Id); - Assert.AreEqual(AccessLevel.Developer, (AccessLevel)groupUser.AccessLevel); - Assert.AreEqual(expiresAt, groupUser.ExpiresAt?.ToString("yyyy-MM-dd")); + Assert.That((AccessLevel)groupUser.AccessLevel, Is.EqualTo(AccessLevel.Developer)); + Assert.That(groupUser.ExpiresAt?.ToString("yyyy-MM-dd"), Is.EqualTo(expiresAt)); } [Test] @@ -120,7 +120,7 @@ public async Task UpsertAccessLevelMemberOfGroup() UserId = user.Id.ToString(CultureInfo.InvariantCulture), }); var groupUser = context.Client.Members.OfGroup(groupId).Single(u => u.Id == user.Id); - Assert.AreEqual(AccessLevel.Developer, (AccessLevel)groupUser.AccessLevel); + Assert.That((AccessLevel)groupUser.AccessLevel, Is.EqualTo(AccessLevel.Developer)); // Update context.Client.Members.UpdateMemberOfGroup(groupId, new GroupMemberUpdate @@ -129,7 +129,7 @@ public async Task UpsertAccessLevelMemberOfGroup() UserId = user.Id.ToString(CultureInfo.InvariantCulture), }); groupUser = context.Client.Members.OfGroup(groupId).Single(u => u.Id == user.Id); - Assert.AreEqual(AccessLevel.Maintainer, (AccessLevel)groupUser.AccessLevel); + Assert.That((AccessLevel)groupUser.AccessLevel, Is.EqualTo(AccessLevel.Maintainer)); } [Test] @@ -149,7 +149,7 @@ public async Task GetAccessLevelMemberOfGroup() // Get var groupUser = context.Client.Members.GetMemberOfGroup(groupId, user.Id.ToString(CultureInfo.InvariantCulture)); - Assert.AreEqual(AccessLevel.Developer, (AccessLevel)groupUser.AccessLevel); + Assert.That((AccessLevel)groupUser.AccessLevel, Is.EqualTo(AccessLevel.Developer)); } } } diff --git a/NGitLab.Tests/MergeRequest/MergeRequestChangesClientTests.cs b/NGitLab.Tests/MergeRequest/MergeRequestChangesClientTests.cs index 90f96152..0293fe26 100644 --- a/NGitLab.Tests/MergeRequest/MergeRequestChangesClientTests.cs +++ b/NGitLab.Tests/MergeRequest/MergeRequestChangesClientTests.cs @@ -22,13 +22,13 @@ public async Task GetChangesOnMergeRequest() changes => changes.Any(), TimeSpan.FromSeconds(10)); - Assert.AreEqual(1, changes.Length); - Assert.AreEqual(100644, changes[0].AMode); - Assert.AreEqual(100644, changes[0].BMode); - Assert.IsFalse(changes[0].DeletedFile); - Assert.IsFalse(changes[0].NewFile); - Assert.IsFalse(changes[0].RenamedFile); - Assert.AreEqual("@@ -1 +1 @@\n-test\n\\ No newline at end of file\n+test2\n\\ No newline at end of file\n", changes[0].Diff); + Assert.That(changes, Has.Length.EqualTo(1)); + Assert.That(changes[0].AMode, Is.EqualTo(100644)); + Assert.That(changes[0].BMode, Is.EqualTo(100644)); + Assert.That(changes[0].DeletedFile, Is.False); + Assert.That(changes[0].NewFile, Is.False); + Assert.That(changes[0].RenamedFile, Is.False); + Assert.That(changes[0].Diff, Is.EqualTo("@@ -1 +1 @@\n-test\n\\ No newline at end of file\n+test2\n\\ No newline at end of file\n")); } } } diff --git a/NGitLab.Tests/MergeRequest/MergeRequestClientTests.cs b/NGitLab.Tests/MergeRequest/MergeRequestClientTests.cs index 859fb59b..f8c25b1d 100644 --- a/NGitLab.Tests/MergeRequest/MergeRequestClientTests.cs +++ b/NGitLab.Tests/MergeRequest/MergeRequestClientTests.cs @@ -20,8 +20,8 @@ public async Task Test_merge_request_api() var (project, mergeRequest) = context.CreateMergeRequest(); var mergeRequestClient = context.Client.GetMergeRequest(project.Id); - Assert.AreEqual(mergeRequest.Id, mergeRequestClient[mergeRequest.Iid].Id, "Test we can get a merge request by IId"); - Assert.AreEqual(mergeRequest.Id, (await mergeRequestClient.GetByIidAsync(mergeRequest.Iid, options: null)).Id, "Test we can get a merge request by IId"); + Assert.That(mergeRequestClient[mergeRequest.Iid].Id, Is.EqualTo(mergeRequest.Id), "Test we can get a merge request by IId"); + Assert.That((await mergeRequestClient.GetByIidAsync(mergeRequest.Iid, options: null)).Id, Is.EqualTo(mergeRequest.Id), "Test we can get a merge request by IId"); ListMergeRequest(mergeRequestClient, mergeRequest); mergeRequest = UpdateMergeRequest(mergeRequestClient, mergeRequest); @@ -34,7 +34,7 @@ await GitLabTestContext.RetryUntilAsync( TimeSpan.FromSeconds(120)) .ConfigureAwait(false); - Assert.IsFalse(context.Client.GetRepository(project.Id).Branches[mergeRequest.SourceBranch].Protected, "The source branch is protected but should not be"); + Assert.That(context.Client.GetRepository(project.Id).Branches[mergeRequest.SourceBranch].Protected, Is.False, "The source branch is protected but should not be"); TestContext.WriteLine("MR is ready to be merged"); AcceptMergeRequest(mergeRequestClient, mergeRequest); @@ -48,12 +48,12 @@ await GitLabTestContext.RetryUntilAsync( // TimeSpan.FromSeconds(240)) // GitLab seems very slow to delete a branch on my machine... // .ConfigureAwait(false); var commits = mergeRequestClient.Commits(mergeRequest.Iid).All; - Assert.IsTrue(commits.Any(), "Can return the commits"); + Assert.That(commits.Any(), Is.True, "Can return the commits"); if (context.IsGitLabVersionInRange(VersionRange.Parse("[15.6,)"), out _)) - Assert.IsNotNull(mergeRequest.DetailedMergeStatus.EnumValue); + Assert.That(mergeRequest.DetailedMergeStatus.EnumValue, Is.Not.Null); else - Assert.IsNull(mergeRequest.DetailedMergeStatus.EnumValue); + Assert.That(mergeRequest.DetailedMergeStatus.EnumValue, Is.Null); } [Test] @@ -84,7 +84,7 @@ public async Task Test_merge_request_rebase() }); var mr = mergeRequestClient[mergeRequest.Iid]; - Assert.AreEqual(1, mr.DivergedCommitsCount, + Assert.That(mr.DivergedCommitsCount, Is.EqualTo(1), "There should be a 1-commit divergence between the default branch NOW and its state at the moment the MR was created"); RebaseMergeRequest(mergeRequestClient, mergeRequest); @@ -94,7 +94,7 @@ public async Task Test_merge_request_rebase() commits => commits.Any(), TimeSpan.FromSeconds(10)); - Assert.IsTrue(commits.Any(), "Can return the commits"); + Assert.That(commits.Any(), Is.True, "Can return the commits"); } [Test] @@ -125,18 +125,18 @@ public async Task Test_merge_request_rebaseasync_skip_ci() }); var mr = mergeRequestClient[mergeRequest.Iid]; - Assert.AreEqual(1, mr.DivergedCommitsCount, + Assert.That(mr.DivergedCommitsCount, Is.EqualTo(1), "There should be a 1-commit divergence between the default branch NOW and its state at the moment the MR was created"); var rebaseResult = await mergeRequestClient.RebaseAsync(mergeRequest.Iid, new MergeRequestRebase { SkipCi = true }); - Assert.IsTrue(rebaseResult.RebaseInProgress); + Assert.That(rebaseResult.RebaseInProgress, Is.True); var commits = await GitLabTestContext.RetryUntilAsync( () => mergeRequestClient.Commits(mergeRequest.Iid).All, commits => commits.Any(), TimeSpan.FromSeconds(10)); - Assert.IsTrue(commits.Any(), "Can return the commits"); + Assert.That(commits.Any(), Is.True, "Can return the commits"); } [Test] @@ -145,7 +145,7 @@ public async Task Test_merge_request_id_is_not_equal_to_iid() { using var context = await GitLabTestContext.CreateAsync(); var (_, mergeRequest) = context.CreateMergeRequest(); - Assert.AreNotEqual(mergeRequest.Id, mergeRequest.Iid); + Assert.That(mergeRequest.Iid, Is.Not.EqualTo(mergeRequest.Id)); } [Test] @@ -166,7 +166,7 @@ public async Task Test_gitlab_returns_an_error_when_trying_to_create_a_request_w }); }); - Assert.AreEqual("[\"You can't use same project/branch for source and target\"]", exception.ErrorMessage); + Assert.That(exception.ErrorMessage, Is.EqualTo("[\"You can't use same project/branch for source and target\"]")); } [Test] @@ -200,7 +200,7 @@ public async Task Test_merge_request_approvers() var approvalClient = mergeRequestClient.ApprovalClient(mergeRequest.Iid); var approvers = approvalClient.Approvals.Approvers; - Assert.AreEqual(0, approvers.Length, "Initially no approver defined"); + Assert.That(approvers, Is.Empty, "Initially no approver defined"); // --- Add the exampleAdminUser as approver for this MR since adding the MR owners won't increment the number of approvers--- var userId = context.AdminClient.Users.Current.Id; @@ -214,8 +214,8 @@ public async Task Test_merge_request_approvers() approvers = approvalClient.Approvals.Approvers; - Assert.AreEqual(1, approvers.Length, "A single approver defined"); - Assert.AreEqual(userId, approvers[0].User.Id, "The approver is the current user"); + Assert.That(approvers, Has.Length.EqualTo(1), "A single approver defined"); + Assert.That(approvers[0].User.Id, Is.EqualTo(userId), "The approver is the current user"); } [Test] @@ -227,10 +227,10 @@ public async Task Test_get_unassigned_merge_requests() var mergeRequestClient = context.Client.GetMergeRequest(project.Id); var mergeRequests = mergeRequestClient.Get(new MergeRequestQuery { AssigneeId = QueryAssigneeId.None }).ToList(); - Assert.AreEqual(1, mergeRequests.Count, "The query retrieved all open merged requests that are unassigned"); + Assert.That(mergeRequests, Has.Count.EqualTo(1), "The query retrieved all open merged requests that are unassigned"); mergeRequests = mergeRequestClient.Get(new MergeRequestQuery { AssigneeId = context.Client.Users.Current.Id }).ToList(); - Assert.AreEqual(0, mergeRequests.Count, "The query retrieved all open merged requests that are unassigned"); + Assert.That(mergeRequests, Is.Empty, "The query retrieved all open merged requests that are unassigned"); } [Test] @@ -244,10 +244,10 @@ public async Task Test_get_assigned_merge_requests() mergeRequestClient.Update(mergeRequest.Iid, new MergeRequestUpdate { AssigneeId = userId }); var mergeRequests = mergeRequestClient.Get(new MergeRequestQuery { AssigneeId = QueryAssigneeId.None }).ToList(); - Assert.AreEqual(0, mergeRequests.Count, "The query retrieved all open merged requests that are unassigned"); + Assert.That(mergeRequests, Is.Empty, "The query retrieved all open merged requests that are unassigned"); mergeRequests = mergeRequestClient.Get(new MergeRequestQuery { AssigneeId = userId }).ToList(); - Assert.AreEqual(1, mergeRequests.Count, "The query retrieved all open merged requests that are unassigned"); + Assert.That(mergeRequests, Has.Count.EqualTo(1), "The query retrieved all open merged requests that are unassigned"); } [Test] @@ -262,11 +262,11 @@ public async Task Test_set_reviewers_merge_requests() mergeRequestClient.Update(mergeRequest.Iid, new MergeRequestUpdate { ReviewerIds = new[] { userId } }); var mergeRequests = mergeRequestClient.Get(new MergeRequestQuery { ReviewerId = userId }).ToList(); - Assert.AreEqual(1, mergeRequests.Count, "The query retrieved all open merged requests that are assigned for a reviewer"); + Assert.That(mergeRequests, Has.Count.EqualTo(1), "The query retrieved all open merged requests that are assigned for a reviewer"); var mergeRequestUpdated = mergeRequests.Single(); var reviewers = mergeRequestUpdated.Reviewers; - Assert.AreEqual(1, reviewers.Length); + Assert.That(reviewers, Has.Length.EqualTo(1)); } [Test] @@ -297,7 +297,7 @@ public async Task Test_merge_request_versions() var version = versions.First(); - Assert.AreEqual(mergeRequest.Sha, version.HeadCommitSha); + Assert.That(version.HeadCommitSha, Is.EqualTo(mergeRequest.Sha)); } [Test] @@ -312,15 +312,15 @@ public async Task Test_merge_request_head_pipeline() mergeRequest = await GitLabTestContext.RetryUntilAsync(() => mergeRequestClient[mergeRequest.Iid], p => p.HeadPipeline != null, TimeSpan.FromSeconds(120)); - Assert.AreEqual(project.Id, mergeRequest.HeadPipeline?.ProjectId); + Assert.That(mergeRequest.HeadPipeline?.ProjectId, Is.EqualTo(project.Id)); } private static void ListMergeRequest(IMergeRequestClient mergeRequestClient, MergeRequest mergeRequest) { - Assert.IsTrue(mergeRequestClient.All.Any(x => x.Id == mergeRequest.Id), "Test 'All' accessor returns the merge request"); - Assert.IsFalse(mergeRequestClient.All.Any(x => x.DivergedCommitsCount.HasValue), "Listing multiple MRs will not set their DivergedCommitsCount property"); - Assert.IsTrue(mergeRequestClient.AllInState(MergeRequestState.opened).Any(x => x.Id == mergeRequest.Id), "Can return all open requests"); - Assert.IsFalse(mergeRequestClient.AllInState(MergeRequestState.merged).Any(x => x.Id == mergeRequest.Id), "Can return all closed requests"); + Assert.That(mergeRequestClient.All.Any(x => x.Id == mergeRequest.Id), Is.True, "Test 'All' accessor returns the merge request"); + Assert.That(mergeRequestClient.All.Any(x => x.DivergedCommitsCount.HasValue), Is.False, "Listing multiple MRs will not set their DivergedCommitsCount property"); + Assert.That(mergeRequestClient.AllInState(MergeRequestState.opened).Any(x => x.Id == mergeRequest.Id), Is.True, "Can return all open requests"); + Assert.That(mergeRequestClient.AllInState(MergeRequestState.merged).Any(x => x.Id == mergeRequest.Id), Is.False, "Can return all closed requests"); } public static MergeRequest UpdateMergeRequest(IMergeRequestClient mergeRequestClient, MergeRequest request) @@ -334,10 +334,10 @@ public static MergeRequest UpdateMergeRequest(IMergeRequestClient mergeRequestCl TargetBranch = request.TargetBranch, }); - Assert.AreEqual("New title", updatedMergeRequest.Title); - Assert.AreEqual("New description", updatedMergeRequest.Description); - Assert.IsFalse(updatedMergeRequest.MergeWhenPipelineSucceeds); - CollectionAssert.AreEqual(new[] { "a", "b" }, updatedMergeRequest.Labels); + Assert.That(updatedMergeRequest.Title, Is.EqualTo("New title")); + Assert.That(updatedMergeRequest.Description, Is.EqualTo("New description")); + Assert.That(updatedMergeRequest.MergeWhenPipelineSucceeds, Is.False); + Assert.That(updatedMergeRequest.Labels, Is.EqualTo(new[] { "a", "b" }).AsCollection); return updatedMergeRequest; } @@ -349,14 +349,14 @@ private static void Test_can_update_a_subset_of_merge_request_fields(IMergeReque Title = "Second update", }); - Assert.AreEqual("Second update", updated.Title); - Assert.AreEqual(mergeRequest.Description, updated.Description); + Assert.That(updated.Title, Is.EqualTo("Second update")); + Assert.That(updated.Description, Is.EqualTo(mergeRequest.Description)); } private static void Test_can_update_labels_with_delta(IMergeRequestClient mergeRequestClient, MergeRequest mergeRequest) { // Ensure original labels are "a,b" - CollectionAssert.AreEqual(new[] { "a", "b" }, mergeRequest.Labels); + Assert.That(mergeRequest.Labels, Is.EqualTo(new[] { "a", "b" }).AsCollection); var updated = mergeRequestClient.Update(mergeRequest.Iid, new MergeRequestUpdate { @@ -364,7 +364,7 @@ private static void Test_can_update_labels_with_delta(IMergeRequestClient mergeR AddLabels = "c,d", }); - CollectionAssert.AreEqual(new[] { "a", "c", "d" }, updated.Labels); + Assert.That(updated.Labels, Is.EqualTo(new[] { "a", "c", "d" }).AsCollection); } public static void AcceptMergeRequest(IMergeRequestClient mergeRequestClient, MergeRequest request) @@ -391,7 +391,7 @@ public static void AcceptMergeRequest(IMergeRequestClient mergeRequestClient, Me public static void RebaseMergeRequest(IMergeRequestClient mergeRequestClient, MergeRequest mergeRequest) { var rebaseResult = mergeRequestClient.Rebase(mergeRequestIid: mergeRequest.Iid); - Assert.IsTrue(rebaseResult.RebaseInProgress); + Assert.That(rebaseResult.RebaseInProgress, Is.True); } public static void AcceptAndCancelMergeRequest(IMergeRequestClient mergeRequestClient, MergeRequest request) diff --git a/NGitLab.Tests/MergeRequest/MergeRequestCommentsClientTests.cs b/NGitLab.Tests/MergeRequest/MergeRequestCommentsClientTests.cs index c391994d..ccf0fdde 100644 --- a/NGitLab.Tests/MergeRequest/MergeRequestCommentsClientTests.cs +++ b/NGitLab.Tests/MergeRequest/MergeRequestCommentsClientTests.cs @@ -58,12 +58,12 @@ public async Task AddEditCommentToMergeRequest() // Get all var comments = mergeRequestComments.All.ToArray(); - CollectionAssert.IsNotEmpty(comments); + Assert.That(comments, Is.Not.Empty); // Delete mergeRequestComments.Delete(comment.Id); comments = mergeRequestComments.All.ToArray(); - CollectionAssert.IsEmpty(comments); + Assert.That(comments, Is.Empty); } [Test] @@ -83,7 +83,7 @@ public async Task AddCommentToMergeRequestOnArchivedProject() context.Client.Projects.Archive(project.Id); var ex = Assert.Throws(() => mergeRequestComments.Add(newComment)); - Assert.AreEqual(ex.StatusCode, HttpStatusCode.Forbidden); + Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.Forbidden)); } } } diff --git a/NGitLab.Tests/MergeRequest/MergeRequestDiscussionsClientTests.cs b/NGitLab.Tests/MergeRequest/MergeRequestDiscussionsClientTests.cs index bb4200ce..efc95133 100644 --- a/NGitLab.Tests/MergeRequest/MergeRequestDiscussionsClientTests.cs +++ b/NGitLab.Tests/MergeRequest/MergeRequestDiscussionsClientTests.cs @@ -31,7 +31,7 @@ public async Task AddDiscussionToMergeRequest_DiscussionCreated() Assert.That(discussion.Notes[0].Resolved, Is.False); var discussions = mergeRequestDiscussions.All.ToArray(); - CollectionAssert.IsNotEmpty(discussions); + Assert.That(discussions, Is.Not.Empty); } [Test] @@ -51,7 +51,7 @@ public async Task GetDiscussion_DiscussionFound() var discussion = mergeRequestDiscussions.Add(newDiscussion); var gotDiscussion = await mergeRequestDiscussions.GetAsync(discussion.Id); - Assert.NotNull(gotDiscussion); + Assert.That(gotDiscussion, Is.Not.Null); } [Test] @@ -104,7 +104,7 @@ public async Task AddDiscussionToMergeRequestOnArchivedProject() var projectClient = context.Client.Projects; projectClient.Archive(project.Id); var ex = Assert.Throws(() => mergeRequestDiscussions.Add(newDiscussion)); - Assert.AreEqual(ex.StatusCode, HttpStatusCode.Forbidden); + Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.Forbidden)); } [Test] diff --git a/NGitLab.Tests/Milestone/MilestoneClientTests.cs b/NGitLab.Tests/Milestone/MilestoneClientTests.cs index b5cc7e5a..9891847b 100644 --- a/NGitLab.Tests/Milestone/MilestoneClientTests.cs +++ b/NGitLab.Tests/Milestone/MilestoneClientTests.cs @@ -19,9 +19,9 @@ public async Task Test_project_milestone_api() var milestone = CreateMilestone(context, MilestoneScope.Projects, project.Id, "my-super-milestone"); - Assert.AreEqual(milestone.Id, milestoneClient[milestone.Id].Id, "Test we can get a milestone by Id"); - Assert.IsTrue(milestoneClient.All.Any(x => x.Id == milestone.Id), "Test 'All' accessor returns the milestone"); - Assert.IsTrue(milestoneClient.AllInState(MilestoneState.active).Any(x => x.Id == milestone.Id), "Can return all active milestone"); + Assert.That(milestoneClient[milestone.Id].Id, Is.EqualTo(milestone.Id), "Test we can get a milestone by Id"); + Assert.That(milestoneClient.All.Any(x => x.Id == milestone.Id), Is.True, "Test 'All' accessor returns the milestone"); + Assert.That(milestoneClient.AllInState(MilestoneState.active).Any(x => x.Id == milestone.Id), Is.True, "Can return all active milestone"); milestone = UpdateMilestone(context, MilestoneScope.Projects, project.Id, milestone); @@ -29,7 +29,7 @@ public async Task Test_project_milestone_api() milestone = CloseMilestone(context, MilestoneScope.Projects, project.Id, milestone); - Assert.IsTrue(milestoneClient.AllInState(MilestoneState.closed).Any(x => x.Id == milestone.Id), "Can return all closed milestone"); + Assert.That(milestoneClient.AllInState(MilestoneState.closed).Any(x => x.Id == milestone.Id), Is.True, "Can return all closed milestone"); milestone = ActivateMilestone(context, MilestoneScope.Projects, project.Id, milestone); @@ -46,9 +46,9 @@ public async Task Test_group_milestone_api() var milestone = CreateMilestone(context, MilestoneScope.Groups, group.Id, "my-super-group-milestone"); - Assert.AreEqual(milestone.Id, milestoneClient[milestone.Id].Id, "Test we can get a milestone by Id"); - Assert.IsTrue(milestoneClient.All.Any(x => x.Id == milestone.Id), "Test 'All' accessor returns the milestone"); - Assert.IsTrue(milestoneClient.AllInState(MilestoneState.active).Any(x => x.Id == milestone.Id), "Can return all active milestone"); + Assert.That(milestoneClient[milestone.Id].Id, Is.EqualTo(milestone.Id), "Test we can get a milestone by Id"); + Assert.That(milestoneClient.All.Any(x => x.Id == milestone.Id), Is.True, "Test 'All' accessor returns the milestone"); + Assert.That(milestoneClient.AllInState(MilestoneState.active).Any(x => x.Id == milestone.Id), Is.True, "Can return all active milestone"); milestone = UpdateMilestone(context, MilestoneScope.Groups, group.Id, milestone); @@ -56,7 +56,7 @@ public async Task Test_group_milestone_api() milestone = CloseMilestone(context, MilestoneScope.Groups, group.Id, milestone); - Assert.IsTrue(milestoneClient.AllInState(MilestoneState.closed).Any(x => x.Id == milestone.Id), "Can return all closed milestone"); + Assert.That(milestoneClient.AllInState(MilestoneState.closed).Any(x => x.Id == milestone.Id), Is.True, "Can return all closed milestone"); milestone = ActivateMilestone(context, MilestoneScope.Groups, group.Id, milestone); @@ -77,7 +77,7 @@ public async Task Test_project_milestone_merge_requests() mergeRequestClient.Update(mergeRequest.Iid, new MergeRequestUpdate { MilestoneId = milestone.Id }); var mergeRequests = milestoneClient.GetMergeRequests(milestone.Id).ToArray(); - Assert.AreEqual(1, mergeRequests.Length, "The query retrieved all merged requests that assigned to the milestone."); + Assert.That(mergeRequests, Has.Length.EqualTo(1), "The query retrieved all merged requests that assigned to the milestone."); } [Test] @@ -95,7 +95,7 @@ public async Task Test_group_milestone_merge_requests() mergeRequestClient.Update(mergeRequest.Iid, new MergeRequestUpdate { MilestoneId = milestone.Id }); var mergeRequests = milestoneClient.GetMergeRequests(milestone.Id).ToArray(); - Assert.AreEqual(1, mergeRequests.Length, "The query retrieved all merged requests that assigned to the milestone."); + Assert.That(mergeRequests, Has.Length.EqualTo(1), "The query retrieved all merged requests that assigned to the milestone."); } private static Models.Milestone CreateMilestone(GitLabTestContext context, MilestoneScope scope, int id, string title) diff --git a/NGitLab.Tests/NGitLab.Tests.csproj b/NGitLab.Tests/NGitLab.Tests.csproj index f2ea6c6d..825afecf 100644 --- a/NGitLab.Tests/NGitLab.Tests.csproj +++ b/NGitLab.Tests/NGitLab.Tests.csproj @@ -18,6 +18,10 @@ + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/NGitLab.Tests/NamespacesTests.cs b/NGitLab.Tests/NamespacesTests.cs index 0b0e1e12..419007c9 100644 --- a/NGitLab.Tests/NamespacesTests.cs +++ b/NGitLab.Tests/NamespacesTests.cs @@ -18,8 +18,8 @@ public async Task Test_namespaces_contains_a_group() var namespacesClient = context.Client.Namespaces; var groupSearch = namespacesClient.Accessible.FirstOrDefault(g => g.Path.Equals(group.Path, StringComparison.Ordinal)); - Assert.IsNotNull(group); - Assert.AreEqual(Namespace.Type.Group, groupSearch.GetKind()); + Assert.That(group, Is.Not.Null); + Assert.That(groupSearch.GetKind(), Is.EqualTo(Namespace.Type.Group)); } [Test] @@ -31,8 +31,8 @@ public async Task Test_namespaces_contains_a_user() var namespacesClient = context.Client.Namespaces; var user = namespacesClient.Accessible.FirstOrDefault(g => g.Path.Equals(context.Client.Users.Current.Username, StringComparison.Ordinal)); - Assert.IsNotNull(user); - Assert.AreEqual(Namespace.Type.User, user.GetKind()); + Assert.That(user, Is.Not.Null); + Assert.That(user.GetKind(), Is.EqualTo(Namespace.Type.User)); } [Test] @@ -44,7 +44,7 @@ public async Task Test_namespaces_search_for_user() var namespacesClient = context.Client.Namespaces; var ns = namespacesClient.Search(context.Client.Users.Current.Username).First(); - Assert.AreEqual(Namespace.Type.User, ns.GetKind()); + Assert.That(ns.GetKind(), Is.EqualTo(Namespace.Type.User)); } [Test] @@ -56,7 +56,7 @@ public async Task Test_namespaces_search_for_group() var namespacesClient = context.Client.Namespaces; var user = namespacesClient.Search(group.Name); - Assert.IsNotNull(user); + Assert.That(user, Is.Not.Null); } } } diff --git a/NGitLab.Tests/PipelineTests.cs b/NGitLab.Tests/PipelineTests.cs index 8991ce29..a5c1fa8e 100644 --- a/NGitLab.Tests/PipelineTests.cs +++ b/NGitLab.Tests/PipelineTests.cs @@ -23,10 +23,10 @@ public async Task Test_can_list_the_pipelines() JobTests.AddGitLabCiFile(context.Client, project); var pipelines = await GitLabTestContext.RetryUntilAsync(() => pipelineClient.All, p => p.Any(), TimeSpan.FromSeconds(120)); - Assert.IsNotEmpty(pipelines); + Assert.That(pipelines, Is.Not.Empty); foreach (var pipeline in pipelines) { - Assert.AreEqual(project.Id, pipeline.ProjectId); + Assert.That(pipeline.ProjectId, Is.EqualTo(project.Id)); } } @@ -58,7 +58,7 @@ public async Task Test_can_get_coverage() }); var pipelineFull = pipelineClient[pipeline.Id]; - Assert.AreEqual(50, pipelineFull.Coverage); + Assert.That(pipelineFull.Coverage, Is.EqualTo(50)); } [Test] @@ -109,7 +109,7 @@ public async Task Test_search_for_pipeline() }; var pipelinesFromQuery = await GitLabTestContext.RetryUntilAsync(() => pipelineClient.Search(query).ToList(), p => p.Any(), TimeSpan.FromSeconds(120)); - Assert.IsTrue(pipelinesFromQuery.Any()); + Assert.That(pipelinesFromQuery.Any(), Is.True); } [Test] @@ -154,13 +154,13 @@ public async Task Test_create_pipeline_with_variables() var variables = pipelineClient.GetVariables(pipeline.Id); var var1 = variables.SingleOrDefault(v => v.Key.Equals("Var1", StringComparison.Ordinal)); - Assert.NotNull(var1); + Assert.That(var1, Is.Not.Null); var var2 = variables.SingleOrDefault(v => v.Key.Equals("Var2", StringComparison.Ordinal)); - Assert.NotNull(var2); + Assert.That(var2, Is.Not.Null); - Assert.AreEqual("Value1", var1.Value); - Assert.AreEqual("+4+", var2.Value); + Assert.That(var1.Value, Is.EqualTo("Value1")); + Assert.That(var2.Value, Is.EqualTo("+4+")); } [Test] @@ -182,29 +182,29 @@ public async Task Test_create_pipeline_with_testreports() var testReports = pipelineClient.GetTestReports(pipeline.Id); var summary = pipelineClient.GetTestReportsSummary(pipeline.Id); - Assert.NotNull(testReports); - Assert.NotNull(summary); + Assert.That(testReports, Is.Not.Null); + Assert.That(summary, Is.Not.Null); - Assert.AreEqual(0, testReports.TotalTime); - Assert.AreEqual(0, summary.Total.Time); + Assert.That(testReports.TotalTime, Is.EqualTo(0)); + Assert.That(summary.Total.Time, Is.EqualTo(0)); - Assert.AreEqual(0, testReports.TotalCount); - Assert.AreEqual(0, summary.Total.Count); + Assert.That(testReports.TotalCount, Is.EqualTo(0)); + Assert.That(summary.Total.Count, Is.EqualTo(0)); - Assert.AreEqual(0, testReports.SuccessCount); - Assert.AreEqual(0, summary.Total.Success); + Assert.That(testReports.SuccessCount, Is.EqualTo(0)); + Assert.That(summary.Total.Success, Is.EqualTo(0)); - Assert.AreEqual(0, testReports.FailedCount); - Assert.AreEqual(0, summary.Total.Failed); + Assert.That(testReports.FailedCount, Is.EqualTo(0)); + Assert.That(summary.Total.Failed, Is.EqualTo(0)); - Assert.AreEqual(0, testReports.SkippedCount); - Assert.AreEqual(0, summary.Total.Skipped); + Assert.That(testReports.SkippedCount, Is.EqualTo(0)); + Assert.That(summary.Total.Skipped, Is.EqualTo(0)); - Assert.AreEqual(0, testReports.ErrorCount); - Assert.AreEqual(0, summary.Total.Error); + Assert.That(testReports.ErrorCount, Is.EqualTo(0)); + Assert.That(summary.Total.Error, Is.EqualTo(0)); - Assert.IsEmpty(testReports.TestSuites); - Assert.IsEmpty(summary.TestSuites); + Assert.That(testReports.TestSuites, Is.Empty); + Assert.That(summary.TestSuites, Is.Empty); } [Test] @@ -224,9 +224,9 @@ public async Task Test_get_triggered_pipeline_variables() var variables = pipelineClient.GetVariables(pipeline.Id); - Assert.IsTrue(variables.Any(v => + Assert.That(variables.Any(v => v.Key.Equals("Test", StringComparison.Ordinal) && - v.Value.Equals("HelloWorld", StringComparison.Ordinal))); + v.Value.Equals("HelloWorld", StringComparison.Ordinal)), Is.True); } [Test] @@ -252,7 +252,7 @@ public async Task Test_retry() }, TimeSpan.FromMinutes(2)); var retriedPipeline = await pipelineClient.RetryAsync(pipeline.Id); - Assert.AreNotEqual(JobStatus.Failed, retriedPipeline.Status); // Should be created or running + Assert.That(retriedPipeline.Status, Is.Not.EqualTo(JobStatus.Failed)); // Should be created or running } } } diff --git a/NGitLab.Tests/ProjectBadgeClientTests.cs b/NGitLab.Tests/ProjectBadgeClientTests.cs index 2e5c3e10..1f817844 100644 --- a/NGitLab.Tests/ProjectBadgeClientTests.cs +++ b/NGitLab.Tests/ProjectBadgeClientTests.cs @@ -21,7 +21,7 @@ public async Task Test_project_badges() badges.ForEach(b => projectBadgeClient.Delete(b.Id)); badges = projectBadgeClient.ProjectsOnly.ToList(); - Assert.IsEmpty(badges); + Assert.That(badges, Is.Empty); // Create var badge = projectBadgeClient.Create(new BadgeCreate @@ -30,9 +30,9 @@ public async Task Test_project_badges() LinkUrl = "http://dummy/image.html", }); - Assert.AreEqual(BadgeKind.Project, badge.Kind); - Assert.AreEqual("http://dummy/image.png", badge.ImageUrl); - Assert.AreEqual("http://dummy/image.html", badge.LinkUrl); + Assert.That(badge.Kind, Is.EqualTo(BadgeKind.Project)); + Assert.That(badge.ImageUrl, Is.EqualTo("http://dummy/image.png")); + Assert.That(badge.LinkUrl, Is.EqualTo("http://dummy/image.html")); // Update badge = projectBadgeClient.Update(badge.Id, new BadgeUpdate @@ -41,22 +41,22 @@ public async Task Test_project_badges() LinkUrl = "http://dummy/image_edit.html", }); - Assert.AreEqual(BadgeKind.Project, badge.Kind); - Assert.AreEqual("http://dummy/image_edit.png", badge.ImageUrl); - Assert.AreEqual("http://dummy/image_edit.html", badge.LinkUrl); + Assert.That(badge.Kind, Is.EqualTo(BadgeKind.Project)); + Assert.That(badge.ImageUrl, Is.EqualTo("http://dummy/image_edit.png")); + Assert.That(badge.LinkUrl, Is.EqualTo("http://dummy/image_edit.html")); // Delete projectBadgeClient.Delete(badge.Id); badges = projectBadgeClient.ProjectsOnly.ToList(); - Assert.IsEmpty(badges); + Assert.That(badges, Is.Empty); // All projectBadgeClient.Create(new BadgeCreate { ImageUrl = "http://dummy/image1.png", LinkUrl = "http://dummy/image1.html", }); projectBadgeClient.Create(new BadgeCreate { ImageUrl = "http://dummy/image2.png", LinkUrl = "http://dummy/image2.html", }); projectBadgeClient.Create(new BadgeCreate { ImageUrl = "http://dummy/image3.png", LinkUrl = "http://dummy/image3.html", }); badges = projectBadgeClient.ProjectsOnly.ToList(); - Assert.AreEqual(3, badges.Count); + Assert.That(badges, Has.Count.EqualTo(3)); } } } diff --git a/NGitLab.Tests/ProjectLevelApprovalRulesClientTests.cs b/NGitLab.Tests/ProjectLevelApprovalRulesClientTests.cs index 846c3031..aa034104 100644 --- a/NGitLab.Tests/ProjectLevelApprovalRulesClientTests.cs +++ b/NGitLab.Tests/ProjectLevelApprovalRulesClientTests.cs @@ -37,9 +37,9 @@ public void CreateApprovalRule() var approvalRule = projectLevelApprovalRulesClient.CreateProjectLevelRule(CreateTestApprovalRuleCreate(project, approvalRuleName, approvalRuleApprovalsRequired)); - Assert.NotNull(approvalRule); - Assert.AreEqual(approvalRuleName, approvalRule.Name); - Assert.AreEqual(approvalRuleApprovalsRequired, approvalRule.ApprovalsRequired); + Assert.That(approvalRule, Is.Not.Null); + Assert.That(approvalRule.Name, Is.EqualTo(approvalRuleName)); + Assert.That(approvalRule.ApprovalsRequired, Is.EqualTo(approvalRuleApprovalsRequired)); } [Test] @@ -55,7 +55,7 @@ public void DeleteApprovalRule() projectLevelApprovalRulesClient.DeleteProjectLevelRule(approvalRule.RuleId); - Assert.AreEqual(0, projectLevelApprovalRulesClient.GetProjectLevelApprovalRules().Count); + Assert.That(projectLevelApprovalRulesClient.GetProjectLevelApprovalRules(), Is.Empty); } [Test] @@ -81,9 +81,9 @@ public void UpdateApprovalRule() ApprovalsRequired = approvalRuleApprovalsRequired, }); - Assert.NotNull(approvalRule); - Assert.AreEqual(approvalRuleName, approvalRule.Name); - Assert.AreEqual(approvalRuleApprovalsRequired, approvalRule.ApprovalsRequired); + Assert.That(approvalRule, Is.Not.Null); + Assert.That(approvalRule.Name, Is.EqualTo(approvalRuleName)); + Assert.That(approvalRule.ApprovalsRequired, Is.EqualTo(approvalRuleApprovalsRequired)); } [Test] @@ -100,9 +100,9 @@ public void GetApprovalRules() var approvalRules = projectLevelApprovalRulesClient.GetProjectLevelApprovalRules(); - Assert.AreEqual(1, approvalRules.Count); - Assert.AreEqual(firstApprovalRuleName, approvalRules[0].Name); - Assert.AreEqual(firstApprovalRuleApprovalsRequired, approvalRules[0].ApprovalsRequired); + Assert.That(approvalRules, Has.Count.EqualTo(1)); + Assert.That(approvalRules[0].Name, Is.EqualTo(firstApprovalRuleName)); + Assert.That(approvalRules[0].ApprovalsRequired, Is.EqualTo(firstApprovalRuleApprovalsRequired)); } private static ApprovalRuleCreate CreateTestApprovalRuleCreate(Project project, string approvalRuleName, int approvalsRequired) diff --git a/NGitLab.Tests/ProjectVariableClientTests.cs b/NGitLab.Tests/ProjectVariableClientTests.cs index ae6f8bc4..7d818be4 100644 --- a/NGitLab.Tests/ProjectVariableClientTests.cs +++ b/NGitLab.Tests/ProjectVariableClientTests.cs @@ -24,9 +24,9 @@ public async Task Test_project_variables() Protected = true, }); - Assert.AreEqual("My_Key", variable.Key); - Assert.AreEqual("My value", variable.Value); - Assert.AreEqual(true, variable.Protected); + Assert.That(variable.Key, Is.EqualTo("My_Key")); + Assert.That(variable.Value, Is.EqualTo("My value")); + Assert.That(variable.Protected, Is.EqualTo(true)); // Update variable = projectVariableClient.Update(variable.Key, new VariableUpdate @@ -35,22 +35,22 @@ public async Task Test_project_variables() Protected = false, }); - Assert.AreEqual("My_Key", variable.Key); - Assert.AreEqual("My value edited", variable.Value); - Assert.AreEqual(false, variable.Protected); + Assert.That(variable.Key, Is.EqualTo("My_Key")); + Assert.That(variable.Value, Is.EqualTo("My value edited")); + Assert.That(variable.Protected, Is.EqualTo(false)); // Delete projectVariableClient.Delete(variable.Key); var variables = projectVariableClient.All.ToList(); - Assert.IsEmpty(variables); + Assert.That(variables, Is.Empty); // All projectVariableClient.Create(new VariableCreate { Key = "Variable1", Value = "test" }); projectVariableClient.Create(new VariableCreate { Key = "Variable2", Value = "test" }); projectVariableClient.Create(new VariableCreate { Key = "Variable3", Value = "test" }); variables = projectVariableClient.All.ToList(); - Assert.AreEqual(3, variables.Count); + Assert.That(variables, Has.Count.EqualTo(3)); } } } diff --git a/NGitLab.Tests/ProjectsTests.cs b/NGitLab.Tests/ProjectsTests.cs index 358d9b07..5d605342 100644 --- a/NGitLab.Tests/ProjectsTests.cs +++ b/NGitLab.Tests/ProjectsTests.cs @@ -21,7 +21,7 @@ public async Task GetProjectByIdAsync() var projectClient = context.Client.Projects; var projectResult = await projectClient.GetByIdAsync(project.Id, new SingleProjectQuery(), CancellationToken.None); - Assert.AreEqual(project.Id, projectResult.Id); + Assert.That(projectResult.Id, Is.EqualTo(project.Id)); } [Test] @@ -33,7 +33,7 @@ public async Task GetByNamespacedPathAsync() var projectClient = context.Client.Projects; var projectResult = await projectClient.GetByNamespacedPathAsync(project.PathWithNamespace, new SingleProjectQuery(), CancellationToken.None); - Assert.AreEqual(project.Id, projectResult.Id); + Assert.That(projectResult.Id, Is.EqualTo(project.Id)); } [Test] @@ -50,7 +50,7 @@ public async Task GetProjectsAsync() projects.Add(item); } - CollectionAssert.IsNotEmpty(projects); + Assert.That(projects, Is.Not.Empty); } [Test] @@ -62,7 +62,7 @@ public async Task GetOwnedProjects() var projectClient = context.Client.Projects; var projects = projectClient.Owned.Take(30).ToArray(); - CollectionAssert.IsNotEmpty(projects); + Assert.That(projects, Is.Not.Empty); } [Test] @@ -75,7 +75,7 @@ public async Task GetVisibleProjects() var projects = projectClient.Visible.Take(30).ToArray(); - CollectionAssert.IsNotEmpty(projects); + Assert.That(projects, Is.Not.Empty); } [Test] @@ -88,7 +88,7 @@ public async Task GetAccessibleProjects() var projects = projectClient.Accessible.Take(30).ToArray(); - CollectionAssert.IsNotEmpty(projects); + Assert.That(projects, Is.Not.Empty); } [Test] @@ -106,7 +106,7 @@ public async Task GetProjectsByQuery() }; var projects = projectClient.Get(query).Take(10).ToArray(); - Assert.AreEqual(1, projects.Length); + Assert.That(projects, Has.Length.EqualTo(1)); } [Test] @@ -123,7 +123,7 @@ public async Task GetProjectsStatistics() Assert.Fail("No projects found."); } - projects.ForEach(p => Assert.IsNotNull(p.Statistics)); + projects.ForEach(p => Assert.That(p.Statistics, Is.Not.Null)); } [Test] @@ -141,8 +141,8 @@ public async Task GetProjectsProperties() Assert.Fail("No projects found."); } - projects.ForEach(p => Assert.IsNotNull(p.Links)); - projects.ForEach(p => Assert.IsNotNull(p.MergeMethod)); + projects.ForEach(p => Assert.That(p.Links, Is.Not.Null)); + projects.ForEach(p => Assert.That(p.MergeMethod, Is.Not.Null)); } [Test] @@ -161,7 +161,7 @@ public async Task GetProjectsByQuery_VisibilityInternal() var projects = projectClient.Get(query).ToList(); - CollectionAssert.IsNotEmpty(projects); + Assert.That(projects, Is.Not.Empty); } [Test] @@ -179,8 +179,8 @@ public async Task GetProjectByIdByQuery_Statistics() project = projectClient.GetById(project.Id, query); - Assert.IsNotNull(project); - Assert.IsNotNull(project.Statistics); + Assert.That(project, Is.Not.Null); + Assert.That(project.Statistics, Is.Not.Null); } [Test] @@ -201,8 +201,8 @@ public async Task GetProjectLanguages() context.Client.GetRepository(project.Id).Files.Create(file); var languages = projectClient.GetLanguages(project.Id.ToString(CultureInfo.InvariantCulture)); - Assert.That(languages.Count, Is.EqualTo(1)); - StringAssert.AreEqualIgnoringCase("javascript", languages.First().Key); + Assert.That(languages, Has.Count.EqualTo(1)); + Assert.That(languages.First().Key, Is.EqualTo("javascript").IgnoreCase); Assert.That(languages.First().Value, Is.EqualTo(100)); } @@ -223,7 +223,7 @@ public async Task GetProjectsCanSpecifyTheProjectPerPageCount() var projects = projectClient.Get(query).Take(10).ToList(); - CollectionAssert.IsNotEmpty(projects); + Assert.That(projects, Is.Not.Empty); Assert.That(context.LastRequest.RequestUri.ToString(), Contains.Substring("per_page=5")); } @@ -255,32 +255,32 @@ public async Task CreateUpdateDelete(bool initiallySetTagsInsteadOfTopics) var createdProject = projectClient.Create(project); - Assert.AreEqual(project.Description, createdProject.Description); - Assert.AreEqual(project.IssuesEnabled, createdProject.IssuesEnabled); - Assert.AreEqual(project.MergeRequestsEnabled, createdProject.MergeRequestsEnabled); - Assert.AreEqual(project.Name, createdProject.Name); - Assert.AreEqual(project.VisibilityLevel, createdProject.VisibilityLevel); - CollectionAssert.AreEquivalent(expectedTopics, createdProject.Topics); - CollectionAssert.AreEquivalent(expectedTopics, createdProject.TagList); - Assert.AreEqual(RepositoryAccessLevel.Enabled, createdProject.RepositoryAccessLevel); + Assert.That(createdProject.Description, Is.EqualTo(project.Description)); + Assert.That(createdProject.IssuesEnabled, Is.EqualTo(project.IssuesEnabled)); + Assert.That(createdProject.MergeRequestsEnabled, Is.EqualTo(project.MergeRequestsEnabled)); + Assert.That(createdProject.Name, Is.EqualTo(project.Name)); + Assert.That(createdProject.VisibilityLevel, Is.EqualTo(project.VisibilityLevel)); + Assert.That(createdProject.Topics, Is.EquivalentTo(expectedTopics)); + Assert.That(createdProject.TagList, Is.EquivalentTo(expectedTopics)); + Assert.That(createdProject.RepositoryAccessLevel, Is.EqualTo(RepositoryAccessLevel.Enabled)); // Update expectedTopics = new List { "Tag-3" }; var updateOptions = new ProjectUpdate { Visibility = VisibilityLevel.Private, Topics = expectedTopics }; var updatedProject = projectClient.Update(createdProject.Id.ToString(CultureInfo.InvariantCulture), updateOptions); - Assert.AreEqual(VisibilityLevel.Private, updatedProject.VisibilityLevel); - CollectionAssert.AreEquivalent(expectedTopics, updatedProject.Topics); - CollectionAssert.AreEquivalent(expectedTopics, updatedProject.TagList); + Assert.That(updatedProject.VisibilityLevel, Is.EqualTo(VisibilityLevel.Private)); + Assert.That(updatedProject.Topics, Is.EquivalentTo(expectedTopics)); + Assert.That(updatedProject.TagList, Is.EquivalentTo(expectedTopics)); updateOptions.Visibility = VisibilityLevel.Public; updateOptions.Topics = null; // If Topics are null, the project's existing topics will remain updatedProject = projectClient.Update(createdProject.Id.ToString(CultureInfo.InvariantCulture), updateOptions); - Assert.AreEqual(VisibilityLevel.Public, updatedProject.VisibilityLevel); - CollectionAssert.AreEquivalent(expectedTopics, updatedProject.Topics); - CollectionAssert.AreEquivalent(expectedTopics, updatedProject.TagList); + Assert.That(updatedProject.VisibilityLevel, Is.EqualTo(VisibilityLevel.Public)); + Assert.That(updatedProject.Topics, Is.EquivalentTo(expectedTopics)); + Assert.That(updatedProject.TagList, Is.EquivalentTo(expectedTopics)); var updatedProject2 = projectClient.Update(createdProject.PathWithNamespace, new ProjectUpdate { Visibility = VisibilityLevel.Internal }); - Assert.AreEqual(VisibilityLevel.Internal, updatedProject2.VisibilityLevel); + Assert.That(updatedProject2.VisibilityLevel, Is.EqualTo(VisibilityLevel.Internal)); projectClient.Delete(createdProject.Id); } @@ -307,7 +307,7 @@ public async Task Test_get_by_project_query_projectQuery_MinAccessLevel_returns_ var result = projectClient.Get(query).Take(10).ToArray(); // Assert - Assert.IsTrue(result.Any()); + Assert.That(result.Any(), Is.True); } [Test] @@ -385,7 +385,7 @@ public async Task GetProjectsByLastActivity() }; var projects = projectClient.Get(query).Take(10).ToList(); - CollectionAssert.IsNotEmpty(projects); + Assert.That(projects, Is.Not.Empty); Assert.That(projects.Select(p => p.LastActivityAt), Is.All.GreaterThan(date.UtcDateTime)); } @@ -401,7 +401,7 @@ public async Task IsEmpty() prj.Name = "Project_Test_" + context.GetRandomNumber().ToString(CultureInfo.InvariantCulture); prj.VisibilityLevel = VisibilityLevel.Internal; }); - Assert.IsTrue(createdProject.EmptyRepo); + Assert.That(createdProject.EmptyRepo, Is.True); context.Client.GetRepository(createdProject.Id).Files.Create(new FileUpsert { @@ -412,7 +412,7 @@ public async Task IsEmpty() }); createdProject = projectClient[createdProject.Id]; - Assert.IsFalse(createdProject.EmptyRepo); + Assert.That(createdProject.EmptyRepo, Is.False); } [Test] @@ -444,7 +444,7 @@ public async Task GetProjectByTopics() var projects = projectClient.Get(query); // Get projects that have both required topics // Assert - Assert.AreEqual(2, projects.Count()); + Assert.That(projects.Count(), Is.EqualTo(2)); static string CreateTopic() => Guid.NewGuid().ToString("N"); } @@ -471,7 +471,7 @@ public async Task CreateProjectWithSquashOption(SquashOption? inputSquashOption) var createdProject = projectClient.Create(project); var expectedSquashOption = inputSquashOption ?? SquashOption.DefaultOff; - Assert.AreEqual(expectedSquashOption, createdProject.SquashOption); + Assert.That(createdProject.SquashOption, Is.EqualTo(expectedSquashOption)); projectClient.Delete(createdProject.Id); } diff --git a/NGitLab.Tests/ProtectedBranchTests.cs b/NGitLab.Tests/ProtectedBranchTests.cs index 260d72f9..72b28e97 100644 --- a/NGitLab.Tests/ProtectedBranchTests.cs +++ b/NGitLab.Tests/ProtectedBranchTests.cs @@ -46,22 +46,22 @@ public async Task ProtectBranch_Test() ProtectedBranchAndBranchProtectAreEquals(branchProtect, protectedBranchClient.GetProtectedBranch(branch.Name)); // Get branches - Assert.IsNotEmpty(protectedBranchClient.GetProtectedBranches()); + Assert.That(protectedBranchClient.GetProtectedBranches(), Is.Not.Empty); var protectedBranches = protectedBranchClient.GetProtectedBranches(branch.Name); - Assert.IsNotEmpty(protectedBranches); + Assert.That(protectedBranches, Is.Not.Empty); ProtectedBranchAndBranchProtectAreEquals(branchProtect, protectedBranches[0]); // Unprotect branch protectedBranchClient.UnprotectBranch(branch.Name); - Assert.IsEmpty(protectedBranchClient.GetProtectedBranches(branch.Name)); + Assert.That(protectedBranchClient.GetProtectedBranches(branch.Name), Is.Empty); } private static void ProtectedBranchAndBranchProtectAreEquals(BranchProtect branchProtect, ProtectedBranch protectedBranch) { - Assert.AreEqual(branchProtect.BranchName, protectedBranch.Name); - Assert.AreEqual(branchProtect.PushAccessLevel, protectedBranch.PushAccessLevels[0].AccessLevel); - Assert.AreEqual(branchProtect.MergeAccessLevel, protectedBranch.MergeAccessLevels[0].AccessLevel); - Assert.AreEqual(branchProtect.AllowForcePush, protectedBranch.AllowForcePush); + Assert.That(protectedBranch.Name, Is.EqualTo(branchProtect.BranchName)); + Assert.That(protectedBranch.PushAccessLevels[0].AccessLevel, Is.EqualTo(branchProtect.PushAccessLevel)); + Assert.That(protectedBranch.MergeAccessLevels[0].AccessLevel, Is.EqualTo(branchProtect.MergeAccessLevel)); + Assert.That(protectedBranch.AllowForcePush, Is.EqualTo(branchProtect.AllowForcePush)); } } } diff --git a/NGitLab.Tests/ProtectedTagTests.cs b/NGitLab.Tests/ProtectedTagTests.cs index ef1f8a6c..d27b6d93 100644 --- a/NGitLab.Tests/ProtectedTagTests.cs +++ b/NGitLab.Tests/ProtectedTagTests.cs @@ -17,11 +17,11 @@ public async Task ProtectTag_Test() var tagClient = context.Client.GetRepository(project.Id).Tags; var tag = tagClient.Create(new TagCreate { Name = "protectedTag", Ref = project.DefaultBranch }); - Assert.False(tag.Protected); + Assert.That(tag.Protected, Is.False); var protectedTagClient = context.Client.GetProtectedTagClient(project.Id); var protectedTags = protectedTagClient.GetProtectedTagsAsync(); - Assert.False(protectedTags.Any()); + Assert.That(protectedTags.Any(), Is.False); await ProtectedTagTest(tag.Name, tag.Name, protectedTagClient, tagClient); await ProtectedTagTest("*", tag.Name, protectedTagClient, tagClient); @@ -35,27 +35,27 @@ private static async Task ProtectedTagTest(string tagProtectName, string tagName CreateAccessLevel = AccessLevel.NoAccess, }; var protectedTag = await protectedTagClient.ProtectTagAsync(tagProtect).ConfigureAwait(false); - Assert.AreEqual(protectedTag.Name, tagProtect.Name); + Assert.That(tagProtect.Name, Is.EqualTo(protectedTag.Name)); var accessLevels = protectedTag.CreateAccessLevels.Select(level => level.AccessLevel).ToArray(); - Assert.Contains(AccessLevel.NoAccess, accessLevels); - Assert.Contains(AccessLevel.Maintainer, accessLevels); + Assert.That(accessLevels, Does.Contain(AccessLevel.NoAccess)); + Assert.That(accessLevels, Does.Contain(AccessLevel.Maintainer)); var getProtectedTag = await protectedTagClient.GetProtectedTagAsync(tagProtectName).ConfigureAwait(false); - Assert.AreEqual(protectedTag.Name, getProtectedTag.Name); + Assert.That(getProtectedTag.Name, Is.EqualTo(protectedTag.Name)); accessLevels = getProtectedTag.CreateAccessLevels.Select(level => level.AccessLevel).ToArray(); - Assert.Contains(AccessLevel.NoAccess, accessLevels); - Assert.Contains(AccessLevel.Maintainer, accessLevels); + Assert.That(accessLevels, Does.Contain(AccessLevel.NoAccess)); + Assert.That(accessLevels, Does.Contain(AccessLevel.Maintainer)); var tag = await tagClient.GetByNameAsync(tagName).ConfigureAwait(false); - Assert.True(tag.Protected); + Assert.That(tag.Protected, Is.True); await protectedTagClient.UnprotectTagAsync(tagProtectName).ConfigureAwait(false); var protectedTags = protectedTagClient.GetProtectedTagsAsync(); - Assert.False(protectedTags.Any()); + Assert.That(protectedTags.Any(), Is.False); tag = await tagClient.GetByNameAsync(tag.Name).ConfigureAwait(false); - Assert.False(tag.Protected); + Assert.That(tag.Protected, Is.False); } } } diff --git a/NGitLab.Tests/ReleaseClientTests.cs b/NGitLab.Tests/ReleaseClientTests.cs index 693d7fe8..5d6c0ef4 100644 --- a/NGitLab.Tests/ReleaseClientTests.cs +++ b/NGitLab.Tests/ReleaseClientTests.cs @@ -30,14 +30,14 @@ public async Task Test_release_api() Description = "test", }); - Assert.AreEqual(ReleasesAccessLevel.Enabled, project.ReleasesAccessLevel); + Assert.That(project.ReleasesAccessLevel, Is.EqualTo(ReleasesAccessLevel.Enabled)); Assert.That(release.TagName, Is.EqualTo("0.7")); Assert.That(release.Name, Is.EqualTo("0.7")); Assert.That(release.Description, Is.EqualTo("test")); Assert.That(release.Links.Self, Is.EqualTo($"{project.WebUrl}/-/releases/0.7")); Assert.That(release.Links.EditUrl, Is.EqualTo($"{project.WebUrl}/-/releases/0.7/edit")); - Assert.IsNotNull(releaseClient.GetAsync().FirstOrDefault(x => string.Equals(x.Name, "0.7", StringComparison.Ordinal))); + Assert.That(releaseClient.GetAsync().FirstOrDefault(x => string.Equals(x.Name, "0.7", StringComparison.Ordinal)), Is.Not.Null); release = releaseClient[tag.Name]; Assert.That(release.TagName, Is.EqualTo("0.7")); @@ -53,9 +53,9 @@ public async Task Test_release_api() Assert.That(release.Name, Is.EqualTo("0.7")); Assert.That(release.Description, Is.EqualTo("test updated")); - Assert.IsNotNull(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "0.7", StringComparison.Ordinal))); + Assert.That(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "0.7", StringComparison.Ordinal)), Is.Not.Null); tagsClient.Delete("0.7"); - Assert.IsNull(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "0.7", StringComparison.Ordinal))); + Assert.That(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "0.7", StringComparison.Ordinal)), Is.Null); } [Test] @@ -92,18 +92,18 @@ public async Task Test_release_links() }); Assert.That(link.Name, Is.EqualTo("test link")); Assert.That(link.Url, Is.EqualTo("https://www.example.com")); - Assert.IsTrue(link.External); + Assert.That(link.External, Is.True); link = linksClient[link.Id.Value]; Assert.That(link.Name, Is.EqualTo("test link")); Assert.That(link.Url, Is.EqualTo("https://www.example.com")); - Assert.IsTrue(link.External); + Assert.That(link.External, Is.True); linksClient.Delete(link.Id.Value); - Assert.IsNull(linksClient.All.FirstOrDefault(x => string.Equals(x.Name, "test link", StringComparison.Ordinal))); + Assert.That(linksClient.All.FirstOrDefault(x => string.Equals(x.Name, "test link", StringComparison.Ordinal)), Is.Null); tagsClient.Delete("0.7"); - Assert.IsNull(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "0.7", StringComparison.Ordinal))); + Assert.That(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "0.7", StringComparison.Ordinal)), Is.Null); } } } diff --git a/NGitLab.Tests/RepositoryClient/BranchClientTests.cs b/NGitLab.Tests/RepositoryClient/BranchClientTests.cs index c7665b0b..7dab22ef 100644 --- a/NGitLab.Tests/RepositoryClient/BranchClientTests.cs +++ b/NGitLab.Tests/RepositoryClient/BranchClientTests.cs @@ -19,7 +19,7 @@ public async Task GetAll() var project = context.CreateProject(initializeWithCommits: true); var branches = context.Client.GetRepository(project.Id).Branches; - CollectionAssert.IsNotEmpty(branches.All.ToArray()); + Assert.That(branches.All.ToArray(), Is.Not.Empty); } [Test] @@ -32,9 +32,9 @@ public async Task GetByName() var branch = branches[project.DefaultBranch]; - Assert.IsNotNull(branch); - Assert.IsNotNull(branch.Name); - Assert.IsTrue(branch.Default); + Assert.That(branch, Is.Not.Null); + Assert.That(branch.Name, Is.Not.Null); + Assert.That(branch.Default, Is.True); } [Test] @@ -54,8 +54,8 @@ public async Task AddDelete() }); var branch = branches[branchName]; - Assert.IsNotNull(branch); - Assert.IsFalse(branch.Default); + Assert.That(branch, Is.Not.Null); + Assert.That(branch.Default, Is.False); branches.Protect(branchName); @@ -82,7 +82,7 @@ public async Task Test_that_branch_names_containing_slashes_are_supported() Ref = project.DefaultBranch, }); - Assert.IsNotNull(branches[branchName]); + Assert.That(branches[branchName], Is.Not.Null); branches.Protect(branchName); @@ -102,7 +102,7 @@ private static void AssertCannotFind(Func get) } catch (GitLabException ex) { - Assert.AreEqual(HttpStatusCode.NotFound, ex.StatusCode); + Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); } } } diff --git a/NGitLab.Tests/RepositoryClient/ProjectHooksClientTests.cs b/NGitLab.Tests/RepositoryClient/ProjectHooksClientTests.cs index 5a031c02..47c08756 100644 --- a/NGitLab.Tests/RepositoryClient/ProjectHooksClientTests.cs +++ b/NGitLab.Tests/RepositoryClient/ProjectHooksClientTests.cs @@ -32,17 +32,17 @@ public async Task CreateUpdateDelete() }; var created = hooksClient.Create(toCreate); - Assert.That(hooksClient.All.ToArray().Length, Is.EqualTo(1)); + Assert.That(hooksClient.All.ToArray(), Has.Length.EqualTo(1)); - Assert.AreEqual(toCreate.MergeRequestsEvents, created.MergeRequestsEvents); - Assert.AreEqual(toCreate.PushEvents, created.PushEvents); - Assert.AreEqual(toCreate.IssuesEvents, created.IssuesEvents); - Assert.AreEqual(toCreate.JobEvents, created.JobEvents); - Assert.AreEqual(toCreate.NoteEvents, created.NoteEvents); - Assert.AreEqual(toCreate.PipelineEvents, created.PipelineEvents); - Assert.AreEqual(toCreate.TagPushEvents, created.TagPushEvents); - Assert.AreEqual(toCreate.EnableSslVerification, created.EnableSslVerification); - Assert.AreEqual(toCreate.Url, created.Url); + Assert.That(created.MergeRequestsEvents, Is.EqualTo(toCreate.MergeRequestsEvents)); + Assert.That(created.PushEvents, Is.EqualTo(toCreate.PushEvents)); + Assert.That(created.IssuesEvents, Is.EqualTo(toCreate.IssuesEvents)); + Assert.That(created.JobEvents, Is.EqualTo(toCreate.JobEvents)); + Assert.That(created.NoteEvents, Is.EqualTo(toCreate.NoteEvents)); + Assert.That(created.PipelineEvents, Is.EqualTo(toCreate.PipelineEvents)); + Assert.That(created.TagPushEvents, Is.EqualTo(toCreate.TagPushEvents)); + Assert.That(created.EnableSslVerification, Is.EqualTo(toCreate.EnableSslVerification)); + Assert.That(created.Url, Is.EqualTo(toCreate.Url)); var toUpdate = new ProjectHookUpsert { @@ -59,20 +59,20 @@ public async Task CreateUpdateDelete() }; var updated = hooksClient.Update(created.Id, toUpdate); - Assert.That(hooksClient.All.ToArray().Length, Is.EqualTo(1)); + Assert.That(hooksClient.All.ToArray(), Has.Length.EqualTo(1)); - Assert.AreEqual(toUpdate.MergeRequestsEvents, updated.MergeRequestsEvents); - Assert.AreEqual(toUpdate.PushEvents, updated.PushEvents); - Assert.AreEqual(toUpdate.IssuesEvents, updated.IssuesEvents); - Assert.AreEqual(toUpdate.JobEvents, updated.JobEvents); - Assert.AreEqual(toUpdate.NoteEvents, updated.NoteEvents); - Assert.AreEqual(toUpdate.PipelineEvents, updated.PipelineEvents); - Assert.AreEqual(toUpdate.TagPushEvents, updated.TagPushEvents); - Assert.AreEqual(toUpdate.EnableSslVerification, updated.EnableSslVerification); - Assert.AreEqual(toUpdate.Url, updated.Url); + Assert.That(updated.MergeRequestsEvents, Is.EqualTo(toUpdate.MergeRequestsEvents)); + Assert.That(updated.PushEvents, Is.EqualTo(toUpdate.PushEvents)); + Assert.That(updated.IssuesEvents, Is.EqualTo(toUpdate.IssuesEvents)); + Assert.That(updated.JobEvents, Is.EqualTo(toUpdate.JobEvents)); + Assert.That(updated.NoteEvents, Is.EqualTo(toUpdate.NoteEvents)); + Assert.That(updated.PipelineEvents, Is.EqualTo(toUpdate.PipelineEvents)); + Assert.That(updated.TagPushEvents, Is.EqualTo(toUpdate.TagPushEvents)); + Assert.That(updated.EnableSslVerification, Is.EqualTo(toUpdate.EnableSslVerification)); + Assert.That(updated.Url, Is.EqualTo(toUpdate.Url)); hooksClient.Delete(updated.Id); - Assert.That(hooksClient.All.ToArray().Length, Is.EqualTo(0)); + Assert.That(hooksClient.All.ToArray(), Is.Empty); } } } diff --git a/NGitLab.Tests/RepositoryClient/RepositoryClientTests.cs b/NGitLab.Tests/RepositoryClient/RepositoryClientTests.cs index 0f756ccb..83fcd878 100644 --- a/NGitLab.Tests/RepositoryClient/RepositoryClientTests.cs +++ b/NGitLab.Tests/RepositoryClient/RepositoryClientTests.cs @@ -79,8 +79,8 @@ public async Task GetAllCommits() var commits = context.RepositoryClient.Commits.ToArray(); - Assert.AreEqual(commitCount, commits.Length); - CollectionAssert.AreEqual(context.Commits.Select(c => c.Message).Reverse(), commits.Select(c => c.Message)); + Assert.That(commits, Has.Length.EqualTo(commitCount)); + Assert.That(commits.Select(c => c.Message), Is.EqualTo(context.Commits.Select(c => c.Message).Reverse()).AsCollection); } [Test] @@ -90,12 +90,12 @@ public async Task GetCommitByBranchName() using var context = await RepositoryClientTestsContext.CreateAsync(commitCount: 2); var defaultBranch = context.Project.DefaultBranch; - CollectionAssert.IsNotEmpty(context.RepositoryClient.GetCommits(defaultBranch)); - CollectionAssert.IsNotEmpty(context.RepositoryClient.GetCommits(defaultBranch, -1)); + Assert.That(context.RepositoryClient.GetCommits(defaultBranch), Is.Not.Empty); + Assert.That(context.RepositoryClient.GetCommits(defaultBranch, -1), Is.Not.Empty); var commits = context.RepositoryClient.GetCommits(defaultBranch, 1).ToArray(); - Assert.AreEqual(1, commits.Length); - Assert.AreEqual(context.Commits[1].Message, commits[0].Message); + Assert.That(commits, Has.Length.EqualTo(1)); + Assert.That(commits[0].Message, Is.EqualTo(context.Commits[1].Message)); } [Test] @@ -106,10 +106,10 @@ public async Task GetCommitBySha1() var sha1 = context.Commits[0].Id; var commit = context.RepositoryClient.GetCommit(sha1); - Assert.AreEqual(sha1, commit.Id); - Assert.AreEqual(context.Commits[0].Message, commit.Message); - Assert.AreEqual(context.Commits[0].WebUrl, commit.WebUrl); - Assert.NotNull(commit.WebUrl); + Assert.That(commit.Id, Is.EqualTo(sha1)); + Assert.That(commit.Message, Is.EqualTo(context.Commits[0].Message)); + Assert.That(commit.WebUrl, Is.EqualTo(context.Commits[0].WebUrl)); + Assert.That(commit.WebUrl, Is.Not.Null); } [Test] @@ -126,8 +126,8 @@ public async Task GetCommitBySha1Range() }; var commits = context.RepositoryClient.GetCommits(commitRequest).Reverse().ToArray(); - Assert.AreEqual(allCommits[2].Id, commits[0].Id); - Assert.AreEqual(allCommits[3].Id, commits[1].Id); + Assert.That(commits[0].Id, Is.EqualTo(allCommits[2].Id)); + Assert.That(commits[1].Id, Is.EqualTo(allCommits[3].Id)); } [Test] @@ -152,7 +152,7 @@ public async Task GetCommitsSince() // Assert var lastRequestQueryString = context.Context.LastRequest.RequestUri.Query; - Assert.True(lastRequestQueryString.Contains($"since={expectedSinceValue}")); + Assert.That(lastRequestQueryString, Does.Contain($"since={expectedSinceValue}")); } [Test] @@ -175,7 +175,7 @@ public async Task GetCommitsDoesntIncludeSinceWhenNotSpecified() // Assert var lastRequestQueryString = context.Context.LastRequest.RequestUri.Query; - Assert.False(lastRequestQueryString.Contains("since=")); + Assert.That(lastRequestQueryString, Does.Not.Contain("since=")); } [Test] @@ -200,7 +200,7 @@ public async Task GetCommitsUntil() // Assert var lastRequestQueryString = context.Context.LastRequest.RequestUri.Query; - Assert.True(lastRequestQueryString.Contains($"until={expectedUntilValue}")); + Assert.That(lastRequestQueryString, Does.Contain($"until={expectedUntilValue}")); } [Test] @@ -223,7 +223,7 @@ public async Task GetCommitsDoesntIncludeUntilWhenNotSpecified() // Assert var lastRequestQueryString = context.Context.LastRequest.RequestUri.Query; - Assert.False(lastRequestQueryString.Contains("until=")); + Assert.That(lastRequestQueryString, Does.Not.Contain("until=")); } [Test] @@ -232,7 +232,7 @@ public async Task GetCommitDiff() { using var context = await RepositoryClientTestsContext.CreateAsync(commitCount: 2); - CollectionAssert.IsNotEmpty(context.RepositoryClient.GetCommitDiff(context.RepositoryClient.Commits.First().Id).ToArray()); + Assert.That(context.RepositoryClient.GetCommitDiff(context.RepositoryClient.Commits.First().Id).ToArray(), Is.Not.Empty); } [TestCase(4)] @@ -247,9 +247,9 @@ public async Task GetAllTreeObjectsAtRoot(int commitCount) var expectedFileCount = (int)Math.Ceiling(commitCount / 2.0); var expectedDirCount = 1; - Assert.AreEqual(expectedFileCount, treeObjects.Count(t => t.Type == ObjectType.blob)); - Assert.AreEqual(expectedDirCount, treeObjects.Count(t => t.Type == ObjectType.tree)); - Assert.IsTrue(treeObjects.All(t => string.Equals(t.Path, t.Name, StringComparison.Ordinal))); + Assert.That(treeObjects.Count(t => t.Type == ObjectType.blob), Is.EqualTo(expectedFileCount)); + Assert.That(treeObjects.Count(t => t.Type == ObjectType.tree), Is.EqualTo(expectedDirCount)); + Assert.That(treeObjects.All(t => string.Equals(t.Path, t.Name, StringComparison.Ordinal)), Is.True); } [TestCase(4)] @@ -264,8 +264,8 @@ public async Task GetAllTreeObjectsRecursivelyFromRoot(int commitCount) var expectedFileCount = commitCount; var expectedDirCount = 1; - Assert.AreEqual(expectedFileCount, treeObjects.Count(t => t.Type == ObjectType.blob)); - Assert.AreEqual(expectedDirCount, treeObjects.Count(t => t.Type == ObjectType.tree)); + Assert.That(treeObjects.Count(t => t.Type == ObjectType.blob), Is.EqualTo(expectedFileCount)); + Assert.That(treeObjects.Count(t => t.Type == ObjectType.tree), Is.EqualTo(expectedDirCount)); } [TestCase(4)] @@ -284,8 +284,8 @@ public async Task GetAllTreeObjectsRecursivelyFromRootAsync(int commitCount) var expectedFileCount = commitCount; var expectedDirCount = 1; - Assert.AreEqual(expectedFileCount, treeObjects.Count(t => t.Type == ObjectType.blob)); - Assert.AreEqual(expectedDirCount, treeObjects.Count(t => t.Type == ObjectType.tree)); + Assert.That(treeObjects.Count(t => t.Type == ObjectType.blob), Is.EqualTo(expectedFileCount)); + Assert.That(treeObjects.Count(t => t.Type == ObjectType.tree), Is.EqualTo(expectedDirCount)); } [TestCase(4)] @@ -301,7 +301,7 @@ public async Task GetAllTreeObjectsRecursivelyFromSubfolderAsync(int commitCount treeObjects.Add(item); } - Assert.True(treeObjects.All(t => t.Path.StartsWith(RepositoryClientTestsContext.SubfolderName, StringComparison.OrdinalIgnoreCase))); + Assert.That(treeObjects.All(t => t.Path.StartsWith(RepositoryClientTestsContext.SubfolderName, StringComparison.OrdinalIgnoreCase)), Is.True); } [Test] @@ -311,7 +311,7 @@ public async Task GetAllTreeObjectsInPathOnRef() using var context = await RepositoryClientTestsContext.CreateAsync(commitCount: 2); var treeObjects = context.RepositoryClient.GetTree(string.Empty, context.Project.DefaultBranch, recursive: false); - Assert.IsNotEmpty(treeObjects); + Assert.That(treeObjects, Is.Not.Empty); } [Test] @@ -321,7 +321,7 @@ public async Task GetAllTreeObjectsInPathWith100ElementsByPage() using var context = await RepositoryClientTestsContext.CreateAsync(commitCount: 2); var treeObjects = context.RepositoryClient.GetTree(new RepositoryGetTreeOptions { Path = string.Empty, PerPage = 100 }); - Assert.IsNotEmpty(treeObjects); + Assert.That(treeObjects, Is.Not.Empty); } [Test] @@ -331,7 +331,7 @@ public async Task GetAllTreeObjectsAtInvalidPath() using var context = await RepositoryClientTestsContext.CreateAsync(commitCount: 2); var treeObjects = context.RepositoryClient.GetTree("Fakepath"); - Assert.IsEmpty(treeObjects); + Assert.That(treeObjects, Is.Empty); } [TestCase(CommitRefType.All)] @@ -346,11 +346,11 @@ public async Task GetCommitRefs(CommitRefType type) if (type == CommitRefType.Tag) { - CollectionAssert.IsEmpty(commitRefs); + Assert.That(commitRefs, Is.Empty); } else { - CollectionAssert.IsNotEmpty(commitRefs); + Assert.That(commitRefs, Is.Not.Empty); } } } diff --git a/NGitLab.Tests/RunnerTests.cs b/NGitLab.Tests/RunnerTests.cs index 16007af3..6089d97f 100644 --- a/NGitLab.Tests/RunnerTests.cs +++ b/NGitLab.Tests/RunnerTests.cs @@ -1,5 +1,4 @@ -using System; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using NGitLab.Models; using NGitLab.Tests.Docker; @@ -23,10 +22,10 @@ public async Task Test_can_enable_and_disable_a_runner_on_a_project() runnersClient.EnableRunner(project2.Id, new RunnerId(runner.Id)); runnersClient.DisableRunner(project1.Id, new RunnerId(runner.Id)); - Assert.IsFalse(IsEnabled()); + Assert.That(IsEnabled(), Is.False); runnersClient.EnableRunner(project1.Id, new RunnerId(runner.Id)); - Assert.IsTrue(IsEnabled()); + Assert.That(IsEnabled(), Is.True); bool IsEnabled() => runnersClient[runner.Id].Projects.Any(x => x.Id == project1.Id); } @@ -43,32 +42,11 @@ public async Task Test_can_find_a_runner_on_a_project() runnersClient.EnableRunner(project2.Id, new RunnerId(runner.Id)); var result = runnersClient.OfProject(project.Id).ToList(); - Assert.IsTrue(result.Any(r => r.Id == runner.Id)); + Assert.That(result.Any(r => r.Id == runner.Id), Is.True); runnersClient.DisableRunner(project.Id, new RunnerId(runner.Id)); result = runnersClient.OfProject(project.Id).ToList(); - Assert.IsTrue(result.All(r => r.Id != runner.Id)); - } - - [Test] - [NGitLabRetry] - public async Task Test_some_runner_fields_are_not_null() - { - using var context = await GitLabTestContext.CreateAsync(); - var project = context.CreateProject(initializeWithCommits: true); - var runnersClient = context.Client.Runners; - var runner = runnersClient.Register(new RunnerRegister { Token = project.RunnersToken }); - - using (await context.StartRunnerForOneJobAsync(project.Id)) - { - var runnerDetails = await GitLabTestContext.RetryUntilAsync(() => runnersClient[runner.Id], runner => runner.IpAddress != null, TimeSpan.FromMinutes(2)); - - Assert.IsNotNull(runnerDetails.Id); - Assert.IsNotNull(runnerDetails.Active); - Assert.IsNotNull(runnerDetails.Locked); - Assert.IsNotNull(runnerDetails.RunUntagged); - Assert.IsNotNull(runnerDetails.IpAddress); - } + Assert.That(result.All(r => r.Id != runner.Id), Is.True); } [Test] @@ -79,13 +57,13 @@ public async Task Test_Runner_Can_Be_Locked_And_Unlocked() var project = context.CreateProject(initializeWithCommits: true); var runnersClient = context.Client.Runners; var runner = runnersClient.Register(new RunnerRegister { Token = project.RunnersToken, Locked = false }); - Assert.IsFalse(runner.Locked, "Runner should not be locked."); + Assert.That(runner.Locked, Is.False, "Runner should not be locked."); runner = runnersClient.Update(runner.Id, new RunnerUpdate { Locked = true }); - Assert.IsTrue(runner.Locked, "Runner should be locked."); + Assert.That(runner.Locked, Is.True, "Runner should be locked."); runner = runnersClient.Update(runner.Id, new RunnerUpdate { Locked = false }); - Assert.IsFalse(runner.Locked, "Runner should not be locked."); + Assert.That(runner.Locked, Is.False, "Runner should not be locked."); } [Test] @@ -96,10 +74,10 @@ public async Task Test_Runner_Can_Update_RunUntagged_Flag() var project = context.CreateProject(initializeWithCommits: true); var runnersClient = context.Client.Runners; var runner = runnersClient.Register(new RunnerRegister { Token = project.RunnersToken, RunUntagged = false, TagList = new[] { "tag" } }); - Assert.False(runner.RunUntagged); + Assert.That(runner.RunUntagged, Is.False); runner = runnersClient.Update(runner.Id, new RunnerUpdate { RunUntagged = true }); - Assert.AreEqual(true, runner.RunUntagged); + Assert.That(runner.RunUntagged, Is.True); } } } diff --git a/NGitLab.Tests/Sha1Tests.cs b/NGitLab.Tests/Sha1Tests.cs index 8b5871b7..d3f93c48 100644 --- a/NGitLab.Tests/Sha1Tests.cs +++ b/NGitLab.Tests/Sha1Tests.cs @@ -9,21 +9,21 @@ public class Sha1Tests public void WhenSha1WithLowerCase_ThenParsedCorrectly() { const string value = "2695effb5807a22ff3d138d593fd856244e155e7"; - Assert.AreEqual(value.ToUpperInvariant(), new Sha1(value).ToString().ToUpperInvariant()); + Assert.That(new Sha1(value).ToString().ToUpperInvariant(), Is.EqualTo(value.ToUpperInvariant())); } [Test] public void WhenSha1WithLeadingZero_ThenParsedCorrectly() { const string value = "59529D73E3E6E2B7015F05D197E12C43B13BA033"; - Assert.AreEqual(value.ToUpperInvariant(), new Sha1(value).ToString().ToUpperInvariant()); + Assert.That(new Sha1(value).ToString().ToUpperInvariant(), Is.EqualTo(value.ToUpperInvariant())); } [Test] public void WhenSha1WithUpperCase_ThenParsedCorrectly() { const string value = "2695EFFB5807A22FF3D138D593FD856244E155E7"; - Assert.AreEqual(value, new Sha1(value).ToString().ToUpperInvariant()); + Assert.That(new Sha1(value).ToString().ToUpperInvariant(), Is.EqualTo(value)); } [Test] diff --git a/NGitLab.Tests/SnippetsTest.cs b/NGitLab.Tests/SnippetsTest.cs index 8ee5c9bc..fda08b78 100644 --- a/NGitLab.Tests/SnippetsTest.cs +++ b/NGitLab.Tests/SnippetsTest.cs @@ -39,11 +39,11 @@ public async Task Test_snippet_public() var returnedUserSnippet = snippetClient.All.First(s => string.Equals(s.Title, snippetName, StringComparison.Ordinal)); - Assert.IsNotNull(returnedUserSnippet.Files); - Assert.AreEqual(2, returnedUserSnippet.Files.Length); + Assert.That(returnedUserSnippet.Files, Is.Not.Null); + Assert.That(returnedUserSnippet.Files, Has.Length.EqualTo(2)); - Assert.IsNotNull(returnedUserSnippet.Files[0]); - Assert.IsTrue(string.Equals(returnedUserSnippet.Files[0].Path, "Path1.txt", StringComparison.Ordinal)); + Assert.That(returnedUserSnippet.Files[0], Is.Not.Null); + Assert.That(string.Equals(returnedUserSnippet.Files[0].Path, "Path1.txt", StringComparison.Ordinal), Is.True); var updatedSnippet = new SnippetUpdate { @@ -61,8 +61,8 @@ public async Task Test_snippet_public() var returnedProjectSnippetAfterUpdate = snippetClient.User.First(s => string.Equals(s.Title, snippetName, StringComparison.Ordinal)); - Assert.AreEqual(1, returnedProjectSnippetAfterUpdate.Files.Length); - Assert.AreEqual("rename.md", returnedProjectSnippetAfterUpdate.Files[0].Path); + Assert.That(returnedProjectSnippetAfterUpdate.Files, Has.Length.EqualTo(1)); + Assert.That(returnedProjectSnippetAfterUpdate.Files[0].Path, Is.EqualTo("rename.md")); snippetClient.Delete(returnedUserSnippet.Id); } @@ -103,11 +103,11 @@ public async Task Test_snippet_inProject(VisibilityLevel visibility) Assert.That(snippetClient.Get(newSnippet.ProjectId, returnedProjectSnippet.Id), Is.Not.Null); - Assert.IsNotNull(returnedProjectSnippet.Files); - Assert.AreEqual(2, returnedProjectSnippet.Files.Length); + Assert.That(returnedProjectSnippet.Files, Is.Not.Null); + Assert.That(returnedProjectSnippet.Files, Has.Length.EqualTo(2)); - Assert.IsNotNull(returnedProjectSnippet.Files[0]); - Assert.IsTrue(string.Equals(returnedProjectSnippet.Files[0].Path, "Path1.txt", StringComparison.Ordinal)); + Assert.That(returnedProjectSnippet.Files[0], Is.Not.Null); + Assert.That(string.Equals(returnedProjectSnippet.Files[0].Path, "Path1.txt", StringComparison.Ordinal), Is.True); var updatedSnippet = new SnippetProjectUpdate { @@ -126,8 +126,8 @@ public async Task Test_snippet_inProject(VisibilityLevel visibility) var returnedProjectSnippetAfterUpdate = snippetClient.User.First(s => string.Equals(s.Title, projectSnippetName, StringComparison.Ordinal)); - Assert.AreEqual(1, returnedProjectSnippetAfterUpdate.Files.Length); - Assert.AreEqual("rename.md", returnedProjectSnippetAfterUpdate.Files[0].Path); + Assert.That(returnedProjectSnippetAfterUpdate.Files, Has.Length.EqualTo(1)); + Assert.That(returnedProjectSnippetAfterUpdate.Files[0].Path, Is.EqualTo("rename.md")); snippetClient.Delete(newSnippet.ProjectId, returnedProjectSnippet.Id); } diff --git a/NGitLab.Tests/TagTests.cs b/NGitLab.Tests/TagTests.cs index 23d88348..daf08b3a 100644 --- a/NGitLab.Tests/TagTests.cs +++ b/NGitLab.Tests/TagTests.cs @@ -25,12 +25,12 @@ public async Task Test_can_tag_a_project() Ref = project.DefaultBranch, }); - Assert.IsNotNull(result); - Assert.IsNotNull(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "v0.5", StringComparison.Ordinal))); - Assert.IsNotNull(tagsClient.All.FirstOrDefault(x => string.Equals(x.Message, "Test message", StringComparison.Ordinal))); + Assert.That(result, Is.Not.Null); + Assert.That(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "v0.5", StringComparison.Ordinal)), Is.Not.Null); + Assert.That(tagsClient.All.FirstOrDefault(x => string.Equals(x.Message, "Test message", StringComparison.Ordinal)), Is.Not.Null); tagsClient.Delete("v0.5"); - Assert.IsNull(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "v0.5", StringComparison.Ordinal))); + Assert.That(tagsClient.All.FirstOrDefault(x => string.Equals(x.Name, "v0.5", StringComparison.Ordinal)), Is.Null); } [NGitLabRetry] @@ -49,18 +49,18 @@ public async Task GetTag(string tagNameSought, bool expectExistence) Message = "Test message", Ref = project.DefaultBranch, }); - Assert.IsNotNull(tagCreated); + Assert.That(tagCreated, Is.Not.Null); // Act/Assert if (expectExistence) { var tagFetched = await tagClient.GetByNameAsync(tagNameSought); - Assert.IsNotNull(tagFetched); + Assert.That(tagFetched, Is.Not.Null); } else { var ex = Assert.ThrowsAsync(() => tagClient.GetByNameAsync(tagNameSought)); - Assert.AreEqual(HttpStatusCode.NotFound, ex.StatusCode); + Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); } } } diff --git a/NGitLab.Tests/TriggerTests.cs b/NGitLab.Tests/TriggerTests.cs index 70b06faf..79b5c309 100644 --- a/NGitLab.Tests/TriggerTests.cs +++ b/NGitLab.Tests/TriggerTests.cs @@ -19,12 +19,12 @@ public async Task Test_can_get_triggers_for_project() var createdTrigger = triggersClient.Create("Unit_Test_Description"); var trigger = triggersClient[createdTrigger.Id]; - Assert.AreEqual("Unit_Test_Description", trigger.Description); + Assert.That(trigger.Description, Is.EqualTo("Unit_Test_Description")); var triggers = triggersClient.All.Take(10).ToArray(); - Assert.IsNotNull(triggers); - Assert.IsNotEmpty(triggers); + Assert.That(triggers, Is.Not.Null); + Assert.That(triggers, Is.Not.Empty); } } } diff --git a/NGitLab.Tests/UsersTests.cs b/NGitLab.Tests/UsersTests.cs index 4cd4460a..f5fb8851 100644 --- a/NGitLab.Tests/UsersTests.cs +++ b/NGitLab.Tests/UsersTests.cs @@ -19,7 +19,7 @@ public async Task GetUsers() { using var context = await GitLabTestContext.CreateAsync(); var users = context.Client.Users.All.Take(100).ToArray(); // We don't want to enumerate all users - CollectionAssert.IsNotEmpty(users); + Assert.That(users, Is.Not.Empty); } [Test] @@ -30,7 +30,7 @@ public async Task GetUser() var current = context.Client.Users.Current; var user = context.Client.Users[current.Id]; - Assert.IsNotNull(user); + Assert.That(user, Is.Not.Null); Assert.That(user.Username, Is.EqualTo(current.Username)); } @@ -111,17 +111,17 @@ public async Task Test_can_add_an_ssh_key_to_the_gitlab_profile() Title = "test key", }); - Assert.IsNotNull(result); - StringAssert.StartsWith(generatedKey.PublicKey, result.Key); + Assert.That(result, Is.Not.Null); + Assert.That(result.Key, Does.StartWith(generatedKey.PublicKey)); var newKey = keys.All.FirstOrDefault(k => k.Id == result.Id); - Assert.IsNotNull(newKey); - Assert.AreEqual(result.Key, newKey.Key); + Assert.That(newKey, Is.Not.Null); + Assert.That(newKey.Key, Is.EqualTo(result.Key)); keys.Remove(result.Id); - Assert.IsNull(keys.All.FirstOrDefault(k => k.Id == result.Id)); + Assert.That(keys.All.FirstOrDefault(k => k.Id == result.Id), Is.Null); } [Test] @@ -141,8 +141,8 @@ public async Task CreateTokenAsAdmin_ReturnsUserToken() var tokenResult = users.CreateToken(tokenRequest); - Assert.IsNotEmpty(tokenResult.Token); - Assert.AreEqual(tokenRequest.Name, tokenResult.Name); + Assert.That(tokenResult.Token, Is.Not.Empty); + Assert.That(tokenResult.Name, Is.EqualTo(tokenRequest.Name)); } [Test] @@ -151,7 +151,7 @@ public async Task GetLastActivityDates() { using var context = await GitLabTestContext.CreateAsync(); var activities = context.AdminClient.Users.GetLastActivityDatesAsync().ToArray(); - CollectionAssert.IsNotEmpty(activities.Where(a => string.Equals(a.Username, context.AdminClient.Users.Current.Username, StringComparison.Ordinal))); + Assert.That(activities.Where(a => string.Equals(a.Username, context.AdminClient.Users.Current.Username, StringComparison.Ordinal)), Is.Not.Empty); } [Test] @@ -161,7 +161,7 @@ public async Task GetLastActivityDatesSinceYesterday() using var context = await GitLabTestContext.CreateAsync(); var yesterday = DateTimeOffset.UtcNow.AddDays(-1); var activities = context.AdminClient.Users.GetLastActivityDatesAsync(from: yesterday).ToArray(); - CollectionAssert.IsNotEmpty(activities); + Assert.That(activities, Is.Not.Empty); } [Test] @@ -171,7 +171,7 @@ public async Task GetLastActivityDatesFromTheFuture() using var context = await GitLabTestContext.CreateAsync(); var tomorrow = DateTimeOffset.UtcNow.AddDays(1); var activities = context.AdminClient.Users.GetLastActivityDatesAsync(from: tomorrow).ToArray(); - CollectionAssert.IsEmpty(activities); + Assert.That(activities, Is.Empty); } [Test] @@ -179,7 +179,7 @@ public async Task GetLastActivityDates_UsingNonAdminCredentials_ThrowsForbidden( { using var context = await GitLabTestContext.CreateAsync(); var exception = Assert.Throws(() => context.Client.Users.GetLastActivityDatesAsync().ToArray()); - Assert.AreEqual(HttpStatusCode.Forbidden, exception.StatusCode); + Assert.That(exception.StatusCode, Is.EqualTo(HttpStatusCode.Forbidden)); } private static User CreateNewUser(GitLabTestContext context) From 329c3dbac75a7eb916a683d3cbb74f18ab2c8af3 Mon Sep 17 00:00:00 2001 From: Louis Zanella Date: Thu, 21 Dec 2023 11:32:12 -0500 Subject: [PATCH 069/122] Use file-scoped namespaces (#604) --- .editorconfig | 2 +- BannedSymbols.txt | 2 +- NGitLab.Mock.Tests/BotUserTests.cs | 57 +- NGitLab.Mock.Tests/BranchesMockTests.cs | 67 +- NGitLab.Mock.Tests/CommitsMockTests.cs | 227 +- NGitLab.Mock.Tests/ConfigTests.cs | 233 +- NGitLab.Mock.Tests/GroupsMockTests.cs | 123 +- NGitLab.Mock.Tests/IssuesMockTests.cs | 207 +- NGitLab.Mock.Tests/LabelsMockTests.cs | 237 +- NGitLab.Mock.Tests/MembersMockTests.cs | 133 +- NGitLab.Mock.Tests/MergeRequestsMockTests.cs | 699 ++-- NGitLab.Mock.Tests/MilestonesMockTests.cs | 269 +- NGitLab.Mock.Tests/PipelineTests.cs | 177 +- NGitLab.Mock.Tests/ProjectsMockTests.cs | 335 +- NGitLab.Mock.Tests/ReleasesMockTests.cs | 155 +- NGitLab.Mock.Tests/TagTests.cs | 39 +- NGitLab.Mock/Badge.cs | 39 +- NGitLab.Mock/BadgeCollection.cs | 63 +- NGitLab.Mock/Change.cs | 47 +- NGitLab.Mock/Clients/AdvancedSearchClient.cs | 23 +- NGitLab.Mock/Clients/BranchClient.cs | 171 +- NGitLab.Mock/Clients/ClientBase.cs | 275 +- NGitLab.Mock/Clients/ClientContext.cs | 53 +- NGitLab.Mock/Clients/ClusterClient.cs | 21 +- NGitLab.Mock/Clients/CommitClient.cs | 85 +- NGitLab.Mock/Clients/CommitStatusClient.cs | 85 +- NGitLab.Mock/Clients/ContributorClient.cs | 51 +- NGitLab.Mock/Clients/EnvironmentClient.cs | 93 +- NGitLab.Mock/Clients/EventClient.cs | 39 +- NGitLab.Mock/Clients/FileClient.cs | 169 +- .../Clients/GitLabBadRequestException.cs | 49 +- NGitLab.Mock/Clients/GitLabClient.cs | 165 +- .../Clients/GitLabForbiddenException.cs | 49 +- .../Clients/GitLabNotFoundException.cs | 49 +- NGitLab.Mock/Clients/GlobalJobsClient.cs | 29 +- NGitLab.Mock/Clients/GraphQLClient.cs | 19 +- NGitLab.Mock/Clients/GroupBadgeClient.cs | 111 +- NGitLab.Mock/Clients/GroupClient.cs | 513 ++- NGitLab.Mock/Clients/GroupSearchClient.cs | 29 +- NGitLab.Mock/Clients/GroupVariableClient.cs | 45 +- NGitLab.Mock/Clients/ICommitActionHandler.cs | 9 +- NGitLab.Mock/Clients/IssueClient.cs | 651 ++-- NGitLab.Mock/Clients/JobClient.cs | 209 +- NGitLab.Mock/Clients/LabelClient.cs | 283 +- .../Clients/LibGit2SharpExtensions.cs | 141 +- NGitLab.Mock/Clients/LintClient.cs | 51 +- NGitLab.Mock/Clients/MembersClient.cs | 217 +- .../Clients/MergeRequestApprovalClient.cs | 39 +- .../Clients/MergeRequestChangeClient.cs | 39 +- NGitLab.Mock/Clients/MergeRequestClient.cs | 1083 +++--- .../Clients/MergeRequestCommentClient.cs | 173 +- .../Clients/MergeRequestCommitClient.cs | 35 +- .../Clients/MergeRequestDiscussionClient.cs | 165 +- NGitLab.Mock/Clients/MilestoneClient.cs | 327 +- NGitLab.Mock/Clients/NamespacesClient.cs | 25 +- NGitLab.Mock/Clients/PipelineClient.cs | 429 ++- NGitLab.Mock/Clients/ProjectBadgeClient.cs | 125 +- NGitLab.Mock/Clients/ProjectClient.cs | 535 ++- NGitLab.Mock/Clients/ProjectHooksClient.cs | 141 +- .../Clients/ProjectIssueNoteClient.cs | 115 +- .../ProjectLevelApprovalRulesClient.cs | 49 +- NGitLab.Mock/Clients/ProjectSearchClient.cs | 29 +- NGitLab.Mock/Clients/ProjectVariableClient.cs | 45 +- NGitLab.Mock/Clients/ProtectedBranchClient.cs | 89 +- NGitLab.Mock/Clients/ReleaseClient.cs | 187 +- NGitLab.Mock/Clients/ReleaseLinkClient.cs | 59 +- NGitLab.Mock/Clients/RepositoryClient.cs | 171 +- NGitLab.Mock/Clients/RunnerClient.cs | 263 +- NGitLab.Mock/Clients/SnippetClient.cs | 87 +- NGitLab.Mock/Clients/SystemHookClient.cs | 107 +- NGitLab.Mock/Clients/TagClient.cs | 127 +- NGitLab.Mock/Clients/TriggerClient.cs | 29 +- NGitLab.Mock/Clients/UserClient.cs | 231 +- NGitLab.Mock/Clients/VersionClient.cs | 19 +- NGitLab.Mock/Clients/WikiClient.cs | 45 +- NGitLab.Mock/Collection.cs | 117 +- NGitLab.Mock/CommitAction.cs | 17 +- NGitLab.Mock/CommitActionCreateHandler.cs | 41 +- NGitLab.Mock/CommitActionDeleteHandler.cs | 21 +- NGitLab.Mock/CommitActionMoveHandler.cs | 25 +- NGitLab.Mock/CommitActionUpdateHandler.cs | 41 +- NGitLab.Mock/CommitInfo.cs | 11 +- NGitLab.Mock/CommitInfoCollection.cs | 33 +- NGitLab.Mock/CommitStatus.cs | 67 +- NGitLab.Mock/CommitStatusCollection.cs | 11 +- NGitLab.Mock/Config/ConfigSerializer.cs | 591 ++- NGitLab.Mock/Config/GitLabCollection.cs | 75 +- NGitLab.Mock/Config/GitLabComment.cs | 71 +- NGitLab.Mock/Config/GitLabCommit.cs | 105 +- NGitLab.Mock/Config/GitLabConfig.cs | 103 +- NGitLab.Mock/Config/GitLabFileDescriptor.cs | 25 +- NGitLab.Mock/Config/GitLabGroup.cs | 59 +- NGitLab.Mock/Config/GitLabHelpers.cs | 3317 ++++++++--------- NGitLab.Mock/Config/GitLabIssue.cs | 79 +- NGitLab.Mock/Config/GitLabJob.cs | 75 +- NGitLab.Mock/Config/GitLabLabel.cs | 39 +- NGitLab.Mock/Config/GitLabMergeRequest.cs | 87 +- NGitLab.Mock/Config/GitLabMilestone.cs | 83 +- NGitLab.Mock/Config/GitLabObject.cs | 37 +- NGitLab.Mock/Config/GitLabPermission.cs | 51 +- NGitLab.Mock/Config/GitLabPipeline.cs | 81 +- NGitLab.Mock/Config/GitLabProject.cs | 93 +- NGitLab.Mock/Config/GitLabReleaseInfo.cs | 35 +- .../Config/GitLabSubModuleDescriptor.cs | 17 +- NGitLab.Mock/Config/GitLabUser.cs | 35 +- NGitLab.Mock/EffectivePermissions.cs | 29 +- NGitLab.Mock/EffectiveUserPermission.cs | 39 +- NGitLab.Mock/Event.cs | 67 +- NGitLab.Mock/EventCollection.cs | 101 +- NGitLab.Mock/File.cs | 33 +- NGitLab.Mock/GitLabClientMockExtensions.cs | 17 +- NGitLab.Mock/GitLabObject.cs | 11 +- NGitLab.Mock/GitLabServer.cs | 205 +- NGitLab.Mock/Group.cs | 381 +- NGitLab.Mock/GroupCollection.cs | 31 +- NGitLab.Mock/GroupExtensions.cs | 31 +- NGitLab.Mock/Internals/DateTimeExtensions.cs | 15 +- .../Internals/GitLabCollectionResponse.cs | 39 +- NGitLab.Mock/Internals/TemporaryDirectory.cs | 373 +- NGitLab.Mock/Issue.cs | 137 +- NGitLab.Mock/IssueCollection.cs | 59 +- NGitLab.Mock/IssueState.cs | 11 +- NGitLab.Mock/Job.cs | 237 +- NGitLab.Mock/JobCollection.cs | 79 +- NGitLab.Mock/Label.cs | 33 +- NGitLab.Mock/LabelsCollection.cs | 91 +- NGitLab.Mock/MergeRequest.cs | 551 ++- NGitLab.Mock/MergeRequestChangeCollection.cs | 53 +- NGitLab.Mock/MergeRequestCollection.cs | 141 +- NGitLab.Mock/MergeRequestComment.cs | 41 +- NGitLab.Mock/Milestone.cs | 95 +- NGitLab.Mock/MilestoneCollection.cs | 59 +- NGitLab.Mock/MilestoneState.cs | 11 +- NGitLab.Mock/Note.cs | 67 +- NGitLab.Mock/NoteCollection.cs | 49 +- NGitLab.Mock/ObjectNotAttachedException.cs | 11 +- NGitLab.Mock/Permission.cs | 31 +- NGitLab.Mock/PermissionCollection.cs | 11 +- NGitLab.Mock/Pipeline.cs | 219 +- NGitLab.Mock/PipelineCollection.cs | 91 +- NGitLab.Mock/Project.cs | 715 ++-- NGitLab.Mock/ProjectCollection.cs | 55 +- NGitLab.Mock/ProjectExtensions.cs | 31 +- NGitLab.Mock/ProjectHook.cs | 67 +- NGitLab.Mock/ProjectHookCollection.cs | 39 +- NGitLab.Mock/ProjectIssueNote.cs | 39 +- NGitLab.Mock/ProtectedBranch.cs | 39 +- NGitLab.Mock/ProtectedBranchCollection.cs | 45 +- NGitLab.Mock/ReleaseCollection.cs | 101 +- NGitLab.Mock/ReleaseInfo.cs | 61 +- NGitLab.Mock/ReleaseTag.cs | 19 +- NGitLab.Mock/Repository.cs | 1115 +++--- NGitLab.Mock/ResourceLabelEvent.cs | 43 +- NGitLab.Mock/ResourceLabelEventCollection.cs | 145 +- NGitLab.Mock/ResourceMilestoneEvent.cs | 43 +- .../ResourceMilestoneEventCollection.cs | 115 +- NGitLab.Mock/ResourceStateEvent.cs | 39 +- NGitLab.Mock/ResourceStateEventCollection.cs | 95 +- NGitLab.Mock/Runner.cs | 75 +- NGitLab.Mock/RunnerCollection.cs | 47 +- NGitLab.Mock/RunnerRef.cs | 35 +- NGitLab.Mock/RunnerRefCollection.cs | 11 +- NGitLab.Mock/Slug.cs | 47 +- NGitLab.Mock/StateEvent.cs | 11 +- NGitLab.Mock/StringExtensions.cs | 11 +- NGitLab.Mock/SystemHook.cs | 47 +- NGitLab.Mock/SystemHookCollection.cs | 39 +- NGitLab.Mock/TextFile.cs | 31 +- NGitLab.Mock/User.cs | 123 +- NGitLab.Mock/UserCollection.cs | 167 +- NGitLab.Mock/UserRef.cs | 99 +- NGitLab.Mock/UserState.cs | 13 +- NGitLab.Tests/APITests.cs | 25 +- NGitLab.Tests/AsyncApiValidation.cs | 73 +- NGitLab.Tests/BranchClientTests.cs | 151 +- NGitLab.Tests/CommitStatusTests.cs | 299 +- NGitLab.Tests/CommitsTests.cs | 185 +- NGitLab.Tests/CompareTests.cs | 101 +- NGitLab.Tests/ContributorsTests.cs | 107 +- NGitLab.Tests/Docker/GitLabCredential.cs | 15 +- NGitLab.Tests/Docker/GitLabDockerContainer.cs | 653 ++-- NGitLab.Tests/Docker/GitLabTestContext.cs | 671 ++-- .../Docker/GitLabTestContextRequestOptions.cs | 551 ++- NGitLab.Tests/Docker/NGitLabRetryAttribute.cs | 73 +- NGitLab.Tests/EnvironmentsTests.cs | 513 ++- NGitLab.Tests/EventTests.cs | 53 +- .../FunctionRetryExtensionsTests.cs | 63 +- NGitLab.Tests/FilesTests.cs | 455 ++- NGitLab.Tests/GitLabChangeDiffCounterTests.cs | 63 +- NGitLab.Tests/GitLabCredentialsTests.cs | 33 +- NGitLab.Tests/GraphQLTests.cs | 79 +- NGitLab.Tests/GroupBadgeClientTests.cs | 87 +- NGitLab.Tests/GroupVariableClientTests.cs | 89 +- NGitLab.Tests/GroupsTests.cs | 1557 ++++---- NGitLab.Tests/HttpRequestorTests.cs | 257 +- NGitLab.Tests/Impl/DynamicEnumTests.cs | 29 +- NGitLab.Tests/Impl/JsonConverterTests.cs | 141 +- NGitLab.Tests/Impl/SimpleJsonTests.cs | 91 +- NGitLab.Tests/IssueTests.cs | 567 ++- NGitLab.Tests/JobTests.cs | 371 +- NGitLab.Tests/JsonTests.cs | 107 +- NGitLab.Tests/LintClientTests.cs | 143 +- NGitLab.Tests/MembersClientTests.cs | 269 +- .../MergeRequestChangesClientTests.cs | 43 +- .../MergeRequest/MergeRequestClientTests.cs | 663 ++-- .../MergeRequestCommentsClientTests.cs | 131 +- .../MergeRequestDiscussionsClientTests.cs | 277 +- .../Milestone/MilestoneClientTests.cs | 327 +- NGitLab.Tests/NamespacesTests.cs | 101 +- NGitLab.Tests/PipelineTests.cs | 399 +- NGitLab.Tests/ProjectBadgeClientTests.cs | 101 +- NGitLab.Tests/ProjectIssueNoteTests.cs | 103 +- .../ProjectLevelApprovalRulesClientTests.cs | 171 +- NGitLab.Tests/ProjectVariableClientTests.cs | 89 +- NGitLab.Tests/ProjectsTests.cs | 787 ++-- NGitLab.Tests/ProtectedBranchTests.cs | 93 +- NGitLab.Tests/ProtectedTagTests.cs | 91 +- NGitLab.Tests/ReleaseClientTests.cs | 191 +- .../RepositoryClient/BranchClientTests.cs | 143 +- .../ProjectHooksClientTests.cs | 119 +- .../RepositoryClient/RepositoryClientTests.cs | 531 ++- NGitLab.Tests/RunnerTests.cs | 121 +- NGitLab.Tests/SetUpFixture.cs | 15 +- NGitLab.Tests/Sha1Tests.cs | 63 +- NGitLab.Tests/SnippetsTest.cs | 207 +- NGitLab.Tests/TagTests.cs | 93 +- NGitLab.Tests/TriggerTests.cs | 33 +- NGitLab.Tests/UsersTests.cs | 419 ++- NGitLab.Tests/Utils.cs | 35 +- NGitLab.Tests/WikiTests.cs | 89 +- NGitLab/DynamicEnum.cs | 99 +- NGitLab/Extensions/FunctionRetryExtensions.cs | 93 +- NGitLab/Extensions/NumberExtensions.cs | 289 +- NGitLab/GetCommitsRequest.cs | 23 +- NGitLab/GitLabClient.cs | 339 +- NGitLab/GitLabException.cs | 101 +- NGitLab/IBranchClient.cs | 23 +- NGitLab/IClusterClient.cs | 15 +- NGitLab/ICommitClient.cs | 51 +- NGitLab/ICommitStatusClient.cs | 11 +- NGitLab/IContributorClient.cs | 9 +- NGitLab/IDeploymentClient.cs | 35 +- NGitLab/IEnvironmentClient.cs | 103 +- NGitLab/IEpicClient.cs | 75 +- NGitLab/IEventClient.cs | 9 +- NGitLab/IFilesClient.cs | 21 +- NGitLab/IGitLabClient.cs | 211 +- NGitLab/IGlobalJobClient.cs | 9 +- NGitLab/IGraphQlClient.cs | 9 +- NGitLab/IGroupBadgeClient.cs | 17 +- NGitLab/IGroupsClient.cs | 69 +- NGitLab/IHttpRequestor.cs | 25 +- NGitLab/IIssueClient.cs | 353 +- NGitLab/IJobClient.cs | 31 +- NGitLab/ILabelClient.cs | 181 +- NGitLab/ILintClient.cs | 17 +- NGitLab/IMembersClient.cs | 39 +- NGitLab/IMergeRequestApprovalClient.cs | 13 +- NGitLab/IMergeRequestChangeClient.cs | 9 +- NGitLab/IMergeRequestClient.cs | 131 +- NGitLab/IMergeRequestCommentClient.cs | 23 +- NGitLab/IMergeRequestCommitClient.cs | 9 +- NGitLab/IMergeRequestDiscussionClient.cs | 19 +- NGitLab/IMilestoneClient.cs | 29 +- NGitLab/INamespacesClient.cs | 33 +- NGitLab/IPipelineClient.cs | 225 +- NGitLab/IProjectBadgeClient.cs | 59 +- NGitLab/IProjectClient.cs | 87 +- NGitLab/IProjectHooksClient.cs | 17 +- NGitLab/IProjectIssueNoteClient.cs | 55 +- NGitLab/IProjectLevelApprovalRulesClient.cs | 53 +- NGitLab/IProtectedBranchClient.cs | 15 +- NGitLab/IProtectedTagClient.cs | 23 +- NGitLab/IReleaseClient.cs | 23 +- NGitLab/IReleaseLinkClient.cs | 17 +- NGitLab/IRepositoryClient.cs | 63 +- NGitLab/IRunnerClient.cs | 179 +- NGitLab/ISearchClient.cs | 9 +- NGitLab/ISnippetClient.cs | 109 +- NGitLab/ISshKeyClient.cs | 15 +- NGitLab/ISystemHookClient.cs | 15 +- NGitLab/ITagClient.cs | 17 +- NGitLab/ITriggerClient.cs | 37 +- NGitLab/IUserClient.cs | 141 +- NGitLab/IVersionClient.cs | 9 +- NGitLab/IWikiClient.cs | 17 +- NGitLab/Impl/API.cs | 99 +- NGitLab/Impl/BadgeClient.cs | 31 +- NGitLab/Impl/BranchClient.cs | 41 +- NGitLab/Impl/ClusterClient.cs | 33 +- NGitLab/Impl/CommitClient.cs | 87 +- NGitLab/Impl/CommitStatusClient.cs | 41 +- NGitLab/Impl/ContributorClient.cs | 39 +- NGitLab/Impl/DeploymentClient.cs | 65 +- NGitLab/Impl/DiffStats.cs | 11 +- NGitLab/Impl/EnvironmentClient.cs | 117 +- NGitLab/Impl/EpicClient.cs | 103 +- NGitLab/Impl/EventClient.cs | 43 +- NGitLab/Impl/FilesClient.cs | 91 +- NGitLab/Impl/GitDiffChangeCounter.cs | 43 +- NGitLab/Impl/GitLabCollectionResponse.cs | 13 +- NGitLab/Impl/GitLabCredentials.cs | 125 +- NGitLab/Impl/GlobalJobsClient.cs | 27 +- NGitLab/Impl/GraphQLClient.cs | 63 +- NGitLab/Impl/GroupBadgeClient.cs | 11 +- NGitLab/Impl/GroupVariableClient.cs | 11 +- NGitLab/Impl/GroupsClient.cs | 299 +- NGitLab/Impl/HttpRequestor.GitLabRequest.cs | 367 +- NGitLab/Impl/HttpRequestor.cs | 313 +- NGitLab/Impl/IGitDiffChangeCounter.cs | 9 +- NGitLab/Impl/IssueClient.cs | 351 +- NGitLab/Impl/JobClient.cs | 195 +- NGitLab/Impl/Json/BooleanConverter.cs | 23 +- NGitLab/Impl/Json/DateTimeConverter.cs | 209 +- NGitLab/Impl/Json/DoubleConverter.cs | 33 +- .../Impl/Json/DynamicEnumConverterFactory.cs | 137 +- NGitLab/Impl/Json/EnumConverterFactory.cs | 105 +- NGitLab/Impl/Json/Int32Converter.cs | 51 +- NGitLab/Impl/Json/Int64Converter.cs | 41 +- NGitLab/Impl/Json/ReflectionExtensions.cs | 73 +- NGitLab/Impl/Json/Serializer.cs | 75 +- NGitLab/Impl/Json/Sha1Converter.cs | 25 +- NGitLab/Impl/LabelClient.cs | 199 +- NGitLab/Impl/LintClient.cs | 57 +- NGitLab/Impl/MembersClient.cs | 129 +- NGitLab/Impl/MergeRequestApprovalClient.cs | 47 +- NGitLab/Impl/MergeRequestChangeClient.cs | 33 +- NGitLab/Impl/MergeRequestClient.cs | 291 +- NGitLab/Impl/MergeRequestCommentClient.cs | 53 +- NGitLab/Impl/MergeRequestCommitClient.cs | 23 +- NGitLab/Impl/MergeRequestDiscussionClient.cs | 33 +- NGitLab/Impl/MethodType.cs | 23 +- NGitLab/Impl/MilestoneClient.cs | 89 +- NGitLab/Impl/MilestoneScope.cs | 11 +- NGitLab/Impl/NamespacesClient.cs | 31 +- NGitLab/Impl/PipelineClient.cs | 349 +- NGitLab/Impl/ProjectBadgeClient.cs | 17 +- NGitLab/Impl/ProjectClient.cs | 315 +- NGitLab/Impl/ProjectHooksClient.cs | 35 +- NGitLab/Impl/ProjectIssueNoteClient.cs | 77 +- .../Impl/ProjectLevelApprovalRulesClient.cs | 71 +- NGitLab/Impl/ProjectVariableClient.cs | 11 +- NGitLab/Impl/ProtectedBranchClient.cs | 37 +- NGitLab/Impl/ProtectedTagClient.cs | 101 +- NGitLab/Impl/ReleaseClient.cs | 63 +- NGitLab/Impl/ReleaseLinkClient.cs | 35 +- NGitLab/Impl/RepositoryClient.cs | 197 +- NGitLab/Impl/RunnerClient.cs | 153 +- NGitLab/Impl/SearchClient.cs | 93 +- NGitLab/Impl/SnippetClient.cs | 81 +- NGitLab/Impl/SshKeyClient.cs | 39 +- NGitLab/Impl/SystemHookClient.cs | 33 +- NGitLab/Impl/TagClient.cs | 65 +- NGitLab/Impl/TriggerClient.cs | 41 +- NGitLab/Impl/UserClient.cs | 171 +- NGitLab/Impl/Utils.cs | 93 +- NGitLab/Impl/VariableClient.cs | 31 +- NGitLab/Impl/VersionClient.cs | 19 +- NGitLab/Impl/WikiClient.cs | 75 +- NGitLab/Models/AccessControl.cs | 37 +- NGitLab/Models/AccessLevel.cs | 37 +- NGitLab/Models/AccessLevelInfo.cs | 15 +- NGitLab/Models/ApprovalRule.cs | 61 +- NGitLab/Models/ApprovalRuleCreate.cs | 93 +- NGitLab/Models/ApprovalRuleUpdate.cs | 93 +- NGitLab/Models/Assignee.cs | 35 +- NGitLab/Models/Author.cs | 39 +- NGitLab/Models/Badge.cs | 31 +- NGitLab/Models/BadgeCreate.cs | 15 +- NGitLab/Models/BadgeKind.cs | 11 +- NGitLab/Models/BadgeUpdate.cs | 15 +- NGitLab/Models/Blame.cs | 49 +- NGitLab/Models/BlameCommit.cs | 109 +- NGitLab/Models/Blob.cs | 23 +- NGitLab/Models/Branch.cs | 39 +- NGitLab/Models/BranchCreate.cs | 15 +- NGitLab/Models/BranchProtect.cs | 49 +- NGitLab/Models/Bridge.cs | 11 +- NGitLab/Models/BuildStatus.cs | 47 +- NGitLab/Models/Change.cs | 39 +- NGitLab/Models/ClusterInfo.cs | 23 +- NGitLab/Models/Commit.cs | 73 +- NGitLab/Models/CommitCherryPick.cs | 23 +- NGitLab/Models/CommitCreate.cs | 71 +- NGitLab/Models/CommitInfo.cs | 59 +- NGitLab/Models/CommitRefType.cs | 21 +- NGitLab/Models/CommitStats.cs | 19 +- NGitLab/Models/CommitStatus.cs | 51 +- NGitLab/Models/CommitStatusCreate.cs | 51 +- NGitLab/Models/CompareQuery.cs | 33 +- NGitLab/Models/CompareResults.cs | 27 +- NGitLab/Models/Contributor.cs | 29 +- NGitLab/Models/Deployment.cs | 37 +- NGitLab/Models/DeploymentQuery.cs | 57 +- NGitLab/Models/DeploymentStatus.cs | 17 +- NGitLab/Models/Diff.cs | 39 +- NGitLab/Models/DiffRefs.cs | 19 +- NGitLab/Models/EnvironmentInfo.cs | 31 +- NGitLab/Models/EnvironmentLastDeployment.cs | 43 +- NGitLab/Models/EnvironmentQuery.cs | 31 +- NGitLab/Models/Epic.cs | 47 +- NGitLab/Models/EpicCreate.cs | 19 +- NGitLab/Models/EpicEdit.cs | 37 +- NGitLab/Models/EpicQuery.cs | 99 +- NGitLab/Models/EpicState.cs | 11 +- NGitLab/Models/Event.cs | 137 +- NGitLab/Models/EventAction.cs | 51 +- NGitLab/Models/EventQuery.cs | 77 +- NGitLab/Models/EventTargetType.cs | 33 +- NGitLab/Models/FileData.cs | 69 +- NGitLab/Models/FileDelete.cs | 25 +- NGitLab/Models/FileUpsert.cs | 61 +- NGitLab/Models/ForkProject.cs | 37 +- NGitLab/Models/ForkedProjectQuery.cs | 111 +- NGitLab/Models/FormDataContent.cs | 31 +- NGitLab/Models/GraphQLQuery.cs | 19 +- NGitLab/Models/Group.cs | 69 +- NGitLab/Models/GroupCreate.cs | 47 +- NGitLab/Models/GroupId.cs | 47 +- NGitLab/Models/GroupLabelEdit.cs | 23 +- NGitLab/Models/GroupMemberCreate.cs | 19 +- NGitLab/Models/GroupMemberUpdate.cs | 19 +- NGitLab/Models/GroupProjectsQuery.cs | 127 +- NGitLab/Models/GroupQuery.cs | 119 +- NGitLab/Models/GroupUpdate.cs | 43 +- NGitLab/Models/GrouptLabelCreate.cs | 19 +- NGitLab/Models/IdOrPathExtensions.cs | 15 +- NGitLab/Models/Identity.cs | 19 +- NGitLab/Models/IidOrPathAddressable.cs | 11 +- NGitLab/Models/Issue.cs | 99 +- NGitLab/Models/IssueClone.cs | 15 +- NGitLab/Models/IssueCreate.cs | 57 +- NGitLab/Models/IssueEdit.cs | 61 +- NGitLab/Models/IssueEpic.cs | 27 +- NGitLab/Models/IssueQuery.cs | 169 +- NGitLab/Models/IssueState.cs | 11 +- NGitLab/Models/IssueType.cs | 13 +- NGitLab/Models/Job.cs | 75 +- NGitLab/Models/JobAction.cs | 15 +- NGitLab/Models/JobArtifactQuery.cs | 19 +- NGitLab/Models/JobBasic.cs | 103 +- NGitLab/Models/JobQuery.cs | 25 +- NGitLab/Models/JobScope.cs | 53 +- NGitLab/Models/Label.cs | 19 +- NGitLab/Models/LabelCreate.cs | 29 +- NGitLab/Models/LabelDelete.cs | 19 +- NGitLab/Models/LabelEdit.cs | 45 +- NGitLab/Models/LastActivityDate.cs | 15 +- NGitLab/Models/LintCI.cs | 25 +- NGitLab/Models/LintCIOptions.cs | 31 +- NGitLab/Models/Membership.cs | 95 +- NGitLab/Models/MergeRequestAccept.cs | 49 +- NGitLab/Models/MergeRequestApprovals.cs | 67 +- NGitLab/Models/MergeRequestApprove.cs | 27 +- NGitLab/Models/MergeRequestApprover.cs | 11 +- NGitLab/Models/MergeRequestChange.cs | 11 +- NGitLab/Models/MergeRequestComment.cs | 43 +- NGitLab/Models/MergeRequestCommentCreate.cs | 15 +- NGitLab/Models/MergeRequestCommentEdit.cs | 11 +- NGitLab/Models/MergeRequestCommentQuery.cs | 41 +- NGitLab/Models/MergeRequestCreate.cs | 59 +- NGitLab/Models/MergeRequestDiscussion.cs | 19 +- .../Models/MergeRequestDiscussionCreate.cs | 15 +- .../Models/MergeRequestDiscussionResolve.cs | 15 +- NGitLab/Models/MergeRequestMerge.cs | 57 +- NGitLab/Models/MergeRequestQuery.cs | 211 +- NGitLab/Models/MergeRequestRebase.cs | 17 +- NGitLab/Models/MergeRequestState.cs | 19 +- NGitLab/Models/MergeRequestUpdate.cs | 95 +- NGitLab/Models/MergeRequestUserInfo.cs | 11 +- NGitLab/Models/MergeRequestVersion.cs | 39 +- NGitLab/Models/Milestone.cs | 61 +- NGitLab/Models/MilestoneCreate.cs | 23 +- NGitLab/Models/MilestoneQuery.cs | 25 +- NGitLab/Models/MilestoneUpdate.cs | 45 +- NGitLab/Models/Namespace.cs | 43 +- NGitLab/Models/NamespaceCreate.cs | 23 +- NGitLab/Models/Note.cs | 55 +- NGitLab/Models/NoteableType.cs | 21 +- NGitLab/Models/ObjectType.cs | 17 +- NGitLab/Models/PersonInfo.cs | 15 +- NGitLab/Models/Pipeline.cs | 91 +- NGitLab/Models/PipelineBasic.cs | 45 +- NGitLab/Models/PipelineBridgeQuery.cs | 13 +- NGitLab/Models/PipelineCreate.cs | 17 +- NGitLab/Models/PipelineDetailedStatus.cs | 43 +- NGitLab/Models/PipelineJobQuery.cs | 17 +- NGitLab/Models/PipelineOrderBy.cs | 17 +- NGitLab/Models/PipelineQuery.cs | 31 +- NGitLab/Models/PipelineScope.cs | 17 +- NGitLab/Models/PipelineSort.cs | 11 +- NGitLab/Models/PipelineVariable.cs | 19 +- NGitLab/Models/Project.cs | 291 +- NGitLab/Models/ProjectCreate.cs | 109 +- NGitLab/Models/ProjectHook.cs | 59 +- NGitLab/Models/ProjectHookUpsert.cs | 49 +- NGitLab/Models/ProjectId.cs | 47 +- NGitLab/Models/ProjectIssueNote.cs | 55 +- NGitLab/Models/ProjectIssueNoteCreate.cs | 21 +- NGitLab/Models/ProjectIssueNoteEdit.cs | 21 +- NGitLab/Models/ProjectLabelCreate.cs | 19 +- NGitLab/Models/ProjectLabelDelete.cs | 15 +- NGitLab/Models/ProjectLabelEdit.cs | 23 +- NGitLab/Models/ProjectLinks.cs | 35 +- NGitLab/Models/ProjectMemberCreate.cs | 19 +- NGitLab/Models/ProjectMemberUpdate.cs | 19 +- NGitLab/Models/ProjectPermission.cs | 15 +- NGitLab/Models/ProjectPermissions.cs | 15 +- NGitLab/Models/ProjectQuery.cs | 183 +- NGitLab/Models/ProjectStatistics.cs | 27 +- NGitLab/Models/ProjectUpdate.cs | 139 +- NGitLab/Models/ProtectedBranch.cs | 31 +- NGitLab/Models/ProtectedTag.cs | 15 +- NGitLab/Models/PushData.cs | 27 +- NGitLab/Models/PushDataAction.cs | 13 +- NGitLab/Models/QueryAssigneeId.cs | 53 +- NGitLab/Models/RebaseResult.cs | 11 +- NGitLab/Models/Ref.cs | 15 +- NGitLab/Models/RelatedMergeRequestsQuery.cs | 17 +- NGitLab/Models/ReleaseAssetSource.cs | 15 +- NGitLab/Models/ReleaseAssetsInfo.cs | 19 +- NGitLab/Models/ReleaseCreate.cs | 91 +- NGitLab/Models/ReleaseEvidence.cs | 19 +- NGitLab/Models/ReleaseInfo.cs | 59 +- NGitLab/Models/ReleaseInfoLinks.cs | 15 +- NGitLab/Models/ReleaseLink.cs | 65 +- NGitLab/Models/ReleaseLinkCreate.cs | 23 +- NGitLab/Models/ReleaseLinkUpdate.cs | 23 +- NGitLab/Models/ReleaseQuery.cs | 47 +- NGitLab/Models/ReleaseUpdate.cs | 59 +- NGitLab/Models/RepositoryAccessLevel.cs | 13 +- NGitLab/Models/RepositoryGetTreeOptions.cs | 15 +- NGitLab/Models/ResourceLabelEvent.cs | 35 +- NGitLab/Models/ResourceLabelEventAction.cs | 11 +- NGitLab/Models/ResourceMilestoneEvent.cs | 35 +- .../Models/ResourceMilestoneEventAction.cs | 11 +- NGitLab/Models/ResourceStateEvent.cs | 31 +- NGitLab/Models/Runner.cs | 71 +- NGitLab/Models/RunnerId.cs | 23 +- NGitLab/Models/RunnerRegister.cs | 31 +- NGitLab/Models/RunnerScope.cs | 17 +- NGitLab/Models/RunnerUpdate.cs | 27 +- NGitLab/Models/SearchBlob.cs | 35 +- NGitLab/Models/Session.cs | 13 +- NGitLab/Models/SingleMergeRequestQuery.cs | 19 +- NGitLab/Models/SingleProjectQuery.cs | 17 +- NGitLab/Models/Snippet.cs | 45 +- NGitLab/Models/SnippetCreate.cs | 47 +- NGitLab/Models/SnippetCreateFile.cs | 31 +- NGitLab/Models/SnippetFile.cs | 15 +- NGitLab/Models/SnippetProjectCreate.cs | 63 +- NGitLab/Models/SnippetProjectUpdate.cs | 71 +- NGitLab/Models/SnippetUpdate.cs | 65 +- NGitLab/Models/SnippetUpdateFile.cs | 75 +- NGitLab/Models/SquashOption.cs | 23 +- NGitLab/Models/SshKey.cs | 23 +- NGitLab/Models/SshKeyCreate.cs | 15 +- NGitLab/Models/SubgroupQuery.cs | 119 +- NGitLab/Models/SystemHook.cs | 39 +- NGitLab/Models/SystemHookUpsert.cs | 37 +- NGitLab/Models/Tag.cs | 31 +- NGitLab/Models/TagCreate.cs | 53 +- NGitLab/Models/TagProtect.cs | 25 +- NGitLab/Models/TagQuery.cs | 13 +- NGitLab/Models/TestCases.cs | 31 +- NGitLab/Models/TestReport.cs | 35 +- NGitLab/Models/TestReportSummary.cs | 15 +- NGitLab/Models/TestReportSummaryTotals.cs | 31 +- NGitLab/Models/TestSuites.cs | 39 +- NGitLab/Models/TimeStats.cs | 23 +- NGitLab/Models/Tree.cs | 29 +- NGitLab/Models/Trigger.cs | 31 +- NGitLab/Models/TwoFactorState.cs | 15 +- NGitLab/Models/UploadedProjectFile.cs | 23 +- NGitLab/Models/User.cs | 201 +- NGitLab/Models/UserQuery.cs | 181 +- NGitLab/Models/UserToken.cs | 43 +- NGitLab/Models/UserTokenCreate.cs | 23 +- NGitLab/Models/UserUpsert.cs | 79 +- NGitLab/Models/Variable.cs | 31 +- NGitLab/Models/VariableCreate.cs | 19 +- NGitLab/Models/VariableType.cs | 15 +- NGitLab/Models/VariableUpdate.cs | 15 +- NGitLab/Models/Version.cs | 17 +- NGitLab/Models/VisibilityLevel.cs | 19 +- NGitLab/Models/WikiPage.cs | 23 +- NGitLab/Models/WikiPageCreate.cs | 19 +- NGitLab/Models/WikiPageUpdate.cs | 19 +- NGitLab/Properties/AssemblyInfo.cs | 17 +- NGitLab/RequestOptions.cs | 147 +- NGitLab/SearchQuery.cs | 67 +- NGitLab/Sha1.cs | 135 +- 592 files changed, 28467 insertions(+), 29057 deletions(-) diff --git a/.editorconfig b/.editorconfig index 69fc9750..7b6b5344 100644 --- a/.editorconfig +++ b/.editorconfig @@ -143,7 +143,7 @@ csharp_preserve_single_line_blocks = true csharp_preserve_single_line_statements = false csharp_using_directive_placement = outside_namespace:silent csharp_prefer_simple_using_statement = true:suggestion -csharp_style_namespace_declarations = block_scoped:silent +csharp_style_namespace_declarations = file_scoped:warning csharp_style_prefer_method_group_conversion = true:silent csharp_style_prefer_top_level_statements = true:silent csharp_style_expression_bodied_methods = false:silent diff --git a/BannedSymbols.txt b/BannedSymbols.txt index e76045b9..95cf777c 100644 --- a/BannedSymbols.txt +++ b/BannedSymbols.txt @@ -1,4 +1,4 @@ -#https://github.com/dotnet/csharplang/blob/main/spec/documentation-comments.md#id-string-format +// https://github.com/dotnet/csharpstandard/blob/standard-v6/standard/documentation-comments.md#d42-id-string-format M:System.String.ToLower;Use ToLowerInvariant instead M:System.String.ToUpper;Use ToUpperInvariant instead diff --git a/NGitLab.Mock.Tests/BotUserTests.cs b/NGitLab.Mock.Tests/BotUserTests.cs index 97489197..47a119cf 100644 --- a/NGitLab.Mock.Tests/BotUserTests.cs +++ b/NGitLab.Mock.Tests/BotUserTests.cs @@ -1,41 +1,40 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public sealed class BotUserTests { - public sealed class BotUserTests + [Test] + public void Test_project_bot_user() { - [Test] - public void Test_project_bot_user() - { - using var server = new GitLabServer(); - var group = new Group("test"); - var project = new Project("test-project"); - server.Groups.Add(group); - group.Projects.Add(project); + using var server = new GitLabServer(); + var group = new Group("test"); + var project = new Project("test-project"); + server.Groups.Add(group); + group.Projects.Add(project); - var bot = project.CreateBotUser("token_name", AccessLevel.Maintainer); + var bot = project.CreateBotUser("token_name", AccessLevel.Maintainer); - Assert.That(bot.Bot, Is.True); - Assert.That(bot.Name, Is.EqualTo("token_name")); - var permissions = project.GetEffectivePermissions(); - var botPermission = permissions.GetEffectivePermission(bot); - Assert.That(botPermission.AccessLevel, Is.EqualTo(AccessLevel.Maintainer)); - } + Assert.That(bot.Bot, Is.True); + Assert.That(bot.Name, Is.EqualTo("token_name")); + var permissions = project.GetEffectivePermissions(); + var botPermission = permissions.GetEffectivePermission(bot); + Assert.That(botPermission.AccessLevel, Is.EqualTo(AccessLevel.Maintainer)); + } - [Test] - public void Test_group_bot_user() - { - using var server = new GitLabServer(); - var group = new Group("test"); - server.Groups.Add(group); + [Test] + public void Test_group_bot_user() + { + using var server = new GitLabServer(); + var group = new Group("test"); + server.Groups.Add(group); - var bot = group.CreateBotUser(AccessLevel.Maintainer); + var bot = group.CreateBotUser(AccessLevel.Maintainer); - Assert.That(bot.Bot, Is.True); - var permissions = group.GetEffectivePermissions(); - var botPermission = permissions.GetEffectivePermission(bot); - Assert.That(botPermission.AccessLevel, Is.EqualTo(AccessLevel.Maintainer)); - } + Assert.That(bot.Bot, Is.True); + var permissions = group.GetEffectivePermissions(); + var botPermission = permissions.GetEffectivePermission(bot); + Assert.That(botPermission.AccessLevel, Is.EqualTo(AccessLevel.Maintainer)); } } diff --git a/NGitLab.Mock.Tests/BranchesMockTests.cs b/NGitLab.Mock.Tests/BranchesMockTests.cs index f9a2d962..c54e7809 100644 --- a/NGitLab.Mock.Tests/BranchesMockTests.cs +++ b/NGitLab.Mock.Tests/BranchesMockTests.cs @@ -2,41 +2,40 @@ using NGitLab.Mock.Config; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class BranchesMockTests { - public class BranchesMockTests + [Test] + public void Test_search_branches() { - [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.That(expectedBranch.Name, Is.EqualTo("main")); - - branches = branchClient.Search("^main$").ToList(); - expectedBranch = branches.Single(); - Assert.That(expectedBranch.Name, Is.EqualTo("main")); - - branches = branchClient.Search("^branch").ToList(); - expectedBranch = branches.Single(); - Assert.That(expectedBranch.Name, Is.EqualTo("branch_1")); - - branches = branchClient.Search("1$").ToList(); - expectedBranch = branches.Single(); - Assert.That(expectedBranch.Name, Is.EqualTo("branch_1")); - - branches = branchClient.Search("foobar").ToList(); - Assert.That(branches, Is.Empty); - } + 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.That(expectedBranch.Name, Is.EqualTo("main")); + + branches = branchClient.Search("^main$").ToList(); + expectedBranch = branches.Single(); + Assert.That(expectedBranch.Name, Is.EqualTo("main")); + + branches = branchClient.Search("^branch").ToList(); + expectedBranch = branches.Single(); + Assert.That(expectedBranch.Name, Is.EqualTo("branch_1")); + + branches = branchClient.Search("1$").ToList(); + expectedBranch = branches.Single(); + Assert.That(expectedBranch.Name, Is.EqualTo("branch_1")); + + branches = branchClient.Search("foobar").ToList(); + Assert.That(branches, Is.Empty); } } diff --git a/NGitLab.Mock.Tests/CommitsMockTests.cs b/NGitLab.Mock.Tests/CommitsMockTests.cs index f7dcd0b7..060cf6d7 100644 --- a/NGitLab.Mock.Tests/CommitsMockTests.cs +++ b/NGitLab.Mock.Tests/CommitsMockTests.cs @@ -3,129 +3,128 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class CommitsMockTests { - public class CommitsMockTests + [Test] + public void Test_commits_added_can_be_found() { - [Test] - public void Test_commits_added_can_be_found() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("test-project", id: 1, configure: project => project - .WithCommit("Initial commit") - .WithCommit("Create branch", sourceBranch: "branch-01")) - .BuildServer(); + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("test-project", id: 1, configure: project => project + .WithCommit("Initial commit") + .WithCommit("Create branch", sourceBranch: "branch-01")) + .BuildServer(); - var client = server.CreateClient(); - var commit = client.GetCommits(1).GetCommit("branch-01"); + var client = server.CreateClient(); + var commit = client.GetCommits(1).GetCommit("branch-01"); - Assert.That(commit.Message.TrimEnd('\r', '\n'), Is.EqualTo("Create branch")); - } + Assert.That(commit.Message.TrimEnd('\r', '\n'), Is.EqualTo("Create branch")); + } - [Test] - public void Test_commits_with_tags_can_be_found() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("test-project", id: 1, configure: project => project - .WithCommit("Initial commit") - .WithCommit("Changes with tag", tags: new[] { "1.0.0" })) - .BuildServer(); + [Test] + public void Test_commits_with_tags_can_be_found() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("test-project", id: 1, configure: project => project + .WithCommit("Initial commit") + .WithCommit("Changes with tag", tags: new[] { "1.0.0" })) + .BuildServer(); - var client = server.CreateClient(); - var commit = client.GetCommits(1).GetCommit("1.0.0"); + var client = server.CreateClient(); + var commit = client.GetCommits(1).GetCommit("1.0.0"); - Assert.That(commit.Message.TrimEnd('\r', '\n'), Is.EqualTo("Changes with tag")); - } + Assert.That(commit.Message.TrimEnd('\r', '\n'), Is.EqualTo("Changes with tag")); + } - [Test] - public void Test_tags_from_commit_can_be_found() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("test-project", id: 1, addDefaultUserAsMaintainer: true, configure: project => project - .WithCommit("Initial commit") - .WithCommit("Changes with tag", tags: new[] { "1.0.0" })) - .BuildServer(); - - var client = server.CreateClient(); - var tags = client.GetRepository(1).Tags.All.ToArray(); - - Assert.That(tags, Has.One.Items); - Assert.That(tags[0].Name, Is.EqualTo("1.0.0")); - } - - [Test] - public void Test_two_branches_can_be_created_from_same_commit() - { - 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") - .WithCommit("Commit for branch_2", sourceBranch: "branch_2", fromBranch: "main")) - .BuildServer(); - - var client = server.CreateClient(); - var repository = client.GetRepository(1); - var commitFromBranch1 = repository.GetCommits("branch_1").FirstOrDefault(); - var commitFromBranch2 = repository.GetCommits("branch_2").FirstOrDefault(); - - Assert.That(commitFromBranch1, Is.Not.Null); - Assert.That(commitFromBranch2, Is.Not.Null); - Assert.That(commitFromBranch1.Parents, Is.Not.Empty); - Assert.That(commitFromBranch2.Parents, Is.Not.Empty); - Assert.That(commitFromBranch2.Parents[0], Is.EqualTo(commitFromBranch1.Parents[0])); - } - - [Test] - public void Test_GetCommitsBetweenTwoRefs() + [Test] + public void Test_tags_from_commit_can_be_found() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("test-project", id: 1, addDefaultUserAsMaintainer: true, configure: project => project + .WithCommit("Initial commit") + .WithCommit("Changes with tag", tags: new[] { "1.0.0" })) + .BuildServer(); + + var client = server.CreateClient(); + var tags = client.GetRepository(1).Tags.All.ToArray(); + + Assert.That(tags, Has.One.Items); + Assert.That(tags[0].Name, Is.EqualTo("1.0.0")); + } + + [Test] + public void Test_two_branches_can_be_created_from_same_commit() + { + 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") + .WithCommit("Commit for branch_2", sourceBranch: "branch_2", fromBranch: "main")) + .BuildServer(); + + var client = server.CreateClient(); + var repository = client.GetRepository(1); + var commitFromBranch1 = repository.GetCommits("branch_1").FirstOrDefault(); + var commitFromBranch2 = repository.GetCommits("branch_2").FirstOrDefault(); + + Assert.That(commitFromBranch1, Is.Not.Null); + Assert.That(commitFromBranch2, Is.Not.Null); + Assert.That(commitFromBranch1.Parents, Is.Not.Empty); + Assert.That(commitFromBranch2.Parents, Is.Not.Empty); + Assert.That(commitFromBranch2.Parents[0], Is.EqualTo(commitFromBranch1.Parents[0])); + } + + [Test] + public void Test_GetCommitsBetweenTwoRefs() + { + // Arrange + 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") + .WithCommit("Yet another commit for branch_1")) + .BuildServer(); + + var client = server.CreateClient(); + var repository = client.GetRepository(1); + + // Act + var intermediateCommits = repository.GetCommits("main..branch_1"); + + // Assert + Assert.That(intermediateCommits.Select(c => c.Title), Is.EqualTo(new[] { - // Arrange - 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") - .WithCommit("Yet another commit for branch_1")) - .BuildServer(); - - var client = server.CreateClient(); - var repository = client.GetRepository(1); - - // Act - var intermediateCommits = repository.GetCommits("main..branch_1"); - - // Assert - Assert.That(intermediateCommits.Select(c => c.Title), Is.EqualTo(new[] - { - "Yet another commit for branch_1", - "Commit for branch_1", - }).AsCollection); - } - - [Test] - public void Test_commits_can_be_cherry_pick() + "Yet another commit for branch_1", + "Commit for branch_1", + }).AsCollection); + } + + [Test] + public void Test_commits_can_be_cherry_pick() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("test-project", id: 1, addDefaultUserAsMaintainer: true, configure: project => project + .WithCommit("Initial commit") + .WithCommit("Changes with tag", sourceBranch: "branch_1")) + .BuildServer(); + + var client = server.CreateClient(); + var repository = client.GetRepository(1); + var commitFromBranch1 = repository.GetCommits("branch_1").FirstOrDefault(); + Assert.That(commitFromBranch1, Is.Not.Null); + + var cherryPicked = client.GetCommits(1).CherryPick(new CommitCherryPick { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("test-project", id: 1, addDefaultUserAsMaintainer: true, configure: project => project - .WithCommit("Initial commit") - .WithCommit("Changes with tag", sourceBranch: "branch_1")) - .BuildServer(); - - var client = server.CreateClient(); - var repository = client.GetRepository(1); - var commitFromBranch1 = repository.GetCommits("branch_1").FirstOrDefault(); - Assert.That(commitFromBranch1, Is.Not.Null); - - var cherryPicked = client.GetCommits(1).CherryPick(new CommitCherryPick - { - Sha = commitFromBranch1.Id, - Branch = "main", - }); - Assert.That(cherryPicked, Is.Not.Null); - } + Sha = commitFromBranch1.Id, + Branch = "main", + }); + Assert.That(cherryPicked, Is.Not.Null); } } diff --git a/NGitLab.Mock.Tests/ConfigTests.cs b/NGitLab.Mock.Tests/ConfigTests.cs index 6e02f336..32488bda 100644 --- a/NGitLab.Mock.Tests/ConfigTests.cs +++ b/NGitLab.Mock.Tests/ConfigTests.cs @@ -4,138 +4,137 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class ConfigTests { - public class ConfigTests + [Test] + public void Test_server_can_be_saved_in_config() { - [Test] - public void Test_server_can_be_saved_in_config() + using var server = new GitLabServer(); + var user = new User("user1"); + server.Users.Add(user); + var group = new Group("unit-tests"); + server.Groups.Add(group); + var project = new Project("test-project") + { + Description = "Test project", + DefaultBranch = "default", + Visibility = VisibilityLevel.Public, + }; + group.Projects.Add(project); + project.Labels.Add("label1"); + project.Issues.Add(new Issue + { + Title = "Issue #1", + Description = "My issue", + Author = new UserRef(user), + Labels = new[] { "label1" }, + }); + project.MergeRequests.Add(new MergeRequest { - using var server = new GitLabServer(); - var user = new User("user1"); - server.Users.Add(user); - var group = new Group("unit-tests"); - server.Groups.Add(group); - var project = new Project("test-project") - { - Description = "Test project", - DefaultBranch = "default", - Visibility = VisibilityLevel.Public, - }; - group.Projects.Add(project); - project.Labels.Add("label1"); - project.Issues.Add(new Issue - { - Title = "Issue #1", - Description = "My issue", - Author = new UserRef(user), - Labels = new[] { "label1" }, - }); - project.MergeRequests.Add(new MergeRequest - { - Title = "Merge request #1", - Description = "My merge request", - Author = new UserRef(user), - }); - project.Permissions.Add(new Permission(user, AccessLevel.Owner)); + Title = "Merge request #1", + Description = "My merge request", + Author = new UserRef(user), + }); + project.Permissions.Add(new Permission(user, AccessLevel.Owner)); - var config = server.ToConfig(); - Assert.That(config, Is.Not.Null); + var config = server.ToConfig(); + Assert.That(config, Is.Not.Null); - Assert.That(config.Users, Has.One.Items); - Assert.That(config.Users[0].Username, Is.EqualTo("user1")); - Assert.That(config.Groups, Has.One.Items); - Assert.That(config.Groups[0].Name, Is.EqualTo("unit-tests")); - Assert.That(config.Projects, Has.One.Items); - Assert.That(config.Projects[0].Name, Is.EqualTo("test-project")); - Assert.That(config.Projects[0].Namespace, Is.EqualTo("unit-tests")); - Assert.That(config.Projects[0].Description, Is.EqualTo("Test project")); - Assert.That(config.Projects[0].DefaultBranch, Is.EqualTo("default")); - Assert.That(config.Projects[0].Visibility, Is.EqualTo(VisibilityLevel.Public)); - Assert.That(config.Projects[0].Labels, Has.One.Items); - Assert.That(config.Projects[0].Labels[0].Name, Is.EqualTo("label1")); - Assert.That(config.Projects[0].Issues, Has.One.Items); - Assert.That(config.Projects[0].Issues[0].Title, Is.EqualTo("Issue #1")); - Assert.That(config.Projects[0].Issues[0].Description, Is.EqualTo("My issue")); - Assert.That(config.Projects[0].Issues[0].Author, Is.EqualTo("user1")); - Assert.That(config.Projects[0].Issues[0].Labels, Has.One.Items); - Assert.That(config.Projects[0].Issues[0].Labels[0], Is.EqualTo("label1")); - Assert.That(config.Projects[0].MergeRequests, Has.One.Items); - Assert.That(config.Projects[0].MergeRequests[0].Title, Is.EqualTo("Merge request #1")); - Assert.That(config.Projects[0].MergeRequests[0].Description, Is.EqualTo("My merge request")); - Assert.That(config.Projects[0].MergeRequests[0].Author, Is.EqualTo("user1")); - Assert.That(config.Projects[0].Permissions, Has.One.Items); - Assert.That(config.Projects[0].Permissions[0].User, Is.EqualTo("user1")); - Assert.That(config.Projects[0].Permissions[0].Level, Is.EqualTo(AccessLevel.Owner)); - } + Assert.That(config.Users, Has.One.Items); + Assert.That(config.Users[0].Username, Is.EqualTo("user1")); + Assert.That(config.Groups, Has.One.Items); + Assert.That(config.Groups[0].Name, Is.EqualTo("unit-tests")); + Assert.That(config.Projects, Has.One.Items); + Assert.That(config.Projects[0].Name, Is.EqualTo("test-project")); + Assert.That(config.Projects[0].Namespace, Is.EqualTo("unit-tests")); + Assert.That(config.Projects[0].Description, Is.EqualTo("Test project")); + Assert.That(config.Projects[0].DefaultBranch, Is.EqualTo("default")); + Assert.That(config.Projects[0].Visibility, Is.EqualTo(VisibilityLevel.Public)); + Assert.That(config.Projects[0].Labels, Has.One.Items); + Assert.That(config.Projects[0].Labels[0].Name, Is.EqualTo("label1")); + Assert.That(config.Projects[0].Issues, Has.One.Items); + Assert.That(config.Projects[0].Issues[0].Title, Is.EqualTo("Issue #1")); + Assert.That(config.Projects[0].Issues[0].Description, Is.EqualTo("My issue")); + Assert.That(config.Projects[0].Issues[0].Author, Is.EqualTo("user1")); + Assert.That(config.Projects[0].Issues[0].Labels, Has.One.Items); + Assert.That(config.Projects[0].Issues[0].Labels[0], Is.EqualTo("label1")); + Assert.That(config.Projects[0].MergeRequests, Has.One.Items); + Assert.That(config.Projects[0].MergeRequests[0].Title, Is.EqualTo("Merge request #1")); + Assert.That(config.Projects[0].MergeRequests[0].Description, Is.EqualTo("My merge request")); + Assert.That(config.Projects[0].MergeRequests[0].Author, Is.EqualTo("user1")); + Assert.That(config.Projects[0].Permissions, Has.One.Items); + Assert.That(config.Projects[0].Permissions[0].User, Is.EqualTo("user1")); + Assert.That(config.Projects[0].Permissions[0].Level, Is.EqualTo(AccessLevel.Owner)); + } - [Test] - public void Test_config_can_be_serialized() - { - var config = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("project-1", description: "Project #1", visibility: VisibilityLevel.Public, - configure: project => project - .WithCommit("Initial commit") - .WithCommit("Create branch", sourceBranch: "branch-01") - .WithIssue("Issue #1") - .WithMergeRequest("branch-01", title: "Merge request #1") - .WithUserPermission("user1", AccessLevel.Maintainer)) - .WithProject("project-2"); + [Test] + public void Test_config_can_be_serialized() + { + var config = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("project-1", description: "Project #1", visibility: VisibilityLevel.Public, + configure: project => project + .WithCommit("Initial commit") + .WithCommit("Create branch", sourceBranch: "branch-01") + .WithIssue("Issue #1") + .WithMergeRequest("branch-01", title: "Merge request #1") + .WithUserPermission("user1", AccessLevel.Maintainer)) + .WithProject("project-2"); - var content = config.Serialize(); - Assert.That(content, Is.Not.Empty); + var content = config.Serialize(); + Assert.That(content, Is.Not.Empty); - var config2 = GitLabConfig.Deserialize(content); - Assert.That(config2, Is.Not.Null); + var config2 = GitLabConfig.Deserialize(content); + Assert.That(config2, Is.Not.Null); - Assert.That(config2.Users, Has.One.Items); - Assert.That(config2.Users[0].Username, Is.EqualTo("user1")); - Assert.That(config2.Projects, Has.Exactly(2).Items); - Assert.That(config2.Projects[0].Name, Is.EqualTo("project-1")); - Assert.That(config2.Projects[0].Description, Is.EqualTo("Project #1")); - Assert.That(config2.Projects[0].Visibility, Is.EqualTo(VisibilityLevel.Public)); - Assert.That(config2.Projects[0].Commits, Has.Exactly(2).Items); - Assert.That(config2.Projects[0].Commits[0].Message, Is.EqualTo("Initial commit")); - Assert.That(config2.Projects[0].Commits[1].Message, Is.EqualTo("Create branch")); - Assert.That(config2.Projects[0].Issues, Has.One.Items); - Assert.That(config2.Projects[0].Issues[0].Title, Is.EqualTo("Issue #1")); - Assert.That(config2.Projects[0].MergeRequests, Has.One.Items); - Assert.That(config2.Projects[0].MergeRequests[0].Title, Is.EqualTo("Merge request #1")); - Assert.That(config2.Projects[0].Permissions, Has.One.Items); - Assert.That(config2.Projects[0].Permissions[0].User, Is.EqualTo("user1")); - Assert.That(config2.Projects[1].Name, Is.EqualTo("project-2")); + Assert.That(config2.Users, Has.One.Items); + Assert.That(config2.Users[0].Username, Is.EqualTo("user1")); + Assert.That(config2.Projects, Has.Exactly(2).Items); + Assert.That(config2.Projects[0].Name, Is.EqualTo("project-1")); + Assert.That(config2.Projects[0].Description, Is.EqualTo("Project #1")); + Assert.That(config2.Projects[0].Visibility, Is.EqualTo(VisibilityLevel.Public)); + Assert.That(config2.Projects[0].Commits, Has.Exactly(2).Items); + Assert.That(config2.Projects[0].Commits[0].Message, Is.EqualTo("Initial commit")); + Assert.That(config2.Projects[0].Commits[1].Message, Is.EqualTo("Create branch")); + Assert.That(config2.Projects[0].Issues, Has.One.Items); + Assert.That(config2.Projects[0].Issues[0].Title, Is.EqualTo("Issue #1")); + Assert.That(config2.Projects[0].MergeRequests, Has.One.Items); + Assert.That(config2.Projects[0].MergeRequests[0].Title, Is.EqualTo("Merge request #1")); + Assert.That(config2.Projects[0].Permissions, Has.One.Items); + Assert.That(config2.Projects[0].Permissions[0].User, Is.EqualTo("user1")); + Assert.That(config2.Projects[1].Name, Is.EqualTo("project-2")); - using var server = config2.BuildServer(); - Assert.That(server, Is.Not.Null); - } + using var server = config2.BuildServer(); + Assert.That(server, Is.Not.Null); + } - [Test] - public void Test_job_ids_are_unique() - { - var config = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("project-1", description: "Project #1", visibility: VisibilityLevel.Public, - configure: project => project - .WithCommit("Initial commit", alias: "C1") - .WithPipeline("C1", p => p.WithJob().WithJob().WithJob())) - .WithProject("project-2", description: "Project #2", visibility: VisibilityLevel.Public, - configure: project => project - .WithCommit("Initial commit", alias: "C1") - .WithPipeline("C1", p => p.WithJob().WithJob())); + [Test] + public void Test_job_ids_are_unique() + { + var config = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("project-1", description: "Project #1", visibility: VisibilityLevel.Public, + configure: project => project + .WithCommit("Initial commit", alias: "C1") + .WithPipeline("C1", p => p.WithJob().WithJob().WithJob())) + .WithProject("project-2", description: "Project #2", visibility: VisibilityLevel.Public, + configure: project => project + .WithCommit("Initial commit", alias: "C1") + .WithPipeline("C1", p => p.WithJob().WithJob())); - using var server = config.BuildServer(); - Assert.That(server, Is.Not.Null); + using var server = config.BuildServer(); + Assert.That(server, Is.Not.Null); - var project1 = server.AllProjects.FirstOrDefault(); - Assert.That(project1, Is.Not.Null); + var project1 = server.AllProjects.FirstOrDefault(); + Assert.That(project1, Is.Not.Null); - project1.Jobs.Should().BeEquivalentTo(new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } }); + project1.Jobs.Should().BeEquivalentTo(new[] { new { Id = 1 }, new { Id = 2 }, new { Id = 3 } }); - var project2 = server.AllProjects.LastOrDefault(); - Assert.That(project2, Is.Not.Null); + var project2 = server.AllProjects.LastOrDefault(); + Assert.That(project2, Is.Not.Null); - project2.Jobs.Should().BeEquivalentTo(new[] { new { Id = 4 }, new { Id = 5 } }); - } + project2.Jobs.Should().BeEquivalentTo(new[] { new { Id = 4 }, new { Id = 5 } }); } } diff --git a/NGitLab.Mock.Tests/GroupsMockTests.cs b/NGitLab.Mock.Tests/GroupsMockTests.cs index a8af88f7..dbb62c29 100644 --- a/NGitLab.Mock.Tests/GroupsMockTests.cs +++ b/NGitLab.Mock.Tests/GroupsMockTests.cs @@ -3,80 +3,79 @@ using NGitLab.Mock.Config; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class GroupsMockTests { - public class GroupsMockTests + [Test] + public async Task Test_group_get_by_id() { - [Test] - public async Task Test_group_get_by_id() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test") - .WithGroup("G1", 1) - .WithGroup("G2", 2) - .WithGroup("G3", 3) - .BuildServer(); + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test") + .WithGroup("G1", 1) + .WithGroup("G2", 2) + .WithGroup("G3", 3) + .BuildServer(); - var client = server.CreateClient("user1"); - var group = await client.Groups.GetByIdAsync(1); + var client = server.CreateClient("user1"); + var group = await client.Groups.GetByIdAsync(1); - Assert.That(group.Name, Is.EqualTo("G1"), "Subgroups found are invalid"); - } + Assert.That(group.Name, Is.EqualTo("G1"), "Subgroups found are invalid"); + } - [Test] - public async Task Test_group_get_by_fullpath() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test") - .WithGroup("G1", @namespace: "name1") - .WithGroup("G2", @namespace: "name2") - .WithGroup("G3", @namespace: "name3") - .BuildServer(); + [Test] + public async Task Test_group_get_by_fullpath() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test") + .WithGroup("G1", @namespace: "name1") + .WithGroup("G2", @namespace: "name2") + .WithGroup("G3", @namespace: "name3") + .BuildServer(); - var client = server.CreateClient("user1"); - var group = await client.Groups.GetByFullPathAsync("name3"); + var client = server.CreateClient("user1"); + var group = await client.Groups.GetByFullPathAsync("name3"); - Assert.That(group.FullPath, Is.EqualTo("name3"), "Subgroups found are invalid"); - } + Assert.That(group.FullPath, Is.EqualTo("name3"), "Subgroups found are invalid"); + } - [Test] - public void Test_get_subgroups_by_id() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", addDefaultUserAsMaintainer: true) - .WithGroup("parentGroup1", configure: group => group.Id = 12) - .WithGroup("parentGroup2", configure: group => group.Id = 89) - .WithGroup("G1", 2, @namespace: "parentGroup1") - .WithGroup("G2", 3, @namespace: "parentGroup1") - .WithGroup("G3", 4, @namespace: "parentGroup2") - .BuildServer(); + [Test] + public void Test_get_subgroups_by_id() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", addDefaultUserAsMaintainer: true) + .WithGroup("parentGroup1", configure: group => group.Id = 12) + .WithGroup("parentGroup2", configure: group => group.Id = 89) + .WithGroup("G1", 2, @namespace: "parentGroup1") + .WithGroup("G2", 3, @namespace: "parentGroup1") + .WithGroup("G3", 4, @namespace: "parentGroup2") + .BuildServer(); - var client = server.CreateClient("user1"); - var group = client.Groups.GetSubgroupsByIdAsync(12, new Models.SubgroupQuery { }); + var client = server.CreateClient("user1"); + var group = client.Groups.GetSubgroupsByIdAsync(12, new Models.SubgroupQuery { }); - Assert.That(group.Count(), Is.EqualTo(2), "Subgroups found are invalid"); - } + Assert.That(group.Count(), Is.EqualTo(2), "Subgroups found are invalid"); + } - [Test] - public void Test_get_subgroups_by_fullpath() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", addDefaultUserAsMaintainer: true) - .WithGroup("parentGroup1", configure: group => group.Id = 12) - .WithGroup("parentGroup2", configure: group => group.Id = 89) - .WithGroup("G1", 2, @namespace: "parentGroup1") - .WithGroup("G2", 3, @namespace: "parentGroup1") - .WithGroup("G3", 4, @namespace: "parentGroup2") - .BuildServer(); + [Test] + public void Test_get_subgroups_by_fullpath() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", addDefaultUserAsMaintainer: true) + .WithGroup("parentGroup1", configure: group => group.Id = 12) + .WithGroup("parentGroup2", configure: group => group.Id = 89) + .WithGroup("G1", 2, @namespace: "parentGroup1") + .WithGroup("G2", 3, @namespace: "parentGroup1") + .WithGroup("G3", 4, @namespace: "parentGroup2") + .BuildServer(); - var client = server.CreateClient("user1"); - var group = client.Groups.GetSubgroupsByFullPathAsync("parentgroup1", new Models.SubgroupQuery { }); + var client = server.CreateClient("user1"); + var group = client.Groups.GetSubgroupsByFullPathAsync("parentgroup1", new Models.SubgroupQuery { }); - Assert.That(group.Count(), Is.EqualTo(2), "Subgroups found are invalid"); - } + Assert.That(group.Count(), Is.EqualTo(2), "Subgroups found are invalid"); } } diff --git a/NGitLab.Mock.Tests/IssuesMockTests.cs b/NGitLab.Mock.Tests/IssuesMockTests.cs index a7b90f3b..2f8b595a 100644 --- a/NGitLab.Mock.Tests/IssuesMockTests.cs +++ b/NGitLab.Mock.Tests/IssuesMockTests.cs @@ -3,115 +3,114 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class IssuesMockTests { - public class IssuesMockTests + [Test] + public void Test_issues_created_by_me_can_be_listed() { - [Test] - public void Test_issues_created_by_me_can_be_listed() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test", configure: project => project - .WithIssue("Issue 1", author: "user1", assignee: "user2") - .WithIssue("Issue 2", author: "user2", assignee: "user1")) - .BuildServer(); - - var client = server.CreateClient("user1"); - var issues = client.Issues.Get(new IssueQuery { Scope = "created_by_me" }).ToArray(); - - Assert.That(issues, Has.Length.EqualTo(1), "Issues count is invalid"); - Assert.That(issues[0].Title, Is.EqualTo("Issue 1"), "Issue found is invalid"); - } - - [Test] - public void Test_issues_assigned_to_me_can_be_listed() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test", configure: project => project - .WithIssue("Issue 1", author: "user1", assignee: "user2") - .WithIssue("Issue 2", author: "user2", assignee: "user1")) - .BuildServer(); - - var client = server.CreateClient("user1"); - var issues = client.Issues.Get(new IssueQuery { Scope = "assigned_to_me" }).ToArray(); - - Assert.That(issues, Has.Length.EqualTo(1), "Issues count is invalid"); - Assert.That(issues[0].Title, Is.EqualTo("Issue 2"), "Issue found is invalid"); - } - - [Test] - public void Test_issues_assignee_not_throwing_when_assignees_is_null() - { - using var server = new GitLabConfig() - .WithUser("user", isDefault: true) - .WithProject("Test", configure: project => project - .WithIssue("Issue title", author: "user")) - .BuildServer(); - - var client = server.CreateClient(); - Assert.DoesNotThrow(() => client.Issues.Get(new IssueQuery { Scope = "assigned_to_me" }).ToArray()); - } - - [Test] - public void Test_issue_by_id_can_be_found() - { - using var server = new GitLabConfig() - .WithUser("user", isDefault: true, isAdmin: true) - .WithProject("Test", configure: project => project - .WithIssue("Issue title", author: "user", id: 5)) - .BuildServer(); + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithIssue("Issue 1", author: "user1", assignee: "user2") + .WithIssue("Issue 2", author: "user2", assignee: "user1")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var issues = client.Issues.Get(new IssueQuery { Scope = "created_by_me" }).ToArray(); + + Assert.That(issues, Has.Length.EqualTo(1), "Issues count is invalid"); + Assert.That(issues[0].Title, Is.EqualTo("Issue 1"), "Issue found is invalid"); + } + + [Test] + public void Test_issues_assigned_to_me_can_be_listed() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithIssue("Issue 1", author: "user1", assignee: "user2") + .WithIssue("Issue 2", author: "user2", assignee: "user1")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var issues = client.Issues.Get(new IssueQuery { Scope = "assigned_to_me" }).ToArray(); + + Assert.That(issues, Has.Length.EqualTo(1), "Issues count is invalid"); + Assert.That(issues[0].Title, Is.EqualTo("Issue 2"), "Issue found is invalid"); + } - var client = server.CreateClient(); + [Test] + public void Test_issues_assignee_not_throwing_when_assignees_is_null() + { + using var server = new GitLabConfig() + .WithUser("user", isDefault: true) + .WithProject("Test", configure: project => project + .WithIssue("Issue title", author: "user")) + .BuildServer(); + + var client = server.CreateClient(); + Assert.DoesNotThrow(() => client.Issues.Get(new IssueQuery { Scope = "assigned_to_me" }).ToArray()); + } + + [Test] + public void Test_issue_by_id_can_be_found() + { + using var server = new GitLabConfig() + .WithUser("user", isDefault: true, isAdmin: true) + .WithProject("Test", configure: project => project + .WithIssue("Issue title", author: "user", id: 5)) + .BuildServer(); + + var client = server.CreateClient(); - var issue = client.Issues.GetById(10001); - Assert.That(issue.IssueId, Is.EqualTo(5)); - Assert.That(issue.Title, Is.EqualTo("Issue title")); - } + var issue = client.Issues.GetById(10001); + Assert.That(issue.IssueId, Is.EqualTo(5)); + Assert.That(issue.Title, Is.EqualTo("Issue title")); + } + + [Test] + public void Test_issue_resource_milestone_events_can_be_found() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, configure: project => project + .WithIssue("Issue title", author: "user", id: 5) + .WithMilestone("Milestone 1") + .WithMilestone("Milestone 2")) + .BuildServer(); + + var client = server.CreateClient(); + var issuesClient = client.Issues; + var milestone = client.GetMilestone(1).All.ToArray()[0]; + + issuesClient.Edit(new IssueEdit + { + ProjectId = 1, + IssueId = 5, + MilestoneId = milestone.Id, + }); - [Test] - public void Test_issue_resource_milestone_events_can_be_found() + issuesClient.Edit(new IssueEdit { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, configure: project => project - .WithIssue("Issue title", author: "user", id: 5) - .WithMilestone("Milestone 1") - .WithMilestone("Milestone 2")) - .BuildServer(); - - var client = server.CreateClient(); - var issuesClient = client.Issues; - var milestone = client.GetMilestone(1).All.ToArray()[0]; - - issuesClient.Edit(new IssueEdit - { - ProjectId = 1, - IssueId = 5, - MilestoneId = milestone.Id, - }); - - issuesClient.Edit(new IssueEdit - { - ProjectId = 1, - IssueId = 5, - MilestoneId = 2, - }); - - var resourceMilestoneEvents = issuesClient.ResourceMilestoneEvents(projectId: 1, issueIid: 5).ToList(); - Assert.That(resourceMilestoneEvents, Has.Count.EqualTo(3)); - - var removeMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Remove).ToArray(); - Assert.That(removeMilestoneEvents, Has.Length.EqualTo(1)); - Assert.That(removeMilestoneEvents[0].Milestone.Id, Is.EqualTo(1)); - - var addMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Add).ToArray(); - Assert.That(addMilestoneEvents, Has.Length.EqualTo(2)); - Assert.That(addMilestoneEvents[0].Milestone.Id, Is.EqualTo(1)); - Assert.That(addMilestoneEvents[1].Milestone.Id, Is.EqualTo(2)); - } + ProjectId = 1, + IssueId = 5, + MilestoneId = 2, + }); + + var resourceMilestoneEvents = issuesClient.ResourceMilestoneEvents(projectId: 1, issueIid: 5).ToList(); + Assert.That(resourceMilestoneEvents, Has.Count.EqualTo(3)); + + var removeMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Remove).ToArray(); + Assert.That(removeMilestoneEvents, Has.Length.EqualTo(1)); + Assert.That(removeMilestoneEvents[0].Milestone.Id, Is.EqualTo(1)); + + var addMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Add).ToArray(); + Assert.That(addMilestoneEvents, Has.Length.EqualTo(2)); + Assert.That(addMilestoneEvents[0].Milestone.Id, Is.EqualTo(1)); + Assert.That(addMilestoneEvents[1].Milestone.Id, Is.EqualTo(2)); } } diff --git a/NGitLab.Mock.Tests/LabelsMockTests.cs b/NGitLab.Mock.Tests/LabelsMockTests.cs index 305c8b94..24fa284a 100644 --- a/NGitLab.Mock.Tests/LabelsMockTests.cs +++ b/NGitLab.Mock.Tests/LabelsMockTests.cs @@ -4,126 +4,125 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class LabelsMockTests { - public class LabelsMockTests + [Test] + public void Test_labels_can_be_found_from_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, configure: project => project + .WithLabel("test1") + .WithLabel("test2")) + .BuildServer(); + + var client = server.CreateClient(); + var labels = client.Labels.ForProject(1).ToArray(); + + Assert.That(labels, Has.Length.EqualTo(2), "Labels count is invalid"); + Assert.That(labels.Any(x => string.Equals(x.Name, "test1", StringComparison.Ordinal)), Is.True, "Label test1 not found"); + Assert.That(labels.Any(x => string.Equals(x.Name, "test2", StringComparison.Ordinal)), Is.True, "Label test2 not found"); + } + + [Test] + public void Test_labels_can_be_added_to_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true) + .BuildServer(); + + var client = server.CreateClient(); + client.Labels.Create(new LabelCreate { Id = 1, Name = "test1" }); + var labels = client.Labels.ForProject(1).ToArray(); + + Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); + Assert.That(labels[0].Name, Is.EqualTo("test1"), "Label not found"); + } + + [Test] + public void Test_labels_can_be_edited_from_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project + .WithLabel("test1")) + .BuildServer(); + + var client = server.CreateClient(); + client.Labels.Edit(new LabelEdit { Id = 1, Name = "test1", NewName = "test2" }); + var labels = client.Labels.ForProject(1).ToArray(); + + Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); + Assert.That(labels[0].Name, Is.EqualTo("test2"), "Label not found"); + } + + [Test] + public void Test_labels_can_be_deleted_from_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project + .WithLabel("test1")) + .BuildServer(); + + var client = server.CreateClient(); + client.Labels.Delete(new LabelDelete { Id = 1, Name = "test1" }); + var labels = client.Labels.ForProject(1).ToArray(); + + Assert.That(labels, Is.Empty, "Labels count is invalid"); + } + + [Test] + public void Test_labels_can_be_found_from_group() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithGroup("Test", id: 2, configure: project => project + .WithLabel("test1") + .WithLabel("test2")) + .BuildServer(); + + var client = server.CreateClient(); + var labels = client.Labels.ForGroup(2).ToArray(); + + Assert.That(labels, Has.Length.EqualTo(2), "Labels count is invalid"); + Assert.That(labels.Any(x => string.Equals(x.Name, "test1", StringComparison.Ordinal)), Is.True, "Label test1 not found"); + Assert.That(labels.Any(x => string.Equals(x.Name, "test2", StringComparison.Ordinal)), Is.True, "Label test2 not found"); + } + + [Test] + public void Test_labels_can_be_added_to_group() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithGroup("Test", id: 2, addDefaultUserAsMaintainer: true) + .BuildServer(); + + var client = server.CreateClient(); + client.Labels.CreateGroupLabel(new LabelCreate { Id = 2, Name = "test1" }); + var labels = client.Labels.ForGroup(2).ToArray(); + + Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); + Assert.That(labels[0].Name, Is.EqualTo("test1"), "Label not found"); + } + + [Test] + public void Test_labels_can_be_edited_from_group() { - [Test] - public void Test_labels_can_be_found_from_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, configure: project => project - .WithLabel("test1") - .WithLabel("test2")) - .BuildServer(); - - var client = server.CreateClient(); - var labels = client.Labels.ForProject(1).ToArray(); - - Assert.That(labels, Has.Length.EqualTo(2), "Labels count is invalid"); - Assert.That(labels.Any(x => string.Equals(x.Name, "test1", StringComparison.Ordinal)), Is.True, "Label test1 not found"); - Assert.That(labels.Any(x => string.Equals(x.Name, "test2", StringComparison.Ordinal)), Is.True, "Label test2 not found"); - } - - [Test] - public void Test_labels_can_be_added_to_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true) - .BuildServer(); - - var client = server.CreateClient(); - client.Labels.Create(new LabelCreate { Id = 1, Name = "test1" }); - var labels = client.Labels.ForProject(1).ToArray(); - - Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); - Assert.That(labels[0].Name, Is.EqualTo("test1"), "Label not found"); - } - - [Test] - public void Test_labels_can_be_edited_from_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project - .WithLabel("test1")) - .BuildServer(); - - var client = server.CreateClient(); - client.Labels.Edit(new LabelEdit { Id = 1, Name = "test1", NewName = "test2" }); - var labels = client.Labels.ForProject(1).ToArray(); - - Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); - Assert.That(labels[0].Name, Is.EqualTo("test2"), "Label not found"); - } - - [Test] - public void Test_labels_can_be_deleted_from_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project - .WithLabel("test1")) - .BuildServer(); - - var client = server.CreateClient(); - client.Labels.Delete(new LabelDelete { Id = 1, Name = "test1" }); - var labels = client.Labels.ForProject(1).ToArray(); - - Assert.That(labels, Is.Empty, "Labels count is invalid"); - } - - [Test] - public void Test_labels_can_be_found_from_group() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithGroup("Test", id: 2, configure: project => project - .WithLabel("test1") - .WithLabel("test2")) - .BuildServer(); - - var client = server.CreateClient(); - var labels = client.Labels.ForGroup(2).ToArray(); - - Assert.That(labels, Has.Length.EqualTo(2), "Labels count is invalid"); - Assert.That(labels.Any(x => string.Equals(x.Name, "test1", StringComparison.Ordinal)), Is.True, "Label test1 not found"); - Assert.That(labels.Any(x => string.Equals(x.Name, "test2", StringComparison.Ordinal)), Is.True, "Label test2 not found"); - } - - [Test] - public void Test_labels_can_be_added_to_group() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithGroup("Test", id: 2, addDefaultUserAsMaintainer: true) - .BuildServer(); - - var client = server.CreateClient(); - client.Labels.CreateGroupLabel(new LabelCreate { Id = 2, Name = "test1" }); - var labels = client.Labels.ForGroup(2).ToArray(); - - Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); - Assert.That(labels[0].Name, Is.EqualTo("test1"), "Label not found"); - } - - [Test] - public void Test_labels_can_be_edited_from_group() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithGroup("Test", id: 2, addDefaultUserAsMaintainer: true, configure: project => project - .WithLabel("test1")) - .BuildServer(); - - var client = server.CreateClient(); - client.Labels.EditGroupLabel(new LabelEdit { Id = 2, Name = "test1", NewName = "test2" }); - var labels = client.Labels.ForGroup(2).ToArray(); - - Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); - Assert.That(labels[0].Name, Is.EqualTo("test2"), "Label not found"); - } + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithGroup("Test", id: 2, addDefaultUserAsMaintainer: true, configure: project => project + .WithLabel("test1")) + .BuildServer(); + + var client = server.CreateClient(); + client.Labels.EditGroupLabel(new LabelEdit { Id = 2, Name = "test1", NewName = "test2" }); + var labels = client.Labels.ForGroup(2).ToArray(); + + Assert.That(labels, Has.Length.EqualTo(1), "Labels count is invalid"); + Assert.That(labels[0].Name, Is.EqualTo("test2"), "Label not found"); } } diff --git a/NGitLab.Mock.Tests/MembersMockTests.cs b/NGitLab.Mock.Tests/MembersMockTests.cs index 961ae7d8..df389007 100644 --- a/NGitLab.Mock.Tests/MembersMockTests.cs +++ b/NGitLab.Mock.Tests/MembersMockTests.cs @@ -2,85 +2,84 @@ using NGitLab.Mock.Config; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class MembersMockTests { - public class MembersMockTests + [Test] + public void Test_members_group_all_direct([Values] bool isDefault) { - [Test] - public void Test_members_group_all_direct([Values] bool isDefault) - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithGroup("G1", 1, addDefaultUserAsMaintainer: true) - .WithGroup("G2", 2, @namespace: "G1", configure: g => g.WithUserPermission("user2", Models.AccessLevel.Maintainer)) - .BuildServer(); + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithGroup("G1", 1, addDefaultUserAsMaintainer: true) + .WithGroup("G2", 2, @namespace: "G1", configure: g => g.WithUserPermission("user2", Models.AccessLevel.Maintainer)) + .BuildServer(); - var client = server.CreateClient("user1"); - var members = isDefault - ? client.Members.OfGroup("2") - : client.Members.OfGroup("2", includeInheritedMembers: false); + var client = server.CreateClient("user1"); + var members = isDefault + ? client.Members.OfGroup("2") + : client.Members.OfGroup("2", includeInheritedMembers: false); - Assert.That(members.Count(), Is.EqualTo(1), "Membership found are invalid"); - } + Assert.That(members.Count(), Is.EqualTo(1), "Membership found are invalid"); + } - [Test] - public void Test_members_group_all_inherited() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test") - .WithGroup("G1", 1, configure: g => g.WithUserPermission("user1", Models.AccessLevel.Maintainer)) - .WithGroup("G2", 2, @namespace: "G1", configure: g => g.WithUserPermission("user2", Models.AccessLevel.Maintainer)) - .BuildServer(); + [Test] + public void Test_members_group_all_inherited() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test") + .WithGroup("G1", 1, configure: g => g.WithUserPermission("user1", Models.AccessLevel.Maintainer)) + .WithGroup("G2", 2, @namespace: "G1", configure: g => g.WithUserPermission("user2", Models.AccessLevel.Maintainer)) + .BuildServer(); - var client = server.CreateClient("user1"); - var members = client.Members.OfGroup("2", includeInheritedMembers: true); + var client = server.CreateClient("user1"); + var members = client.Members.OfGroup("2", includeInheritedMembers: true); - Assert.That(members.Count(), Is.EqualTo(2), "Membership found are invalid"); - } + Assert.That(members.Count(), Is.EqualTo(2), "Membership found are invalid"); + } - [Test] - public void Test_members_project_all_direct([Values] bool isDefault) - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithUser("user3") - .WithGroup("G1", 1, addDefaultUserAsMaintainer: true) - .WithGroup("G2", 2, @namespace: "G1", configure: g => g.WithUserPermission("user2", Models.AccessLevel.Maintainer)) - .WithProject("Project", @namespace: "G1", configure: g => - g.WithUserPermission("user3", Models.AccessLevel.Maintainer) - .WithGroupPermission("G2", Models.AccessLevel.Developer)) - .BuildServer(); + [Test] + public void Test_members_project_all_direct([Values] bool isDefault) + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithUser("user3") + .WithGroup("G1", 1, addDefaultUserAsMaintainer: true) + .WithGroup("G2", 2, @namespace: "G1", configure: g => g.WithUserPermission("user2", Models.AccessLevel.Maintainer)) + .WithProject("Project", @namespace: "G1", configure: g => + g.WithUserPermission("user3", Models.AccessLevel.Maintainer) + .WithGroupPermission("G2", Models.AccessLevel.Developer)) + .BuildServer(); - var client = server.CreateClient("user1"); - var members = isDefault - ? client.Members.OfProject("1") - : client.Members.OfProject("1", includeInheritedMembers: false); + var client = server.CreateClient("user1"); + var members = isDefault + ? client.Members.OfProject("1") + : client.Members.OfProject("1", includeInheritedMembers: false); - Assert.That(members.Count(), Is.EqualTo(1), "Membership found are invalid"); - } + Assert.That(members.Count(), Is.EqualTo(1), "Membership found are invalid"); + } - [Test] - public void Test_members_project_all_inherited() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithUser("user3") - .WithGroup("G1", addDefaultUserAsMaintainer: true) - .WithGroup("G2", @namespace: "G1", configure: g => g.WithUserPermission("user2", Models.AccessLevel.Maintainer)) - .WithProject("Project", 1, @namespace: "G1", configure: g => - g.WithUserPermission("user3", Models.AccessLevel.Maintainer) - .WithGroupPermission("G1/G2", Models.AccessLevel.Developer)) - .BuildServer(); + [Test] + public void Test_members_project_all_inherited() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithUser("user3") + .WithGroup("G1", addDefaultUserAsMaintainer: true) + .WithGroup("G2", @namespace: "G1", configure: g => g.WithUserPermission("user2", Models.AccessLevel.Maintainer)) + .WithProject("Project", 1, @namespace: "G1", configure: g => + g.WithUserPermission("user3", Models.AccessLevel.Maintainer) + .WithGroupPermission("G1/G2", Models.AccessLevel.Developer)) + .BuildServer(); - var client = server.CreateClient("user1"); - var members = client.Members.OfProject("1", includeInheritedMembers: true); + var client = server.CreateClient("user1"); + var members = client.Members.OfProject("1", includeInheritedMembers: true); - Assert.That(members.Count(), Is.EqualTo(3), "Membership found are invalid"); - } + Assert.That(members.Count(), Is.EqualTo(3), "Membership found are invalid"); } } diff --git a/NGitLab.Mock.Tests/MergeRequestsMockTests.cs b/NGitLab.Mock.Tests/MergeRequestsMockTests.cs index 7750c48a..af62b06e 100644 --- a/NGitLab.Mock.Tests/MergeRequestsMockTests.cs +++ b/NGitLab.Mock.Tests/MergeRequestsMockTests.cs @@ -5,412 +5,411 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class MergeRequestsMockTests { - public class MergeRequestsMockTests + [Test] + public void Test_merge_requests_created_by_me_can_be_listed() { - [Test] - public void Test_merge_requests_created_by_me_can_be_listed() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test", configure: project => project - .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2") - .WithMergeRequest("branch-02", title: "Merge request 2", author: "user2", assignee: "user1")) - .BuildServer(); - - var client = server.CreateClient("user1"); - var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "created_by_me" }).ToArray(); - - Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); - Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 1"), "Merge request found is invalid"); - } - - [Test] - public void Test_merge_requests_assigned_to_me_can_be_listed() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test", configure: project => project - .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2") - .WithMergeRequest("branch-02", title: "Merge request 2", author: "user2", assignee: "user1")) - .BuildServer(); - - var client = server.CreateClient("user1"); - var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "assigned_to_me" }).ToArray(); - - Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); - Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); - } - - [Test] - public void Test_merge_requests_approvable_by_me_can_be_listed() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test", configure: project => project - .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", approvers: new[] { "user2" }) - .WithMergeRequest("branch-02", title: "Merge request 2", author: "user2", approvers: new[] { "user1" })) - .BuildServer(); - - var client = server.CreateClient("user1"); - var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { ApproverIds = new[] { 1 } }).ToArray(); - - Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); - Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); - } - - [Test] - public void Test_merge_requests_can_be_listed_when_assignee_not_set() - { - using var gitLabServer = new GitLabServer(); - var user1 = new User("user1"); - gitLabServer.Users.Add(user1); - var user2 = new User("user2"); - gitLabServer.Users.Add(user2); - var group = new Group("TestGroup"); - gitLabServer.Groups.Add(group); - var project = new Project("Test") { Visibility = VisibilityLevel.Internal }; - group.Projects.Add(project); - var mergeRequest1 = new MergeRequest { Author = new UserRef(user1), Title = "Merge request 1", SourceProject = project }; - project.MergeRequests.Add(mergeRequest1); - var mergeRequest2 = new MergeRequest { Author = new UserRef(user2), Assignee = new UserRef(user1), Title = "Merge request 2", SourceProject = project }; - project.MergeRequests.Add(mergeRequest2); - - var client = gitLabServer.CreateClient(user1); - var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "assigned_to_me" }).ToArray(); - - Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); - Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); - } - - [Test] - public void Test_merge_requests_assignee_should_update_assignees_and_vice_versa() - { - var user1 = new User("user1"); - var user2 = new User("user2"); - - var mergeRequestSingle = new MergeRequest - { - Assignee = new UserRef(user1), - }; - - var mergeRequestTwo = new MergeRequest - { - Assignees = new[] { new UserRef(user1), new UserRef(user2) }, - }; - - Assert.That(mergeRequestSingle.Assignees, Has.Count.EqualTo(1), "Merge request assignees count invalid"); - Assert.That(mergeRequestTwo.Assignee.UserName, Is.EqualTo("user1"), "Merge request assignee is invalid"); - } - - [TestCase(false)] - [TestCase(true)] - public void Test_merge_request_with_no_rebase_required_can_be_accepted(bool sourceProjectSameAsTargetProject) - { - // Arrange - using var server = new GitLabServer(); + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2") + .WithMergeRequest("branch-02", title: "Merge request 2", author: "user2", assignee: "user1")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "created_by_me" }).ToArray(); + + Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); + Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 1"), "Merge request found is invalid"); + } - var contributor = server.Users.AddNew("contributor"); - var maintainer = server.Users.AddNew("maintainer"); + [Test] + public void Test_merge_requests_assigned_to_me_can_be_listed() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2") + .WithMergeRequest("branch-02", title: "Merge request 2", author: "user2", assignee: "user1")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "assigned_to_me" }).ToArray(); + + Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); + Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); + } - var targetGroup = new Group("TheTargetGroup"); - server.Groups.Add(targetGroup); + [Test] + public void Test_merge_requests_approvable_by_me_can_be_listed() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", approvers: new[] { "user2" }) + .WithMergeRequest("branch-02", title: "Merge request 2", author: "user2", approvers: new[] { "user1" })) + .BuildServer(); + + var client = server.CreateClient("user1"); + var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { ApproverIds = new[] { 1 } }).ToArray(); + + Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); + Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); + } - var targetProject = new Project("TheTargetProject") { Visibility = VisibilityLevel.Internal }; - targetGroup.Projects.Add(targetProject); + [Test] + public void Test_merge_requests_can_be_listed_when_assignee_not_set() + { + using var gitLabServer = new GitLabServer(); + var user1 = new User("user1"); + gitLabServer.Users.Add(user1); + var user2 = new User("user2"); + gitLabServer.Users.Add(user2); + var group = new Group("TestGroup"); + gitLabServer.Groups.Add(group); + var project = new Project("Test") { Visibility = VisibilityLevel.Internal }; + group.Projects.Add(project); + var mergeRequest1 = new MergeRequest { Author = new UserRef(user1), Title = "Merge request 1", SourceProject = project }; + project.MergeRequests.Add(mergeRequest1); + var mergeRequest2 = new MergeRequest { Author = new UserRef(user2), Assignee = new UserRef(user1), Title = "Merge request 2", SourceProject = project }; + project.MergeRequests.Add(mergeRequest2); + + var client = gitLabServer.CreateClient(user1); + var mergeRequests = client.MergeRequests.Get(new MergeRequestQuery { Scope = "assigned_to_me" }).ToArray(); + + Assert.That(mergeRequests, Has.Length.EqualTo(1), "Merge requests count is invalid"); + Assert.That(mergeRequests[0].Title, Is.EqualTo("Merge request 2"), "Merge request found is invalid"); + } - targetProject.Permissions.Add(new Permission(maintainer, AccessLevel.Maintainer)); - targetProject.Repository.Commit(maintainer, "A commit"); + [Test] + public void Test_merge_requests_assignee_should_update_assignees_and_vice_versa() + { + var user1 = new User("user1"); + var user2 = new User("user2"); - var sourceProject = sourceProjectSameAsTargetProject ? - targetProject : - targetProject.Fork(contributor.Namespace, contributor, "TheSourceProject"); - sourceProject.Repository.CreateAndCheckoutBranch("to-be-merged"); - sourceProject.Repository.Commit(contributor, "add a file", new[] { File.CreateFromText(Guid.NewGuid().ToString("N"), "This is the new file's content") }); + var mergeRequestSingle = new MergeRequest + { + Assignee = new UserRef(user1), + }; - var mr = targetProject.CreateMergeRequest(contributor, "A great title", "A great description", targetProject.DefaultBranch, "to-be-merged", sourceProject); - mr.Assignee = new UserRef(maintainer); + var mergeRequestTwo = new MergeRequest + { + Assignees = new[] { new UserRef(user1), new UserRef(user2) }, + }; - targetProject.MergeMethod = "ff"; + Assert.That(mergeRequestSingle.Assignees, Has.Count.EqualTo(1), "Merge request assignees count invalid"); + Assert.That(mergeRequestTwo.Assignee.UserName, Is.EqualTo("user1"), "Merge request assignee is invalid"); + } - var maintainerClient = server.CreateClient("maintainer"); + [TestCase(false)] + [TestCase(true)] + public void Test_merge_request_with_no_rebase_required_can_be_accepted(bool sourceProjectSameAsTargetProject) + { + // Arrange + using var server = new GitLabServer(); - // Act - var modelMr = maintainerClient.GetMergeRequest(mr.Project.Id).Accept(mr.Iid, new MergeRequestMerge - { - MergeWhenPipelineSucceeds = mr.HeadPipeline != null, - ShouldRemoveSourceBranch = true, - Sha = mr.HeadSha, - }); + var contributor = server.Users.AddNew("contributor"); + var maintainer = server.Users.AddNew("maintainer"); - // Assert - Assert.That(modelMr.HasConflicts, Is.False); - Assert.That(modelMr.DivergedCommitsCount, Is.EqualTo(0)); - Assert.That(modelMr.DiffRefs?.BaseSha, Is.Not.Null); - Assert.That(modelMr.DiffRefs.StartSha, Is.EqualTo(modelMr.DiffRefs.BaseSha)); - Assert.That(modelMr.State, Is.EqualTo("merged")); + var targetGroup = new Group("TheTargetGroup"); + server.Groups.Add(targetGroup); - Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.False, - "Since the merge succeeded and 'ShouldRemoveSourceBranch' was set, 'to-be-merged' branch should be gone"); + var targetProject = new Project("TheTargetProject") { Visibility = VisibilityLevel.Internal }; + targetGroup.Projects.Add(targetProject); - Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.False, - "Since the merge succeeded and 'ShouldRemoveSourceBranch' was set, 'to-be-merged' branch should be gone"); - } + targetProject.Permissions.Add(new Permission(maintainer, AccessLevel.Maintainer)); + targetProject.Repository.Commit(maintainer, "A commit"); - [TestCase(false)] - [TestCase(true)] - public void Test_merge_request_with_non_conflicting_rebase_needed_and_merge_method_ff_cannot_be_accepted(bool sourceProjectSameAsTargetProject) - { - // Arrange - using var server = new GitLabServer(); + var sourceProject = sourceProjectSameAsTargetProject ? + targetProject : + targetProject.Fork(contributor.Namespace, contributor, "TheSourceProject"); + sourceProject.Repository.CreateAndCheckoutBranch("to-be-merged"); + sourceProject.Repository.Commit(contributor, "add a file", new[] { File.CreateFromText(Guid.NewGuid().ToString("N"), "This is the new file's content") }); + + var mr = targetProject.CreateMergeRequest(contributor, "A great title", "A great description", targetProject.DefaultBranch, "to-be-merged", sourceProject); + mr.Assignee = new UserRef(maintainer); - var contributor = server.Users.AddNew("contributor"); - var maintainer = server.Users.AddNew("maintainer"); + targetProject.MergeMethod = "ff"; - var targetGroup = new Group("TheTargetGroup"); - server.Groups.Add(targetGroup); + var maintainerClient = server.CreateClient("maintainer"); - var targetProject = new Project("TheTargetProject") { Visibility = VisibilityLevel.Internal }; - targetGroup.Projects.Add(targetProject); + // Act + var modelMr = maintainerClient.GetMergeRequest(mr.Project.Id).Accept(mr.Iid, new MergeRequestMerge + { + MergeWhenPipelineSucceeds = mr.HeadPipeline != null, + ShouldRemoveSourceBranch = true, + Sha = mr.HeadSha, + }); + + // Assert + Assert.That(modelMr.HasConflicts, Is.False); + Assert.That(modelMr.DivergedCommitsCount, Is.EqualTo(0)); + Assert.That(modelMr.DiffRefs?.BaseSha, Is.Not.Null); + Assert.That(modelMr.DiffRefs.StartSha, Is.EqualTo(modelMr.DiffRefs.BaseSha)); + Assert.That(modelMr.State, Is.EqualTo("merged")); + + Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.False, + "Since the merge succeeded and 'ShouldRemoveSourceBranch' was set, 'to-be-merged' branch should be gone"); + + Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.False, + "Since the merge succeeded and 'ShouldRemoveSourceBranch' was set, 'to-be-merged' branch should be gone"); + } - targetProject.Permissions.Add(new Permission(maintainer, AccessLevel.Maintainer)); - targetProject.Repository.Commit(maintainer, "A commit"); + [TestCase(false)] + [TestCase(true)] + public void Test_merge_request_with_non_conflicting_rebase_needed_and_merge_method_ff_cannot_be_accepted(bool sourceProjectSameAsTargetProject) + { + // Arrange + using var server = new GitLabServer(); - var sourceProject = sourceProjectSameAsTargetProject ? - targetProject : - targetProject.Fork(contributor.Namespace, contributor, "TheSourceProject"); - sourceProject.Repository.CreateAndCheckoutBranch("to-be-merged"); - sourceProject.Repository.Commit(contributor, "add a file", new[] { File.CreateFromText(Guid.NewGuid().ToString("N"), "This is the new file's content") }); + var contributor = server.Users.AddNew("contributor"); + var maintainer = server.Users.AddNew("maintainer"); - targetProject.MergeMethod = "ff"; + var targetGroup = new Group("TheTargetGroup"); + server.Groups.Add(targetGroup); - targetProject.Repository.Checkout(targetProject.DefaultBranch); - targetProject.Repository.Commit(maintainer, "add a file", new[] { File.CreateFromText(Guid.NewGuid().ToString("N"), "This is the new file's content") }); + var targetProject = new Project("TheTargetProject") { Visibility = VisibilityLevel.Internal }; + targetGroup.Projects.Add(targetProject); - var mr = targetProject.CreateMergeRequest(contributor, "A great title", "A great description", targetProject.DefaultBranch, "to-be-merged", sourceProject); - mr.Assignee = new UserRef(maintainer); + targetProject.Permissions.Add(new Permission(maintainer, AccessLevel.Maintainer)); + targetProject.Repository.Commit(maintainer, "A commit"); - var maintainerClient = server.CreateClient("maintainer"); + var sourceProject = sourceProjectSameAsTargetProject ? + targetProject : + targetProject.Fork(contributor.Namespace, contributor, "TheSourceProject"); + sourceProject.Repository.CreateAndCheckoutBranch("to-be-merged"); + sourceProject.Repository.Commit(contributor, "add a file", new[] { File.CreateFromText(Guid.NewGuid().ToString("N"), "This is the new file's content") }); - // Act/Assert - var exception = Assert.Throws(() => maintainerClient.GetMergeRequest(mr.Project.Id).Accept(mr.Iid, new MergeRequestMerge - { - MergeWhenPipelineSucceeds = mr.HeadPipeline != null, - ShouldRemoveSourceBranch = true, - })); - Assert.That(exception.StatusCode, Is.EqualTo(HttpStatusCode.MethodNotAllowed)); - Assert.That(exception.Message.Equals("The MR cannot be merged with method 'ff': the source branch must first be rebased", StringComparison.Ordinal), Is.True); + targetProject.MergeMethod = "ff"; - Assert.That(mr.HasConflicts, Is.False); - Assert.That(mr.DivergedCommitsCount, Is.EqualTo(1)); - Assert.That(mr.StartSha, Is.Not.EqualTo(mr.BaseSha)); + targetProject.Repository.Checkout(targetProject.DefaultBranch); + targetProject.Repository.Commit(maintainer, "add a file", new[] { File.CreateFromText(Guid.NewGuid().ToString("N"), "This is the new file's content") }); - Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, - "Since the merge failed, 'to-be-merged' branch should still be there"); + var mr = targetProject.CreateMergeRequest(contributor, "A great title", "A great description", targetProject.DefaultBranch, "to-be-merged", sourceProject); + mr.Assignee = new UserRef(maintainer); - Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, - "Since the merge failed, 'to-be-merged' branch should still be there"); - } + var maintainerClient = server.CreateClient("maintainer"); - [TestCase(false)] - [TestCase(true)] - public void Test_merge_request_with_conflicts_cannot_be_accepted(bool sourceProjectSameAsTargetProject) + // Act/Assert + var exception = Assert.Throws(() => maintainerClient.GetMergeRequest(mr.Project.Id).Accept(mr.Iid, new MergeRequestMerge { - // Arrange - using var server = new GitLabServer(); + MergeWhenPipelineSucceeds = mr.HeadPipeline != null, + ShouldRemoveSourceBranch = true, + })); + Assert.That(exception.StatusCode, Is.EqualTo(HttpStatusCode.MethodNotAllowed)); + Assert.That(exception.Message.Equals("The MR cannot be merged with method 'ff': the source branch must first be rebased", StringComparison.Ordinal), Is.True); - var contributor = server.Users.AddNew("contributor"); - var maintainer = server.Users.AddNew("maintainer"); + Assert.That(mr.HasConflicts, Is.False); + Assert.That(mr.DivergedCommitsCount, Is.EqualTo(1)); + Assert.That(mr.StartSha, Is.Not.EqualTo(mr.BaseSha)); - var targetGroup = new Group("TheTargetGroup"); - server.Groups.Add(targetGroup); + Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, + "Since the merge failed, 'to-be-merged' branch should still be there"); - var targetProject = new Project("TheTargetProject") { Visibility = VisibilityLevel.Internal }; - targetGroup.Projects.Add(targetProject); + Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, + "Since the merge failed, 'to-be-merged' branch should still be there"); + } - targetProject.Permissions.Add(new Permission(maintainer, AccessLevel.Maintainer)); - targetProject.Repository.Commit(maintainer, "A commit"); + [TestCase(false)] + [TestCase(true)] + public void Test_merge_request_with_conflicts_cannot_be_accepted(bool sourceProjectSameAsTargetProject) + { + // Arrange + using var server = new GitLabServer(); - var sourceProject = sourceProjectSameAsTargetProject ? - targetProject : - targetProject.Fork(contributor.Namespace, contributor, "TheSourceProject"); - var conflictingFile = Guid.NewGuid().ToString("N"); - sourceProject.Repository.CreateAndCheckoutBranch("to-be-merged"); - sourceProject.Repository.Commit(contributor, "add a file", new[] { File.CreateFromText(conflictingFile, "This is the new file's content") }); + var contributor = server.Users.AddNew("contributor"); + var maintainer = server.Users.AddNew("maintainer"); - targetProject.MergeMethod = "ff"; + var targetGroup = new Group("TheTargetGroup"); + server.Groups.Add(targetGroup); - targetProject.Repository.Checkout(targetProject.DefaultBranch); - targetProject.Repository.Commit(maintainer, "add a file", new[] { File.CreateFromText(conflictingFile, "This is conflicting content") }); + var targetProject = new Project("TheTargetProject") { Visibility = VisibilityLevel.Internal }; + targetGroup.Projects.Add(targetProject); - var mr = targetProject.CreateMergeRequest(contributor, "A great title", "A great description", targetProject.DefaultBranch, "to-be-merged", sourceProject); - mr.Assignee = new UserRef(maintainer); + targetProject.Permissions.Add(new Permission(maintainer, AccessLevel.Maintainer)); + targetProject.Repository.Commit(maintainer, "A commit"); - var maintainerClient = server.CreateClient("maintainer"); + var sourceProject = sourceProjectSameAsTargetProject ? + targetProject : + targetProject.Fork(contributor.Namespace, contributor, "TheSourceProject"); + var conflictingFile = Guid.NewGuid().ToString("N"); + sourceProject.Repository.CreateAndCheckoutBranch("to-be-merged"); + sourceProject.Repository.Commit(contributor, "add a file", new[] { File.CreateFromText(conflictingFile, "This is the new file's content") }); - // Act/Assert - var exception = Assert.Throws(() => maintainerClient.GetMergeRequest(mr.Project.Id).Accept(mr.Iid, new MergeRequestMerge - { - MergeWhenPipelineSucceeds = mr.HeadPipeline != null, - ShouldRemoveSourceBranch = true, - })); - Assert.That(exception.StatusCode, Is.EqualTo(HttpStatusCode.NotAcceptable)); - Assert.That(exception.Message.Equals("The merge request has some conflicts and cannot be merged", StringComparison.Ordinal), Is.True); + targetProject.MergeMethod = "ff"; - Assert.That(mr.HasConflicts, Is.True); - Assert.That(mr.DivergedCommitsCount, Is.EqualTo(1)); - Assert.That(mr.StartSha, Is.Not.EqualTo(mr.BaseSha)); + targetProject.Repository.Checkout(targetProject.DefaultBranch); + targetProject.Repository.Commit(maintainer, "add a file", new[] { File.CreateFromText(conflictingFile, "This is conflicting content") }); - Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, - "Since the merge failed, 'to-be-merged' branch should still be there"); + var mr = targetProject.CreateMergeRequest(contributor, "A great title", "A great description", targetProject.DefaultBranch, "to-be-merged", sourceProject); + mr.Assignee = new UserRef(maintainer); - Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, - "Since the merge failed, 'to-be-merged' branch should still be there"); - } + var maintainerClient = server.CreateClient("maintainer"); - [Test] - public void Test_merge_request_with_head_pipeline() + // Act/Assert + var exception = Assert.Throws(() => maintainerClient.GetMergeRequest(mr.Project.Id).Accept(mr.Iid, new MergeRequestMerge { - using var server = new GitLabServer(); - var user = server.Users.AddNew(); - var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); - var commit = project.Repository.Commit(user, "test"); + MergeWhenPipelineSucceeds = mr.HeadPipeline != null, + ShouldRemoveSourceBranch = true, + })); + Assert.That(exception.StatusCode, Is.EqualTo(HttpStatusCode.NotAcceptable)); + Assert.That(exception.Message.Equals("The merge request has some conflicts and cannot be merged", StringComparison.Ordinal), Is.True); - var branch = "my-branch"; - project.Repository.CreateAndCheckoutBranch(branch); - commit = project.Repository.Commit(user, "another test"); + Assert.That(mr.HasConflicts, Is.True); + Assert.That(mr.DivergedCommitsCount, Is.EqualTo(1)); + Assert.That(mr.StartSha, Is.Not.EqualTo(mr.BaseSha)); - var mr = project.CreateMergeRequest(user, "A great title", "A great description", project.DefaultBranch, branch); - Assert.That(mr.HeadPipeline, Is.Null, "No pipeline created yet on the source branch"); + Assert.That(targetProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, + "Since the merge failed, 'to-be-merged' branch should still be there"); - var pipeline = project.Pipelines.Add(branch, JobStatus.Success, user); - Assert.That(mr.HeadPipeline, Is.EqualTo(pipeline), "A pipeline was just created on the source branch"); - } + Assert.That(sourceProject.Repository.GetAllBranches().Any(b => b.FriendlyName.EndsWith("to-be-merged", StringComparison.Ordinal)), Is.True, + "Since the merge failed, 'to-be-merged' branch should still be there"); + } - [Test] - public void Test_merge_request_resource_state_events_found_on_close_and_reopen() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test", configure: project => project - .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2")) - .BuildServer(); + [Test] + public void Test_merge_request_with_head_pipeline() + { + using var server = new GitLabServer(); + var user = server.Users.AddNew(); + var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); + var commit = project.Repository.Commit(user, "test"); - var client = server.CreateClient("user1"); - var projectId = server.AllProjects.First().Id; - var mrClient = client.GetMergeRequest(projectId); - var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); + var branch = "my-branch"; + project.Repository.CreateAndCheckoutBranch(branch); + commit = project.Repository.Commit(user, "another test"); - mrClient.Close(mergeRequest.Iid); - mrClient.Reopen(mergeRequest.Iid); + var mr = project.CreateMergeRequest(user, "A great title", "A great description", project.DefaultBranch, branch); + Assert.That(mr.HeadPipeline, Is.Null, "No pipeline created yet on the source branch"); - var resourceStateEvents = mrClient.ResourceStateEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); - Assert.That(resourceStateEvents, Has.Length.EqualTo(2)); + var pipeline = project.Pipelines.Add(branch, JobStatus.Success, user); + Assert.That(mr.HeadPipeline, Is.EqualTo(pipeline), "A pipeline was just created on the source branch"); + } + + [Test] + public void Test_merge_request_resource_state_events_found_on_close_and_reopen() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2")) + .BuildServer(); - var closeStateEvents = resourceStateEvents.Where(e => string.Equals(e.State, "closed", StringComparison.Ordinal)).ToArray(); - Assert.That(closeStateEvents, Has.Length.EqualTo(1)); + var client = server.CreateClient("user1"); + var projectId = server.AllProjects.First().Id; + var mrClient = client.GetMergeRequest(projectId); + var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); - var reopenMilestoneEvents = resourceStateEvents.Where(e => string.Equals(e.State, "reopened", StringComparison.Ordinal)).ToArray(); - Assert.That(reopenMilestoneEvents, Has.Length.EqualTo(1)); - } + mrClient.Close(mergeRequest.Iid); + mrClient.Reopen(mergeRequest.Iid); - [Test] - public void Test_merge_request_resource_label_events_found() + var resourceStateEvents = mrClient.ResourceStateEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); + Assert.That(resourceStateEvents, Has.Length.EqualTo(2)); + + var closeStateEvents = resourceStateEvents.Where(e => string.Equals(e.State, "closed", StringComparison.Ordinal)).ToArray(); + Assert.That(closeStateEvents, Has.Length.EqualTo(1)); + + var reopenMilestoneEvents = resourceStateEvents.Where(e => string.Equals(e.State, "reopened", StringComparison.Ordinal)).ToArray(); + Assert.That(reopenMilestoneEvents, Has.Length.EqualTo(1)); + } + + [Test] + public void Test_merge_request_resource_label_events_found() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var projectId = server.AllProjects.First().Id; + var mrClient = client.GetMergeRequest(projectId); + var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() + { + AddLabels = "first,second,third", + }); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() + { + RemoveLabels = "second", + }); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test", configure: project => project - .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2")) - .BuildServer(); - - var client = server.CreateClient("user1"); - var projectId = server.AllProjects.First().Id; - var mrClient = client.GetMergeRequest(projectId); - var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); - - mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() - { - AddLabels = "first,second,third", - }); - - mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() - { - RemoveLabels = "second", - }); - - mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() - { - Labels = "first,second", - }); - - /* We're expecting this sequence - * 1. Add first - * 1. Add second - * 1. Add third - * 2. Remove second - * 3. Add second - * 3. Remove third - */ - var resourceLabelEvents = mrClient.ResourceLabelEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); - Assert.That(resourceLabelEvents, Has.Length.EqualTo(6)); - - var addLabelEvents = resourceLabelEvents.Where(e => e.Action == ResourceLabelEventAction.Add).ToArray(); - Assert.That(addLabelEvents, Has.Length.EqualTo(4)); - - var removeLabelEvents = resourceLabelEvents.Where(e => e.Action == ResourceLabelEventAction.Remove).ToArray(); - Assert.That(removeLabelEvents, Has.Length.EqualTo(2)); - } - - [Test] - public void Test_merge_request_resource_milestone_events_found() + Labels = "first,second", + }); + + /* We're expecting this sequence + * 1. Add first + * 1. Add second + * 1. Add third + * 2. Remove second + * 3. Add second + * 3. Remove third + */ + var resourceLabelEvents = mrClient.ResourceLabelEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); + Assert.That(resourceLabelEvents, Has.Length.EqualTo(6)); + + var addLabelEvents = resourceLabelEvents.Where(e => e.Action == ResourceLabelEventAction.Add).ToArray(); + Assert.That(addLabelEvents, Has.Length.EqualTo(4)); + + var removeLabelEvents = resourceLabelEvents.Where(e => e.Action == ResourceLabelEventAction.Remove).ToArray(); + Assert.That(removeLabelEvents, Has.Length.EqualTo(2)); + } + + [Test] + public void Test_merge_request_resource_milestone_events_found() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithUser("user2") + .WithProject("Test", configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2") + .WithMilestone("Milestone 1") + .WithMilestone("Milestone 2")) + .BuildServer(); + + var client = server.CreateClient("user1"); + var projectId = server.AllProjects.First().Id; + var mrClient = client.GetMergeRequest(projectId); + var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); + var milestones = client.GetMilestone(1).All.ToArray(); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() + { + MilestoneId = milestones[0].Id, + }); + + mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithUser("user2") - .WithProject("Test", configure: project => project - .WithMergeRequest("branch-01", title: "Merge request 1", author: "user1", assignee: "user2") - .WithMilestone("Milestone 1") - .WithMilestone("Milestone 2")) - .BuildServer(); - - var client = server.CreateClient("user1"); - var projectId = server.AllProjects.First().Id; - var mrClient = client.GetMergeRequest(projectId); - var mergeRequest = mrClient.Get(new MergeRequestQuery { Scope = "created_by_me" }).First(); - var milestones = client.GetMilestone(1).All.ToArray(); - - mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() - { - MilestoneId = milestones[0].Id, - }); - - mrClient.Update(mergeRequest.Iid, new MergeRequestUpdate() - { - MilestoneId = milestones[1].Id, - }); - - /* We're expecting this sequence - * 1. Add milestone 1 - * 2. Remove milestone 1 - * 2. Add milestone 2 - */ - var resourceMilestoneEvents = mrClient.ResourceMilestoneEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); - Assert.That(resourceMilestoneEvents, Has.Length.EqualTo(3)); - - var removeMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Remove).ToArray(); - Assert.That(removeMilestoneEvents, Has.Length.EqualTo(1)); - Assert.That(removeMilestoneEvents[0].Milestone.Id, Is.EqualTo(milestones[0].Id)); - - var addMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Add).ToArray(); - Assert.That(addMilestoneEvents, Has.Length.EqualTo(2)); - Assert.That(addMilestoneEvents[0].Milestone.Id, Is.EqualTo(milestones[0].Id)); - Assert.That(addMilestoneEvents[1].Milestone.Id, Is.EqualTo(milestones[1].Id)); - } + MilestoneId = milestones[1].Id, + }); + + /* We're expecting this sequence + * 1. Add milestone 1 + * 2. Remove milestone 1 + * 2. Add milestone 2 + */ + var resourceMilestoneEvents = mrClient.ResourceMilestoneEventsAsync(projectId: projectId, mergeRequestIid: mergeRequest.Iid).ToArray(); + Assert.That(resourceMilestoneEvents, Has.Length.EqualTo(3)); + + var removeMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Remove).ToArray(); + Assert.That(removeMilestoneEvents, Has.Length.EqualTo(1)); + Assert.That(removeMilestoneEvents[0].Milestone.Id, Is.EqualTo(milestones[0].Id)); + + var addMilestoneEvents = resourceMilestoneEvents.Where(e => e.Action == ResourceMilestoneEventAction.Add).ToArray(); + Assert.That(addMilestoneEvents, Has.Length.EqualTo(2)); + Assert.That(addMilestoneEvents[0].Milestone.Id, Is.EqualTo(milestones[0].Id)); + Assert.That(addMilestoneEvents[1].Milestone.Id, Is.EqualTo(milestones[1].Id)); } } diff --git a/NGitLab.Mock.Tests/MilestonesMockTests.cs b/NGitLab.Mock.Tests/MilestonesMockTests.cs index 83212ae2..151a5819 100644 --- a/NGitLab.Mock.Tests/MilestonesMockTests.cs +++ b/NGitLab.Mock.Tests/MilestonesMockTests.cs @@ -4,142 +4,141 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class MilestonesMockTests { - public class MilestonesMockTests + [Test] + public void Test_milestones_can_be_found_from_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, configure: project => project + .WithMilestone("Milestone 1") + .WithMilestone("Milestone 2")) + .BuildServer(); + + var client = server.CreateClient(); + var milestones = client.GetMilestone(1).All.ToArray(); + + Assert.That(milestones, Has.Length.EqualTo(2), "Milestones count is invalid"); + Assert.That(milestones.Any(x => string.Equals(x.Title, "Milestone 1", StringComparison.Ordinal)), Is.True, "Milestone 'Milestone 1' not found"); + Assert.That(milestones.Any(x => string.Equals(x.Title, "Milestone 2", StringComparison.Ordinal)), Is.True, "Milestone 'Milestone 2' not found"); + } + + [Test] + public void Test_milestones_can_be_added_to_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true) + .BuildServer(); + + var client = server.CreateClient(); + client.GetMilestone(1).Create(new MilestoneCreate { Title = "Milestone 1" }); + var milestones = client.GetMilestone(1).All.ToArray(); + + Assert.That(milestones, Has.Length.EqualTo(1), "Milestones count is invalid"); + Assert.That(milestones[0].Title, Is.EqualTo("Milestone 1"), "Milestone 'Milestone 1' not found"); + } + + [Test] + public void Test_milestones_can_be_edited_from_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project + .WithMilestone("Milestone 1", id: 1)) + .BuildServer(); + + var client = server.CreateClient(); + client.GetMilestone(1).Update(1, new MilestoneUpdate { Title = "Milestone 2" }); + var milestones = client.GetMilestone(1).All.ToArray(); + + Assert.That(milestones, Has.Length.EqualTo(1), "Milestones count is invalid"); + Assert.That(milestones[0].Title, Is.EqualTo("Milestone 2"), "Milestone 'Milestone 2' not found"); + } + + [Test] + public void Test_milestones_can_be_deleted_from_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project + .WithMilestone("Milestone 1", id: 1)) + .BuildServer(); + + var client = server.CreateClient(); + client.GetMilestone(1).Delete(1); + var milestones = client.GetMilestone(1).All.ToArray(); + + Assert.That(milestones, Is.Empty, "Milestones count is invalid"); + } + + [Test] + public void Test_milestones_can_be_closed_and_activated_from_project() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project + .WithMilestone("Milestone 1", id: 1)) + .BuildServer(); + + var client = server.CreateClient(); + client.GetMilestone(1).Close(1); + var activeMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.active).ToArray(); + var closedMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.closed).ToArray(); + + Assert.That(activeMilestones, Is.Empty, "Active milestones count is invalid"); + Assert.That(closedMilestones, Has.Length.EqualTo(1), "Closed milestones count is invalid"); + + client.GetMilestone(1).Activate(1); + activeMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.active).ToArray(); + closedMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.closed).ToArray(); + + Assert.That(activeMilestones, Has.Length.EqualTo(1), "Active milestones count is invalid"); + Assert.That(closedMilestones, Is.Empty, "Closed milestones count is invalid"); + } + + [Test] + public void Test_projects_merge_request_can_be_found_from_milestone() + { + const int ProjectId = 1; + const int MilestoneId = 1; + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", id: ProjectId, addDefaultUserAsMaintainer: true, configure: project => project + .WithMilestone("Milestone 1", id: MilestoneId) + .WithMergeRequest("branch-01", title: "Merge request 1", milestone: "Milestone 1") + .WithMergeRequest("branch-02", title: "Merge request 2", milestone: "Milestone 1") + .WithMergeRequest("branch-03", title: "Merge request 3", milestone: "Milestone 2")) + .BuildServer(); + + var client = server.CreateClient(); + var mergeRequests = client.GetMilestone(ProjectId).GetMergeRequests(MilestoneId).ToArray(); + Assert.That(mergeRequests, Has.Length.EqualTo(2), "Merge requests count is invalid"); + } + + [Test] + public void Test_groups_merge_request_can_be_found_from_milestone() { - [Test] - public void Test_milestones_can_be_found_from_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, configure: project => project - .WithMilestone("Milestone 1") - .WithMilestone("Milestone 2")) - .BuildServer(); - - var client = server.CreateClient(); - var milestones = client.GetMilestone(1).All.ToArray(); - - Assert.That(milestones, Has.Length.EqualTo(2), "Milestones count is invalid"); - Assert.That(milestones.Any(x => string.Equals(x.Title, "Milestone 1", StringComparison.Ordinal)), Is.True, "Milestone 'Milestone 1' not found"); - Assert.That(milestones.Any(x => string.Equals(x.Title, "Milestone 2", StringComparison.Ordinal)), Is.True, "Milestone 'Milestone 2' not found"); - } - - [Test] - public void Test_milestones_can_be_added_to_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true) - .BuildServer(); - - var client = server.CreateClient(); - client.GetMilestone(1).Create(new MilestoneCreate { Title = "Milestone 1" }); - var milestones = client.GetMilestone(1).All.ToArray(); - - Assert.That(milestones, Has.Length.EqualTo(1), "Milestones count is invalid"); - Assert.That(milestones[0].Title, Is.EqualTo("Milestone 1"), "Milestone 'Milestone 1' not found"); - } - - [Test] - public void Test_milestones_can_be_edited_from_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project - .WithMilestone("Milestone 1", id: 1)) - .BuildServer(); - - var client = server.CreateClient(); - client.GetMilestone(1).Update(1, new MilestoneUpdate { Title = "Milestone 2" }); - var milestones = client.GetMilestone(1).All.ToArray(); - - Assert.That(milestones, Has.Length.EqualTo(1), "Milestones count is invalid"); - Assert.That(milestones[0].Title, Is.EqualTo("Milestone 2"), "Milestone 'Milestone 2' not found"); - } - - [Test] - public void Test_milestones_can_be_deleted_from_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project - .WithMilestone("Milestone 1", id: 1)) - .BuildServer(); - - var client = server.CreateClient(); - client.GetMilestone(1).Delete(1); - var milestones = client.GetMilestone(1).All.ToArray(); - - Assert.That(milestones, Is.Empty, "Milestones count is invalid"); - } - - [Test] - public void Test_milestones_can_be_closed_and_activated_from_project() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: 1, addDefaultUserAsMaintainer: true, configure: project => project - .WithMilestone("Milestone 1", id: 1)) - .BuildServer(); - - var client = server.CreateClient(); - client.GetMilestone(1).Close(1); - var activeMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.active).ToArray(); - var closedMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.closed).ToArray(); - - Assert.That(activeMilestones, Is.Empty, "Active milestones count is invalid"); - Assert.That(closedMilestones, Has.Length.EqualTo(1), "Closed milestones count is invalid"); - - client.GetMilestone(1).Activate(1); - activeMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.active).ToArray(); - closedMilestones = client.GetMilestone(1).AllInState(Models.MilestoneState.closed).ToArray(); - - Assert.That(activeMilestones, Has.Length.EqualTo(1), "Active milestones count is invalid"); - Assert.That(closedMilestones, Is.Empty, "Closed milestones count is invalid"); - } - - [Test] - public void Test_projects_merge_request_can_be_found_from_milestone() - { - const int ProjectId = 1; - const int MilestoneId = 1; - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", id: ProjectId, addDefaultUserAsMaintainer: true, configure: project => project - .WithMilestone("Milestone 1", id: MilestoneId) - .WithMergeRequest("branch-01", title: "Merge request 1", milestone: "Milestone 1") - .WithMergeRequest("branch-02", title: "Merge request 2", milestone: "Milestone 1") - .WithMergeRequest("branch-03", title: "Merge request 3", milestone: "Milestone 2")) - .BuildServer(); - - var client = server.CreateClient(); - var mergeRequests = client.GetMilestone(ProjectId).GetMergeRequests(MilestoneId).ToArray(); - Assert.That(mergeRequests, Has.Length.EqualTo(2), "Merge requests count is invalid"); - } - - [Test] - public void Test_groups_merge_request_can_be_found_from_milestone() - { - const int projectId = 1; - const int milestoneId = 1; - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithGroup("parentGroup", id: projectId, configure: group => group - .WithMilestone("Milestone 1", id: milestoneId)) - .WithGroup("subGroup1", 2, @namespace: "parentGroup") - .WithGroup("subGroup2", 3, @namespace: "parentGroup") - .WithProject("project1", @namespace: "parentGroup/subGroup1", addDefaultUserAsMaintainer: true, configure: project => project - .WithMergeRequest("branch-01", title: "Merge request 1", milestone: "Milestone 1") - .WithMergeRequest("branch-02", title: "Merge request 2", milestone: "Milestone 2")) - .WithProject("project2", @namespace: "parentGroup/subGroup2", addDefaultUserAsMaintainer: true, configure: project => project - .WithMergeRequest("branch-03", title: "Merge request 3", milestone: "Milestone 1")) - .BuildServer(); - - var client = server.CreateClient(); - var mergeRequests = client.GetGroupMilestone(projectId).GetMergeRequests(milestoneId).ToArray(); - Assert.That(mergeRequests, Has.Length.EqualTo(2), "Merge requests count is invalid"); - } + const int projectId = 1; + const int milestoneId = 1; + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithGroup("parentGroup", id: projectId, configure: group => group + .WithMilestone("Milestone 1", id: milestoneId)) + .WithGroup("subGroup1", 2, @namespace: "parentGroup") + .WithGroup("subGroup2", 3, @namespace: "parentGroup") + .WithProject("project1", @namespace: "parentGroup/subGroup1", addDefaultUserAsMaintainer: true, configure: project => project + .WithMergeRequest("branch-01", title: "Merge request 1", milestone: "Milestone 1") + .WithMergeRequest("branch-02", title: "Merge request 2", milestone: "Milestone 2")) + .WithProject("project2", @namespace: "parentGroup/subGroup2", addDefaultUserAsMaintainer: true, configure: project => project + .WithMergeRequest("branch-03", title: "Merge request 3", milestone: "Milestone 1")) + .BuildServer(); + + var client = server.CreateClient(); + var mergeRequests = client.GetGroupMilestone(projectId).GetMergeRequests(milestoneId).ToArray(); + Assert.That(mergeRequests, Has.Length.EqualTo(2), "Merge requests count is invalid"); } } diff --git a/NGitLab.Mock.Tests/PipelineTests.cs b/NGitLab.Mock.Tests/PipelineTests.cs index 53365340..fb3c7907 100644 --- a/NGitLab.Mock.Tests/PipelineTests.cs +++ b/NGitLab.Mock.Tests/PipelineTests.cs @@ -3,112 +3,111 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class PipelineTests { - public class PipelineTests + [Test] + public async Task Test_pipelines() { - [Test] - public async Task Test_pipelines() - { - using var server = new GitLabServer(); - var user = server.Users.AddNew(); - var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); - var commit = project.Repository.Commit(user, "test"); + using var server = new GitLabServer(); + var user = server.Users.AddNew(); + var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); + var commit = project.Repository.Commit(user, "test"); - var pipeline = project.Pipelines.Add(commit.Sha, JobStatus.Success, user); - var job = pipeline.AddNewJob("Test_job", JobStatus.Success); - job.Trace = "This is a trace\nWith Multiple line"; - - var client = server.CreateClient(); - Assert.That(await client.GetJobs(project.Id).GetTraceAsync(job.Id), Is.EqualTo(job.Trace)); - } + var pipeline = project.Pipelines.Add(commit.Sha, JobStatus.Success, user); + var job = pipeline.AddNewJob("Test_job", JobStatus.Success); + job.Trace = "This is a trace\nWith Multiple line"; - [Test] - public void Test_pipelines_testreport_summary() - { - using var server = new GitLabServer(); - var user = server.Users.AddNew(); - var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); - var commit = project.Repository.Commit(user, "test"); + var client = server.CreateClient(); + Assert.That(await client.GetJobs(project.Id).GetTraceAsync(job.Id), Is.EqualTo(job.Trace)); + } - var pipeline = project.Pipelines.Add(commit.Sha, JobStatus.Success, user); - pipeline.TestReportsSummary = new TestReportSummary - { - Total = new TestReportSummaryTotals - { - Time = 60, - Count = 1157, - Success = 1157, - Failed = 0, - Skipped = 0, - Error = 0, - }, - }; - - var client = server.CreateClient(); - var summary = client.GetPipelines(project.Id).GetTestReportsSummary(pipeline.Id); - Assert.That(summary.Total.Time, Is.EqualTo(60)); - Assert.That(summary.Total.Count, Is.EqualTo(1157)); - Assert.That(summary.Total.Success, Is.EqualTo(1157)); - Assert.That(summary.Total.Skipped, Is.EqualTo(0)); - Assert.That(summary.Total.Failed, Is.EqualTo(0)); - Assert.That(summary.Total.Error, Is.EqualTo(0)); - } + [Test] + public void Test_pipelines_testreport_summary() + { + using var server = new GitLabServer(); + var user = server.Users.AddNew(); + var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); + var commit = project.Repository.Commit(user, "test"); - [TestCase(false)] - [TestCase(true)] - public void Test_create_pipeline_with_branch_ref_sets_sha(bool addCommitAfterBranching) + var pipeline = project.Pipelines.Add(commit.Sha, JobStatus.Success, user); + pipeline.TestReportsSummary = new TestReportSummary { - using var server = new GitLabServer(); - var user = server.Users.AddNew(); - var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); - var commit = project.Repository.Commit(user, "test"); - - var branch = "my-branch"; - if (addCommitAfterBranching) + Total = new TestReportSummaryTotals { - project.Repository.CreateAndCheckoutBranch(branch); - var commit2 = project.Repository.Commit(user, "another test"); - Assert.That(commit2.Sha, Is.Not.EqualTo(commit.Sha)); - commit = commit2; - } - else - { - project.Repository.CreateBranch(branch); - } + Time = 60, + Count = 1157, + Success = 1157, + Failed = 0, + Skipped = 0, + Error = 0, + }, + }; + + var client = server.CreateClient(); + var summary = client.GetPipelines(project.Id).GetTestReportsSummary(pipeline.Id); + Assert.That(summary.Total.Time, Is.EqualTo(60)); + Assert.That(summary.Total.Count, Is.EqualTo(1157)); + Assert.That(summary.Total.Success, Is.EqualTo(1157)); + Assert.That(summary.Total.Skipped, Is.EqualTo(0)); + Assert.That(summary.Total.Failed, Is.EqualTo(0)); + Assert.That(summary.Total.Error, Is.EqualTo(0)); + } - var pipeline = project.Pipelines.Add(branch, JobStatus.Success, user); + [TestCase(false)] + [TestCase(true)] + public void Test_create_pipeline_with_branch_ref_sets_sha(bool addCommitAfterBranching) + { + using var server = new GitLabServer(); + var user = server.Users.AddNew(); + var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); + var commit = project.Repository.Commit(user, "test"); - Assert.That(pipeline.Sha, Is.EqualTo(new Sha1(commit.Sha))); + var branch = "my-branch"; + if (addCommitAfterBranching) + { + project.Repository.CreateAndCheckoutBranch(branch); + var commit2 = project.Repository.Commit(user, "another test"); + Assert.That(commit2.Sha, Is.Not.EqualTo(commit.Sha)); + commit = commit2; } - - [Test] - public void Test_create_pipeline_with_tag_ref_sets_sha() + else { - using var server = new GitLabServer(); - var user = server.Users.AddNew(); - var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); - var commit = project.Repository.Commit(user, "test"); + project.Repository.CreateBranch(branch); + } - var tag = "my-tag"; - project.Repository.CreateTag(tag); + var pipeline = project.Pipelines.Add(branch, JobStatus.Success, user); - var pipeline = project.Pipelines.Add(tag, JobStatus.Success, user); + Assert.That(pipeline.Sha, Is.EqualTo(new Sha1(commit.Sha))); + } - Assert.That(pipeline.Sha, Is.EqualTo(new Sha1(commit.Sha))); - } + [Test] + public void Test_create_pipeline_with_tag_ref_sets_sha() + { + using var server = new GitLabServer(); + var user = server.Users.AddNew(); + var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); + var commit = project.Repository.Commit(user, "test"); - [Test] - public void Test_create_pipeline_with_invalid_ref_does_not_set_sha() - { - using var server = new GitLabServer(); - var user = server.Users.AddNew(); - var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); - var commit = project.Repository.Commit(user, "test"); + var tag = "my-tag"; + project.Repository.CreateTag(tag); - var pipeline = project.Pipelines.Add("invalid_ref", JobStatus.Success, user); + var pipeline = project.Pipelines.Add(tag, JobStatus.Success, user); - Assert.That(pipeline.Sha, Is.EqualTo(default(Sha1))); - } + Assert.That(pipeline.Sha, Is.EqualTo(new Sha1(commit.Sha))); + } + + [Test] + public void Test_create_pipeline_with_invalid_ref_does_not_set_sha() + { + using var server = new GitLabServer(); + var user = server.Users.AddNew(); + var project = user.Namespace.Projects.AddNew(project => project.Visibility = VisibilityLevel.Internal); + var commit = project.Repository.Commit(user, "test"); + + var pipeline = project.Pipelines.Add("invalid_ref", JobStatus.Success, user); + + Assert.That(pipeline.Sha, Is.EqualTo(default(Sha1))); } } diff --git a/NGitLab.Mock.Tests/ProjectsMockTests.cs b/NGitLab.Mock.Tests/ProjectsMockTests.cs index c28ceee3..88194a72 100644 --- a/NGitLab.Mock.Tests/ProjectsMockTests.cs +++ b/NGitLab.Mock.Tests/ProjectsMockTests.cs @@ -5,175 +5,174 @@ using NGitLab.Models; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class ProjectsMockTests { - public class ProjectsMockTests + [Test] + public void Test_projects_created_can_be_found() + { + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("Test", @namespace: "testgroup", addDefaultUserAsMaintainer: true) + .BuildServer(); + + var client = server.CreateClient(); + var project = client.Projects["testgroup/Test"]; + + Assert.That(project, Is.Not.Null); + Assert.That(project.Name, Is.EqualTo("Test")); + Assert.That(project.Namespace.FullPath, Is.EqualTo("testgroup")); + } + + [Test] + public void Test_project_can_be_cloned_by_default() + { + using var tempDir = TemporaryDirectory.Create(); + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("Test", clonePath: tempDir.FullPath) + .BuildServer(); + + Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); + } + + [Test] + public void Test_project_with_submodules() + { + using var tempDir = TemporaryDirectory.Create(); + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("ModuleA", configure: x => x.WithCommit(configure: c => c.WithFile("A.txt"))) + .WithProject("ModuleB", configure: x => x.WithCommit(configure: c => c.WithFile("B.txt"))) + .WithProject("Test", clonePath: tempDir.FullPath, configure: x => + x.WithCommit("Init", configure: c + => c.WithSubModule("ModuleA") + .WithSubModule("ModuleB"))) + .BuildServer(); + + Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/.git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/A.txt")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt")), Is.True); + } + + [Test] + public void Test_project_with_nested_submodules() + { + using var tempDir = TemporaryDirectory.Create(); + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("ModuleA", configure: x => x.WithCommit(configure: c => c.WithFile("A.txt"))) + .WithProject("ModuleB", configure: x => x.WithCommit(configure: c + => c.WithFile("B.txt") + .WithSubModule("ModuleA"))) + .WithProject("Test", clonePath: tempDir.FullPath, configure: x => + x.WithCommit(configure: c + => c.WithSubModule("ModuleB"))) + .BuildServer(); + + Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/.git")), Is.True); + Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/A.txt")), Is.True); + } + + [Test] + public void Test_projects_created_url_ends_with_namespace_and_name() + { + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("Test", @namespace: "testgroup", addDefaultUserAsMaintainer: true) + .BuildServer(); + + var client = server.CreateClient(); + var project = client.Projects["testgroup/Test"]; + + Assert.That(project, Is.Not.Null); + Assert.That(project.SshUrl, Does.EndWith($"testgroup{Path.DirectorySeparatorChar}test")); + Assert.That(project.HttpUrl, Does.EndWith($"testgroup{Path.DirectorySeparatorChar}test")); + Assert.That(project.WebUrl, Does.EndWith("testgroup/test")); + } + + [Test] + public void Test_get_languages() + { + using var server = new GitLabServer(); + var user = server.Users.AddNew(); + var project = user.Namespace.Projects.AddNew(); + + var client = server.CreateClient(user); + Assert.That(client.Projects.GetLanguages(project.Id.ToString(CultureInfo.InvariantCulture)), Is.Empty); + + project.Repository.Commit(user, "dummy", new[] { File.CreateFromText("test.cs", "dummy"), File.CreateFromText("test.js", "dummy") }); + var languages = client.Projects.GetLanguages(project.Id.ToString(CultureInfo.InvariantCulture)); + Assert.That(languages, Has.Count.EqualTo(2)); + Assert.That(languages["C#"], Is.EqualTo(0.5d)); + Assert.That(languages["JavaScript"], Is.EqualTo(0.5d)); + } + + [Test] + public void Test_empty_repo() + { + using var server = new GitLabServer(); + var user = server.Users.AddNew(); + var project = user.Namespace.Projects.AddNew(); + + Assert.That(project.ToClientProject(user).EmptyRepo, Is.True); + + project.Repository.Commit(user, "dummy"); + Assert.That(project.ToClientProject(user).EmptyRepo, Is.False); + } + + [Test] + public void Test_project_permissions_maintainer_with_project_access() + { + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("Test", @namespace: "testgroup", addDefaultUserAsMaintainer: true) + .BuildServer(); + + var client = server.CreateClient(); + var project = client.Projects["testgroup/Test"]; + + project.Should().NotBeNull(); + project.Permissions.GroupAccess.Should().BeNull(); + project.Permissions.ProjectAccess.AccessLevel.Should().Be(AccessLevel.Maintainer); + } + + [Test] + public void Test_project_permissions_with_no_access() + { + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithProject("Test", @namespace: "testgroup") + .BuildServer(); + + var client = server.CreateClient(); + var project = client.Projects["testgroup/Test"]; + + project.Should().NotBeNull(); + project.Permissions.GroupAccess.Should().BeNull(); + project.Permissions.ProjectAccess.Should().BeNull(); + } + + [Test] + public void Test_project_permissions_with_group_access() { - [Test] - public void Test_projects_created_can_be_found() - { - using var server = new GitLabConfig() - .WithUser("Test", isDefault: true) - .WithProject("Test", @namespace: "testgroup", addDefaultUserAsMaintainer: true) - .BuildServer(); - - var client = server.CreateClient(); - var project = client.Projects["testgroup/Test"]; - - Assert.That(project, Is.Not.Null); - Assert.That(project.Name, Is.EqualTo("Test")); - Assert.That(project.Namespace.FullPath, Is.EqualTo("testgroup")); - } - - [Test] - public void Test_project_can_be_cloned_by_default() - { - using var tempDir = TemporaryDirectory.Create(); - using var server = new GitLabConfig() - .WithUser("Test", isDefault: true) - .WithProject("Test", clonePath: tempDir.FullPath) - .BuildServer(); - - Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); - } - - [Test] - public void Test_project_with_submodules() - { - using var tempDir = TemporaryDirectory.Create(); - using var server = new GitLabConfig() - .WithUser("Test", isDefault: true) - .WithProject("ModuleA", configure: x => x.WithCommit(configure: c => c.WithFile("A.txt"))) - .WithProject("ModuleB", configure: x => x.WithCommit(configure: c => c.WithFile("B.txt"))) - .WithProject("Test", clonePath: tempDir.FullPath, configure: x => - x.WithCommit("Init", configure: c - => c.WithSubModule("ModuleA") - .WithSubModule("ModuleB"))) - .BuildServer(); - - Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); - Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/.git")), Is.True); - Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleA/A.txt")), Is.True); - Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git")), Is.True); - Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt")), Is.True); - } - - [Test] - public void Test_project_with_nested_submodules() - { - using var tempDir = TemporaryDirectory.Create(); - using var server = new GitLabConfig() - .WithUser("Test", isDefault: true) - .WithProject("ModuleA", configure: x => x.WithCommit(configure: c => c.WithFile("A.txt"))) - .WithProject("ModuleB", configure: x => x.WithCommit(configure: c - => c.WithFile("B.txt") - .WithSubModule("ModuleA"))) - .WithProject("Test", clonePath: tempDir.FullPath, configure: x => - x.WithCommit(configure: c - => c.WithSubModule("ModuleB"))) - .BuildServer(); - - Assert.That(Directory.Exists(tempDir.GetFullPath(".git")), Is.True); - Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/.git")), Is.True); - Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/B.txt")), Is.True); - Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/.git")), Is.True); - Assert.That(System.IO.File.Exists(tempDir.GetFullPath("ModuleB/ModuleA/A.txt")), Is.True); - } - - [Test] - public void Test_projects_created_url_ends_with_namespace_and_name() - { - using var server = new GitLabConfig() - .WithUser("Test", isDefault: true) - .WithProject("Test", @namespace: "testgroup", addDefaultUserAsMaintainer: true) - .BuildServer(); - - var client = server.CreateClient(); - var project = client.Projects["testgroup/Test"]; - - Assert.That(project, Is.Not.Null); - Assert.That(project.SshUrl, Does.EndWith($"testgroup{Path.DirectorySeparatorChar}test")); - Assert.That(project.HttpUrl, Does.EndWith($"testgroup{Path.DirectorySeparatorChar}test")); - Assert.That(project.WebUrl, Does.EndWith("testgroup/test")); - } - - [Test] - public void Test_get_languages() - { - using var server = new GitLabServer(); - var user = server.Users.AddNew(); - var project = user.Namespace.Projects.AddNew(); - - var client = server.CreateClient(user); - Assert.That(client.Projects.GetLanguages(project.Id.ToString(CultureInfo.InvariantCulture)), Is.Empty); - - project.Repository.Commit(user, "dummy", new[] { File.CreateFromText("test.cs", "dummy"), File.CreateFromText("test.js", "dummy") }); - var languages = client.Projects.GetLanguages(project.Id.ToString(CultureInfo.InvariantCulture)); - Assert.That(languages, Has.Count.EqualTo(2)); - Assert.That(languages["C#"], Is.EqualTo(0.5d)); - Assert.That(languages["JavaScript"], Is.EqualTo(0.5d)); - } - - [Test] - public void Test_empty_repo() - { - using var server = new GitLabServer(); - var user = server.Users.AddNew(); - var project = user.Namespace.Projects.AddNew(); - - Assert.That(project.ToClientProject(user).EmptyRepo, Is.True); - - project.Repository.Commit(user, "dummy"); - Assert.That(project.ToClientProject(user).EmptyRepo, Is.False); - } - - [Test] - public void Test_project_permissions_maintainer_with_project_access() - { - using var server = new GitLabConfig() - .WithUser("Test", isDefault: true) - .WithProject("Test", @namespace: "testgroup", addDefaultUserAsMaintainer: true) - .BuildServer(); - - var client = server.CreateClient(); - var project = client.Projects["testgroup/Test"]; - - project.Should().NotBeNull(); - project.Permissions.GroupAccess.Should().BeNull(); - project.Permissions.ProjectAccess.AccessLevel.Should().Be(AccessLevel.Maintainer); - } - - [Test] - public void Test_project_permissions_with_no_access() - { - using var server = new GitLabConfig() - .WithUser("Test", isDefault: true) - .WithProject("Test", @namespace: "testgroup") - .BuildServer(); - - var client = server.CreateClient(); - var project = client.Projects["testgroup/Test"]; - - project.Should().NotBeNull(); - project.Permissions.GroupAccess.Should().BeNull(); - project.Permissions.ProjectAccess.Should().BeNull(); - } - - [Test] - public void Test_project_permissions_with_group_access() - { - using var server = new GitLabConfig() - .WithUser("Test", isDefault: true) - .WithGroup("testgroup", addDefaultUserAsMaintainer: true) - .WithProject("Test", @namespace: "testgroup") - .BuildServer(); - - var client = server.CreateClient(); - var project = client.Projects["testgroup/Test"]; - - project.Should().NotBeNull(); - project.Permissions.ProjectAccess.Should().BeNull(); - project.Permissions.GroupAccess.AccessLevel.Should().Be(AccessLevel.Maintainer); - } + using var server = new GitLabConfig() + .WithUser("Test", isDefault: true) + .WithGroup("testgroup", addDefaultUserAsMaintainer: true) + .WithProject("Test", @namespace: "testgroup") + .BuildServer(); + + var client = server.CreateClient(); + var project = client.Projects["testgroup/Test"]; + + project.Should().NotBeNull(); + project.Permissions.ProjectAccess.Should().BeNull(); + project.Permissions.GroupAccess.AccessLevel.Should().Be(AccessLevel.Maintainer); } } diff --git a/NGitLab.Mock.Tests/ReleasesMockTests.cs b/NGitLab.Mock.Tests/ReleasesMockTests.cs index 0ee979e7..7a351399 100644 --- a/NGitLab.Mock.Tests/ReleasesMockTests.cs +++ b/NGitLab.Mock.Tests/ReleasesMockTests.cs @@ -3,98 +3,97 @@ using NGitLab.Mock.Config; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class ReleasesMockTests { - public class ReleasesMockTests + [Test] + public void Test_release() { - [Test] - public void Test_release() - { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", configure: project => project - .WithCommit("Changes with tag", tags: new[] { "1.2.3" }) - .WithRelease("user1", "1.2.3")) - .BuildServer(); + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", configure: project => project + .WithCommit("Changes with tag", tags: new[] { "1.2.3" }) + .WithRelease("user1", "1.2.3")) + .BuildServer(); - var client = server.CreateClient("user1"); - var project = client.Projects.Visible.First(); - var releaseClient = client.GetReleases(project.Id); - var singleRelease = releaseClient.All.SingleOrDefault(); + var client = server.CreateClient("user1"); + var project = client.Projects.Visible.First(); + var releaseClient = client.GetReleases(project.Id); + var singleRelease = releaseClient.All.SingleOrDefault(); - Assert.That(singleRelease, Is.Not.Null); - Assert.That(singleRelease.TagName, Is.EqualTo("1.2.3")); - Assert.That(singleRelease.Links.Self, Is.EqualTo($"{project.WebUrl}/-/releases/1.2.3")); - } + Assert.That(singleRelease, Is.Not.Null); + Assert.That(singleRelease.TagName, Is.EqualTo("1.2.3")); + Assert.That(singleRelease.Links.Self, Is.EqualTo($"{project.WebUrl}/-/releases/1.2.3")); + } + + [Test] + public void Test_release_page() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", configure: project => project + .WithCommit("Changes with tag", tags: new[] { "1.2.3", "1.2.4" }) + .WithRelease("user1", "1.2.3", createdAt: DateTime.UtcNow.AddHours(-2), releasedAt: DateTime.UtcNow.AddHours(-2)) + .WithRelease("user1", "1.2.4", createdAt: DateTime.UtcNow.AddHours(-1), releasedAt: DateTime.UtcNow.AddHours(-1))) + .BuildServer(); - [Test] - public void Test_release_page() + var client = server.CreateClient("user1"); + var project = client.Projects.Visible.First(); + var releaseClient = client.GetReleases(project.Id); + var firstRelease = releaseClient.GetAsync(new Models.ReleaseQuery { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", configure: project => project - .WithCommit("Changes with tag", tags: new[] { "1.2.3", "1.2.4" }) - .WithRelease("user1", "1.2.3", createdAt: DateTime.UtcNow.AddHours(-2), releasedAt: DateTime.UtcNow.AddHours(-2)) - .WithRelease("user1", "1.2.4", createdAt: DateTime.UtcNow.AddHours(-1), releasedAt: DateTime.UtcNow.AddHours(-1))) - .BuildServer(); + PerPage = 1, + Page = 2, + }).SingleOrDefault(); - var client = server.CreateClient("user1"); - var project = client.Projects.Visible.First(); - var releaseClient = client.GetReleases(project.Id); - var firstRelease = releaseClient.GetAsync(new Models.ReleaseQuery - { - PerPage = 1, - Page = 2, - }).SingleOrDefault(); + Assert.That(firstRelease, Is.Not.Null); + Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); + } - Assert.That(firstRelease, Is.Not.Null); - Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); - } + [Test] + public void Test_release_sort() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", configure: project => project + .WithCommit("Changes with tag", tags: new[] { "1.2.3", "1.2.4" }) + .WithRelease("user1", "1.2.3", createdAt: DateTime.UtcNow.AddHours(-2), releasedAt: DateTime.UtcNow.AddHours(-2)) + .WithRelease("user1", "1.2.4", createdAt: DateTime.UtcNow.AddHours(-1), releasedAt: DateTime.UtcNow.AddHours(-1))) + .BuildServer(); - [Test] - public void Test_release_sort() + var client = server.CreateClient("user1"); + var project = client.Projects.Visible.First(); + var releaseClient = client.GetReleases(project.Id); + var firstRelease = releaseClient.GetAsync(new Models.ReleaseQuery { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", configure: project => project - .WithCommit("Changes with tag", tags: new[] { "1.2.3", "1.2.4" }) - .WithRelease("user1", "1.2.3", createdAt: DateTime.UtcNow.AddHours(-2), releasedAt: DateTime.UtcNow.AddHours(-2)) - .WithRelease("user1", "1.2.4", createdAt: DateTime.UtcNow.AddHours(-1), releasedAt: DateTime.UtcNow.AddHours(-1))) - .BuildServer(); + Sort = "asc", + }).First(); - var client = server.CreateClient("user1"); - var project = client.Projects.Visible.First(); - var releaseClient = client.GetReleases(project.Id); - var firstRelease = releaseClient.GetAsync(new Models.ReleaseQuery - { - Sort = "asc", - }).First(); + Assert.That(firstRelease, Is.Not.Null); + Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); + } - Assert.That(firstRelease, Is.Not.Null); - Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); - } + [Test] + public void Test_release_orderBy() + { + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("Test", configure: project => project + .WithCommit("Changes with tag", tags: new[] { "1.2.3", "1.2.4" }) + .WithRelease("user1", "1.2.3", createdAt: DateTime.UtcNow.AddHours(-1), releasedAt: DateTime.UtcNow.AddHours(-1)) + .WithRelease("user1", "1.2.4", createdAt: DateTime.UtcNow.AddHours(-2), releasedAt: DateTime.UtcNow.AddHours(-2))) + .BuildServer(); - [Test] - public void Test_release_orderBy() + var client = server.CreateClient("user1"); + var project = client.Projects.Visible.First(); + var releaseClient = client.GetReleases(project.Id); + var firstRelease = releaseClient.GetAsync(new Models.ReleaseQuery { - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("Test", configure: project => project - .WithCommit("Changes with tag", tags: new[] { "1.2.3", "1.2.4" }) - .WithRelease("user1", "1.2.3", createdAt: DateTime.UtcNow.AddHours(-1), releasedAt: DateTime.UtcNow.AddHours(-1)) - .WithRelease("user1", "1.2.4", createdAt: DateTime.UtcNow.AddHours(-2), releasedAt: DateTime.UtcNow.AddHours(-2))) - .BuildServer(); - - var client = server.CreateClient("user1"); - var project = client.Projects.Visible.First(); - var releaseClient = client.GetReleases(project.Id); - var firstRelease = releaseClient.GetAsync(new Models.ReleaseQuery - { - OrderBy = "created_at", - }).First(); + OrderBy = "created_at", + }).First(); - Assert.That(firstRelease, Is.Not.Null); - Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); - } + Assert.That(firstRelease, Is.Not.Null); + Assert.That(firstRelease.TagName, Is.EqualTo("1.2.3")); } } diff --git a/NGitLab.Mock.Tests/TagTests.cs b/NGitLab.Mock.Tests/TagTests.cs index 6720a950..54f95d51 100644 --- a/NGitLab.Mock.Tests/TagTests.cs +++ b/NGitLab.Mock.Tests/TagTests.cs @@ -3,30 +3,29 @@ using NGitLab.Mock.Config; using NUnit.Framework; -namespace NGitLab.Mock.Tests +namespace NGitLab.Mock.Tests; + +public class TagTests { - public class TagTests + [Test] + public async Task GetTagAsync() { - [Test] - public async Task GetTagAsync() - { - // Arrange - using var server = new GitLabConfig() - .WithUser("user1", isDefault: true) - .WithProject("test-project", id: 1, addDefaultUserAsMaintainer: true, configure: project => project - .WithCommit("Initial commit") - .WithCommit("Changes with tag", tags: new[] { "1.0.0" })) - .BuildServer(); + // Arrange + using var server = new GitLabConfig() + .WithUser("user1", isDefault: true) + .WithProject("test-project", id: 1, addDefaultUserAsMaintainer: true, configure: project => project + .WithCommit("Initial commit") + .WithCommit("Changes with tag", tags: new[] { "1.0.0" })) + .BuildServer(); - var client = server.CreateClient(); - var tagClient = client.GetRepository(1).Tags; + var client = server.CreateClient(); + var tagClient = client.GetRepository(1).Tags; - // Act/Assert - var tag = await tagClient.GetByNameAsync("1.0.0"); - Assert.That(tag.Name, Is.EqualTo("1.0.0")); + // Act/Assert + var tag = await tagClient.GetByNameAsync("1.0.0"); + Assert.That(tag.Name, Is.EqualTo("1.0.0")); - var ex = Assert.ThrowsAsync(() => tagClient.GetByNameAsync("1.0.1")); - Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); - } + var ex = Assert.ThrowsAsync(() => tagClient.GetByNameAsync("1.0.1")); + Assert.That(ex.StatusCode, Is.EqualTo(HttpStatusCode.NotFound)); } } diff --git a/NGitLab.Mock/Badge.cs b/NGitLab.Mock/Badge.cs index de99da4e..2d64f307 100644 --- a/NGitLab.Mock/Badge.cs +++ b/NGitLab.Mock/Badge.cs @@ -1,32 +1,31 @@ using NGitLab.Models; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public sealed class Badge : GitLabObject { - public sealed class Badge : GitLabObject - { - public int Id { get; set; } + public int Id { get; set; } - public string LinkUrl { get; set; } + public string LinkUrl { get; set; } - public string ImageUrl { get; set; } + public string ImageUrl { get; set; } - public string RenderedLinkUrl { get; set; } + public string RenderedLinkUrl { get; set; } - public string RenderedImageUrl { get; set; } + public string RenderedImageUrl { get; set; } - public BadgeKind Kind => Parent is Project ? BadgeKind.Project : BadgeKind.Group; + public BadgeKind Kind => Parent is Project ? BadgeKind.Project : BadgeKind.Group; - public Models.Badge ToBadgeModel() + public Models.Badge ToBadgeModel() + { + return new Models.Badge { - return new Models.Badge - { - Id = Id, - ImageUrl = ImageUrl, - Kind = Kind, - LinkUrl = LinkUrl, - RenderedImageUrl = RenderedImageUrl, - RenderedLinkUrl = RenderedLinkUrl, - }; - } + Id = Id, + ImageUrl = ImageUrl, + Kind = Kind, + LinkUrl = LinkUrl, + RenderedImageUrl = RenderedImageUrl, + RenderedLinkUrl = RenderedLinkUrl, + }; } } diff --git a/NGitLab.Mock/BadgeCollection.cs b/NGitLab.Mock/BadgeCollection.cs index b3917c75..5ecc312a 100644 --- a/NGitLab.Mock/BadgeCollection.cs +++ b/NGitLab.Mock/BadgeCollection.cs @@ -1,48 +1,47 @@ using System; using System.Linq; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public sealed class BadgeCollection : Collection { - public sealed class BadgeCollection : Collection + public BadgeCollection(GitLabObject parent) + : base(parent) { - public BadgeCollection(GitLabObject parent) - : base(parent) - { - } + } + + public Badge GetById(int id) + { + return this.FirstOrDefault(badge => badge.Id == id); + } - public Badge GetById(int id) + public override void Add(Badge item) + { + if (item == null) + throw new ArgumentNullException(nameof(item)); + + if (item.Id == default) { - return this.FirstOrDefault(badge => badge.Id == id); + item.Id = Server.GetNewBadgeId(); } - - public override void Add(Badge item) + else if (GetById(item.Id) != null) { - if (item == null) - throw new ArgumentNullException(nameof(item)); - - if (item.Id == default) - { - item.Id = Server.GetNewBadgeId(); - } - else if (GetById(item.Id) != null) - { - throw new GitLabException("Badge already exists."); - } - - base.Add(item); + throw new GitLabException("Badge already exists."); } - public Badge Add(string linkUrl, string imageUrl) + base.Add(item); + } + + public Badge Add(string linkUrl, string imageUrl) + { + var badge = new Badge { - var badge = new Badge - { - LinkUrl = linkUrl, - ImageUrl = imageUrl, - }; + LinkUrl = linkUrl, + ImageUrl = imageUrl, + }; - Add(badge); + Add(badge); - return badge; - } + return badge; } } diff --git a/NGitLab.Mock/Change.cs b/NGitLab.Mock/Change.cs index 7ce4eb20..cecac488 100644 --- a/NGitLab.Mock/Change.cs +++ b/NGitLab.Mock/Change.cs @@ -1,36 +1,35 @@ -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public class Change : GitLabObject { - public class Change : GitLabObject - { - public string OldPath { get; set; } + public string OldPath { get; set; } - public string NewPath { get; set; } + public string NewPath { get; set; } - public long AMode { get; set; } + public long AMode { get; set; } - public long BMode { get; set; } + public long BMode { get; set; } - public bool NewFile { get; set; } + public bool NewFile { get; set; } - public bool RenamedFile { get; set; } + public bool RenamedFile { get; set; } - public bool DeletedFile { get; set; } + public bool DeletedFile { get; set; } - public string Diff { get; set; } + public string Diff { get; set; } - public Models.Change ToChange() + public Models.Change ToChange() + { + return new () { - return new () - { - Diff = Diff, - AMode = AMode, - BMode = BMode, - DeletedFile = DeletedFile, - NewFile = NewFile, - NewPath = NewPath, - OldPath = OldPath, - RenamedFile = RenamedFile, - }; - } + Diff = Diff, + AMode = AMode, + BMode = BMode, + DeletedFile = DeletedFile, + NewFile = NewFile, + NewPath = NewPath, + OldPath = OldPath, + RenamedFile = RenamedFile, + }; } } diff --git a/NGitLab.Mock/Clients/AdvancedSearchClient.cs b/NGitLab.Mock/Clients/AdvancedSearchClient.cs index 3c817d56..ad3834d4 100644 --- a/NGitLab.Mock/Clients/AdvancedSearchClient.cs +++ b/NGitLab.Mock/Clients/AdvancedSearchClient.cs @@ -1,20 +1,19 @@ using System; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class AdvancedSearchClient : ISearchClient { - internal sealed class AdvancedSearchClient : ISearchClient - { - private readonly ClientContext _context; + private readonly ClientContext _context; - public AdvancedSearchClient(ClientContext context) - { - _context = context; - } + public AdvancedSearchClient(ClientContext context) + { + _context = context; + } - public GitLabCollectionResponse GetBlobsAsync(SearchQuery query) - { - throw new NotImplementedException(); - } + public GitLabCollectionResponse GetBlobsAsync(SearchQuery query) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/BranchClient.cs b/NGitLab.Mock/Clients/BranchClient.cs index 194e31c6..e8cc8654 100644 --- a/NGitLab.Mock/Clients/BranchClient.cs +++ b/NGitLab.Mock/Clients/BranchClient.cs @@ -4,121 +4,120 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class BranchClient : ClientBase, IBranchClient { - internal sealed class BranchClient : ClientBase, IBranchClient + private readonly int _projectId; + + public BranchClient(ClientContext context, int projectId) + : base(context) { - private readonly int _projectId; + _projectId = projectId; + } - public BranchClient(ClientContext context, int projectId) - : base(context) + public IEnumerable Search(string search) + { + Func filterBranch; + switch (search) { - _projectId = projectId; + 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; } - public IEnumerable Search(string search) + using (Context.BeginOperationScope()) { - Func 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)); - } + var project = GetProject(_projectId, ProjectPermission.View); + return project.Repository.GetAllBranches() + .Where(branch => filterBranch(branch.FriendlyName)) + .Select(branch => branch.ToBranchClient(project)); } + } - public GitLabCollectionResponse SearchAsync(string search) - { - return GitLabCollectionResponse.Create(Search(search)); - } + public GitLabCollectionResponse SearchAsync(string search) + { + return GitLabCollectionResponse.Create(Search(search)); + } - public Branch this[string name] + public Branch this[string name] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var branch = project.Repository.GetBranch(name); - if (branch == null) - throw new GitLabNotFoundException(); - - return branch.ToBranchClient(project); - } - } - } + var project = GetProject(_projectId, ProjectPermission.View); + var branch = project.Repository.GetBranch(name); + if (branch == null) + throw new GitLabNotFoundException(); - public IEnumerable All - { - get - { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.Repository.GetAllBranches().Select(branch => branch.ToBranchClient(project)).ToList(); - } + return branch.ToBranchClient(project); } } + } - public Branch Create(BranchCreate branch) + public IEnumerable All + { + get { using (Context.BeginOperationScope()) { - var project = GetProject(_projectId, ProjectPermission.Contribute); - if (branch.Ref != null) - { - return project.Repository.CreateBranch(branch.Name, branch.Ref).ToBranchClient(project); - } - - return project.Repository.CreateBranch(branch.Name).ToBranchClient(project); + var project = GetProject(_projectId, ProjectPermission.View); + return project.Repository.GetAllBranches().Select(branch => branch.ToBranchClient(project)).ToList(); } } + } - public void Delete(string name) + public Branch Create(BranchCreate branch) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.Contribute); + if (branch.Ref != null) { - var project = GetProject(_projectId, ProjectPermission.Contribute); - project.Repository.RemoveBranch(name); + return project.Repository.CreateBranch(branch.Name, branch.Ref).ToBranchClient(project); } - } - public Branch Protect(string name) - { - throw new NotImplementedException(); + return project.Repository.CreateBranch(branch.Name).ToBranchClient(project); } + } - public Branch Unprotect(string name) + public void Delete(string name) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var project = GetProject(_projectId, ProjectPermission.Contribute); + project.Repository.RemoveBranch(name); } } + + public Branch Protect(string name) + { + throw new NotImplementedException(); + } + + public Branch Unprotect(string name) + { + throw new NotImplementedException(); + } } diff --git a/NGitLab.Mock/Clients/ClientBase.cs b/NGitLab.Mock/Clients/ClientBase.cs index ab9868c7..8b90ce93 100644 --- a/NGitLab.Mock/Clients/ClientBase.cs +++ b/NGitLab.Mock/Clients/ClientBase.cs @@ -1,174 +1,173 @@ using System; using System.Net; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal abstract class ClientBase { - internal abstract class ClientBase + protected ClientBase(ClientContext context) { - protected ClientBase(ClientContext context) - { - Context = context; - } - - protected GitLabServer Server => Context.Server; + Context = context; + } - protected ClientContext Context { get; } + protected GitLabServer Server => Context.Server; - protected Group GetGroup(object id, GroupPermission permissions) - { - if (id is null) - throw new ArgumentNullException(nameof(id)); + protected ClientContext Context { get; } - if (Context.User.State == UserState.blocked && permissions != GroupPermission.View) - { - throw new GitLabException("403 Forbidden - Your account has been blocked.") - { - StatusCode = HttpStatusCode.Forbidden, - }; - } + protected Group GetGroup(object id, GroupPermission permissions) + { + if (id is null) + throw new ArgumentNullException(nameof(id)); - var group = id switch + if (Context.User.State == UserState.blocked && permissions != GroupPermission.View) + { + throw new GitLabException("403 Forbidden - Your account has been blocked.") { - int idInt => Server.AllGroups.FindById(idInt), - string idStr => Server.AllGroups.FindGroup(idStr), - _ => throw new ArgumentException($"Id of type '{id.GetType()}' is not supported"), + StatusCode = HttpStatusCode.Forbidden, }; + } - if (group == null || !group.CanUserViewGroup(Context.User)) - throw new GitLabNotFoundException("Group does not exist or user doesn't have permission to view it"); - - switch (permissions) - { - case GroupPermission.View: - // Already checked before - break; - - case GroupPermission.Edit: - if (!group.CanUserEditGroup(Context.User)) - throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to edit the group '{group.Name}'"); - break; - - case GroupPermission.Delete: - if (!group.CanUserDeleteGroup(Context.User)) - throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to delete the group '{group.Name}'"); - break; + var group = id switch + { + int idInt => Server.AllGroups.FindById(idInt), + string idStr => Server.AllGroups.FindGroup(idStr), + _ => throw new ArgumentException($"Id of type '{id.GetType()}' is not supported"), + }; - default: - throw new ArgumentOutOfRangeException(nameof(permissions)); - } + if (group == null || !group.CanUserViewGroup(Context.User)) + throw new GitLabNotFoundException("Group does not exist or user doesn't have permission to view it"); - return group; + switch (permissions) + { + case GroupPermission.View: + // Already checked before + break; + + case GroupPermission.Edit: + if (!group.CanUserEditGroup(Context.User)) + throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to edit the group '{group.Name}'"); + break; + + case GroupPermission.Delete: + if (!group.CanUserDeleteGroup(Context.User)) + throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to delete the group '{group.Name}'"); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(permissions)); } - protected Project GetProject(object id, ProjectPermission permissions) - { - if (id is null) - throw new ArgumentNullException(nameof(id)); + return group; + } - if (Context.User.State == UserState.blocked && permissions != ProjectPermission.View) - { - throw new GitLabException("403 Forbidden - Your account has been blocked.") - { - StatusCode = HttpStatusCode.Forbidden, - }; - } + protected Project GetProject(object id, ProjectPermission permissions) + { + if (id is null) + throw new ArgumentNullException(nameof(id)); - var project = id switch + if (Context.User.State == UserState.blocked && permissions != ProjectPermission.View) + { + throw new GitLabException("403 Forbidden - Your account has been blocked.") { - int idInt => Server.AllProjects.FindById(idInt), - string idStr => Server.AllProjects.FindProject(idStr), - _ => throw new ArgumentException($"Id of type '{id.GetType()}' is not supported"), + StatusCode = HttpStatusCode.Forbidden, }; - - if (project == null || !project.CanUserViewProject(Context.User)) - throw new GitLabNotFoundException("Project does not exist or User doesn't have permission to view it"); - - switch (permissions) - { - case ProjectPermission.View: - // Already checked before - break; - - case ProjectPermission.Contribute: - if (!project.CanUserContributeToProject(Context.User)) - throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to contribute to the project '{project.Name}'"); - break; - - case ProjectPermission.Edit: - if (!project.CanUserEditProject(Context.User)) - throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to edit the project '{project.Name}'"); - break; - - case ProjectPermission.Delete: - if (!project.CanUserDeleteProject(Context.User)) - throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to delete the project '{project.Name}'"); - break; - - default: - throw new ArgumentOutOfRangeException(nameof(permissions)); - } - - return project; } - protected User GetUser(int userId) + var project = id switch { - var user = Server.Users.GetById(userId); - if (user == null) - throw new GitLabNotFoundException(); + int idInt => Server.AllProjects.FindById(idInt), + string idStr => Server.AllProjects.FindProject(idStr), + _ => throw new ArgumentException($"Id of type '{id.GetType()}' is not supported"), + }; - return user; - } + if (project == null || !project.CanUserViewProject(Context.User)) + throw new GitLabNotFoundException("Project does not exist or User doesn't have permission to view it"); - protected Issue GetIssue(int projectId, int issueId) + switch (permissions) { - var project = GetProject(projectId, ProjectPermission.View); - var issue = project.Issues.GetByIid(issueId); - if (issue == null) - throw new GitLabNotFoundException(); - - return issue; + case ProjectPermission.View: + // Already checked before + break; + + case ProjectPermission.Contribute: + if (!project.CanUserContributeToProject(Context.User)) + throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to contribute to the project '{project.Name}'"); + break; + + case ProjectPermission.Edit: + if (!project.CanUserEditProject(Context.User)) + throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to edit the project '{project.Name}'"); + break; + + case ProjectPermission.Delete: + if (!project.CanUserDeleteProject(Context.User)) + throw new GitLabForbiddenException($"User '{Context.User.Name}' does not have the permission to delete the project '{project.Name}'"); + break; + + default: + throw new ArgumentOutOfRangeException(nameof(permissions)); } - protected Milestone GetMilestone(int projectId, int milestoneId) - { - var project = GetProject(projectId, ProjectPermission.View); - var milestone = project.Milestones.GetByIid(milestoneId); - if (milestone == null) - throw new GitLabNotFoundException(); + return project; + } - return milestone; - } + protected User GetUser(int userId) + { + var user = Server.Users.GetById(userId); + if (user == null) + throw new GitLabNotFoundException(); - protected MergeRequest GetMergeRequest(int projectId, int mergeRequestIid) - { - var project = GetProject(projectId, ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + return user; + } - return mergeRequest; - } + protected Issue GetIssue(int projectId, int issueId) + { + var project = GetProject(projectId, ProjectPermission.View); + var issue = project.Issues.GetByIid(issueId); + if (issue == null) + throw new GitLabNotFoundException(); - protected void EnsureUserIsAuthenticated() - { - if (Context.User == null) - throw new GitLabException { StatusCode = HttpStatusCode.Unauthorized }; - } + return issue; + } - internal enum ProjectPermission - { - View, - Contribute, - Edit, - Delete, - } + protected Milestone GetMilestone(int projectId, int milestoneId) + { + var project = GetProject(projectId, ProjectPermission.View); + var milestone = project.Milestones.GetByIid(milestoneId); + if (milestone == null) + throw new GitLabNotFoundException(); - internal enum GroupPermission - { - View, - Edit, - Delete, - } + return milestone; + } + + protected MergeRequest GetMergeRequest(int projectId, int mergeRequestIid) + { + var project = GetProject(projectId, ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); + + return mergeRequest; + } + + protected void EnsureUserIsAuthenticated() + { + if (Context.User == null) + throw new GitLabException { StatusCode = HttpStatusCode.Unauthorized }; + } + + internal enum ProjectPermission + { + View, + Contribute, + Edit, + Delete, + } + + internal enum GroupPermission + { + View, + Edit, + Delete, } } diff --git a/NGitLab.Mock/Clients/ClientContext.cs b/NGitLab.Mock/Clients/ClientContext.cs index fbd06210..664a5646 100644 --- a/NGitLab.Mock/Clients/ClientContext.cs +++ b/NGitLab.Mock/Clients/ClientContext.cs @@ -1,44 +1,43 @@ using System; using System.Threading; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ClientContext { - internal sealed class ClientContext + private readonly object _operationLock = new(); + + public ClientContext(GitLabServer server, User user) { - private readonly object _operationLock = new(); + Server = server; + User = user; + } - public ClientContext(GitLabServer server, User user) - { - Server = server; - User = user; - } + public GitLabServer Server { get; } - public GitLabServer Server { get; } + public User User { get; } - public User User { get; } + public bool IsAuthenticated => User != null; - public bool IsAuthenticated => User != null; + public IDisposable BeginOperationScope() + { + Server.RaiseOnClientOperation(); + Monitor.Enter(_operationLock); + return new Releaser(_operationLock); + } + + private sealed class Releaser : IDisposable + { + private readonly object _operationLock; - public IDisposable BeginOperationScope() + public Releaser(object operationLock) { - Server.RaiseOnClientOperation(); - Monitor.Enter(_operationLock); - return new Releaser(_operationLock); + _operationLock = operationLock; } - private sealed class Releaser : IDisposable + public void Dispose() { - private readonly object _operationLock; - - public Releaser(object operationLock) - { - _operationLock = operationLock; - } - - public void Dispose() - { - Monitor.Exit(_operationLock); - } + Monitor.Exit(_operationLock); } } } diff --git a/NGitLab.Mock/Clients/ClusterClient.cs b/NGitLab.Mock/Clients/ClusterClient.cs index f45d36e4..22c85344 100644 --- a/NGitLab.Mock/Clients/ClusterClient.cs +++ b/NGitLab.Mock/Clients/ClusterClient.cs @@ -2,18 +2,17 @@ using System.Collections.Generic; using NGitLab.Models; -namespace NGitLab.Mock.Clients -{ - internal sealed class ClusterClient : ClientBase, IClusterClient - { - private readonly int _projectId; +namespace NGitLab.Mock.Clients; - public ClusterClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } +internal sealed class ClusterClient : ClientBase, IClusterClient +{ + private readonly int _projectId; - public IEnumerable All => throw new NotImplementedException(); + public ClusterClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; } + + public IEnumerable All => throw new NotImplementedException(); } diff --git a/NGitLab.Mock/Clients/CommitClient.cs b/NGitLab.Mock/Clients/CommitClient.cs index c5acccbf..6fa09f4d 100644 --- a/NGitLab.Mock/Clients/CommitClient.cs +++ b/NGitLab.Mock/Clients/CommitClient.cs @@ -3,69 +3,68 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class CommitClient : ClientBase, ICommitClient { - internal sealed class CommitClient : ClientBase, ICommitClient - { - private readonly int _projectId; + private readonly int _projectId; - public CommitClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public CommitClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public Commit Create(CommitCreate commit) + public Commit Create(CommitCreate commit) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var gitCommit = project.Repository.Commit(commit); + var project = GetProject(_projectId, ProjectPermission.Contribute); + var gitCommit = project.Repository.Commit(commit); - return gitCommit.ToCommitClient(project); - } + return gitCommit.ToCommitClient(project); } + } - public Commit GetCommit(string @ref) + public Commit GetCommit(string @ref) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var commit = project.Repository.GetCommit(@ref); + var project = GetProject(_projectId, ProjectPermission.View); + var commit = project.Repository.GetCommit(@ref); - return commit?.ToCommitClient(project); - } + return commit?.ToCommitClient(project); } + } - public Commit CherryPick(CommitCherryPick cherryPick) + public Commit CherryPick(CommitCherryPick cherryPick) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var gitCommit = project.Repository.CherryPick(cherryPick); + var project = GetProject(_projectId, ProjectPermission.Contribute); + var gitCommit = project.Repository.CherryPick(cherryPick); - return gitCommit.ToCommitClient(project); - } + return gitCommit.ToCommitClient(project); } + } - public JobStatus GetJobStatus(string branchName) - { - throw new NotImplementedException(); - } + public JobStatus GetJobStatus(string branchName) + { + throw new NotImplementedException(); + } - public GitLabCollectionResponse GetRelatedMergeRequestsAsync(RelatedMergeRequestsQuery query) + public GitLabCollectionResponse GetRelatedMergeRequestsAsync(RelatedMergeRequestsQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); + var project = GetProject(_projectId, ProjectPermission.View); - var mergeRequests = project.MergeRequests.Where(mr => mr.Commits.SingleOrDefault( - commit => commit.Sha.Equals(query.Sha.ToString(), StringComparison.OrdinalIgnoreCase)) != null); + var mergeRequests = project.MergeRequests.Where(mr => mr.Commits.SingleOrDefault( + commit => commit.Sha.Equals(query.Sha.ToString(), StringComparison.OrdinalIgnoreCase)) != null); - var relatedMerqueRequests = mergeRequests.Select(mr => mr.ToMergeRequestClient()); + var relatedMerqueRequests = mergeRequests.Select(mr => mr.ToMergeRequestClient()); - return GitLabCollectionResponse.Create(relatedMerqueRequests); - } + return GitLabCollectionResponse.Create(relatedMerqueRequests); } } } diff --git a/NGitLab.Mock/Clients/CommitStatusClient.cs b/NGitLab.Mock/Clients/CommitStatusClient.cs index d124b2ee..0de30ba8 100644 --- a/NGitLab.Mock/Clients/CommitStatusClient.cs +++ b/NGitLab.Mock/Clients/CommitStatusClient.cs @@ -3,59 +3,58 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class CommitStatusClient : ClientBase, ICommitStatusClient { - internal sealed class CommitStatusClient : ClientBase, ICommitStatusClient - { - private readonly int _projectId; + private readonly int _projectId; - public CommitStatusClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public CommitStatusClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public CommitStatusCreate AddOrUpdate(CommitStatusCreate status) + public CommitStatusCreate AddOrUpdate(CommitStatusCreate status) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.Contribute); + var commitStatus = project.CommitStatuses.FirstOrDefault(cs => Equals(cs, status)); + if (commitStatus == null) { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var commitStatus = project.CommitStatuses.FirstOrDefault(cs => Equals(cs, status)); - if (commitStatus == null) - { - commitStatus = new CommitStatus(); - project.CommitStatuses.Add(commitStatus); - } - - commitStatus.Name = status.Name; - commitStatus.Description = status.Description; - commitStatus.Coverage = status.Coverage; - commitStatus.Ref = status.Ref; - commitStatus.Sha = status.CommitSha; - commitStatus.Status = status.Status; - commitStatus.TargetUrl = status.TargetUrl; - return commitStatus.ToClientCommitStatusCreate(); + commitStatus = new CommitStatus(); + project.CommitStatuses.Add(commitStatus); } - static bool Equals(CommitStatus a, CommitStatusCreate b) - { - return string.Equals(a.Name, b.Name, StringComparison.Ordinal) && - string.Equals(a.Ref, b.Ref, StringComparison.Ordinal) && - string.Equals(a.Sha, b.CommitSha, StringComparison.OrdinalIgnoreCase) && - string.Equals(a.TargetUrl, b.TargetUrl, StringComparison.Ordinal); - } + commitStatus.Name = status.Name; + commitStatus.Description = status.Description; + commitStatus.Coverage = status.Coverage; + commitStatus.Ref = status.Ref; + commitStatus.Sha = status.CommitSha; + commitStatus.Status = status.Status; + commitStatus.TargetUrl = status.TargetUrl; + return commitStatus.ToClientCommitStatusCreate(); } - public IEnumerable AllBySha(string commitSha) + static bool Equals(CommitStatus a, CommitStatusCreate b) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.CommitStatuses - .Where(p => string.Equals(p.Sha, commitSha, StringComparison.OrdinalIgnoreCase)) - .Select(p => p.ToClientCommitStatus()) - .ToList(); - } + return string.Equals(a.Name, b.Name, StringComparison.Ordinal) && + string.Equals(a.Ref, b.Ref, StringComparison.Ordinal) && + string.Equals(a.Sha, b.CommitSha, StringComparison.OrdinalIgnoreCase) && + string.Equals(a.TargetUrl, b.TargetUrl, StringComparison.Ordinal); + } + } + + public IEnumerable AllBySha(string commitSha) + { + using (Context.BeginOperationScope()) + { + var project = GetProject(_projectId, ProjectPermission.View); + return project.CommitStatuses + .Where(p => string.Equals(p.Sha, commitSha, StringComparison.OrdinalIgnoreCase)) + .Select(p => p.ToClientCommitStatus()) + .ToList(); } } } diff --git a/NGitLab.Mock/Clients/ContributorClient.cs b/NGitLab.Mock/Clients/ContributorClient.cs index 177a8b8a..ad5d9c85 100644 --- a/NGitLab.Mock/Clients/ContributorClient.cs +++ b/NGitLab.Mock/Clients/ContributorClient.cs @@ -4,40 +4,39 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ContributorClient : ClientBase, IContributorClient { - internal sealed class ContributorClient : ClientBase, IContributorClient - { - private readonly int _projectId; + private readonly int _projectId; - public ContributorClient(ClientContext context, int projectId) - : base(context) - { - _projectId = projectId; - } + public ContributorClient(ClientContext context, int projectId) + : base(context) + { + _projectId = projectId; + } - public IEnumerable All + public IEnumerable All + { + get { - get + // Note: Counting the number of addition / deletion is too slow. + using (Context.BeginOperationScope()) { - // Note: Counting the number of addition / deletion is too slow. - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - if (project.Repository.IsEmpty) - return Enumerable.Empty(); - - var result = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - foreach (var commit in project.Repository.GetCommits(project.DefaultBranch)) - { - var contributor = result.GetOrAdd(commit.Author.Email, email => new Contributor() { Email = email }); + var project = GetProject(_projectId, ProjectPermission.View); + if (project.Repository.IsEmpty) + return Enumerable.Empty(); - contributor.Name ??= commit.Author.Name; - contributor.Commits++; - } + var result = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); + foreach (var commit in project.Repository.GetCommits(project.DefaultBranch)) + { + var contributor = result.GetOrAdd(commit.Author.Email, email => new Contributor() { Email = email }); - return result.Values.ToArray(); + contributor.Name ??= commit.Author.Name; + contributor.Commits++; } + + return result.Values.ToArray(); } } } diff --git a/NGitLab.Mock/Clients/EnvironmentClient.cs b/NGitLab.Mock/Clients/EnvironmentClient.cs index d79c15dc..d0fbbd44 100644 --- a/NGitLab.Mock/Clients/EnvironmentClient.cs +++ b/NGitLab.Mock/Clients/EnvironmentClient.cs @@ -5,53 +5,52 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class EnvironmentClient : ClientBase, IEnvironmentClient { - internal sealed class EnvironmentClient : ClientBase, IEnvironmentClient - { - private readonly int _projectId; - - public EnvironmentClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } - - public IEnumerable All => throw new NotImplementedException(); - - public EnvironmentInfo Create(string name, string externalUrl) - { - throw new NotImplementedException(); - } - - public void Delete(int environmentId) - { - throw new NotImplementedException(); - } - - public EnvironmentInfo Edit(int environmentId, string name, string externalUrl) - { - throw new NotImplementedException(); - } - - public EnvironmentInfo Stop(int environmentId) - { - throw new NotImplementedException(); - } - - public GitLabCollectionResponse GetEnvironmentsAsync(EnvironmentQuery query) - { - return GitLabCollectionResponse.Create(Array.Empty()); - } - - public EnvironmentInfo GetById(int environmentId) - { - throw new NotImplementedException(); - } - - public Task GetByIdAsync(int environmentId, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + private readonly int _projectId; + + public EnvironmentClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } + + public IEnumerable All => throw new NotImplementedException(); + + public EnvironmentInfo Create(string name, string externalUrl) + { + throw new NotImplementedException(); + } + + public void Delete(int environmentId) + { + throw new NotImplementedException(); + } + + public EnvironmentInfo Edit(int environmentId, string name, string externalUrl) + { + throw new NotImplementedException(); + } + + public EnvironmentInfo Stop(int environmentId) + { + throw new NotImplementedException(); + } + + public GitLabCollectionResponse GetEnvironmentsAsync(EnvironmentQuery query) + { + return GitLabCollectionResponse.Create(Array.Empty()); + } + + public EnvironmentInfo GetById(int environmentId) + { + throw new NotImplementedException(); + } + + public Task GetByIdAsync(int environmentId, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/EventClient.cs b/NGitLab.Mock/Clients/EventClient.cs index 4b48d1d4..09f82642 100644 --- a/NGitLab.Mock/Clients/EventClient.cs +++ b/NGitLab.Mock/Clients/EventClient.cs @@ -2,31 +2,30 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class EventClient : ClientBase, IEventClient { - internal sealed class EventClient : ClientBase, IEventClient - { - private readonly int? _userId; - private readonly int? _projectId; + private readonly int? _userId; + private readonly int? _projectId; - public EventClient(ClientContext context) - : base(context) - { - } + public EventClient(ClientContext context) + : base(context) + { + } - public EventClient(ClientContext context, int? userId = null, ProjectId? projectId = null) - : base(context) - { - _userId = userId; - _projectId = projectId.HasValue ? Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id : null; - } + public EventClient(ClientContext context, int? userId = null, ProjectId? projectId = null) + : base(context) + { + _userId = userId; + _projectId = projectId.HasValue ? Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id : null; + } - IEnumerable IEventClient.Get(EventQuery query) + IEnumerable IEventClient.Get(EventQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Server.Events.Get(query, _userId, _projectId).Select(e => e.ToClientEvent()); - } + return Server.Events.Get(query, _userId, _projectId).Select(e => e.ToClientEvent()); } } } diff --git a/NGitLab.Mock/Clients/FileClient.cs b/NGitLab.Mock/Clients/FileClient.cs index dbe7ab82..ff5a138d 100644 --- a/NGitLab.Mock/Clients/FileClient.cs +++ b/NGitLab.Mock/Clients/FileClient.cs @@ -4,125 +4,124 @@ using System.Threading.Tasks; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class FileClient : ClientBase, IFilesClient { - internal sealed class FileClient : ClientBase, IFilesClient - { - private readonly int _projectId; + private readonly int _projectId; - public FileClient(ClientContext context, int projectId) - : base(context) - { - _projectId = projectId; - } + public FileClient(ClientContext context, int projectId) + : base(context) + { + _projectId = projectId; + } - public void Create(FileUpsert file) + public void Create(FileUpsert file) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.Contribute); + var commitCreate = new CommitCreate { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var commitCreate = new CommitCreate + Branch = file.Branch, + CommitMessage = file.CommitMessage, + AuthorEmail = Context.User.Email, + AuthorName = Context.User.Name, + Actions = new[] { - Branch = file.Branch, - CommitMessage = file.CommitMessage, - AuthorEmail = Context.User.Email, - AuthorName = Context.User.Name, - Actions = new[] + new CreateCommitAction { - new CreateCommitAction - { - Action = nameof(CommitAction.Create), - Content = file.Content, - Encoding = file.Encoding, - FilePath = file.Path, - }, + Action = nameof(CommitAction.Create), + Content = file.Content, + Encoding = file.Encoding, + FilePath = file.Path, }, - }; + }, + }; - project.Repository.Commit(commitCreate); - } + project.Repository.Commit(commitCreate); } + } - public void Delete(FileDelete file) + public void Delete(FileDelete file) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.Contribute); + var commitCreate = new CommitCreate { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var commitCreate = new CommitCreate + Branch = file.Branch, + CommitMessage = file.CommitMessage, + AuthorEmail = Context.User.Email, + AuthorName = Context.User.Name, + Actions = new[] { - Branch = file.Branch, - CommitMessage = file.CommitMessage, - AuthorEmail = Context.User.Email, - AuthorName = Context.User.Name, - Actions = new[] + new CreateCommitAction { - new CreateCommitAction - { - Action = nameof(CommitAction.Delete), - FilePath = file.Path, - }, + Action = nameof(CommitAction.Delete), + FilePath = file.Path, }, - }; + }, + }; - project.Repository.Commit(commitCreate); - } + project.Repository.Commit(commitCreate); } + } - public FileData Get(string filePath, string @ref) + public FileData Get(string filePath, string @ref) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var fileSystemPath = WebUtility.UrlDecode(filePath); + var fileSystemPath = WebUtility.UrlDecode(filePath); - var project = GetProject(_projectId, ProjectPermission.View); - return project.Repository.GetFile(fileSystemPath, @ref); - } + var project = GetProject(_projectId, ProjectPermission.View); + return project.Repository.GetFile(fileSystemPath, @ref); } + } - public bool FileExists(string filePath, string @ref) + public bool FileExists(string filePath, string @ref) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Get(filePath, @ref) != null; - } + return Get(filePath, @ref) != null; } + } - public Blame[] Blame(string filePath, string @ref) - { - throw new NotImplementedException(); - } + public Blame[] Blame(string filePath, string @ref) + { + throw new NotImplementedException(); + } - public void Update(FileUpsert file) + public void Update(FileUpsert file) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.Contribute); + var commitCreate = new CommitCreate { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var commitCreate = new CommitCreate + Branch = file.Branch, + CommitMessage = file.CommitMessage, + AuthorEmail = Context.User.Email, + AuthorName = Context.User.Name, + Actions = new[] { - Branch = file.Branch, - CommitMessage = file.CommitMessage, - AuthorEmail = Context.User.Email, - AuthorName = Context.User.Name, - Actions = new[] + new CreateCommitAction { - new CreateCommitAction - { - Action = nameof(CommitAction.Update), - Content = file.Content, - Encoding = file.Encoding, - FilePath = file.Path, - }, + Action = nameof(CommitAction.Update), + Content = file.Content, + Encoding = file.Encoding, + FilePath = file.Path, }, - }; + }, + }; - project.Repository.Commit(commitCreate); - } + project.Repository.Commit(commitCreate); } + } - public async Task GetAsync(string filePath, string @ref, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Get(filePath, @ref); - } + public async Task GetAsync(string filePath, string @ref, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Get(filePath, @ref); } } diff --git a/NGitLab.Mock/Clients/GitLabBadRequestException.cs b/NGitLab.Mock/Clients/GitLabBadRequestException.cs index 00a6cac5..4d48fdf4 100644 --- a/NGitLab.Mock/Clients/GitLabBadRequestException.cs +++ b/NGitLab.Mock/Clients/GitLabBadRequestException.cs @@ -2,36 +2,35 @@ using System.Net; using System.Runtime.Serialization; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +public sealed class GitLabBadRequestException : GitLabException { - public sealed class GitLabBadRequestException : GitLabException + public GitLabBadRequestException() { - public GitLabBadRequestException() - { - Initialize(); - } + Initialize(); + } - public GitLabBadRequestException(string message) - : base(message) - { - Initialize(); - } + public GitLabBadRequestException(string message) + : base(message) + { + Initialize(); + } - public GitLabBadRequestException(string message, Exception inner) - : base(message, inner) - { - Initialize(); - } + public GitLabBadRequestException(string message, Exception inner) + : base(message, inner) + { + Initialize(); + } - private GitLabBadRequestException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - Initialize(); - } + private GitLabBadRequestException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + Initialize(); + } - private void Initialize() - { - StatusCode = HttpStatusCode.BadRequest; - } + private void Initialize() + { + StatusCode = HttpStatusCode.BadRequest; } } diff --git a/NGitLab.Mock/Clients/GitLabClient.cs b/NGitLab.Mock/Clients/GitLabClient.cs index 4bcb1bf9..ba0fbe09 100644 --- a/NGitLab.Mock/Clients/GitLabClient.cs +++ b/NGitLab.Mock/Clients/GitLabClient.cs @@ -1,156 +1,155 @@ using NGitLab.Impl; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class GitLabClient : ClientBase, IGitLabClient { - internal sealed class GitLabClient : ClientBase, IGitLabClient - { - private IGraphQLClient _graphQLClient; + private IGraphQLClient _graphQLClient; - public GitLabClient(ClientContext context) - : base(context) - { - } + public GitLabClient(ClientContext context) + : base(context) + { + } - public IGroupsClient Groups => new GroupClient(Context); + public IGroupsClient Groups => new GroupClient(Context); - public IUserClient Users => new UserClient(Context); + public IUserClient Users => new UserClient(Context); - public IProjectClient Projects => new ProjectClient(Context); + public IProjectClient Projects => new ProjectClient(Context); - public IMembersClient Members => new MembersClient(Context); + public IMembersClient Members => new MembersClient(Context); - public ICommitClient GetCommits(int projectId) => GetCommits((long)projectId); + public ICommitClient GetCommits(int projectId) => GetCommits((long)projectId); - public ICommitClient GetCommits(ProjectId projectId) => new CommitClient(Context, projectId); + public ICommitClient GetCommits(ProjectId projectId) => new CommitClient(Context, projectId); - public IIssueClient Issues => new IssueClient(Context); + public IIssueClient Issues => new IssueClient(Context); - public ILabelClient Labels => new LabelClient(Context); + public ILabelClient Labels => new LabelClient(Context); - public IRunnerClient Runners => new RunnerClient(Context); + public IRunnerClient Runners => new RunnerClient(Context); - public IVersionClient Version => new VersionClient(Context); + public IVersionClient Version => new VersionClient(Context); - public INamespacesClient Namespaces => new NamespacesClient(Context); + public INamespacesClient Namespaces => new NamespacesClient(Context); - public ISnippetClient Snippets => new SnippetClient(Context); + public ISnippetClient Snippets => new SnippetClient(Context); - public ISystemHookClient SystemHooks => new SystemHookClient(Context); + public ISystemHookClient SystemHooks => new SystemHookClient(Context); - public IDeploymentClient Deployments { get; } + public IDeploymentClient Deployments { get; } - public IEpicClient Epics { get; } + public IEpicClient Epics { get; } - public IMergeRequestClient MergeRequests => new MergeRequestClient(Context); + public IMergeRequestClient MergeRequests => new MergeRequestClient(Context); - public IGlobalJobClient Jobs => new GlobalJobsClient(Context); + public IGlobalJobClient Jobs => new GlobalJobsClient(Context); - public IGraphQLClient GraphQL - { - get => _graphQLClient ??= Server.DefaultGraphQLClient ??= new GraphQLClient(Context); - internal set => _graphQLClient = value; - } + public IGraphQLClient GraphQL + { + get => _graphQLClient ??= Server.DefaultGraphQLClient ??= new GraphQLClient(Context); + internal set => _graphQLClient = value; + } - public ISearchClient AdvancedSearch => new AdvancedSearchClient(Context); + public ISearchClient AdvancedSearch => new AdvancedSearchClient(Context); - public ILintClient Lint => new LintClient(Context); + public ILintClient Lint => new LintClient(Context); - public IEventClient GetEvents() => new EventClient(Context); + public IEventClient GetEvents() => new EventClient(Context); - public IEventClient GetUserEvents(int userId) => new EventClient(Context, userId); + public IEventClient GetUserEvents(int userId) => new EventClient(Context, userId); - public IEventClient GetProjectEvents(int projectId) => GetProjectEvents((long)projectId); + public IEventClient GetProjectEvents(int projectId) => GetProjectEvents((long)projectId); - public IEventClient GetProjectEvents(ProjectId projectId) => new EventClient(Context, null, projectId); + public IEventClient GetProjectEvents(ProjectId projectId) => new EventClient(Context, null, projectId); - public ICommitStatusClient GetCommitStatus(int projectId) => GetCommitStatus((long)projectId); + public ICommitStatusClient GetCommitStatus(int projectId) => GetCommitStatus((long)projectId); - public ICommitStatusClient GetCommitStatus(ProjectId projectId) => new CommitStatusClient(Context, projectId); + public ICommitStatusClient GetCommitStatus(ProjectId projectId) => new CommitStatusClient(Context, projectId); - public IEnvironmentClient GetEnvironmentClient(int projectId) => GetEnvironmentClient((long)projectId); + public IEnvironmentClient GetEnvironmentClient(int projectId) => GetEnvironmentClient((long)projectId); - public IEnvironmentClient GetEnvironmentClient(ProjectId projectId) => new EnvironmentClient(Context, projectId); + public IEnvironmentClient GetEnvironmentClient(ProjectId projectId) => new EnvironmentClient(Context, projectId); - public IClusterClient GetClusterClient(int projectId) => GetClusterClient((long)projectId); + public IClusterClient GetClusterClient(int projectId) => GetClusterClient((long)projectId); - public IClusterClient GetClusterClient(ProjectId projectId) => new ClusterClient(Context, projectId); + public IClusterClient GetClusterClient(ProjectId projectId) => new ClusterClient(Context, projectId); - public IGroupBadgeClient GetGroupBadgeClient(int groupId) => GetGroupBadgeClient((long)groupId); + public IGroupBadgeClient GetGroupBadgeClient(int groupId) => GetGroupBadgeClient((long)groupId); - public IGroupBadgeClient GetGroupBadgeClient(GroupId groupId) => new GroupBadgeClient(Context, groupId); + public IGroupBadgeClient GetGroupBadgeClient(GroupId groupId) => new GroupBadgeClient(Context, groupId); - public IGroupVariableClient GetGroupVariableClient(int groupId) => GetGroupVariableClient((long)groupId); + public IGroupVariableClient GetGroupVariableClient(int groupId) => GetGroupVariableClient((long)groupId); - public IGroupVariableClient GetGroupVariableClient(GroupId groupId) => new GroupVariableClient(Context, groupId); + public IGroupVariableClient GetGroupVariableClient(GroupId groupId) => new GroupVariableClient(Context, groupId); - public IJobClient GetJobs(int projectId) => GetJobs((long)projectId); + public IJobClient GetJobs(int projectId) => GetJobs((long)projectId); - public IJobClient GetJobs(ProjectId projectId) => new JobClient(Context, projectId); + public IJobClient GetJobs(ProjectId projectId) => new JobClient(Context, projectId); - public IMergeRequestClient GetMergeRequest(int projectId) => GetMergeRequest((long)projectId); + public IMergeRequestClient GetMergeRequest(int projectId) => GetMergeRequest((long)projectId); - public IMergeRequestClient GetMergeRequest(ProjectId projectId) => new MergeRequestClient(Context, projectId); + public IMergeRequestClient GetMergeRequest(ProjectId projectId) => new MergeRequestClient(Context, projectId); - public IMilestoneClient GetMilestone(int projectId) => GetMilestone((long)projectId); + public IMilestoneClient GetMilestone(int projectId) => GetMilestone((long)projectId); - public IMilestoneClient GetMilestone(ProjectId projectId) => new MilestoneClient(Context, projectId, MilestoneScope.Projects); + public IMilestoneClient GetMilestone(ProjectId projectId) => new MilestoneClient(Context, projectId, MilestoneScope.Projects); - public IMilestoneClient GetGroupMilestone(int groupId) => GetGroupMilestone((long)groupId); + public IMilestoneClient GetGroupMilestone(int groupId) => GetGroupMilestone((long)groupId); - public IMilestoneClient GetGroupMilestone(GroupId groupId) => new MilestoneClient(Context, groupId, MilestoneScope.Groups); + public IMilestoneClient GetGroupMilestone(GroupId groupId) => new MilestoneClient(Context, groupId, MilestoneScope.Groups); - public IReleaseClient GetReleases(int projectId) => GetReleases((long)projectId); + public IReleaseClient GetReleases(int projectId) => GetReleases((long)projectId); - public IReleaseClient GetReleases(ProjectId projectId) => new ReleaseClient(Context, projectId); + public IReleaseClient GetReleases(ProjectId projectId) => new ReleaseClient(Context, projectId); - public IPipelineClient GetPipelines(int projectId) => GetPipelines((long)projectId); + public IPipelineClient GetPipelines(int projectId) => GetPipelines((long)projectId); - public IPipelineClient GetPipelines(ProjectId projectId) => new PipelineClient(Context, jobClient: GetJobs(projectId), projectId: projectId); + public IPipelineClient GetPipelines(ProjectId projectId) => new PipelineClient(Context, jobClient: GetJobs(projectId), projectId: projectId); - public IProjectBadgeClient GetProjectBadgeClient(int projectId) => GetProjectBadgeClient((long)projectId); + public IProjectBadgeClient GetProjectBadgeClient(int projectId) => GetProjectBadgeClient((long)projectId); - public IProjectBadgeClient GetProjectBadgeClient(ProjectId projectId) => new ProjectBadgeClient(Context, projectId); + public IProjectBadgeClient GetProjectBadgeClient(ProjectId projectId) => new ProjectBadgeClient(Context, projectId); - public IProjectIssueNoteClient GetProjectIssueNoteClient(int projectId) => GetProjectIssueNoteClient((long)projectId); + public IProjectIssueNoteClient GetProjectIssueNoteClient(int projectId) => GetProjectIssueNoteClient((long)projectId); - public IProjectIssueNoteClient GetProjectIssueNoteClient(ProjectId projectId) => new ProjectIssueNoteClient(Context, projectId); + public IProjectIssueNoteClient GetProjectIssueNoteClient(ProjectId projectId) => new ProjectIssueNoteClient(Context, projectId); - public IProjectVariableClient GetProjectVariableClient(int projectId) => GetProjectVariableClient((long)projectId); + public IProjectVariableClient GetProjectVariableClient(int projectId) => GetProjectVariableClient((long)projectId); - public IProjectVariableClient GetProjectVariableClient(ProjectId projectId) => new ProjectVariableClient(Context, projectId); + public IProjectVariableClient GetProjectVariableClient(ProjectId projectId) => new ProjectVariableClient(Context, projectId); - public IRepositoryClient GetRepository(int projectId) => GetRepository((long)projectId); + public IRepositoryClient GetRepository(int projectId) => GetRepository((long)projectId); - public IRepositoryClient GetRepository(ProjectId projectId) => new RepositoryClient(Context, projectId); + public IRepositoryClient GetRepository(ProjectId projectId) => new RepositoryClient(Context, projectId); - public ITriggerClient GetTriggers(int projectId) => GetTriggers((long)projectId); + public ITriggerClient GetTriggers(int projectId) => GetTriggers((long)projectId); - public ITriggerClient GetTriggers(ProjectId projectId) => new TriggerClient(Context, projectId); + public ITriggerClient GetTriggers(ProjectId projectId) => new TriggerClient(Context, projectId); - public IWikiClient GetWikiClient(int projectId) => GetWikiClient((long)projectId); + public IWikiClient GetWikiClient(int projectId) => GetWikiClient((long)projectId); - public IWikiClient GetWikiClient(ProjectId projectId) => new WikiClient(Context, projectId); + public IWikiClient GetWikiClient(ProjectId projectId) => new WikiClient(Context, projectId); - public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId) => GetProjectLevelApprovalRulesClient((long)projectId); + public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(int projectId) => GetProjectLevelApprovalRulesClient((long)projectId); - public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(ProjectId projectId) => new ProjectLevelApprovalRulesClient(Context, projectId); + public IProjectLevelApprovalRulesClient GetProjectLevelApprovalRulesClient(ProjectId projectId) => new ProjectLevelApprovalRulesClient(Context, projectId); - public IProtectedBranchClient GetProtectedBranchClient(int projectId) => GetProtectedBranchClient((long)projectId); + public IProtectedBranchClient GetProtectedBranchClient(int projectId) => GetProtectedBranchClient((long)projectId); - public IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId) => new ProtectedBranchClient(Context, projectId); + public IProtectedBranchClient GetProtectedBranchClient(ProjectId projectId) => new ProtectedBranchClient(Context, projectId); - public IProtectedTagClient GetProtectedTagClient(ProjectId projectId) - { - throw new System.NotImplementedException(); - } + public IProtectedTagClient GetProtectedTagClient(ProjectId projectId) + { + throw new System.NotImplementedException(); + } - public ISearchClient GetGroupSearchClient(int groupId) => GetGroupSearchClient((long)groupId); + public ISearchClient GetGroupSearchClient(int groupId) => GetGroupSearchClient((long)groupId); - public ISearchClient GetGroupSearchClient(GroupId groupId) => new GroupSearchClient(Context, groupId); + public ISearchClient GetGroupSearchClient(GroupId groupId) => new GroupSearchClient(Context, groupId); - public ISearchClient GetProjectSearchClient(int projectId) => GetProjectSearchClient((long)projectId); + public ISearchClient GetProjectSearchClient(int projectId) => GetProjectSearchClient((long)projectId); - public ISearchClient GetProjectSearchClient(ProjectId projectId) => new ProjectSearchClient(Context, projectId); - } + public ISearchClient GetProjectSearchClient(ProjectId projectId) => new ProjectSearchClient(Context, projectId); } diff --git a/NGitLab.Mock/Clients/GitLabForbiddenException.cs b/NGitLab.Mock/Clients/GitLabForbiddenException.cs index 2b3962a6..3c350cf6 100644 --- a/NGitLab.Mock/Clients/GitLabForbiddenException.cs +++ b/NGitLab.Mock/Clients/GitLabForbiddenException.cs @@ -2,36 +2,35 @@ using System.Net; using System.Runtime.Serialization; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +public sealed class GitLabForbiddenException : GitLabException { - public sealed class GitLabForbiddenException : GitLabException + public GitLabForbiddenException() { - public GitLabForbiddenException() - { - Initialize(); - } + Initialize(); + } - public GitLabForbiddenException(string message) - : base(message) - { - Initialize(); - } + public GitLabForbiddenException(string message) + : base(message) + { + Initialize(); + } - public GitLabForbiddenException(string message, Exception inner) - : base(message, inner) - { - Initialize(); - } + public GitLabForbiddenException(string message, Exception inner) + : base(message, inner) + { + Initialize(); + } - private GitLabForbiddenException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - Initialize(); - } + private GitLabForbiddenException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + Initialize(); + } - private void Initialize() - { - StatusCode = HttpStatusCode.Forbidden; - } + private void Initialize() + { + StatusCode = HttpStatusCode.Forbidden; } } diff --git a/NGitLab.Mock/Clients/GitLabNotFoundException.cs b/NGitLab.Mock/Clients/GitLabNotFoundException.cs index 12f9c184..7758d90a 100644 --- a/NGitLab.Mock/Clients/GitLabNotFoundException.cs +++ b/NGitLab.Mock/Clients/GitLabNotFoundException.cs @@ -2,36 +2,35 @@ using System.Net; using System.Runtime.Serialization; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +public sealed class GitLabNotFoundException : GitLabException { - public sealed class GitLabNotFoundException : GitLabException + public GitLabNotFoundException() { - public GitLabNotFoundException() - { - Initialize(); - } + Initialize(); + } - public GitLabNotFoundException(string message) - : base(message) - { - Initialize(); - } + public GitLabNotFoundException(string message) + : base(message) + { + Initialize(); + } - public GitLabNotFoundException(string message, Exception inner) - : base(message, inner) - { - Initialize(); - } + public GitLabNotFoundException(string message, Exception inner) + : base(message, inner) + { + Initialize(); + } - private GitLabNotFoundException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - Initialize(); - } + private GitLabNotFoundException(SerializationInfo info, StreamingContext context) + : base(info, context) + { + Initialize(); + } - private void Initialize() - { - StatusCode = HttpStatusCode.NotFound; - } + private void Initialize() + { + StatusCode = HttpStatusCode.NotFound; } } diff --git a/NGitLab.Mock/Clients/GlobalJobsClient.cs b/NGitLab.Mock/Clients/GlobalJobsClient.cs index 2bd434a6..99f4150c 100644 --- a/NGitLab.Mock/Clients/GlobalJobsClient.cs +++ b/NGitLab.Mock/Clients/GlobalJobsClient.cs @@ -3,27 +3,26 @@ using System.Threading; using System.Threading.Tasks; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class GlobalJobsClient : ClientBase, IGlobalJobClient { - internal sealed class GlobalJobsClient : ClientBase, IGlobalJobClient + public GlobalJobsClient(ClientContext context) + : base(context) { - public GlobalJobsClient(ClientContext context) - : base(context) - { - } + } - async Task IGlobalJobClient.GetJobFromJobTokenAsync(string token, CancellationToken cancellationToken) + async Task IGlobalJobClient.GetJobFromJobTokenAsync(string token, CancellationToken cancellationToken) + { + await Task.Yield(); + using (Context.BeginOperationScope()) { - await Task.Yield(); - using (Context.BeginOperationScope()) - { - var job = Server.AllProjects.SelectMany(p => p.Jobs).FirstOrDefault(j => string.Equals(j.JobToken, token, StringComparison.Ordinal)); + var job = Server.AllProjects.SelectMany(p => p.Jobs).FirstOrDefault(j => string.Equals(j.JobToken, token, StringComparison.Ordinal)); - if (job == null) - throw new GitLabNotFoundException(); + if (job == null) + throw new GitLabNotFoundException(); - return job.ToJobClient(); - } + return job.ToJobClient(); } } } diff --git a/NGitLab.Mock/Clients/GraphQLClient.cs b/NGitLab.Mock/Clients/GraphQLClient.cs index 74a97574..671a46a3 100644 --- a/NGitLab.Mock/Clients/GraphQLClient.cs +++ b/NGitLab.Mock/Clients/GraphQLClient.cs @@ -3,18 +3,17 @@ using System.Threading.Tasks; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class GraphQLClient : ClientBase, IGraphQLClient { - internal sealed class GraphQLClient : ClientBase, IGraphQLClient + public GraphQLClient(ClientContext context) + : base(context) { - public GraphQLClient(ClientContext context) - : base(context) - { - } + } - public Task ExecuteAsync(GraphQLQuery query, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public Task ExecuteAsync(GraphQLQuery query, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/GroupBadgeClient.cs b/NGitLab.Mock/Clients/GroupBadgeClient.cs index 89a426bd..6deff5dd 100644 --- a/NGitLab.Mock/Clients/GroupBadgeClient.cs +++ b/NGitLab.Mock/Clients/GroupBadgeClient.cs @@ -2,87 +2,86 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class GroupBadgeClient : ClientBase, IGroupBadgeClient { - internal sealed class GroupBadgeClient : ClientBase, IGroupBadgeClient - { - private readonly int _groupId; + private readonly int _groupId; - public GroupBadgeClient(ClientContext context, GroupId groupId) - : base(context) - { - _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; - } + public GroupBadgeClient(ClientContext context, GroupId groupId) + : base(context) + { + _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; + } - public Models.Badge this[int id] + public Models.Badge this[int id] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = GetGroup(_groupId, GroupPermission.View); - var badge = group.Badges.GetById(id); - if (badge == null) - throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in group with id '{_groupId}'"); + var group = GetGroup(_groupId, GroupPermission.View); + var badge = group.Badges.GetById(id); + if (badge == null) + throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in group with id '{_groupId}'"); - return badge.ToBadgeModel(); - } + return badge.ToBadgeModel(); } } + } - public IEnumerable All + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = GetGroup(_groupId, GroupPermission.View); - return group.Badges.Select(badge => badge.ToBadgeModel()).ToList(); - } + var group = GetGroup(_groupId, GroupPermission.View); + return group.Badges.Select(badge => badge.ToBadgeModel()).ToList(); } } + } - public Models.Badge Create(BadgeCreate badge) - { - EnsureUserIsAuthenticated(); + public Models.Badge Create(BadgeCreate badge) + { + EnsureUserIsAuthenticated(); - using (Context.BeginOperationScope()) - { - var createdBadge = GetGroup(_groupId, GroupPermission.Edit).Badges.Add(badge.LinkUrl, badge.ImageUrl); - return createdBadge.ToBadgeModel(); - } + using (Context.BeginOperationScope()) + { + var createdBadge = GetGroup(_groupId, GroupPermission.Edit).Badges.Add(badge.LinkUrl, badge.ImageUrl); + return createdBadge.ToBadgeModel(); } + } - public void Delete(int id) - { - EnsureUserIsAuthenticated(); + public void Delete(int id) + { + EnsureUserIsAuthenticated(); - using (Context.BeginOperationScope()) + using (Context.BeginOperationScope()) + { + var badgeToRemove = GetGroup(_groupId, GroupPermission.View).Badges.FirstOrDefault(b => b.Id == id); + if (badgeToRemove == null) { - var badgeToRemove = GetGroup(_groupId, GroupPermission.View).Badges.FirstOrDefault(b => b.Id == id); - if (badgeToRemove == null) - { - throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in group with id '{_groupId}'"); - } - - GetGroup(_groupId, GroupPermission.Edit).Badges.Remove(badgeToRemove); + throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in group with id '{_groupId}'"); } + + GetGroup(_groupId, GroupPermission.Edit).Badges.Remove(badgeToRemove); } + } - public Models.Badge Update(int id, BadgeUpdate badge) + public Models.Badge Update(int id, BadgeUpdate badge) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var badgeToUpdate = GetGroup(_groupId, GroupPermission.Edit).Badges.FirstOrDefault(b => b.Id == id); + if (badgeToUpdate == null) { - var badgeToUpdate = GetGroup(_groupId, GroupPermission.Edit).Badges.FirstOrDefault(b => b.Id == id); - if (badgeToUpdate == null) - { - throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in group with id '{_groupId}'"); - } - - badgeToUpdate.LinkUrl = badge.LinkUrl; - badgeToUpdate.ImageUrl = badge.ImageUrl; - return badgeToUpdate.ToBadgeModel(); + throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in group with id '{_groupId}'"); } + + badgeToUpdate.LinkUrl = badge.LinkUrl; + badgeToUpdate.ImageUrl = badge.ImageUrl; + return badgeToUpdate.ToBadgeModel(); } } } diff --git a/NGitLab.Mock/Clients/GroupClient.cs b/NGitLab.Mock/Clients/GroupClient.cs index 40eec7d8..689e9ef3 100644 --- a/NGitLab.Mock/Clients/GroupClient.cs +++ b/NGitLab.Mock/Clients/GroupClient.cs @@ -7,356 +7,355 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class GroupClient : ClientBase, IGroupsClient { - internal sealed class GroupClient : ClientBase, IGroupsClient + public GroupClient(ClientContext context) + : base(context) { - public GroupClient(ClientContext context) - : base(context) - { - } + } - public Models.Group this[int id] + public Models.Group this[int id] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = Server.AllGroups.FirstOrDefault(g => g.Id == id); - if (group == null || !group.CanUserViewGroup(Context.User)) - throw new GitLabNotFoundException(); + var group = Server.AllGroups.FirstOrDefault(g => g.Id == id); + if (group == null || !group.CanUserViewGroup(Context.User)) + throw new GitLabNotFoundException(); - return group.ToClientGroup(Context.User); - } + return group.ToClientGroup(Context.User); } } + } - public Models.Group this[string fullPath] + public Models.Group this[string fullPath] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = Server.AllGroups.FindGroup(fullPath); - if (group == null || !group.CanUserViewGroup(Context.User)) - throw new GitLabNotFoundException(); + var group = Server.AllGroups.FindGroup(fullPath); + if (group == null || !group.CanUserViewGroup(Context.User)) + throw new GitLabNotFoundException(); - return group.ToClientGroup(Context.User); - } + return group.ToClientGroup(Context.User); } } + } - public IEnumerable Accessible + public IEnumerable Accessible + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Server.AllGroups.Where(group => group.CanUserViewGroup(Context.User)).Select(group => group.ToClientGroup(Context.User)).ToList(); - } + return Server.AllGroups.Where(group => group.CanUserViewGroup(Context.User)).Select(group => group.ToClientGroup(Context.User)).ToList(); } } + } - public Models.Group Create(GroupCreate group) + public Models.Group Create(GroupCreate group) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + Group parentGroup = null; + if (group.ParentId != null) { - Group parentGroup = null; - if (group.ParentId != null) - { - parentGroup = Server.AllGroups.FirstOrDefault(g => g.Id == group.ParentId.Value); - if (parentGroup == null || !parentGroup.CanUserViewGroup(Context.User)) - throw new GitLabNotFoundException(); + parentGroup = Server.AllGroups.FirstOrDefault(g => g.Id == group.ParentId.Value); + if (parentGroup == null || !parentGroup.CanUserViewGroup(Context.User)) + throw new GitLabNotFoundException(); - if (!parentGroup.CanUserAddGroup(Context.User)) - throw new GitLabForbiddenException(); - } + if (!parentGroup.CanUserAddGroup(Context.User)) + throw new GitLabForbiddenException(); + } - var newGroup = new Group - { - Name = group.Name, - Description = group.Description, - Visibility = group.Visibility, - Permissions = - { - new Permission(Context.User, AccessLevel.Owner), - }, - }; - - if (parentGroup != null) - { - parentGroup.Groups.Add(newGroup); - } - else + var newGroup = new Group + { + Name = group.Name, + Description = group.Description, + Visibility = group.Visibility, + Permissions = { - Server.Groups.Add(newGroup); - } + new Permission(Context.User, AccessLevel.Owner), + }, + }; - return newGroup.ToClientGroup(Context.User); + if (parentGroup != null) + { + parentGroup.Groups.Add(newGroup); + } + else + { + Server.Groups.Add(newGroup); } - } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task CreateAsync(GroupCreate group, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Create(group); + return newGroup.ToClientGroup(Context.User); } + } + + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task CreateAsync(GroupCreate group, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Create(group); + } - public void Delete(int id) + public void Delete(int id) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = Server.AllGroups.FirstOrDefault(g => g.Id == id); - if (group == null || !group.CanUserViewGroup(Context.User)) - throw new GitLabNotFoundException(); + var group = Server.AllGroups.FirstOrDefault(g => g.Id == id); + if (group == null || !group.CanUserViewGroup(Context.User)) + throw new GitLabNotFoundException(); - if (!group.CanUserDeleteGroup(Context.User)) - throw new GitLabForbiddenException(); + if (!group.CanUserDeleteGroup(Context.User)) + throw new GitLabForbiddenException(); - group.ToClientGroup(Context.User); - } + group.ToClientGroup(Context.User); } + } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task DeleteAsync(int id, CancellationToken cancellationToken = default) - { - await Task.Yield(); - Delete(id); - } + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task DeleteAsync(int id, CancellationToken cancellationToken = default) + { + await Task.Yield(); + Delete(id); + } - public IEnumerable Get(GroupQuery query) + public IEnumerable Get(GroupQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var groups = Server.AllGroups; + if (query != null) { - var groups = Server.AllGroups; - if (query != null) + if (query.SkipGroups != null && query.SkipGroups.Length > 0) + { + groups = groups.Where(g => !query.SkipGroups.Contains(g.Id)); + } + + if (query.Owned is true) { - if (query.SkipGroups != null && query.SkipGroups.Length > 0) - { - groups = groups.Where(g => !query.SkipGroups.Contains(g.Id)); - } - - if (query.Owned is true) - { - groups = groups.Where(g => g.IsUserOwner(Context.User)); - } - - if (query.MinAccessLevel != null) - { - groups = groups.Where(g => g.GetEffectivePermissions().GetAccessLevel(Context.User) >= query.MinAccessLevel); - } - - if (!string.IsNullOrEmpty(query.Search)) - throw new NotImplementedException(); + groups = groups.Where(g => g.IsUserOwner(Context.User)); } - return groups.Select(g => g.ToClientGroup(Context.User)).ToArray(); + if (query.MinAccessLevel != null) + { + groups = groups.Where(g => g.GetEffectivePermissions().GetAccessLevel(Context.User) >= query.MinAccessLevel); + } + + if (!string.IsNullOrEmpty(query.Search)) + throw new NotImplementedException(); } - } - public GitLabCollectionResponse GetAsync(GroupQuery query) - { - return GitLabCollectionResponse.Create(Get(query)); + return groups.Select(g => g.ToClientGroup(Context.User)).ToArray(); } + } - public async Task GetByFullPathAsync(string fullPath, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return this[fullPath]; - } + public GitLabCollectionResponse GetAsync(GroupQuery query) + { + return GitLabCollectionResponse.Create(Get(query)); + } - public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return this[id]; - } + public async Task GetByFullPathAsync(string fullPath, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return this[fullPath]; + } - public void Restore(int id) - { - throw new NotImplementedException(); - } + public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return this[id]; + } - public IEnumerable Search(string search) - { - throw new NotImplementedException(); - } + public void Restore(int id) + { + throw new NotImplementedException(); + } - public GitLabCollectionResponse SearchAsync(string search) - { - return GitLabCollectionResponse.Create(Search(search)); - } + public IEnumerable Search(string search) + { + throw new NotImplementedException(); + } - public IEnumerable SearchProjects(int groupId, string search) - { - throw new NotImplementedException(); - } + public GitLabCollectionResponse SearchAsync(string search) + { + return GitLabCollectionResponse.Create(Search(search)); + } + + public IEnumerable SearchProjects(int groupId, string search) + { + throw new NotImplementedException(); + } - public GitLabCollectionResponse GetProjectsAsync(int groupId, GroupProjectsQuery query) + public GitLabCollectionResponse GetProjectsAsync(int groupId, GroupProjectsQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var group = Server.AllGroups.FirstOrDefault(g => g.Id == groupId); + if (group == null || !group.CanUserViewGroup(Context.User)) + throw new GitLabNotFoundException(); + + var projects = query?.IncludeSubGroups is true ? group.AllProjects : group.Projects; + + if (query != null) { - var group = Server.AllGroups.FirstOrDefault(g => g.Id == groupId); - if (group == null || !group.CanUserViewGroup(Context.User)) - throw new GitLabNotFoundException(); + if (query.Archived != null) + { + projects = projects.Where(project => project.Archived == query.Archived); + } - var projects = query?.IncludeSubGroups is true ? group.AllProjects : group.Projects; + if (query.Owned != null) + { + projects = projects.Where(project => project.IsUserOwner(Context.User)); + } - if (query != null) + if (query.Visibility != null) { - if (query.Archived != null) - { - projects = projects.Where(project => project.Archived == query.Archived); - } - - if (query.Owned != null) - { - projects = projects.Where(project => project.IsUserOwner(Context.User)); - } - - if (query.Visibility != null) - { - projects = projects.Where(project => project.Visibility >= query.Visibility.Value); - } - - if (!string.IsNullOrEmpty(query.Search)) - throw new NotImplementedException(); - - if (query.MinAccessLevel != null) - throw new NotImplementedException(); + projects = projects.Where(project => project.Visibility >= query.Visibility.Value); } - projects = projects.Where(project => project.CanUserViewProject(Context.User)); - return GitLabCollectionResponse.Create(projects.Select(project => project.ToClientProject(Context.User)).ToArray()); + if (!string.IsNullOrEmpty(query.Search)) + throw new NotImplementedException(); + + if (query.MinAccessLevel != null) + throw new NotImplementedException(); } + + projects = projects.Where(project => project.CanUserViewProject(Context.User)); + return GitLabCollectionResponse.Create(projects.Select(project => project.ToClientProject(Context.User)).ToArray()); } + } - public Models.Group Update(int id, GroupUpdate groupUpdate) + public Models.Group Update(int id, GroupUpdate groupUpdate) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var group = Server.AllGroups.FindById(id); + if (group == null || !group.CanUserViewGroup(Context.User)) + throw new GitLabNotFoundException(); + + if (!group.CanUserEditGroup(Context.User)) + throw new GitLabForbiddenException(); + + if (groupUpdate.Description != null) { - var group = Server.AllGroups.FindById(id); - if (group == null || !group.CanUserViewGroup(Context.User)) - throw new GitLabNotFoundException(); + group.Description = groupUpdate.Description; + } - if (!group.CanUserEditGroup(Context.User)) - throw new GitLabForbiddenException(); + if (groupUpdate.ExtraSharedRunnersMinutesLimit != null) + { + group.ExtraSharedRunnersLimit = TimeSpan.FromMinutes(groupUpdate.ExtraSharedRunnersMinutesLimit.Value); + } - if (groupUpdate.Description != null) - { - group.Description = groupUpdate.Description; - } + if (groupUpdate.LfsEnabled != null) + { + group.LfsEnabled = groupUpdate.LfsEnabled.Value; + } - if (groupUpdate.ExtraSharedRunnersMinutesLimit != null) - { - group.ExtraSharedRunnersLimit = TimeSpan.FromMinutes(groupUpdate.ExtraSharedRunnersMinutesLimit.Value); - } + if (groupUpdate.Name != null) + { + group.Name = groupUpdate.Name; + } - if (groupUpdate.LfsEnabled != null) - { - group.LfsEnabled = groupUpdate.LfsEnabled.Value; - } + if (groupUpdate.Path != null) + { + group.Path = groupUpdate.Path; + } - if (groupUpdate.Name != null) - { - group.Name = groupUpdate.Name; - } + if (groupUpdate.RequestAccessEnabled != null) + { + group.RequestAccessEnabled = groupUpdate.RequestAccessEnabled.Value; + } - if (groupUpdate.Path != null) - { - group.Path = groupUpdate.Path; - } + if (groupUpdate.SharedRunnersMinutesLimit != null) + { + group.SharedRunnersLimit = TimeSpan.FromMinutes(groupUpdate.SharedRunnersMinutesLimit.Value); + } + + if (groupUpdate.Visibility != null) + { + group.Visibility = groupUpdate.Visibility.Value; + } + + return group.ToClientGroup(Context.User); + } + } + + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task UpdateAsync(int id, GroupUpdate groupUpdate, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Update(id, groupUpdate); + } - if (groupUpdate.RequestAccessEnabled != null) + public GitLabCollectionResponse GetSubgroupsByIdAsync(int id, SubgroupQuery query = null) + { + using (Context.BeginOperationScope()) + { + var parentGroup = this[id]; + var groups = Server.AllGroups; + if (query != null) + { + if (query.SkipGroups != null && query.SkipGroups.Length > 0) { - group.RequestAccessEnabled = groupUpdate.RequestAccessEnabled.Value; + groups = groups.Where(g => !query.SkipGroups.Contains(g.Id)); } - if (groupUpdate.SharedRunnersMinutesLimit != null) + if (query.Owned is true) { - group.SharedRunnersLimit = TimeSpan.FromMinutes(groupUpdate.SharedRunnersMinutesLimit.Value); + groups = groups.Where(g => g.IsUserOwner(Context.User)); } - if (groupUpdate.Visibility != null) + if (query.MinAccessLevel != null) { - group.Visibility = groupUpdate.Visibility.Value; + groups = groups.Where(g => g.GetEffectivePermissions().GetAccessLevel(Context.User) >= query.MinAccessLevel); } - return group.ToClientGroup(Context.User); + if (!string.IsNullOrEmpty(query.Search)) + throw new NotImplementedException(); } - } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task UpdateAsync(int id, GroupUpdate groupUpdate, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Update(id, groupUpdate); + var clientGroups = groups.Select(g => g.ToClientGroup(Context.User)); + + return GitLabCollectionResponse.Create(clientGroups.Where(g => g.ParentId == parentGroup.Id)); } + } - public GitLabCollectionResponse GetSubgroupsByIdAsync(int id, SubgroupQuery query = null) + public GitLabCollectionResponse GetSubgroupsByFullPathAsync(string fullPath, SubgroupQuery query = null) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var parentGroup = this[fullPath]; + var groups = Server.AllGroups; + if (query != null) { - var parentGroup = this[id]; - var groups = Server.AllGroups; - if (query != null) + if (query.SkipGroups != null && query.SkipGroups.Length > 0) { - if (query.SkipGroups != null && query.SkipGroups.Length > 0) - { - groups = groups.Where(g => !query.SkipGroups.Contains(g.Id)); - } - - if (query.Owned is true) - { - groups = groups.Where(g => g.IsUserOwner(Context.User)); - } - - if (query.MinAccessLevel != null) - { - groups = groups.Where(g => g.GetEffectivePermissions().GetAccessLevel(Context.User) >= query.MinAccessLevel); - } - - if (!string.IsNullOrEmpty(query.Search)) - throw new NotImplementedException(); + groups = groups.Where(g => !query.SkipGroups.Contains(g.Id)); } - var clientGroups = groups.Select(g => g.ToClientGroup(Context.User)); - - return GitLabCollectionResponse.Create(clientGroups.Where(g => g.ParentId == parentGroup.Id)); - } - } - - public GitLabCollectionResponse GetSubgroupsByFullPathAsync(string fullPath, SubgroupQuery query = null) - { - using (Context.BeginOperationScope()) - { - var parentGroup = this[fullPath]; - var groups = Server.AllGroups; - if (query != null) + if (query.Owned is true) { - if (query.SkipGroups != null && query.SkipGroups.Length > 0) - { - groups = groups.Where(g => !query.SkipGroups.Contains(g.Id)); - } - - if (query.Owned is true) - { - groups = groups.Where(g => g.IsUserOwner(Context.User)); - } - - if (query.MinAccessLevel != null) - { - groups = groups.Where(g => g.GetEffectivePermissions().GetAccessLevel(Context.User) >= query.MinAccessLevel); - } - - if (!string.IsNullOrEmpty(query.Search)) - throw new NotImplementedException(); + groups = groups.Where(g => g.IsUserOwner(Context.User)); } - var clientGroups = groups.Select(g => g.ToClientGroup(Context.User)); + if (query.MinAccessLevel != null) + { + groups = groups.Where(g => g.GetEffectivePermissions().GetAccessLevel(Context.User) >= query.MinAccessLevel); + } - return GitLabCollectionResponse.Create(clientGroups.Where(g => g.ParentId == parentGroup.Id)); + if (!string.IsNullOrEmpty(query.Search)) + throw new NotImplementedException(); } + + var clientGroups = groups.Select(g => g.ToClientGroup(Context.User)); + + return GitLabCollectionResponse.Create(clientGroups.Where(g => g.ParentId == parentGroup.Id)); } } } diff --git a/NGitLab.Mock/Clients/GroupSearchClient.cs b/NGitLab.Mock/Clients/GroupSearchClient.cs index b9742dba..4c240d0c 100644 --- a/NGitLab.Mock/Clients/GroupSearchClient.cs +++ b/NGitLab.Mock/Clients/GroupSearchClient.cs @@ -1,23 +1,22 @@ using System; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class GroupSearchClient : ClientBase, ISearchClient { - internal sealed class GroupSearchClient : ClientBase, ISearchClient - { - private readonly ClientContext _context; - private readonly int _groupId; + private readonly ClientContext _context; + private readonly int _groupId; - public GroupSearchClient(ClientContext context, GroupId groupId) - : base(context) - { - _context = context; - _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; - } + public GroupSearchClient(ClientContext context, GroupId groupId) + : base(context) + { + _context = context; + _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; + } - public GitLabCollectionResponse GetBlobsAsync(SearchQuery query) - { - throw new NotImplementedException(); - } + public GitLabCollectionResponse GetBlobsAsync(SearchQuery query) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/GroupVariableClient.cs b/NGitLab.Mock/Clients/GroupVariableClient.cs index b681a38c..1cde7d30 100644 --- a/NGitLab.Mock/Clients/GroupVariableClient.cs +++ b/NGitLab.Mock/Clients/GroupVariableClient.cs @@ -2,35 +2,34 @@ using System.Collections.Generic; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class GroupVariableClient : ClientBase, IGroupVariableClient { - internal sealed class GroupVariableClient : ClientBase, IGroupVariableClient - { - private readonly int _groupId; + private readonly int _groupId; - public GroupVariableClient(ClientContext context, GroupId groupId) - : base(context) - { - _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; - } + public GroupVariableClient(ClientContext context, GroupId groupId) + : base(context) + { + _groupId = Server.AllGroups.FindGroup(groupId.ValueAsUriParameter()).Id; + } - public Variable this[string key] => throw new NotImplementedException(); + public Variable this[string key] => throw new NotImplementedException(); - public IEnumerable All => throw new NotImplementedException(); + public IEnumerable All => throw new NotImplementedException(); - public Variable Create(VariableCreate model) - { - throw new NotImplementedException(); - } + public Variable Create(VariableCreate model) + { + throw new NotImplementedException(); + } - public void Delete(string key) - { - throw new NotImplementedException(); - } + public void Delete(string key) + { + throw new NotImplementedException(); + } - public Variable Update(string key, VariableUpdate model) - { - throw new NotImplementedException(); - } + public Variable Update(string key, VariableUpdate model) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/ICommitActionHandler.cs b/NGitLab.Mock/Clients/ICommitActionHandler.cs index 2f76ac5f..e6bb4496 100644 --- a/NGitLab.Mock/Clients/ICommitActionHandler.cs +++ b/NGitLab.Mock/Clients/ICommitActionHandler.cs @@ -1,9 +1,8 @@ using NGitLab.Models; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +internal interface ICommitActionHandler { - internal interface ICommitActionHandler - { - void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository); - } + void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository); } diff --git a/NGitLab.Mock/Clients/IssueClient.cs b/NGitLab.Mock/Clients/IssueClient.cs index 394097fc..987b7e4c 100644 --- a/NGitLab.Mock/Clients/IssueClient.cs +++ b/NGitLab.Mock/Clients/IssueClient.cs @@ -8,448 +8,447 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class IssueClient : ClientBase, IIssueClient { - internal sealed class IssueClient : ClientBase, IIssueClient + public IssueClient(ClientContext context) + : base(context) { - public IssueClient(ClientContext context) - : base(context) - { - } + } - public IEnumerable Owned + public IEnumerable Owned + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var viewableProjects = Server.AllProjects.Where(p => p.CanUserViewProject(Context.User)); - var allIssues = viewableProjects.SelectMany(p => p.Issues); - var assignedOrAuthoredIssues = allIssues.Where(i => i.CanUserViewIssue(Context.User)); - return assignedOrAuthoredIssues.Select(i => i.ToClientIssue()).ToList(); - } + var viewableProjects = Server.AllProjects.Where(p => p.CanUserViewProject(Context.User)); + var allIssues = viewableProjects.SelectMany(p => p.Issues); + var assignedOrAuthoredIssues = allIssues.Where(i => i.CanUserViewIssue(Context.User)); + return assignedOrAuthoredIssues.Select(i => i.ToClientIssue()).ToList(); } } + } - public Models.Issue Create(IssueCreate issueCreate) + public Models.Issue Create(IssueCreate issueCreate) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(issueCreate.ProjectId, ProjectPermission.View); + + var issue = new Issue { - var project = GetProject(issueCreate.ProjectId, ProjectPermission.View); - - var issue = new Issue - { - Description = issueCreate.Description, - Title = issueCreate.Title, - Author = Context.User, - Confidential = issueCreate.Confidential, - }; - - if (!string.IsNullOrEmpty(issueCreate.Labels)) - { - issue.Labels = issueCreate.Labels.Split(','); - } - - if (issueCreate.AssigneeId != null) - { - issue.Assignee = Server.Users.FirstOrDefault(u => u.Id == issueCreate.AssigneeId); - } - - project.Issues.Add(issue); - return project.Issues.First(i => i.Iid == issue.Iid).ToClientIssue(); - } - } + Description = issueCreate.Description, + Title = issueCreate.Title, + Author = Context.User, + Confidential = issueCreate.Confidential, + }; - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task CreateAsync(IssueCreate issueCreate, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Create(issueCreate); - } + if (!string.IsNullOrEmpty(issueCreate.Labels)) + { + issue.Labels = issueCreate.Labels.Split(','); + } - public Models.Issue Edit(IssueEdit issueEdit) - { - using (Context.BeginOperationScope()) + if (issueCreate.AssigneeId != null) { - var projectId = issueEdit.ProjectId; - var issueToModify = GetIssue(projectId, issueEdit.IssueId); - - if (issueEdit.AssigneeId.HasValue) - { - issueToModify.Assignee = GetUser(issueEdit.AssigneeId.Value); - } - - var prevMilestone = issueToModify.Milestone; - - if (issueEdit.MilestoneId.HasValue) - { - issueToModify.Milestone = GetMilestone(projectId, issueEdit.MilestoneId.Value); - Server.ResourceMilestoneEvents.CreateResourceMilestoneEvents(Context.User, issueToModify.Id, prevMilestone, issueToModify.Milestone, "Issue"); - } - - issueToModify.Title = issueEdit.Title; - issueToModify.Description = issueEdit.Description; - - string[] labelsEdit; - - if (issueEdit.Labels is null) - { - labelsEdit = null; - } - else if (string.Equals(issueEdit.Labels, string.Empty, StringComparison.Ordinal)) - { - labelsEdit = Array.Empty(); - } - else - { - labelsEdit = issueEdit.Labels.Split(','); - } - - if (labelsEdit is not null) - { - Server.ResourceLabelEvents.CreateResourceLabelEvents(Context.User, issueToModify.Labels, labelsEdit, issueToModify.Id, "issue"); - issueToModify.Labels = labelsEdit; - } - - issueToModify.UpdatedAt = DateTimeOffset.UtcNow; - var isValidState = Enum.TryParse(issueEdit.State, out var requestedState); - if (isValidState) - { - issueToModify.State = (IssueState)requestedState; - } - - return issueToModify.ToClientIssue(); + issue.Assignee = Server.Users.FirstOrDefault(u => u.Id == issueCreate.AssigneeId); } - } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task EditAsync(IssueEdit issueEdit, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Edit(issueEdit); + project.Issues.Add(issue); + return project.Issues.First(i => i.Iid == issue.Iid).ToClientIssue(); } + } + + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task CreateAsync(IssueCreate issueCreate, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Create(issueCreate); + } - public IEnumerable ResourceLabelEvents(int projectId, int issueIid) + public Models.Issue Edit(IssueEdit issueEdit) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var projectId = issueEdit.ProjectId; + var issueToModify = GetIssue(projectId, issueEdit.IssueId); + + if (issueEdit.AssigneeId.HasValue) { - var issue = GetIssue(projectId, issueIid); - return Server.ResourceLabelEvents.Get(issue.Id).Select(rle => rle.ToClientResourceLabelEvent()); + issueToModify.Assignee = GetUser(issueEdit.AssigneeId.Value); } - } - public GitLabCollectionResponse ResourceLabelEventsAsync(int projectId, int issueIid) - { - using (Context.BeginOperationScope()) - { - var issue = GetIssue(projectId, issueIid); - var resourceLabelEvents = Server.ResourceLabelEvents.Get(issue.Id); + var prevMilestone = issueToModify.Milestone; - return GitLabCollectionResponse.Create(resourceLabelEvents.Select(rle => rle.ToClientResourceLabelEvent())); + if (issueEdit.MilestoneId.HasValue) + { + issueToModify.Milestone = GetMilestone(projectId, issueEdit.MilestoneId.Value); + Server.ResourceMilestoneEvents.CreateResourceMilestoneEvents(Context.User, issueToModify.Id, prevMilestone, issueToModify.Milestone, "Issue"); } - } - public IEnumerable ResourceMilestoneEvents(int projectId, int issueIid) - { - using (Context.BeginOperationScope()) + issueToModify.Title = issueEdit.Title; + issueToModify.Description = issueEdit.Description; + + string[] labelsEdit; + + if (issueEdit.Labels is null) { - var issue = GetIssue(projectId, issueIid); - return Server.ResourceMilestoneEvents.Get(issue.Id).Select(rme => rme.ToClientResourceMilestoneEvent()); + labelsEdit = null; } - } - - public GitLabCollectionResponse ResourceMilestoneEventsAsync(int projectId, int issueIid) - { - using (Context.BeginOperationScope()) + else if (string.Equals(issueEdit.Labels, string.Empty, StringComparison.Ordinal)) { - var issue = GetIssue(projectId, issueIid); - var resourceMilestoneEvents = Server.ResourceMilestoneEvents.Get(issue.Id); - - return GitLabCollectionResponse.Create(resourceMilestoneEvents.Select(rme => rme.ToClientResourceMilestoneEvent())); + labelsEdit = Array.Empty(); } - } - - public IEnumerable ResourceStateEvents(int projectId, int issueIid) - { - using (Context.BeginOperationScope()) + else { - var issue = GetIssue(projectId, issueIid); - return Server.ResourceStateEvents.Get(issue.Id).Select(rle => rle.ToClientResourceStateEvent()); + labelsEdit = issueEdit.Labels.Split(','); } - } - public GitLabCollectionResponse ResourceStateEventsAsync(int projectId, int issueIid) - { - using (Context.BeginOperationScope()) + if (labelsEdit is not null) { - var issue = GetIssue(projectId, issueIid); - var resourceStateEvents = Server.ResourceStateEvents.Get(issue.Id); + Server.ResourceLabelEvents.CreateResourceLabelEvents(Context.User, issueToModify.Labels, labelsEdit, issueToModify.Id, "issue"); + issueToModify.Labels = labelsEdit; + } - return GitLabCollectionResponse.Create(resourceStateEvents.Select(rle => rle.ToClientResourceStateEvent())); + issueToModify.UpdatedAt = DateTimeOffset.UtcNow; + var isValidState = Enum.TryParse(issueEdit.State, out var requestedState); + if (isValidState) + { + issueToModify.State = (IssueState)requestedState; } - } - public IEnumerable RelatedTo(int projectId, int issueId) - { - throw new NotImplementedException(); + return issueToModify.ToClientIssue(); } + } - public GitLabCollectionResponse RelatedToAsync(int projectId, int issueIid) + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task EditAsync(IssueEdit issueEdit, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Edit(issueEdit); + } + + public IEnumerable ResourceLabelEvents(int projectId, int issueIid) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var issue = GetIssue(projectId, issueIid); + return Server.ResourceLabelEvents.Get(issue.Id).Select(rle => rle.ToClientResourceLabelEvent()); } + } - public IEnumerable ClosedBy(int projectId, int issueId) + public GitLabCollectionResponse ResourceLabelEventsAsync(int projectId, int issueIid) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var issue = GetIssue(projectId, issueIid); + var resourceLabelEvents = Server.ResourceLabelEvents.Get(issue.Id); + + return GitLabCollectionResponse.Create(resourceLabelEvents.Select(rle => rle.ToClientResourceLabelEvent())); } + } - public GitLabCollectionResponse ClosedByAsync(int projectId, int issueIid) + public IEnumerable ResourceMilestoneEvents(int projectId, int issueIid) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var issue = GetIssue(projectId, issueIid); + return Server.ResourceMilestoneEvents.Get(issue.Id).Select(rme => rme.ToClientResourceMilestoneEvent()); } + } - public Task TimeStatsAsync(int projectId, int issueIid, CancellationToken cancellationToken = default) + public GitLabCollectionResponse ResourceMilestoneEventsAsync(int projectId, int issueIid) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var issue = GetIssue(projectId, issueIid); + var resourceMilestoneEvents = Server.ResourceMilestoneEvents.Get(issue.Id); + + return GitLabCollectionResponse.Create(resourceMilestoneEvents.Select(rme => rme.ToClientResourceMilestoneEvent())); } + } - public Task CloneAsync(int projectId, int issueIid, IssueClone issueClone, CancellationToken cancellationToken = default) + public IEnumerable ResourceStateEvents(int projectId, int issueIid) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var issue = GetIssue(projectId, issueIid); + return Server.ResourceStateEvents.Get(issue.Id).Select(rle => rle.ToClientResourceStateEvent()); } + } - public IEnumerable ForProject(int projectId) + public GitLabCollectionResponse ResourceStateEventsAsync(int projectId, int issueIid) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.View); + var issue = GetIssue(projectId, issueIid); + var resourceStateEvents = Server.ResourceStateEvents.Get(issue.Id); - return project - .Issues - .Where(i => i.CanUserViewIssue(Context.User)) - .Select(i => i.ToClientIssue()) - .ToList(); - } + return GitLabCollectionResponse.Create(resourceStateEvents.Select(rle => rle.ToClientResourceStateEvent())); } + } + + public IEnumerable RelatedTo(int projectId, int issueId) + { + throw new NotImplementedException(); + } + + public GitLabCollectionResponse RelatedToAsync(int projectId, int issueIid) + { + throw new NotImplementedException(); + } + + public IEnumerable ClosedBy(int projectId, int issueId) + { + throw new NotImplementedException(); + } + + public GitLabCollectionResponse ClosedByAsync(int projectId, int issueIid) + { + throw new NotImplementedException(); + } + + public Task TimeStatsAsync(int projectId, int issueIid, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public Task CloneAsync(int projectId, int issueIid, IssueClone issueClone, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } - public GitLabCollectionResponse ForProjectAsync(int projectId) + public IEnumerable ForProject(int projectId) + { + using (Context.BeginOperationScope()) { - return GitLabCollectionResponse.Create(ForProject(projectId)); + var project = GetProject(projectId, ProjectPermission.View); + + return project + .Issues + .Where(i => i.CanUserViewIssue(Context.User)) + .Select(i => i.ToClientIssue()) + .ToList(); } + } + + public GitLabCollectionResponse ForProjectAsync(int projectId) + { + return GitLabCollectionResponse.Create(ForProject(projectId)); + } + + public GitLabCollectionResponse ForGroupsAsync(int groupId) + { + throw new NotImplementedException(); + } + + public GitLabCollectionResponse ForGroupsAsync(int groupId, IssueQuery query) + { + throw new NotImplementedException(); + } - public GitLabCollectionResponse ForGroupsAsync(int groupId) + public Models.Issue Get(int projectId, int issueId) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var project = GetProject(projectId, ProjectPermission.View); + return project.Issues.FirstOrDefault(i => i.Iid == issueId && + i.CanUserViewIssue(Context.User))? + .ToClientIssue() ?? throw new GitLabNotFoundException(); } + } + + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task GetAsync(int projectId, int issueId, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Get(projectId, issueId); + } - public GitLabCollectionResponse ForGroupsAsync(int groupId, IssueQuery query) + public IEnumerable Get(IssueQuery query) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var viewableProjects = Server.AllProjects.Where(p => p.CanUserViewProject(Context.User)); + var issues = viewableProjects.SelectMany(p => p.Issues.Where(i => i.CanUserViewIssue(Context.User))); + return FilterByQuery(issues, query).Select(i => i.ToClientIssue()).ToList(); } + } + + public GitLabCollectionResponse GetAsync(IssueQuery query) + { + return GitLabCollectionResponse.Create(Get(query)); + } - public Models.Issue Get(int projectId, int issueId) + public IEnumerable Get(int projectId, IssueQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.View); - return project.Issues.FirstOrDefault(i => i.Iid == issueId && - i.CanUserViewIssue(Context.User))? - .ToClientIssue() ?? throw new GitLabNotFoundException(); - } + var project = GetProject(projectId, ProjectPermission.View); + var issues = project.Issues.Where(i => i.CanUserViewIssue(Context.User)); + return FilterByQuery(issues, query).Select(i => i.ToClientIssue()).ToList(); } + } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task GetAsync(int projectId, int issueId, CancellationToken cancellationToken = default) + public GitLabCollectionResponse GetAsync(int projectId, IssueQuery query) + { + return GitLabCollectionResponse.Create(Get(projectId, query)); + } + + public async Task GetByIdAsync(int issueId, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return GetById(issueId); + } + + public GitLabCollectionResponse LinkedToAsync(int projectId, int issueId) + { + throw new NotImplementedException(); + } + + public bool CreateLinkBetweenIssues(int sourceProjectId, int sourceIssueId, int targetProjectId, int targetIssueId) + { + throw new NotImplementedException(); + } + + public Models.Issue GetById(int issueId) + { + using (Context.BeginOperationScope()) { - await Task.Yield(); - return Get(projectId, issueId); + var viewableProjects = Server.AllProjects.Where(p => p.CanUserViewProject(Context.User)); + return viewableProjects + .SelectMany(p => p.Issues.Where(i => i.CanUserViewIssue(Context.User) && i.Id == issueId)) + .FirstOrDefault()? + .ToClientIssue() ?? throw new GitLabNotFoundException(); } + } - public IEnumerable Get(IssueQuery query) + private IEnumerable FilterByQuery(IEnumerable issues, IssueQuery query) + { + if (query.State != null) { - using (Context.BeginOperationScope()) + var isValidState = Enum.TryParse(query.State.ToString(), out var requestedState); + if (isValidState) { - var viewableProjects = Server.AllProjects.Where(p => p.CanUserViewProject(Context.User)); - var issues = viewableProjects.SelectMany(p => p.Issues.Where(i => i.CanUserViewIssue(Context.User))); - return FilterByQuery(issues, query).Select(i => i.ToClientIssue()).ToList(); + issues = issues.Where(i => i.State == requestedState); } } - public GitLabCollectionResponse GetAsync(IssueQuery query) + if (query.Milestone != null) { - return GitLabCollectionResponse.Create(Get(query)); + issues = issues.Where(i => string.Equals(i.Milestone?.Title, query.Milestone, StringComparison.Ordinal)); } - public IEnumerable Get(int projectId, IssueQuery query) + if (!string.IsNullOrEmpty(query.Labels)) { - using (Context.BeginOperationScope()) + foreach (var label in query.Labels.Split(',')) { - var project = GetProject(projectId, ProjectPermission.View); - var issues = project.Issues.Where(i => i.CanUserViewIssue(Context.User)); - return FilterByQuery(issues, query).Select(i => i.ToClientIssue()).ToList(); + issues = issues.Where(i => i.Labels.Contains(label, StringComparer.Ordinal)); } } - public GitLabCollectionResponse GetAsync(int projectId, IssueQuery query) + if (query.CreatedAfter != null) { - return GitLabCollectionResponse.Create(Get(projectId, query)); + issues = issues.Where(i => i.CreatedAt > query.CreatedAfter); } - public async Task GetByIdAsync(int issueId, CancellationToken cancellationToken = default) + if (query.CreatedBefore != null) { - await Task.Yield(); - return GetById(issueId); + issues = issues.Where(i => i.CreatedAt < query.CreatedBefore); } - public GitLabCollectionResponse LinkedToAsync(int projectId, int issueId) + if (query.UpdatedAfter != null) { - throw new NotImplementedException(); + issues = issues.Where(i => i.UpdatedAt > query.UpdatedAfter); } - public bool CreateLinkBetweenIssues(int sourceProjectId, int sourceIssueId, int targetProjectId, int targetIssueId) + if (query.UpdatedBefore != null) { - throw new NotImplementedException(); + issues = issues.Where(i => i.UpdatedAt < query.UpdatedBefore); } - public Models.Issue GetById(int issueId) + if (query.Scope != null) { - using (Context.BeginOperationScope()) + var userId = Context.User.Id; + switch (query.Scope) { - var viewableProjects = Server.AllProjects.Where(p => p.CanUserViewProject(Context.User)); - return viewableProjects - .SelectMany(p => p.Issues.Where(i => i.CanUserViewIssue(Context.User) && i.Id == issueId)) - .FirstOrDefault()? - .ToClientIssue() ?? throw new GitLabNotFoundException(); + case "created_by_me": + case "created-by-me": + issues = issues.Where(i => i.Author.Id == userId); + break; + case "assigned_to_me": + case "assigned-to-me": + issues = issues.Where(i => i.Assignees?.Any(x => x.Id == userId) == true); + break; + case "all": + break; + default: + throw new NotSupportedException($"Scope '{query.Scope}' is not supported"); } } - private IEnumerable FilterByQuery(IEnumerable issues, IssueQuery query) + if (query.AuthorId != null) { - if (query.State != null) - { - var isValidState = Enum.TryParse(query.State.ToString(), out var requestedState); - if (isValidState) - { - issues = issues.Where(i => i.State == requestedState); - } - } - - if (query.Milestone != null) - { - issues = issues.Where(i => string.Equals(i.Milestone?.Title, query.Milestone, StringComparison.Ordinal)); - } - - if (!string.IsNullOrEmpty(query.Labels)) - { - foreach (var label in query.Labels.Split(',')) - { - issues = issues.Where(i => i.Labels.Contains(label, StringComparer.Ordinal)); - } - } - - if (query.CreatedAfter != null) - { - issues = issues.Where(i => i.CreatedAt > query.CreatedAfter); - } - - if (query.CreatedBefore != null) - { - issues = issues.Where(i => i.CreatedAt < query.CreatedBefore); - } - - if (query.UpdatedAfter != null) - { - issues = issues.Where(i => i.UpdatedAt > query.UpdatedAfter); - } - - if (query.UpdatedBefore != null) - { - issues = issues.Where(i => i.UpdatedAt < query.UpdatedBefore); - } - - if (query.Scope != null) - { - var userId = Context.User.Id; - switch (query.Scope) - { - case "created_by_me": - case "created-by-me": - issues = issues.Where(i => i.Author.Id == userId); - break; - case "assigned_to_me": - case "assigned-to-me": - issues = issues.Where(i => i.Assignees?.Any(x => x.Id == userId) == true); - break; - case "all": - break; - default: - throw new NotSupportedException($"Scope '{query.Scope}' is not supported"); - } - } + issues = issues.Where(i => i.Author.Id == query.AuthorId); + } - if (query.AuthorId != null) - { - issues = issues.Where(i => i.Author.Id == query.AuthorId); - } + if (query.UpdatedBefore != null) + { + issues = issues.Where(i => i.UpdatedAt < query.UpdatedBefore); + } - if (query.UpdatedBefore != null) - { - issues = issues.Where(i => i.UpdatedAt < query.UpdatedBefore); - } + if (query.AssigneeId != null) + { + var isUserId = int.TryParse(query.AssigneeId.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var userId); - if (query.AssigneeId != null) + if (isUserId) { - var isUserId = int.TryParse(query.AssigneeId.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var userId); - - if (isUserId) - { - issues = issues.Where(i => i.Assignee != null && i.Assignee.Id == userId); - } - else if (string.Equals(query.AssigneeId.ToString(), "None", StringComparison.OrdinalIgnoreCase)) - { - issues = issues.Where(i => i.Assignee == null); - } + issues = issues.Where(i => i.Assignee != null && i.Assignee.Id == userId); } - - if (query.Milestone != null) + else if (string.Equals(query.AssigneeId.ToString(), "None", StringComparison.OrdinalIgnoreCase)) { - issues = issues.Where(i => string.Equals(i.Milestone?.Title, query.Milestone, StringComparison.Ordinal)); + issues = issues.Where(i => i.Assignee == null); } + } - if (query.Confidential != null) - { - issues = issues.Where(i => i.Confidential == query.Confidential.Value); - } + if (query.Milestone != null) + { + issues = issues.Where(i => string.Equals(i.Milestone?.Title, query.Milestone, StringComparison.Ordinal)); + } - if (query.Search != null) - { - issues = issues - .Where(i => i.Title.Contains(query.Search, StringComparison.OrdinalIgnoreCase) - || i.Description.Contains(query.Search, StringComparison.OrdinalIgnoreCase)); - } + if (query.Confidential != null) + { + issues = issues.Where(i => i.Confidential == query.Confidential.Value); + } - if (query.PerPage != null) - { - issues = issues.Take(query.PerPage.Value); - } + if (query.Search != null) + { + issues = issues + .Where(i => i.Title.Contains(query.Search, StringComparison.OrdinalIgnoreCase) + || i.Description.Contains(query.Search, StringComparison.OrdinalIgnoreCase)); + } - if (query.OrderBy != null) - { - issues = query.OrderBy switch - { - "created_at" => issues.OrderBy(i => i.CreatedAt), - "updated_at" => issues.OrderBy(i => i.UpdatedAt), - _ => throw new NotSupportedException($"OrderBy '{query.OrderBy}' is not supported"), - }; - } + if (query.PerPage != null) + { + issues = issues.Take(query.PerPage.Value); + } - if (string.Equals(query.Sort, "asc", StringComparison.Ordinal)) + if (query.OrderBy != null) + { + issues = query.OrderBy switch { - issues = issues.Reverse(); - } + "created_at" => issues.OrderBy(i => i.CreatedAt), + "updated_at" => issues.OrderBy(i => i.UpdatedAt), + _ => throw new NotSupportedException($"OrderBy '{query.OrderBy}' is not supported"), + }; + } - return issues; + if (string.Equals(query.Sort, "asc", StringComparison.Ordinal)) + { + issues = issues.Reverse(); } + + return issues; } } diff --git a/NGitLab.Mock/Clients/JobClient.cs b/NGitLab.Mock/Clients/JobClient.cs index 41682f1f..89f082c6 100644 --- a/NGitLab.Mock/Clients/JobClient.cs +++ b/NGitLab.Mock/Clients/JobClient.cs @@ -7,143 +7,142 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class JobClient : ClientBase, IJobClient { - internal sealed class JobClient : ClientBase, IJobClient - { - private readonly int _projectId; + private readonly int _projectId; - public JobClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public JobClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public Models.Job Get(int jobId) + public Models.Job Get(int jobId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var job = project.Jobs.GetById(jobId); + var project = GetProject(_projectId, ProjectPermission.View); + var job = project.Jobs.GetById(jobId); - if (job == null) - throw new GitLabNotFoundException(); + if (job == null) + throw new GitLabNotFoundException(); - return job.ToJobClient(); - } + return job.ToJobClient(); } + } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task GetAsync(int jobId, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Get(jobId); - } + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task GetAsync(int jobId, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Get(jobId); + } - public byte[] GetJobArtifacts(int jobId) - { - throw new NotImplementedException(); - } + public byte[] GetJobArtifacts(int jobId) + { + throw new NotImplementedException(); + } - public byte[] GetJobArtifact(int jobId, string path) - { - throw new NotImplementedException(); - } + public byte[] GetJobArtifact(int jobId, string path) + { + throw new NotImplementedException(); + } - public byte[] GetJobArtifact(JobArtifactQuery query) - { - throw new NotImplementedException(); - } + public byte[] GetJobArtifact(JobArtifactQuery query) + { + throw new NotImplementedException(); + } - public IEnumerable GetJobs(JobScopeMask scope) - { - return GetJobs(new JobQuery { Scope = scope }); - } + public IEnumerable GetJobs(JobScopeMask scope) + { + return GetJobs(new JobQuery { Scope = scope }); + } - public IEnumerable GetJobs(JobQuery query) + public IEnumerable GetJobs(JobQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); + var project = GetProject(_projectId, ProjectPermission.View); - if (query.Scope == JobScopeMask.All) - return project.Jobs.Select(j => j.ToJobClient()); + if (query.Scope == JobScopeMask.All) + return project.Jobs.Select(j => j.ToJobClient()); - var scopes = new List(); - foreach (Enum value in Enum.GetValues(query.Scope.GetType())) + var scopes = new List(); + foreach (Enum value in Enum.GetValues(query.Scope.GetType())) + { + if (query.Scope.HasFlag(value)) { - if (query.Scope.HasFlag(value)) - { - scopes.Add(value.ToString()); - } + scopes.Add(value.ToString()); } - - var jobs = project.Jobs.Where(j => scopes.Any(scope => string.Equals(j.Status.ToString(), scope, StringComparison.OrdinalIgnoreCase))); - return jobs.Select(j => j.ToJobClient()).ToList(); } - } - public GitLabCollectionResponse GetJobsAsync(JobQuery query) - { - return GitLabCollectionResponse.Create(GetJobs(query)); + var jobs = project.Jobs.Where(j => scopes.Any(scope => string.Equals(j.Status.ToString(), scope, StringComparison.OrdinalIgnoreCase))); + return jobs.Select(j => j.ToJobClient()).ToList(); } + } - public string GetTrace(int jobId) + public GitLabCollectionResponse GetJobsAsync(JobQuery query) + { + return GitLabCollectionResponse.Create(GetJobs(query)); + } + + public string GetTrace(int jobId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var job = project.Jobs.GetById(jobId); + var project = GetProject(_projectId, ProjectPermission.View); + var job = project.Jobs.GetById(jobId); - if (job == null) - throw new GitLabNotFoundException(); + if (job == null) + throw new GitLabNotFoundException(); - return job.Trace; - } + return job.Trace; } + } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task GetTraceAsync(int jobId, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return GetTrace(jobId); - } + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task GetTraceAsync(int jobId, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return GetTrace(jobId); + } - public Models.Job RunAction(int jobId, JobAction action) + public Models.Job RunAction(int jobId, JobAction action) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var job = project.Jobs.GetById(jobId); - - switch (action) - { - case JobAction.Cancel: - job.Status = JobStatus.Canceled; - break; - case JobAction.Erase: - job.Artifacts = null; - job.Trace = null; - break; - case JobAction.Play: - job.Status = JobStatus.Running; - break; - case JobAction.Retry: - var retryJob = job.Clone(); - retryJob.Status = JobStatus.Running; - project.Jobs.Add(retryJob, project.Pipelines.GetById(job.Pipeline.Id)); - return retryJob.ToJobClient(); - } + var project = GetProject(_projectId, ProjectPermission.View); + var job = project.Jobs.GetById(jobId); - return job.ToJobClient(); + switch (action) + { + case JobAction.Cancel: + job.Status = JobStatus.Canceled; + break; + case JobAction.Erase: + job.Artifacts = null; + job.Trace = null; + break; + case JobAction.Play: + job.Status = JobStatus.Running; + break; + case JobAction.Retry: + var retryJob = job.Clone(); + retryJob.Status = JobStatus.Running; + project.Jobs.Add(retryJob, project.Pipelines.GetById(job.Pipeline.Id)); + return retryJob.ToJobClient(); } - } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task RunActionAsync(int jobId, JobAction action, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return RunAction(jobId, action); + return job.ToJobClient(); } } + + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task RunActionAsync(int jobId, JobAction action, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return RunAction(jobId, action); + } } diff --git a/NGitLab.Mock/Clients/LabelClient.cs b/NGitLab.Mock/Clients/LabelClient.cs index 6a266248..6f172ee6 100644 --- a/NGitLab.Mock/Clients/LabelClient.cs +++ b/NGitLab.Mock/Clients/LabelClient.cs @@ -4,197 +4,196 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class LabelClient : ClientBase, ILabelClient { - internal sealed class LabelClient : ClientBase, ILabelClient + public LabelClient(ClientContext context) + : base(context) { - public LabelClient(ClientContext context) - : base(context) - { - } + } - public Models.Label CreateProjectLabel(int projectId, ProjectLabelCreate label) + public Models.Label CreateProjectLabel(int projectId, ProjectLabelCreate label) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.Edit); - return project.Labels.Add(label.Name, label.Color, label.Description).ToClientLabel(); - } + var project = GetProject(projectId, ProjectPermission.Edit); + return project.Labels.Add(label.Name, label.Color, label.Description).ToClientLabel(); } + } - [EditorBrowsable(EditorBrowsableState.Never)] - public Models.Label Create(LabelCreate label) + [EditorBrowsable(EditorBrowsableState.Never)] + public Models.Label Create(LabelCreate label) + { + return CreateProjectLabel(label.Id, new ProjectLabelCreate { - return CreateProjectLabel(label.Id, new ProjectLabelCreate - { - Name = label.Name, - Color = label.Color, - Description = label.Description, - }); - } + Name = label.Name, + Color = label.Color, + Description = label.Description, + }); + } - public Models.Label CreateGroupLabel(int groupId, GroupLabelCreate label) + public Models.Label CreateGroupLabel(int groupId, GroupLabelCreate label) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = GetGroup(groupId, GroupPermission.Edit); - return group.Labels.Add(label.Name, label.Color, label.Description).ToClientLabel(); - } + var group = GetGroup(groupId, GroupPermission.Edit); + return group.Labels.Add(label.Name, label.Color, label.Description).ToClientLabel(); } + } - [EditorBrowsable(EditorBrowsableState.Never)] - public Models.Label CreateGroupLabel(LabelCreate label) + [EditorBrowsable(EditorBrowsableState.Never)] + public Models.Label CreateGroupLabel(LabelCreate label) + { + return CreateGroupLabel(label.Id, new GroupLabelCreate { - return CreateGroupLabel(label.Id, new GroupLabelCreate - { - Name = label.Name, - Color = label.Color, - Description = label.Description, - }); - } + Name = label.Name, + Color = label.Color, + Description = label.Description, + }); + } - public Models.Label DeleteProjectLabel(int projectId, ProjectLabelDelete label) + public Models.Label DeleteProjectLabel(int projectId, ProjectLabelDelete label) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.Edit); - var l = FindLabel(project.Labels, label.Name) ?? throw new GitLabNotFoundException($"Cannot find label '{label.Name}'"); - project.Labels.Remove(l); - return l.ToClientLabel(); - } + var project = GetProject(projectId, ProjectPermission.Edit); + var l = FindLabel(project.Labels, label.Name) ?? throw new GitLabNotFoundException($"Cannot find label '{label.Name}'"); + project.Labels.Remove(l); + return l.ToClientLabel(); } + } - [EditorBrowsable(EditorBrowsableState.Never)] - public Models.Label Delete(LabelDelete label) + [EditorBrowsable(EditorBrowsableState.Never)] + public Models.Label Delete(LabelDelete label) + { + return DeleteProjectLabel(label.Id, new ProjectLabelDelete { - return DeleteProjectLabel(label.Id, new ProjectLabelDelete - { - Id = label.Id, - Name = label.Name, - }); - } + Id = label.Id, + Name = label.Name, + }); + } - public Models.Label EditProjectLabel(int projectId, ProjectLabelEdit label) + public Models.Label EditProjectLabel(int projectId, ProjectLabelEdit label) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.Edit); - var l = FindLabel(project.Labels, label.Name) ?? throw new GitLabNotFoundException($"Cannot find label '{label.Name}'"); + var project = GetProject(projectId, ProjectPermission.Edit); + var l = FindLabel(project.Labels, label.Name) ?? throw new GitLabNotFoundException($"Cannot find label '{label.Name}'"); - if (!string.IsNullOrEmpty(label.NewName)) - { - l.Name = label.NewName; - } - - if (!string.IsNullOrEmpty(label.Color)) - { - l.Color = label.Color; - } - - if (label.Description != null) - { - l.Description = label.Description; - } - - return l.ToClientLabel(); + if (!string.IsNullOrEmpty(label.NewName)) + { + l.Name = label.NewName; } - } - [EditorBrowsable(EditorBrowsableState.Never)] - public Models.Label Edit(LabelEdit label) - { - return EditProjectLabel(label.Id, new ProjectLabelEdit + if (!string.IsNullOrEmpty(label.Color)) { - Name = label.Name, - NewName = label.NewName, - Color = label.Color, - Description = label.Description, - }); - } + l.Color = label.Color; + } - public Models.Label EditGroupLabel(int groupId, GroupLabelEdit label) - { - using (Context.BeginOperationScope()) + if (label.Description != null) { - var group = GetGroup(groupId, GroupPermission.Edit); - var l = FindLabel(group.Labels, label.Name) ?? throw new GitLabNotFoundException($"Cannot find label '{label.Name}'"); + l.Description = label.Description; + } - if (!string.IsNullOrEmpty(label.NewName)) - { - l.Name = label.NewName; - } + return l.ToClientLabel(); + } + } - if (!string.IsNullOrEmpty(label.Color)) - { - l.Color = label.Color; - } + [EditorBrowsable(EditorBrowsableState.Never)] + public Models.Label Edit(LabelEdit label) + { + return EditProjectLabel(label.Id, new ProjectLabelEdit + { + Name = label.Name, + NewName = label.NewName, + Color = label.Color, + Description = label.Description, + }); + } - if (label.Description != null) - { - l.Description = label.Description; - } + public Models.Label EditGroupLabel(int groupId, GroupLabelEdit label) + { + using (Context.BeginOperationScope()) + { + var group = GetGroup(groupId, GroupPermission.Edit); + var l = FindLabel(group.Labels, label.Name) ?? throw new GitLabNotFoundException($"Cannot find label '{label.Name}'"); - return l.ToClientLabel(); + if (!string.IsNullOrEmpty(label.NewName)) + { + l.Name = label.NewName; } - } - [EditorBrowsable(EditorBrowsableState.Never)] - public Models.Label EditGroupLabel(LabelEdit label) - { - return EditGroupLabel(label.Id, new GroupLabelEdit + if (!string.IsNullOrEmpty(label.Color)) { - Name = label.Name, - NewName = label.NewName, - Color = label.Color, - Description = label.Description, - }); - } + l.Color = label.Color; + } - public IEnumerable ForGroup(int groupId) - { - using (Context.BeginOperationScope()) + if (label.Description != null) { - var group = GetGroup(groupId, GroupPermission.View); - return group.Labels.Select(x => x.ToClientLabel()); + l.Description = label.Description; } + + return l.ToClientLabel(); } + } - public IEnumerable ForProject(int projectId) + [EditorBrowsable(EditorBrowsableState.Never)] + public Models.Label EditGroupLabel(LabelEdit label) + { + return EditGroupLabel(label.Id, new GroupLabelEdit { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.View); - return project.Labels.Select(x => x.ToClientLabel()); - } - } + Name = label.Name, + NewName = label.NewName, + Color = label.Color, + Description = label.Description, + }); + } - public Models.Label GetGroupLabel(int groupId, string name) + public IEnumerable ForGroup(int groupId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = GetGroup(groupId, GroupPermission.View); - return FindLabel(group.Labels, name)?.ToClientLabel(); - } + var group = GetGroup(groupId, GroupPermission.View); + return group.Labels.Select(x => x.ToClientLabel()); } + } - public Models.Label GetProjectLabel(int projectId, string name) + public IEnumerable ForProject(int projectId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.View); - return FindLabel(project.Labels, name)?.ToClientLabel(); - } + var project = GetProject(projectId, ProjectPermission.View); + return project.Labels.Select(x => x.ToClientLabel()); } + } - [EditorBrowsable(EditorBrowsableState.Never)] - public Models.Label GetLabel(int projectId, string name) + public Models.Label GetGroupLabel(int groupId, string name) + { + using (Context.BeginOperationScope()) { - return GetProjectLabel(projectId, name); + var group = GetGroup(groupId, GroupPermission.View); + return FindLabel(group.Labels, name)?.ToClientLabel(); } + } - private static Label FindLabel(LabelsCollection collection, string name) + public Models.Label GetProjectLabel(int projectId, string name) + { + using (Context.BeginOperationScope()) { - return collection.FirstOrDefault(x => x.Name.Equals(name, StringComparison.Ordinal)); + var project = GetProject(projectId, ProjectPermission.View); + return FindLabel(project.Labels, name)?.ToClientLabel(); } } + + [EditorBrowsable(EditorBrowsableState.Never)] + public Models.Label GetLabel(int projectId, string name) + { + return GetProjectLabel(projectId, name); + } + + private static Label FindLabel(LabelsCollection collection, string name) + { + return collection.FirstOrDefault(x => x.Name.Equals(name, StringComparison.Ordinal)); + } } diff --git a/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs b/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs index 82c6ce1d..3b494f6d 100644 --- a/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs +++ b/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs @@ -3,86 +3,85 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +public static class LibGit2SharpExtensions { - public static class LibGit2SharpExtensions + public static Commit ToCommitClient(this LibGit2Sharp.Commit commit, Project project) { - public static Commit ToCommitClient(this LibGit2Sharp.Commit commit, Project project) + var commitSha = new Sha1(commit.Sha); + var commitInfo = project.CommitInfos.SingleOrDefault(c => commitSha.Equals(new Sha1(c.Sha))); + return new Commit { - var commitSha = new Sha1(commit.Sha); - var commitInfo = project.CommitInfos.SingleOrDefault(c => commitSha.Equals(new Sha1(c.Sha))); - return new Commit - { - AuthoredDate = commit.Author.When.UtcDateTime, - AuthorEmail = commit.Author.Email, - AuthorName = commit.Author.Name, - CommittedDate = commit.Committer.When.UtcDateTime, - CommitterEmail = commit.Committer.Email, - CommitterName = commit.Committer.Name, - CreatedAt = commit.Committer.When.UtcDateTime, - Id = new Sha1(commit.Sha), - Message = commit.Message, - ShortId = commit.Sha.Substring(0, 8), - Title = commit.MessageShort, - Parents = commit.Parents.Select(p => new Sha1(p.Sha)).ToArray(), - Status = commitInfo?.Status ?? "success", - WebUrl = $"{project.WebUrl}/-/commits/{commit.Sha}", - }; - } + AuthoredDate = commit.Author.When.UtcDateTime, + AuthorEmail = commit.Author.Email, + AuthorName = commit.Author.Name, + CommittedDate = commit.Committer.When.UtcDateTime, + CommitterEmail = commit.Committer.Email, + CommitterName = commit.Committer.Name, + CreatedAt = commit.Committer.When.UtcDateTime, + Id = new Sha1(commit.Sha), + Message = commit.Message, + ShortId = commit.Sha.Substring(0, 8), + Title = commit.MessageShort, + Parents = commit.Parents.Select(p => new Sha1(p.Sha)).ToArray(), + Status = commitInfo?.Status ?? "success", + WebUrl = $"{project.WebUrl}/-/commits/{commit.Sha}", + }; + } - public static Branch ToBranchClient(this LibGit2Sharp.Branch branch, Project project) + public static Branch ToBranchClient(this LibGit2Sharp.Branch branch, Project project) + { + var commit = branch.Tip; + return new Branch { - var commit = branch.Tip; - return new Branch - { - CanPush = true, - Protected = false, - DevelopersCanMerge = true, - DevelopersCanPush = true, - Merged = false, - Name = branch.FriendlyName, - Default = string.Equals(branch.FriendlyName, project.DefaultBranch, StringComparison.Ordinal), - Commit = ToCommitInfo(commit), - }; - } + CanPush = true, + Protected = false, + DevelopersCanMerge = true, + DevelopersCanPush = true, + Merged = false, + Name = branch.FriendlyName, + Default = string.Equals(branch.FriendlyName, project.DefaultBranch, StringComparison.Ordinal), + Commit = ToCommitInfo(commit), + }; + } + + public static Models.CommitInfo ToCommitInfo(this LibGit2Sharp.Commit commit) + { + return new Models.CommitInfo + { + Id = new Sha1(commit.Sha), + AuthorName = commit.Author.Name, + AuthorEmail = commit.Author.Email, + AuthoredDate = commit.Author.When.UtcDateTime, + CommitterName = commit.Committer.Name, + CommitterEmail = commit.Committer.Email, + CommittedDate = commit.Committer.When.UtcDateTime, + Message = commit.Message, + Parents = commit.Parents.Select(c => new Sha1(c.Sha)).ToArray(), + }; + } - public static Models.CommitInfo ToCommitInfo(this LibGit2Sharp.Commit commit) + internal static LibGit2Sharp.Commit GetLastCommitForFileChanges(this LibGit2Sharp.Repository repository, string filePath) + { + try { - return new Models.CommitInfo - { - Id = new Sha1(commit.Sha), - AuthorName = commit.Author.Name, - AuthorEmail = commit.Author.Email, - AuthoredDate = commit.Author.When.UtcDateTime, - CommitterName = commit.Committer.Name, - CommitterEmail = commit.Committer.Email, - CommittedDate = commit.Committer.When.UtcDateTime, - Message = commit.Message, - Parents = commit.Parents.Select(c => new Sha1(c.Sha)).ToArray(), - }; + return repository.Commits.QueryBy(filePath).FirstOrDefault()?.Commit; } - - internal static LibGit2Sharp.Commit GetLastCommitForFileChanges(this LibGit2Sharp.Repository repository, string filePath) + catch (KeyNotFoundException) { - try - { - return repository.Commits.QueryBy(filePath).FirstOrDefault()?.Commit; - } - catch (KeyNotFoundException) - { - // LibGit2Sharp sometimes fails with the following exception - // System.Collections.Generic.KeyNotFoundException: The given key '1d08df45e551942eaa70d9f5ab6f5f7665a3f5b3' was not present in the dictionary. - // at System.Collections.Generic.Dictionary`2.get_Item(TKey key) - // at LibGit2Sharp.Core.FileHistory.FullHistory(IRepository repo, String path, CommitFilter filter)+MoveNext() in /_/LibGit2Sharp/Core/FileHistory.cs:line 120 - // at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found) - // at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) - // at NGitLab.Mock.Clients.LibGit2SharpExtensions.GetLastCommitForFileChanges(Repository repository, String filePath) in /_/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs:line 65 - // at NGitLab.Mock.Repository.GetFile(String filePath, String ref) in /_/NGitLab.Mock/Repository.cs:line 485 - // at NGitLab.Mock.Clients.FileClient.Get(String filePath, String ref) in /_/NGitLab.Mock/Clients/FileClient.cs:line 77 - // at NGitLab.Mock.Clients.FileClient.GetAsync(String filePath, String ref, CancellationToken cancellationToken) in /_/NGitLab.Mock/Clients/FileClient.cs:line 125 - } - - return null; + // LibGit2Sharp sometimes fails with the following exception + // System.Collections.Generic.KeyNotFoundException: The given key '1d08df45e551942eaa70d9f5ab6f5f7665a3f5b3' was not present in the dictionary. + // at System.Collections.Generic.Dictionary`2.get_Item(TKey key) + // at LibGit2Sharp.Core.FileHistory.FullHistory(IRepository repo, String path, CommitFilter filter)+MoveNext() in /_/LibGit2Sharp/Core/FileHistory.cs:line 120 + // at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found) + // at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) + // at NGitLab.Mock.Clients.LibGit2SharpExtensions.GetLastCommitForFileChanges(Repository repository, String filePath) in /_/NGitLab.Mock/Clients/LibGit2SharpExtensions.cs:line 65 + // at NGitLab.Mock.Repository.GetFile(String filePath, String ref) in /_/NGitLab.Mock/Repository.cs:line 485 + // at NGitLab.Mock.Clients.FileClient.Get(String filePath, String ref) in /_/NGitLab.Mock/Clients/FileClient.cs:line 77 + // at NGitLab.Mock.Clients.FileClient.GetAsync(String filePath, String ref, CancellationToken cancellationToken) in /_/NGitLab.Mock/Clients/FileClient.cs:line 125 } + + return null; } } diff --git a/NGitLab.Mock/Clients/LintClient.cs b/NGitLab.Mock/Clients/LintClient.cs index cefee115..a9ca8c43 100644 --- a/NGitLab.Mock/Clients/LintClient.cs +++ b/NGitLab.Mock/Clients/LintClient.cs @@ -4,40 +4,39 @@ using System.Threading.Tasks; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal class LintClient : ClientBase, ILintClient { - internal class LintClient : ClientBase, ILintClient + public LintClient(ClientContext context) + : base(context) { - public LintClient(ClientContext context) - : base(context) - { - } + } - public Task ValidateCIYamlContentAsync(string projectId, string yamlContent, LintCIOptions options, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); - } + public Task ValidateCIYamlContentAsync(string projectId, string yamlContent, LintCIOptions options, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public async Task ValidateProjectCIConfigurationAsync(string projectId, LintCIOptions options, CancellationToken cancellationToken = default) + { + await Task.Yield(); - public async Task ValidateProjectCIConfigurationAsync(string projectId, LintCIOptions options, CancellationToken cancellationToken = default) + using (Context.BeginOperationScope()) { - await Task.Yield(); + var project = GetProject(projectId, ProjectPermission.View); + var @ref = string.IsNullOrEmpty(options.Ref) ? project.DefaultBranch : options.Ref; - using (Context.BeginOperationScope()) + var lintCi = project.LintCIs.FirstOrDefault(ci => { - var project = GetProject(projectId, ProjectPermission.View); - var @ref = string.IsNullOrEmpty(options.Ref) ? project.DefaultBranch : options.Ref; - - var lintCi = project.LintCIs.FirstOrDefault(ci => - { - return string.Equals(ci.Ref, @ref, StringComparison.Ordinal); - }) ?? new LintCI(@ref, valid: false, "Reference not found"); + return string.Equals(ci.Ref, @ref, StringComparison.Ordinal); + }) ?? new LintCI(@ref, valid: false, "Reference not found"); - return new Models.LintCI - { - Valid = lintCi.Valid, - Errors = lintCi.Errors, - }; - } + return new Models.LintCI + { + Valid = lintCi.Valid, + Errors = lintCi.Errors, + }; } } } diff --git a/NGitLab.Mock/Clients/MembersClient.cs b/NGitLab.Mock/Clients/MembersClient.cs index 7b33a3e2..8e13059d 100644 --- a/NGitLab.Mock/Clients/MembersClient.cs +++ b/NGitLab.Mock/Clients/MembersClient.cs @@ -5,161 +5,160 @@ using System.Net; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class MembersClient : ClientBase, IMembersClient { - internal sealed class MembersClient : ClientBase, IMembersClient + public MembersClient(ClientContext context) + : base(context) { - public MembersClient(ClientContext context) - : base(context) - { - } + } - public Membership AddMemberToProject(string projectId, ProjectMemberCreate projectMemberCreate) + public Membership AddMemberToProject(string projectId, ProjectMemberCreate projectMemberCreate) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.Edit); - var user = Server.Users.GetById(projectMemberCreate.UserId); + var project = GetProject(projectId, ProjectPermission.Edit); + var user = Server.Users.GetById(projectMemberCreate.UserId); - CheckUserPermissionOfProject(projectMemberCreate.AccessLevel, user, project); + CheckUserPermissionOfProject(projectMemberCreate.AccessLevel, user, project); - var permission = new Permission(user, projectMemberCreate.AccessLevel); - project.Permissions.Add(permission); + var permission = new Permission(user, projectMemberCreate.AccessLevel); + project.Permissions.Add(permission); - return project.GetEffectivePermissions().GetEffectivePermission(user).ToMembershipClient(); - } + return project.GetEffectivePermissions().GetEffectivePermission(user).ToMembershipClient(); } + } - public Membership UpdateMemberOfProject(string projectId, ProjectMemberUpdate projectMemberUpdate) + public Membership UpdateMemberOfProject(string projectId, ProjectMemberUpdate projectMemberUpdate) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.Edit); - var user = Server.Users.GetById(projectMemberUpdate.UserId); + var project = GetProject(projectId, ProjectPermission.Edit); + var user = Server.Users.GetById(projectMemberUpdate.UserId); - CheckUserPermissionOfProject(projectMemberUpdate.AccessLevel, user, project); - return project.GetEffectivePermissions().GetEffectivePermission(user).ToMembershipClient(); - } + CheckUserPermissionOfProject(projectMemberUpdate.AccessLevel, user, project); + return project.GetEffectivePermissions().GetEffectivePermission(user).ToMembershipClient(); } + } - public Membership AddMemberToGroup(string groupId, GroupMemberCreate groupMemberCreate) + public Membership AddMemberToGroup(string groupId, GroupMemberCreate groupMemberCreate) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = GetGroup(groupId, GroupPermission.Edit); - var user = Server.Users.GetById(groupMemberCreate.UserId); + var group = GetGroup(groupId, GroupPermission.Edit); + var user = Server.Users.GetById(groupMemberCreate.UserId); - CheckUserPermissionOfGroup(groupMemberCreate.AccessLevel, user, group); + CheckUserPermissionOfGroup(groupMemberCreate.AccessLevel, user, group); - var permission = new Permission(user, groupMemberCreate.AccessLevel); - group.Permissions.Add(permission); + var permission = new Permission(user, groupMemberCreate.AccessLevel); + group.Permissions.Add(permission); - return group.GetEffectivePermissions().GetEffectivePermission(user).ToMembershipClient(); - } + return group.GetEffectivePermissions().GetEffectivePermission(user).ToMembershipClient(); } + } - public Membership UpdateMemberOfGroup(string groupId, GroupMemberUpdate groupMemberUpdate) + public Membership UpdateMemberOfGroup(string groupId, GroupMemberUpdate groupMemberUpdate) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = GetGroup(groupId, GroupPermission.Edit); - var user = Server.Users.GetById(groupMemberUpdate.UserId); + var group = GetGroup(groupId, GroupPermission.Edit); + var user = Server.Users.GetById(groupMemberUpdate.UserId); - CheckUserPermissionOfGroup(groupMemberUpdate.AccessLevel, user, group); - return group.GetEffectivePermissions().GetEffectivePermission(user).ToMembershipClient(); - } + CheckUserPermissionOfGroup(groupMemberUpdate.AccessLevel, user, group); + return group.GetEffectivePermissions().GetEffectivePermission(user).ToMembershipClient(); } + } - public Membership GetMemberOfGroup(string groupId, string userId) - { - return OfGroup(groupId, includeInheritedMembers: false) - .FirstOrDefault(u => string.Equals(u.Id.ToString(CultureInfo.InvariantCulture), userId, StringComparison.Ordinal)); - } + public Membership GetMemberOfGroup(string groupId, string userId) + { + return OfGroup(groupId, includeInheritedMembers: false) + .FirstOrDefault(u => string.Equals(u.Id.ToString(CultureInfo.InvariantCulture), userId, StringComparison.Ordinal)); + } - public Membership GetMemberOfProject(string projectId, string userId) - { - return OfProject(projectId, includeInheritedMembers: false) - .FirstOrDefault(u => string.Equals(u.Id.ToString(CultureInfo.InvariantCulture), userId, StringComparison.Ordinal)); - } + public Membership GetMemberOfProject(string projectId, string userId) + { + return OfProject(projectId, includeInheritedMembers: false) + .FirstOrDefault(u => string.Equals(u.Id.ToString(CultureInfo.InvariantCulture), userId, StringComparison.Ordinal)); + } - public Membership GetMemberOfProject(string projectId, string userId, bool includeInheritedMembers) - { - return OfProject(projectId, includeInheritedMembers) - .FirstOrDefault(u => string.Equals(u.Id.ToString(CultureInfo.InvariantCulture), userId, StringComparison.Ordinal)); - } + public Membership GetMemberOfProject(string projectId, string userId, bool includeInheritedMembers) + { + return OfProject(projectId, includeInheritedMembers) + .FirstOrDefault(u => string.Equals(u.Id.ToString(CultureInfo.InvariantCulture), userId, StringComparison.Ordinal)); + } - public IEnumerable OfGroup(string groupId) - { - return OfGroup(groupId, includeInheritedMembers: false); - } + public IEnumerable OfGroup(string groupId) + { + return OfGroup(groupId, includeInheritedMembers: false); + } - public IEnumerable OfGroup(string groupId, bool includeInheritedMembers) + public IEnumerable OfGroup(string groupId, bool includeInheritedMembers) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var group = GetGroup(groupId, GroupPermission.View); - var members = group.GetEffectivePermissions(includeInheritedMembers).Permissions; - return members.Select(member => member.ToMembershipClient()); - } + var group = GetGroup(groupId, GroupPermission.View); + var members = group.GetEffectivePermissions(includeInheritedMembers).Permissions; + return members.Select(member => member.ToMembershipClient()); } + } - public IEnumerable OfNamespace(string groupId) - { - return OfGroup(groupId); - } + public IEnumerable OfNamespace(string groupId) + { + return OfGroup(groupId); + } - public IEnumerable OfProject(string projectId) - { - return OfProject(projectId, includeInheritedMembers: false); - } + public IEnumerable OfProject(string projectId) + { + return OfProject(projectId, includeInheritedMembers: false); + } - public IEnumerable OfProject(string projectId, bool includeInheritedMembers) + public IEnumerable OfProject(string projectId, bool includeInheritedMembers) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.View); - var members = project.GetEffectivePermissions(includeInheritedMembers).Permissions; - return members.Select(member => member.ToMembershipClient()); - } + var project = GetProject(projectId, ProjectPermission.View); + var members = project.GetEffectivePermissions(includeInheritedMembers).Permissions; + return members.Select(member => member.ToMembershipClient()); } + } - private static void CheckUserPermissionOfProject(AccessLevel accessLevel, User user, Project project) + private static void CheckUserPermissionOfProject(AccessLevel accessLevel, User user, Project project) + { + var existingPermission = project.GetEffectivePermissions().GetEffectivePermission(user); + if (existingPermission != null) { - var existingPermission = project.GetEffectivePermissions().GetEffectivePermission(user); - if (existingPermission != null) + if (existingPermission.AccessLevel > accessLevel) { - if (existingPermission.AccessLevel > accessLevel) + throw new GitLabException("{\"access_level\":[\"should be greater than or equal to Owner inherited membership from group Runners\"]}.") { - throw new GitLabException("{\"access_level\":[\"should be greater than or equal to Owner inherited membership from group Runners\"]}.") - { - StatusCode = HttpStatusCode.BadRequest, - }; - } + StatusCode = HttpStatusCode.BadRequest, + }; + } - if (existingPermission.AccessLevel == accessLevel) - { - throw new GitLabException { StatusCode = HttpStatusCode.Conflict }; - } + if (existingPermission.AccessLevel == accessLevel) + { + throw new GitLabException { StatusCode = HttpStatusCode.Conflict }; } } + } - private static void CheckUserPermissionOfGroup(AccessLevel accessLevel, User user, Group group) + private static void CheckUserPermissionOfGroup(AccessLevel accessLevel, User user, Group group) + { + var existingPermission = group.GetEffectivePermissions().GetEffectivePermission(user); + if (existingPermission != null) { - var existingPermission = group.GetEffectivePermissions().GetEffectivePermission(user); - if (existingPermission != null) + if (existingPermission.AccessLevel > accessLevel) { - if (existingPermission.AccessLevel > accessLevel) + throw new GitLabException("{\"access_level\":[\"should be greater than or equal to Owner inherited membership from group Runners\"]}.") { - throw new GitLabException("{\"access_level\":[\"should be greater than or equal to Owner inherited membership from group Runners\"]}.") - { - StatusCode = HttpStatusCode.BadRequest, - }; - } + StatusCode = HttpStatusCode.BadRequest, + }; + } - if (existingPermission.AccessLevel == accessLevel) - { - throw new GitLabException { StatusCode = HttpStatusCode.Conflict }; - } + if (existingPermission.AccessLevel == accessLevel) + { + throw new GitLabException { StatusCode = HttpStatusCode.Conflict }; } } } diff --git a/NGitLab.Mock/Clients/MergeRequestApprovalClient.cs b/NGitLab.Mock/Clients/MergeRequestApprovalClient.cs index 7092a281..799add0d 100644 --- a/NGitLab.Mock/Clients/MergeRequestApprovalClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestApprovalClient.cs @@ -1,30 +1,29 @@ using System; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class MergeRequestApprovalClient : ClientBase, IMergeRequestApprovalClient { - internal sealed class MergeRequestApprovalClient : ClientBase, IMergeRequestApprovalClient - { - private readonly int _projectId; - private readonly int _mergeRequestIid; + private readonly int _projectId; + private readonly int _mergeRequestIid; - public MergeRequestApprovalClient(ClientContext context, int projectId, int mergeRequestIid) - : base(context) - { - _projectId = projectId; - _mergeRequestIid = mergeRequestIid; - } + public MergeRequestApprovalClient(ClientContext context, int projectId, int mergeRequestIid) + : base(context) + { + _projectId = projectId; + _mergeRequestIid = mergeRequestIid; + } - public MergeRequestApprovals Approvals => new(); + public MergeRequestApprovals Approvals => new(); - public MergeRequestApprovals ApproveMergeRequest(MergeRequestApproveRequest request = null) - { - throw new NotImplementedException(); - } + public MergeRequestApprovals ApproveMergeRequest(MergeRequestApproveRequest request = null) + { + throw new NotImplementedException(); + } - public void ChangeApprovers(MergeRequestApproversChange approversChange) - { - throw new NotImplementedException(); - } + public void ChangeApprovers(MergeRequestApproversChange approversChange) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/MergeRequestChangeClient.cs b/NGitLab.Mock/Clients/MergeRequestChangeClient.cs index bf169d76..0d5e2748 100644 --- a/NGitLab.Mock/Clients/MergeRequestChangeClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestChangeClient.cs @@ -1,32 +1,31 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class MergeRequestChangeClient : ClientBase, IMergeRequestChangeClient { - internal sealed class MergeRequestChangeClient : ClientBase, IMergeRequestChangeClient - { - private readonly int _projectId; - private readonly int _mergeRequestIid; + private readonly int _projectId; + private readonly int _mergeRequestIid; - public MergeRequestChangeClient(ClientContext context, int projectId, int mergeRequestIid) - : base(context) - { - _projectId = projectId; - _mergeRequestIid = mergeRequestIid; - } + public MergeRequestChangeClient(ClientContext context, int projectId, int mergeRequestIid) + : base(context) + { + _projectId = projectId; + _mergeRequestIid = mergeRequestIid; + } - public MergeRequestChange MergeRequestChange + public MergeRequestChange MergeRequestChange + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + return new MergeRequestChange { - return new MergeRequestChange - { - Changes = GetMergeRequest(_projectId, _mergeRequestIid).Changes.Select(a => a.ToChange()) - .ToArray(), - }; - } + Changes = GetMergeRequest(_projectId, _mergeRequestIid).Changes.Select(a => a.ToChange()) + .ToArray(), + }; } } } diff --git a/NGitLab.Mock/Clients/MergeRequestClient.cs b/NGitLab.Mock/Clients/MergeRequestClient.cs index 48072735..38ea22dc 100644 --- a/NGitLab.Mock/Clients/MergeRequestClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestClient.cs @@ -8,749 +8,748 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class MergeRequestClient : ClientBase, IMergeRequestClient { - internal sealed class MergeRequestClient : ClientBase, IMergeRequestClient + private readonly int? _projectId; + + public MergeRequestClient(ClientContext context) + : base(context) { - private readonly int? _projectId; + } - public MergeRequestClient(ClientContext context) - : base(context) - { - } + public MergeRequestClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public MergeRequestClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + private void AssertProjectId() + { + if (_projectId == null) + throw new InvalidOperationException("Valid only for a specific project"); + } - private void AssertProjectId() + public Models.MergeRequest this[int iid] + { + get { - if (_projectId == null) - throw new InvalidOperationException("Valid only for a specific project"); - } + AssertProjectId(); - public Models.MergeRequest this[int iid] - { - get + using (Context.BeginOperationScope()) { - AssertProjectId(); - - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(iid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(iid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - return mergeRequest.ToMergeRequestClient(); - } + return mergeRequest.ToMergeRequestClient(); } } + } - public Task GetByIidAsync(int iid, SingleMergeRequestQuery options, CancellationToken cancellationToken = default) - { - return Task.FromResult(this[iid]); - } + public Task GetByIidAsync(int iid, SingleMergeRequestQuery options, CancellationToken cancellationToken = default) + { + return Task.FromResult(this[iid]); + } - public IEnumerable All + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + if (_projectId == null) { - if (_projectId == null) - { - return Server.AllProjects - .Where(project => project.CanUserViewProject(Context.User)) - .SelectMany(project => project.MergeRequests) - .Select(mr => mr.ToMergeRequestClient()) - .ToList(); - } - - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - return project.MergeRequests.Select(mr => mr.ToMergeRequestClient()).ToList(); + return Server.AllProjects + .Where(project => project.CanUserViewProject(Context.User)) + .SelectMany(project => project.MergeRequests) + .Select(mr => mr.ToMergeRequestClient()) + .ToList(); } + + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + return project.MergeRequests.Select(mr => mr.ToMergeRequestClient()).ToList(); } } + } - public Models.MergeRequest Accept(int mergeRequestIid, MergeRequestAccept message) + public Models.MergeRequest Accept(int mergeRequestIid, MergeRequestAccept message) + { + return Accept(mergeRequestIid, new MergeRequestMerge { - return Accept(mergeRequestIid, new MergeRequestMerge - { - Sha = message.Sha, - ShouldRemoveSourceBranch = message.ShouldRemoveSourceBranch, - }); - } + Sha = message.Sha, + ShouldRemoveSourceBranch = message.ShouldRemoveSourceBranch, + }); + } - public Models.MergeRequest Accept(int mergeRequestIid, MergeRequestMerge message) + public Models.MergeRequest Accept(int mergeRequestIid, MergeRequestMerge message) + { + AssertProjectId(); + using (Context.BeginOperationScope()) { - AssertProjectId(); - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + var project = GetProject(_projectId, ProjectPermission.Contribute); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - mergeRequest.ShouldRemoveSourceBranch = message.ShouldRemoveSourceBranch ?? false; + mergeRequest.ShouldRemoveSourceBranch = message.ShouldRemoveSourceBranch ?? false; - if (project.ApprovalsBeforeMerge > mergeRequest.Approvers.Count) - { - throw new GitLabException("The merge request needs to be approved before merging") - { - StatusCode = HttpStatusCode.Unauthorized, - }; - } - - if (message.Sha != null) + if (project.ApprovalsBeforeMerge > mergeRequest.Approvers.Count) + { + throw new GitLabException("The merge request needs to be approved before merging") { - var commit = mergeRequest.SourceBranchHeadCommit; - if (!string.Equals(commit.Sha, message.Sha, StringComparison.OrdinalIgnoreCase)) - { - throw new GitLabException("SHA does not match HEAD of source branch") - { - StatusCode = HttpStatusCode.Conflict, - }; - } - } + StatusCode = HttpStatusCode.Unauthorized, + }; + } - if (mergeRequest.HasConflicts) + if (message.Sha != null) + { + var commit = mergeRequest.SourceBranchHeadCommit; + if (!string.Equals(commit.Sha, message.Sha, StringComparison.OrdinalIgnoreCase)) { - throw new GitLabException("The merge request has some conflicts and cannot be merged") + throw new GitLabException("SHA does not match HEAD of source branch") { - StatusCode = HttpStatusCode.NotAcceptable, + StatusCode = HttpStatusCode.Conflict, }; } + } - if (project.MergeMethod != null && - (string.Equals(project.MergeMethod, "ff", StringComparison.Ordinal) || string.Equals(project.MergeMethod, "rebase_merge", StringComparison.Ordinal)) && - project.Repository.IsRebaseNeeded(mergeRequest.ConsolidatedSourceBranch, mergeRequest.TargetBranch)) + if (mergeRequest.HasConflicts) + { + throw new GitLabException("The merge request has some conflicts and cannot be merged") { - throw new GitLabException($"The MR cannot be merged with method '{project.MergeMethod}': the source branch must first be rebased") - { - StatusCode = HttpStatusCode.MethodNotAllowed, - }; - } + StatusCode = HttpStatusCode.NotAcceptable, + }; + } - mergeRequest.Accept(Context.User); - return mergeRequest.ToMergeRequestClient(); + if (project.MergeMethod != null && + (string.Equals(project.MergeMethod, "ff", StringComparison.Ordinal) || string.Equals(project.MergeMethod, "rebase_merge", StringComparison.Ordinal)) && + project.Repository.IsRebaseNeeded(mergeRequest.ConsolidatedSourceBranch, mergeRequest.TargetBranch)) + { + throw new GitLabException($"The MR cannot be merged with method '{project.MergeMethod}': the source branch must first be rebased") + { + StatusCode = HttpStatusCode.MethodNotAllowed, + }; } + + mergeRequest.Accept(Context.User); + return mergeRequest.ToMergeRequestClient(); } + } - public Models.MergeRequest Approve(int mergeRequestIid, MergeRequestApprove message) - { - AssertProjectId(); + public Models.MergeRequest Approve(int mergeRequestIid, MergeRequestApprove message) + { + AssertProjectId(); - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - project.CanUserContributeToProject(Context.User); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + using (Context.BeginOperationScope()) + { + var project = GetProject(_projectId, ProjectPermission.Contribute); + project.CanUserContributeToProject(Context.User); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - // Check if user has already aproved the merge request - if (mergeRequest.Approvers.Any(x => x.Id == Context.User.Id)) + // Check if user has already aproved the merge request + if (mergeRequest.Approvers.Any(x => x.Id == Context.User.Id)) + { + throw new GitLabException("GitLab server returned an error (Unauthorized): Empty Response.") { - throw new GitLabException("GitLab server returned an error (Unauthorized): Empty Response.") - { - StatusCode = HttpStatusCode.Unauthorized, - }; - } + StatusCode = HttpStatusCode.Unauthorized, + }; + } - /* To be implemented - * need get configuration for GitLab merge request approval: https://docs.gitlab.com/ee/api/merge_request_approvals.html) - * 1) Check if project approval rules require password input - * 2) Check if project approval rules prevents merge request committers from approving - * 3) Check if project approval rules prevents merge request author from approving - */ + /* To be implemented + * need get configuration for GitLab merge request approval: https://docs.gitlab.com/ee/api/merge_request_approvals.html) + * 1) Check if project approval rules require password input + * 2) Check if project approval rules prevents merge request committers from approving + * 3) Check if project approval rules prevents merge request author from approving + */ - if (message.Sha != null) + if (message.Sha != null) + { + var commit = project.Repository.GetBranchTipCommit(mergeRequest.SourceBranch); + if (!string.Equals(commit.Sha, message.Sha, StringComparison.OrdinalIgnoreCase)) { - var commit = project.Repository.GetBranchTipCommit(mergeRequest.SourceBranch); - if (!string.Equals(commit.Sha, message.Sha, StringComparison.OrdinalIgnoreCase)) + throw new GitLabException("SHA does not match HEAD of source branch") { - throw new GitLabException("SHA does not match HEAD of source branch") - { - StatusCode = HttpStatusCode.Conflict, - }; - } + StatusCode = HttpStatusCode.Conflict, + }; } - - mergeRequest.Approvers.Add(new UserRef(Context.User)); - return mergeRequest.ToMergeRequestClient(); } + + mergeRequest.Approvers.Add(new UserRef(Context.User)); + return mergeRequest.ToMergeRequestClient(); } + } - public RebaseResult Rebase(int mergeRequestIid) + public RebaseResult Rebase(int mergeRequestIid) + { + AssertProjectId(); + using (Context.BeginOperationScope()) { - AssertProjectId(); - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + var project = GetProject(_projectId, ProjectPermission.Contribute); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - return mergeRequest.Rebase(Context.User); - } + return mergeRequest.Rebase(Context.User); } + } - public Task RebaseAsync(int mergeRequestIid, MergeRequestRebase options, CancellationToken cancellationToken = default) - { - return Task.FromResult(Rebase(mergeRequestIid)); - } + public Task RebaseAsync(int mergeRequestIid, MergeRequestRebase options, CancellationToken cancellationToken = default) + { + return Task.FromResult(Rebase(mergeRequestIid)); + } - public IEnumerable AllInState(MergeRequestState state) + public IEnumerable AllInState(MergeRequestState state) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + if (_projectId == null) { - if (_projectId == null) - { - return Server.AllProjects - .Where(project => project.CanUserViewProject(Context.User)) - .SelectMany(project => project.MergeRequests) - .Where(mr => mr.State == state) - .Select(mr => mr.ToMergeRequestClient()) - .ToList(); - } + return Server.AllProjects + .Where(project => project.CanUserViewProject(Context.User)) + .SelectMany(project => project.MergeRequests) + .Where(mr => mr.State == state) + .Select(mr => mr.ToMergeRequestClient()) + .ToList(); + } - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - if (!project.AccessibleMergeRequests) + if (!project.AccessibleMergeRequests) + { + throw new GitLabException("403 Forbidden") { - throw new GitLabException("403 Forbidden") - { - StatusCode = HttpStatusCode.Forbidden, - }; - } - - return project.MergeRequests.Where(mr => mr.State == state).Select(mr => mr.ToMergeRequestClient()).ToList(); + StatusCode = HttpStatusCode.Forbidden, + }; } + + return project.MergeRequests.Where(mr => mr.State == state).Select(mr => mr.ToMergeRequestClient()).ToList(); } + } - public IMergeRequestChangeClient Changes(int mergeRequestIid) - { - AssertProjectId(); + public IMergeRequestChangeClient Changes(int mergeRequestIid) + { + AssertProjectId(); - return new MergeRequestChangeClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); - } + return new MergeRequestChangeClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); + } - public IMergeRequestApprovalClient ApprovalClient(int mergeRequestIid) - { - AssertProjectId(); + public IMergeRequestApprovalClient ApprovalClient(int mergeRequestIid) + { + AssertProjectId(); - return new MergeRequestApprovalClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); - } + return new MergeRequestApprovalClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); + } - public Models.MergeRequest Close(int mergeRequestIid) - { - AssertProjectId(); + public Models.MergeRequest Close(int mergeRequestIid) + { + AssertProjectId(); - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + using (Context.BeginOperationScope()) + { + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - if (mergeRequest.State != MergeRequestState.opened) - throw new GitLabBadRequestException(); + if (mergeRequest.State != MergeRequestState.opened) + throw new GitLabBadRequestException(); - mergeRequest.ClosedAt = DateTimeOffset.UtcNow; - mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; + mergeRequest.ClosedAt = DateTimeOffset.UtcNow; + mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; - Server.ResourceStateEvents.CreateResourceStateEvent(Context.User, "closed", mergeRequest.Id, "MergeRequest"); - return mergeRequest.ToMergeRequestClient(); - } + Server.ResourceStateEvents.CreateResourceStateEvent(Context.User, "closed", mergeRequest.Id, "MergeRequest"); + return mergeRequest.ToMergeRequestClient(); } + } - public IMergeRequestCommentClient Comments(int mergeRequestIid) - { - AssertProjectId(); + public IMergeRequestCommentClient Comments(int mergeRequestIid) + { + AssertProjectId(); - return new MergeRequestCommentClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); - } + return new MergeRequestCommentClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); + } - public IMergeRequestCommitClient Commits(int mergeRequestIid) - { - AssertProjectId(); + public IMergeRequestCommitClient Commits(int mergeRequestIid) + { + AssertProjectId(); - return new MergeRequestCommitClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); - } + return new MergeRequestCommitClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); + } - public Models.MergeRequest CancelMergeWhenPipelineSucceeds(int mergeRequestIid) - { - AssertProjectId(); + public Models.MergeRequest CancelMergeWhenPipelineSucceeds(int mergeRequestIid) + { + AssertProjectId(); - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + using (Context.BeginOperationScope()) + { + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - if (mergeRequest.State != MergeRequestState.opened) - throw new GitLabBadRequestException(); + if (mergeRequest.State != MergeRequestState.opened) + throw new GitLabBadRequestException(); - mergeRequest.MergeWhenPipelineSucceeds = false; - mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; - return mergeRequest.ToMergeRequestClient(); - } + mergeRequest.MergeWhenPipelineSucceeds = false; + mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; + return mergeRequest.ToMergeRequestClient(); } + } - public Models.MergeRequest Create(MergeRequestCreate mergeRequestCreate) - { - AssertProjectId(); + public Models.MergeRequest Create(MergeRequestCreate mergeRequestCreate) + { + AssertProjectId(); - EnsureUserIsAuthenticated(); + EnsureUserIsAuthenticated(); - using (Context.BeginOperationScope()) - { - var sourceProject = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.Contribute); - var targetProject = GetProject(mergeRequestCreate.TargetProjectId, ProjectPermission.View); + using (Context.BeginOperationScope()) + { + var sourceProject = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.Contribute); + var targetProject = GetProject(mergeRequestCreate.TargetProjectId, ProjectPermission.View); - // Ensure the branches exist - _ = sourceProject.Repository.GetBranch(mergeRequestCreate.SourceBranch) ?? throw new GitLabBadRequestException("Source branch not found"); - _ = targetProject.Repository.GetBranch(mergeRequestCreate.TargetBranch) ?? throw new GitLabBadRequestException("Target branch not found"); + // Ensure the branches exist + _ = sourceProject.Repository.GetBranch(mergeRequestCreate.SourceBranch) ?? throw new GitLabBadRequestException("Source branch not found"); + _ = targetProject.Repository.GetBranch(mergeRequestCreate.TargetBranch) ?? throw new GitLabBadRequestException("Target branch not found"); - UserRef assignee = null; - if (mergeRequestCreate.AssigneeId != null) - { - assignee = Server.Users.GetById(mergeRequestCreate.AssigneeId.Value) ?? throw new GitLabBadRequestException("assignee not found"); - } + UserRef assignee = null; + if (mergeRequestCreate.AssigneeId != null) + { + assignee = Server.Users.GetById(mergeRequestCreate.AssigneeId.Value) ?? throw new GitLabBadRequestException("assignee not found"); + } - var mergeRequest = targetProject.MergeRequests.Add(sourceProject, mergeRequestCreate.SourceBranch, mergeRequestCreate.TargetBranch, mergeRequestCreate.Title, Context.User); - mergeRequest.Assignee = assignee; - mergeRequest.Description = mergeRequestCreate.Description; - mergeRequest.ShouldRemoveSourceBranch = mergeRequestCreate.RemoveSourceBranch; - mergeRequest.Squash = mergeRequestCreate.Squash; - SetLabels(mergeRequest, mergeRequestCreate.Labels, labelsToAdd: null, labelsToRemove: null); + var mergeRequest = targetProject.MergeRequests.Add(sourceProject, mergeRequestCreate.SourceBranch, mergeRequestCreate.TargetBranch, mergeRequestCreate.Title, Context.User); + mergeRequest.Assignee = assignee; + mergeRequest.Description = mergeRequestCreate.Description; + mergeRequest.ShouldRemoveSourceBranch = mergeRequestCreate.RemoveSourceBranch; + mergeRequest.Squash = mergeRequestCreate.Squash; + SetLabels(mergeRequest, mergeRequestCreate.Labels, labelsToAdd: null, labelsToRemove: null); - return mergeRequest.ToMergeRequestClient(); - } + return mergeRequest.ToMergeRequestClient(); } + } - private void SetLabels(MergeRequest mergeRequest, string labels, string labelsToAdd, string labelsToRemove) + private void SetLabels(MergeRequest mergeRequest, string labels, string labelsToAdd, string labelsToRemove) + { + if (labels is not null || labelsToAdd is not null || labelsToRemove is not null) { - if (labels is not null || labelsToAdd is not null || labelsToRemove is not null) + var newLabels = mergeRequest.Labels.ToArray(); + if (labels is not null) { - var newLabels = mergeRequest.Labels.ToArray(); - if (labels is not null) - { - newLabels = labels.Split(',').Distinct(StringComparer.Ordinal).ToArray(); - } + newLabels = labels.Split(',').Distinct(StringComparer.Ordinal).ToArray(); + } - if (labelsToAdd is not null) - { - newLabels = newLabels.Concat(labelsToAdd.Split(',')).Distinct(StringComparer.Ordinal).ToArray(); - } + if (labelsToAdd is not null) + { + newLabels = newLabels.Concat(labelsToAdd.Split(',')).Distinct(StringComparer.Ordinal).ToArray(); + } - if (labelsToRemove is not null) - { - newLabels = newLabels.Except(labelsToRemove.Split(','), StringComparer.Ordinal).Distinct(StringComparer.Ordinal).ToArray(); - } + if (labelsToRemove is not null) + { + newLabels = newLabels.Except(labelsToRemove.Split(','), StringComparer.Ordinal).Distinct(StringComparer.Ordinal).ToArray(); + } - if (newLabels is not null) - { - Server.ResourceLabelEvents.CreateResourceLabelEvents(Context.User, mergeRequest.Labels.ToArray(), newLabels, mergeRequest.Id, "MergeRequest"); - } + if (newLabels is not null) + { + Server.ResourceLabelEvents.CreateResourceLabelEvents(Context.User, mergeRequest.Labels.ToArray(), newLabels, mergeRequest.Id, "MergeRequest"); + } - mergeRequest.Labels.Clear(); - foreach (var newLabel in newLabels) + mergeRequest.Labels.Clear(); + foreach (var newLabel in newLabels) + { + if (!string.IsNullOrEmpty(newLabel)) { - if (!string.IsNullOrEmpty(newLabel)) - { - mergeRequest.Labels.Add(newLabel); - } + mergeRequest.Labels.Add(newLabel); } } } + } + + public void Delete(int mergeRequestIid) + { + AssertProjectId(); - public void Delete(int mergeRequestIid) + using (Context.BeginOperationScope()) { - AssertProjectId(); + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + project.MergeRequests.Remove(mergeRequest); + } + } - project.MergeRequests.Remove(mergeRequest); - } + public IEnumerable Get(MergeRequestQuery query) + { + using (Context.BeginOperationScope()) + { + var projects = _projectId == null + ? Server.AllProjects.Where(project => project.CanUserViewProject(Context.User)) + : new[] { GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View) }; + var mergeRequests = projects.SelectMany(x => x.MergeRequests); + return FilterByQuery(mergeRequests, query); } + } - public IEnumerable Get(MergeRequestQuery query) + [SuppressMessage("Design", "MA0051:Method is too long", Justification = "There are lots of cases to support")] + public IEnumerable FilterByQuery(IEnumerable mergeRequests, MergeRequestQuery query) + { + if (query != null) { - using (Context.BeginOperationScope()) + if (query.ApproverIds != null) { - var projects = _projectId == null - ? Server.AllProjects.Where(project => project.CanUserViewProject(Context.User)) - : new[] { GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View) }; - var mergeRequests = projects.SelectMany(x => x.MergeRequests); - return FilterByQuery(mergeRequests, query); + var approverIds = query.ApproverIds; + mergeRequests = mergeRequests.Where(mr => mr.Approvers.Any(x => approverIds.Contains(x.Id))); } - } - [SuppressMessage("Design", "MA0051:Method is too long", Justification = "There are lots of cases to support")] - public IEnumerable FilterByQuery(IEnumerable mergeRequests, MergeRequestQuery query) - { - if (query != null) + if (query.AssigneeId != null) { - if (query.ApproverIds != null) - { - var approverIds = query.ApproverIds; - mergeRequests = mergeRequests.Where(mr => mr.Approvers.Any(x => approverIds.Contains(x.Id))); - } + var assigneeId = string.Equals(query.AssigneeId.ToString(), "None", StringComparison.OrdinalIgnoreCase) ? (int?)null : int.Parse(query.AssigneeId.ToString()); + mergeRequests = mergeRequests.Where(mr => mr.Assignee?.Id == assigneeId); + } - if (query.AssigneeId != null) + if (query.ReviewerId != null) + { + if (query.ReviewerId == QueryAssigneeId.None) { - var assigneeId = string.Equals(query.AssigneeId.ToString(), "None", StringComparison.OrdinalIgnoreCase) ? (int?)null : int.Parse(query.AssigneeId.ToString()); - mergeRequests = mergeRequests.Where(mr => mr.Assignee?.Id == assigneeId); + mergeRequests = mergeRequests.Where(mr => mr.Reviewers == null || mr.Reviewers.Count == 0); } - - if (query.ReviewerId != null) + else if (query.ReviewerId == QueryAssigneeId.Any) { - if (query.ReviewerId == QueryAssigneeId.None) - { - mergeRequests = mergeRequests.Where(mr => mr.Reviewers == null || mr.Reviewers.Count == 0); - } - else if (query.ReviewerId == QueryAssigneeId.Any) - { - mergeRequests = mergeRequests.Where(mr => mr.Reviewers != null || mr.Reviewers.Any()); - } - else - { - var reviewerId = int.Parse(query.ReviewerId.ToString()); - mergeRequests = mergeRequests.Where(mr => mr.Reviewers.Any(x => reviewerId.Equals(x.Id))); - } + mergeRequests = mergeRequests.Where(mr => mr.Reviewers != null || mr.Reviewers.Any()); } - - if (query.AuthorId != null) + else { - mergeRequests = mergeRequests.Where(mr => mr.Author.Id == query.AuthorId); + var reviewerId = int.Parse(query.ReviewerId.ToString()); + mergeRequests = mergeRequests.Where(mr => mr.Reviewers.Any(x => reviewerId.Equals(x.Id))); } + } - if (query.CreatedAfter != null) - { - mergeRequests = mergeRequests.Where(mr => mr.CreatedAt >= query.CreatedAfter.Value.ToDateTimeOffsetAssumeUtc()); - } + if (query.AuthorId != null) + { + mergeRequests = mergeRequests.Where(mr => mr.Author.Id == query.AuthorId); + } - if (query.CreatedBefore != null) - { - mergeRequests = mergeRequests.Where(mr => mr.CreatedAt <= query.CreatedBefore.Value.ToDateTimeOffsetAssumeUtc()); - } + if (query.CreatedAfter != null) + { + mergeRequests = mergeRequests.Where(mr => mr.CreatedAt >= query.CreatedAfter.Value.ToDateTimeOffsetAssumeUtc()); + } - if (!string.IsNullOrEmpty(query.Labels)) - { - foreach (var label in query.Labels.Split(',')) - { - mergeRequests = mergeRequests.Where(mr => mr.Labels.Contains(label, StringComparer.Ordinal)); - } - } + if (query.CreatedBefore != null) + { + mergeRequests = mergeRequests.Where(mr => mr.CreatedAt <= query.CreatedBefore.Value.ToDateTimeOffsetAssumeUtc()); + } - if (query.Milestone != null) + if (!string.IsNullOrEmpty(query.Labels)) + { + foreach (var label in query.Labels.Split(',')) { - throw new NotImplementedException(); + mergeRequests = mergeRequests.Where(mr => mr.Labels.Contains(label, StringComparer.Ordinal)); } + } - if (query.Scope != null) - { - var userId = Context.User.Id; - switch (query.Scope) - { - case "created_by_me": - case "created-by-me": - mergeRequests = mergeRequests.Where(mr => mr.Author.Id == userId); - break; - case "assigned_to_me": - case "assigned-to-me": - mergeRequests = mergeRequests.Where(mr => mr.Assignee?.Id == userId); - break; - case "all": - break; - default: - throw new NotSupportedException($"Scope '{query.Scope}' is not supported"); - } - } + if (query.Milestone != null) + { + throw new NotImplementedException(); + } - if (query.Search != null) - { - throw new NotImplementedException(); + if (query.Scope != null) + { + var userId = Context.User.Id; + switch (query.Scope) + { + case "created_by_me": + case "created-by-me": + mergeRequests = mergeRequests.Where(mr => mr.Author.Id == userId); + break; + case "assigned_to_me": + case "assigned-to-me": + mergeRequests = mergeRequests.Where(mr => mr.Assignee?.Id == userId); + break; + case "all": + break; + default: + throw new NotSupportedException($"Scope '{query.Scope}' is not supported"); } + } - if (query.SourceBranch != null) - { - mergeRequests = mergeRequests.Where(mr => string.Equals(mr.SourceBranch, query.SourceBranch, StringComparison.Ordinal)); - } + if (query.Search != null) + { + throw new NotImplementedException(); + } - if (query.TargetBranch != null) - { - mergeRequests = mergeRequests.Where(mr => string.Equals(mr.TargetBranch, query.TargetBranch, StringComparison.Ordinal)); - } + if (query.SourceBranch != null) + { + mergeRequests = mergeRequests.Where(mr => string.Equals(mr.SourceBranch, query.SourceBranch, StringComparison.Ordinal)); + } - if (query.UpdatedAfter != null) - { - mergeRequests = mergeRequests.Where(mr => mr.UpdatedAt >= query.UpdatedAfter.Value.ToDateTimeOffsetAssumeUtc()); - } + if (query.TargetBranch != null) + { + mergeRequests = mergeRequests.Where(mr => string.Equals(mr.TargetBranch, query.TargetBranch, StringComparison.Ordinal)); + } - if (query.UpdatedBefore != null) - { - mergeRequests = mergeRequests.Where(mr => mr.UpdatedAt <= query.UpdatedBefore.Value.ToDateTimeOffsetAssumeUtc()); - } + if (query.UpdatedAfter != null) + { + mergeRequests = mergeRequests.Where(mr => mr.UpdatedAt >= query.UpdatedAfter.Value.ToDateTimeOffsetAssumeUtc()); + } - if (query.State != null) - { - mergeRequests = mergeRequests.Where(mr => mr.State == query.State); - } + if (query.UpdatedBefore != null) + { + mergeRequests = mergeRequests.Where(mr => mr.UpdatedAt <= query.UpdatedBefore.Value.ToDateTimeOffsetAssumeUtc()); + } - if (string.Equals(query.Sort, "asc", StringComparison.Ordinal)) - { - mergeRequests = mergeRequests.Reverse(); - } + if (query.State != null) + { + mergeRequests = mergeRequests.Where(mr => mr.State == query.State); + } - if (query.OrderBy != null) - { - mergeRequests = query.OrderBy switch - { - "created_at" => mergeRequests.OrderBy(mr => mr.CreatedAt), - "updated_at" => mergeRequests.OrderBy(mr => mr.UpdatedAt), - _ => throw new NotSupportedException($"OrderBy '{query.OrderBy}' is not supported"), - }; - } + if (string.Equals(query.Sort, "asc", StringComparison.Ordinal)) + { + mergeRequests = mergeRequests.Reverse(); + } - if (query.PerPage != null) + if (query.OrderBy != null) + { + mergeRequests = query.OrderBy switch { - mergeRequests = mergeRequests.Take(query.PerPage.Value); - } + "created_at" => mergeRequests.OrderBy(mr => mr.CreatedAt), + "updated_at" => mergeRequests.OrderBy(mr => mr.UpdatedAt), + _ => throw new NotSupportedException($"OrderBy '{query.OrderBy}' is not supported"), + }; + } - if (query.Wip != null) - { - mergeRequests = mergeRequests.Where(mr => (bool)query.Wip ? mr.Draft : !mr.Draft); - } + if (query.PerPage != null) + { + mergeRequests = mergeRequests.Take(query.PerPage.Value); } - return mergeRequests.Select(mr => mr.ToMergeRequestClient()).ToList(); + if (query.Wip != null) + { + mergeRequests = mergeRequests.Where(mr => (bool)query.Wip ? mr.Draft : !mr.Draft); + } } - public IEnumerable GetParticipants(int mergeRequestIid) - { - AssertProjectId(); + return mergeRequests.Select(mr => mr.ToMergeRequestClient()).ToList(); + } - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + public IEnumerable GetParticipants(int mergeRequestIid) + { + AssertProjectId(); - return mergeRequest.Comments.Select(c => c.Author) - .Union(new[] { mergeRequest.Author }) - .Select(u => u.ToClientAuthor()) - .ToList(); - } + using (Context.BeginOperationScope()) + { + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); + + return mergeRequest.Comments.Select(c => c.Author) + .Union(new[] { mergeRequest.Author }) + .Select(u => u.ToClientAuthor()) + .ToList(); } + } - public IEnumerable GetPipelines(int mergeRequestIid) + public IEnumerable GetPipelines(int mergeRequestIid) + { + AssertProjectId(); + + using (Context.BeginOperationScope()) { - AssertProjectId(); + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - if (mergeRequest == null) - throw new GitLabNotFoundException(); - - var allSha1 = mergeRequest.Commits.Select(m => new Sha1(m.Sha)); + var allSha1 = mergeRequest.Commits.Select(m => new Sha1(m.Sha)); - return mergeRequest.SourceProject.Pipelines - .Where(p => allSha1.Contains(p.Sha)) - .OrderByDescending(p => p.CreatedAt) - .Select(p => p.ToPipelineBasicClient()) - .ToList(); - } + return mergeRequest.SourceProject.Pipelines + .Where(p => allSha1.Contains(p.Sha)) + .OrderByDescending(p => p.CreatedAt) + .Select(p => p.ToPipelineBasicClient()) + .ToList(); } + } - public Models.MergeRequest Reopen(int mergeRequestIid) - { - AssertProjectId(); + public Models.MergeRequest Reopen(int mergeRequestIid) + { + AssertProjectId(); - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); + using (Context.BeginOperationScope()) + { + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - if (mergeRequest.State != MergeRequestState.closed) - throw new GitLabBadRequestException(); + if (mergeRequest.State != MergeRequestState.closed) + throw new GitLabBadRequestException(); - mergeRequest.ClosedAt = null; - mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; + mergeRequest.ClosedAt = null; + mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; - Server.ResourceStateEvents.CreateResourceStateEvent(Context.User, "reopened", mergeRequest.Id, "MergeRequest"); - return mergeRequest.ToMergeRequestClient(); - } + Server.ResourceStateEvents.CreateResourceStateEvent(Context.User, "reopened", mergeRequest.Id, "MergeRequest"); + return mergeRequest.ToMergeRequestClient(); } + } + + public Models.MergeRequest Update(int mergeRequestIid, MergeRequestUpdate mergeRequestUpdate) + { + AssertProjectId(); - public Models.MergeRequest Update(int mergeRequestIid, MergeRequestUpdate mergeRequestUpdate) + using (Context.BeginOperationScope()) { - AssertProjectId(); + var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); + var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); + if (mergeRequest == null) + throw new GitLabNotFoundException(); - using (Context.BeginOperationScope()) + if (mergeRequestUpdate.AssigneeIds != null) { - var project = GetProject(_projectId.GetValueOrDefault(), ProjectPermission.View); - var mergeRequest = project.MergeRequests.GetByIid(mergeRequestIid); - if (mergeRequest == null) - throw new GitLabNotFoundException(); - - if (mergeRequestUpdate.AssigneeIds != null) + mergeRequest.Assignees.Clear(); + if (mergeRequestUpdate.AssigneeIds.Length == 0) { - mergeRequest.Assignees.Clear(); - if (mergeRequestUpdate.AssigneeIds.Length == 0) - { - mergeRequest.Assignee = null; - } - else - { - foreach (var assigneeId in mergeRequestUpdate.AssigneeIds) - { - var user = Server.Users.GetById(assigneeId); - if (user == null) - throw new GitLabBadRequestException("user not found"); - - mergeRequest.Assignees.Add(new UserRef(user)); - } - } + mergeRequest.Assignee = null; } - else if (mergeRequestUpdate.AssigneeId != null) + else { - if (mergeRequestUpdate.AssigneeId.Value == 0) - { - mergeRequest.Assignee = null; - } - else + foreach (var assigneeId in mergeRequestUpdate.AssigneeIds) { - var user = Server.Users.GetById(mergeRequestUpdate.AssigneeId.Value); + var user = Server.Users.GetById(assigneeId); if (user == null) throw new GitLabBadRequestException("user not found"); - mergeRequest.Assignee = new UserRef(user); + mergeRequest.Assignees.Add(new UserRef(user)); } } - - if (mergeRequestUpdate.MilestoneId != null) + } + else if (mergeRequestUpdate.AssigneeId != null) + { + if (mergeRequestUpdate.AssigneeId.Value == 0) { - var prevMilestone = mergeRequest.Milestone; - mergeRequest.Milestone = GetMilestone(project.Id, mergeRequestUpdate.MilestoneId.Value); - Server.ResourceMilestoneEvents.CreateResourceMilestoneEvents(Context.User, mergeRequest.Id, prevMilestone, mergeRequest.Milestone, "MergeRequest"); + mergeRequest.Assignee = null; } - - if (mergeRequestUpdate.ReviewerIds != null) + else { - foreach (var reviewerId in mergeRequestUpdate.ReviewerIds) - { - var reviewer = Server.Users.GetById(reviewerId); - if (reviewer == null) - throw new GitLabBadRequestException("user not found"); + var user = Server.Users.GetById(mergeRequestUpdate.AssigneeId.Value); + if (user == null) + throw new GitLabBadRequestException("user not found"); - mergeRequest.Reviewers.Add(reviewer); - } + mergeRequest.Assignee = new UserRef(user); } + } - if (mergeRequestUpdate.Description != null) - { - mergeRequest.Description = mergeRequestUpdate.Description; - } + if (mergeRequestUpdate.MilestoneId != null) + { + var prevMilestone = mergeRequest.Milestone; + mergeRequest.Milestone = GetMilestone(project.Id, mergeRequestUpdate.MilestoneId.Value); + Server.ResourceMilestoneEvents.CreateResourceMilestoneEvents(Context.User, mergeRequest.Id, prevMilestone, mergeRequest.Milestone, "MergeRequest"); + } - if (mergeRequestUpdate.NewState != null) + if (mergeRequestUpdate.ReviewerIds != null) + { + foreach (var reviewerId in mergeRequestUpdate.ReviewerIds) { - throw new NotImplementedException(); - } + var reviewer = Server.Users.GetById(reviewerId); + if (reviewer == null) + throw new GitLabBadRequestException("user not found"); - if (mergeRequestUpdate.SourceBranch != null) - { - mergeRequest.SourceBranch = mergeRequestUpdate.SourceBranch; + mergeRequest.Reviewers.Add(reviewer); } + } - if (mergeRequestUpdate.TargetBranch != null) - { - mergeRequest.TargetBranch = mergeRequestUpdate.TargetBranch; - } + if (mergeRequestUpdate.Description != null) + { + mergeRequest.Description = mergeRequestUpdate.Description; + } - if (mergeRequestUpdate.Title != null) - { - mergeRequest.Title = mergeRequestUpdate.Title; - } + if (mergeRequestUpdate.NewState != null) + { + throw new NotImplementedException(); + } - SetLabels(mergeRequest, mergeRequestUpdate.Labels, mergeRequestUpdate.AddLabels, mergeRequestUpdate.RemoveLabels); + if (mergeRequestUpdate.SourceBranch != null) + { + mergeRequest.SourceBranch = mergeRequestUpdate.SourceBranch; + } - mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; - return mergeRequest.ToMergeRequestClient(); + if (mergeRequestUpdate.TargetBranch != null) + { + mergeRequest.TargetBranch = mergeRequestUpdate.TargetBranch; } - } - public IEnumerable ClosesIssues(int mergeRequestIid) - { - throw new NotImplementedException(); - } + if (mergeRequestUpdate.Title != null) + { + mergeRequest.Title = mergeRequestUpdate.Title; + } - public GitLabCollectionResponse GetVersionsAsync(int mergeRequestIid) - { - throw new NotImplementedException(); - } + SetLabels(mergeRequest, mergeRequestUpdate.Labels, mergeRequestUpdate.AddLabels, mergeRequestUpdate.RemoveLabels); - public Task TimeStatsAsync(int mergeRequestIid, CancellationToken cancellationToken = default) - { - throw new NotImplementedException(); + mergeRequest.UpdatedAt = DateTimeOffset.UtcNow; + return mergeRequest.ToMergeRequestClient(); } + } - public IMergeRequestDiscussionClient Discussions(int mergeRequestIid) - { - AssertProjectId(); + public IEnumerable ClosesIssues(int mergeRequestIid) + { + throw new NotImplementedException(); + } - return new MergeRequestDiscussionClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); - } + public GitLabCollectionResponse GetVersionsAsync(int mergeRequestIid) + { + throw new NotImplementedException(); + } - public GitLabCollectionResponse ResourceLabelEventsAsync(int projectId, int mergeRequestIid) + public Task TimeStatsAsync(int mergeRequestIid, CancellationToken cancellationToken = default) + { + throw new NotImplementedException(); + } + + public IMergeRequestDiscussionClient Discussions(int mergeRequestIid) + { + AssertProjectId(); + + return new MergeRequestDiscussionClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid); + } + + public GitLabCollectionResponse ResourceLabelEventsAsync(int projectId, int mergeRequestIid) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); - var resourceLabelEvents = Server.ResourceLabelEvents.Get(mergeRequest.Id); + var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); + var resourceLabelEvents = Server.ResourceLabelEvents.Get(mergeRequest.Id); - return GitLabCollectionResponse.Create(resourceLabelEvents.Select(rle => rle.ToClientResourceLabelEvent())); - } + return GitLabCollectionResponse.Create(resourceLabelEvents.Select(rle => rle.ToClientResourceLabelEvent())); } + } - public GitLabCollectionResponse ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid) + public GitLabCollectionResponse ResourceMilestoneEventsAsync(int projectId, int mergeRequestIid) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); - var resourceMilestoneEvents = Server.ResourceMilestoneEvents.Get(mergeRequest.Id); + var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); + var resourceMilestoneEvents = Server.ResourceMilestoneEvents.Get(mergeRequest.Id); - return GitLabCollectionResponse.Create(resourceMilestoneEvents.Select(rme => rme.ToClientResourceMilestoneEvent())); - } + return GitLabCollectionResponse.Create(resourceMilestoneEvents.Select(rme => rme.ToClientResourceMilestoneEvent())); } + } - public GitLabCollectionResponse ResourceStateEventsAsync(int projectId, int mergeRequestIid) + public GitLabCollectionResponse ResourceStateEventsAsync(int projectId, int mergeRequestIid) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); - var resourceStateEvents = Server.ResourceStateEvents.Get(mergeRequest.Id); + var mergeRequest = GetMergeRequest(projectId, mergeRequestIid); + var resourceStateEvents = Server.ResourceStateEvents.Get(mergeRequest.Id); - return GitLabCollectionResponse.Create(resourceStateEvents.Select(rle => rle.ToClientResourceStateEvent())); - } + return GitLabCollectionResponse.Create(resourceStateEvents.Select(rle => rle.ToClientResourceStateEvent())); } } } diff --git a/NGitLab.Mock/Clients/MergeRequestCommentClient.cs b/NGitLab.Mock/Clients/MergeRequestCommentClient.cs index ea8457f5..b40cf35e 100644 --- a/NGitLab.Mock/Clients/MergeRequestCommentClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestCommentClient.cs @@ -3,126 +3,125 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class MergeRequestCommentClient : ClientBase, IMergeRequestCommentClient { - internal sealed class MergeRequestCommentClient : ClientBase, IMergeRequestCommentClient - { - private readonly int _projectId; - private readonly int _mergeRequestIid; + private readonly int _projectId; + private readonly int _mergeRequestIid; - public MergeRequestCommentClient(ClientContext context, int projectId, int mergeRequestIid) - : base(context) - { - _projectId = projectId; - _mergeRequestIid = mergeRequestIid; - } + public MergeRequestCommentClient(ClientContext context, int projectId, int mergeRequestIid) + : base(context) + { + _projectId = projectId; + _mergeRequestIid = mergeRequestIid; + } - private MergeRequest GetMergeRequest() => GetMergeRequest(_projectId, _mergeRequestIid); + private MergeRequest GetMergeRequest() => GetMergeRequest(_projectId, _mergeRequestIid); - public IEnumerable All + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return GetMergeRequest().Comments.Select(mr => mr.ToMergeRequestCommentClient()).ToList(); - } + return GetMergeRequest().Comments.Select(mr => mr.ToMergeRequestCommentClient()).ToList(); } } + } - public IEnumerable Discussions + public IEnumerable Discussions + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return GetMergeRequest().GetDiscussions().ToList(); - } + return GetMergeRequest().GetDiscussions().ToList(); } } + } - public Models.MergeRequestComment Add(Models.MergeRequestComment comment) + public Models.MergeRequestComment Add(Models.MergeRequestComment comment) + { + return Add(new MergeRequestCommentCreate { - return Add(new MergeRequestCommentCreate - { - Body = comment.Body, - CreatedAt = null, - }); - } + Body = comment.Body, + CreatedAt = null, + }); + } + + public Models.MergeRequestComment Add(MergeRequestCommentCreate commentCreate) + { + EnsureUserIsAuthenticated(); - public Models.MergeRequestComment Add(MergeRequestCommentCreate commentCreate) + using (Context.BeginOperationScope()) { - EnsureUserIsAuthenticated(); + var project = GetProject(_projectId, ProjectPermission.View); + if (project.Archived) + throw new GitLabForbiddenException(); - using (Context.BeginOperationScope()) + var comment = new MergeRequestComment { - var project = GetProject(_projectId, ProjectPermission.View); - if (project.Archived) - throw new GitLabForbiddenException(); - - var comment = new MergeRequestComment - { - Author = Context.User, - Body = commentCreate.Body, - }; - - GetMergeRequest().Comments.Add(comment); - return comment.ToMergeRequestCommentClient(); - } + Author = Context.User, + Body = commentCreate.Body, + }; + + GetMergeRequest().Comments.Add(comment); + return comment.ToMergeRequestCommentClient(); } + } - public Models.MergeRequestComment Edit(long id, MergeRequestCommentEdit edit) + public Models.MergeRequestComment Edit(long id, MergeRequestCommentEdit edit) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - if (project.Archived) - throw new GitLabForbiddenException(); + var project = GetProject(_projectId, ProjectPermission.View); + if (project.Archived) + throw new GitLabForbiddenException(); - var comment = GetMergeRequest().Comments.GetById(id); - if (comment == null) - throw new GitLabNotFoundException(); + var comment = GetMergeRequest().Comments.GetById(id); + if (comment == null) + throw new GitLabNotFoundException(); - comment.Body = edit.Body; - return comment.ToMergeRequestCommentClient(); - } + comment.Body = edit.Body; + return comment.ToMergeRequestCommentClient(); } + } - public void Delete(long id) + public void Delete(long id) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var comments = GetMergeRequest().Comments; - var comment = comments.GetById(id); - if (comment == null) - throw new GitLabNotFoundException(); + var comments = GetMergeRequest().Comments; + var comment = comments.GetById(id); + if (comment == null) + throw new GitLabNotFoundException(); - comments.Remove(comment); - } + comments.Remove(comment); } + } - public IEnumerable Get(MergeRequestCommentQuery query) + public IEnumerable Get(MergeRequestCommentQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var comments = GetMergeRequest().Comments.Select(mr => mr.ToMergeRequestCommentClient()); + var orderByUpdated = query.OrderBy != null && query.OrderBy.Equals("updated_at", StringComparison.Ordinal); + + if (string.Equals(query.Sort, "asc", StringComparison.Ordinal)) { - var comments = GetMergeRequest().Comments.Select(mr => mr.ToMergeRequestCommentClient()); - var orderByUpdated = query.OrderBy != null && query.OrderBy.Equals("updated_at", StringComparison.Ordinal); - - if (string.Equals(query.Sort, "asc", StringComparison.Ordinal)) - { - comments = orderByUpdated ? comments.OrderBy(comment => comment.UpdatedAt) : comments.OrderBy(comment => comment.CreatedAt); - } - else - { - comments = orderByUpdated ? comments.OrderByDescending(comment => comment.UpdatedAt) : comments.OrderByDescending(comment => comment.CreatedAt); - } - - var pageIndex = query.Page.HasValue ? query.Page.Value - 1 : 0; - var perPage = query.PerPage ?? 20; - var lowerBound = pageIndex * perPage; - - return comments.Skip(lowerBound).Take(perPage); + comments = orderByUpdated ? comments.OrderBy(comment => comment.UpdatedAt) : comments.OrderBy(comment => comment.CreatedAt); } + else + { + comments = orderByUpdated ? comments.OrderByDescending(comment => comment.UpdatedAt) : comments.OrderByDescending(comment => comment.CreatedAt); + } + + var pageIndex = query.Page.HasValue ? query.Page.Value - 1 : 0; + var perPage = query.PerPage ?? 20; + var lowerBound = pageIndex * perPage; + + return comments.Skip(lowerBound).Take(perPage); } } } diff --git a/NGitLab.Mock/Clients/MergeRequestCommitClient.cs b/NGitLab.Mock/Clients/MergeRequestCommitClient.cs index 5c2f4530..7f9e4dd1 100644 --- a/NGitLab.Mock/Clients/MergeRequestCommitClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestCommitClient.cs @@ -2,29 +2,28 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class MergeRequestCommitClient : ClientBase, IMergeRequestCommitClient { - internal sealed class MergeRequestCommitClient : ClientBase, IMergeRequestCommitClient - { - private readonly int _projectId; - private readonly int _mergeRequestIid; + private readonly int _projectId; + private readonly int _mergeRequestIid; - public MergeRequestCommitClient(ClientContext context, int projectId, int mergeRequestIid) - : base(context) - { - _projectId = projectId; - _mergeRequestIid = mergeRequestIid; - } + public MergeRequestCommitClient(ClientContext context, int projectId, int mergeRequestIid) + : base(context) + { + _projectId = projectId; + _mergeRequestIid = mergeRequestIid; + } - public IEnumerable All + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var mergeRequest = GetMergeRequest(_projectId, _mergeRequestIid); - return mergeRequest.Commits.Select(commit => commit.ToCommitClient(mergeRequest.SourceProject)).ToList(); - } + var mergeRequest = GetMergeRequest(_projectId, _mergeRequestIid); + return mergeRequest.Commits.Select(commit => commit.ToCommitClient(mergeRequest.SourceProject)).ToList(); } } } diff --git a/NGitLab.Mock/Clients/MergeRequestDiscussionClient.cs b/NGitLab.Mock/Clients/MergeRequestDiscussionClient.cs index 82ad734f..1008e47a 100644 --- a/NGitLab.Mock/Clients/MergeRequestDiscussionClient.cs +++ b/NGitLab.Mock/Clients/MergeRequestDiscussionClient.cs @@ -5,119 +5,118 @@ using System.Threading.Tasks; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class MergeRequestDiscussionClient : ClientBase, IMergeRequestDiscussionClient { - internal sealed class MergeRequestDiscussionClient : ClientBase, IMergeRequestDiscussionClient - { - private readonly int _projectId; - private readonly int _mergeRequestIid; + private readonly int _projectId; + private readonly int _mergeRequestIid; - public MergeRequestDiscussionClient(ClientContext context, int projectId, int mergeRequestIid) - : base(context) - { - _projectId = projectId; - _mergeRequestIid = mergeRequestIid; - } + public MergeRequestDiscussionClient(ClientContext context, int projectId, int mergeRequestIid) + : base(context) + { + _projectId = projectId; + _mergeRequestIid = mergeRequestIid; + } - private MergeRequest GetMergeRequest() => GetMergeRequest(_projectId, _mergeRequestIid); + private MergeRequest GetMergeRequest() => GetMergeRequest(_projectId, _mergeRequestIid); - public IEnumerable All - { - get - { - using (Context.BeginOperationScope()) - { - return GetMergeRequest().GetDiscussions().ToList(); - } - } - } - - public MergeRequestDiscussion Get(string id) + public IEnumerable All + { + get { using (Context.BeginOperationScope()) { - var discussions = GetMergeRequest().GetDiscussions(); - var discussion = discussions.FirstOrDefault(x => string.Equals(x.Id, id, StringComparison.Ordinal)); - return discussion ?? throw new GitLabNotFoundException(); + return GetMergeRequest().GetDiscussions().ToList(); } } + } - public Task GetAsync(string id, CancellationToken cancellationToken = default) + public MergeRequestDiscussion Get(string id) + { + using (Context.BeginOperationScope()) { - return Task.FromResult(Get(id)); + var discussions = GetMergeRequest().GetDiscussions(); + var discussion = discussions.FirstOrDefault(x => string.Equals(x.Id, id, StringComparison.Ordinal)); + return discussion ?? throw new GitLabNotFoundException(); } + } - public MergeRequestDiscussion Add(Models.MergeRequestComment comment) + public Task GetAsync(string id, CancellationToken cancellationToken = default) + { + return Task.FromResult(Get(id)); + } + + public MergeRequestDiscussion Add(Models.MergeRequestComment comment) + { + return Add(new MergeRequestDiscussionCreate { - return Add(new MergeRequestDiscussionCreate - { - Body = comment.Body, - CreatedAt = null, - }); - } + Body = comment.Body, + CreatedAt = null, + }); + } + + public MergeRequestDiscussion Add(MergeRequestDiscussionCreate commentCreate) + { + EnsureUserIsAuthenticated(); - public MergeRequestDiscussion Add(MergeRequestDiscussionCreate commentCreate) + using (Context.BeginOperationScope()) { - EnsureUserIsAuthenticated(); + var project = GetProject(_projectId, ProjectPermission.View); + if (project.Archived) + throw new GitLabForbiddenException(); - using (Context.BeginOperationScope()) + var comment = new MergeRequestComment { - var project = GetProject(_projectId, ProjectPermission.View); - if (project.Archived) - throw new GitLabForbiddenException(); - - var comment = new MergeRequestComment - { - Author = Context.User, - Body = commentCreate.Body, - }; + Author = Context.User, + Body = commentCreate.Body, + }; - GetMergeRequest().Comments.Add(comment); + GetMergeRequest().Comments.Add(comment); - return new MergeRequestDiscussion - { - Id = comment.ThreadId, - IndividualNote = false, - Notes = new[] { comment.ToMergeRequestCommentClient() }, - }; - } + return new MergeRequestDiscussion + { + Id = comment.ThreadId, + IndividualNote = false, + Notes = new[] { comment.ToMergeRequestCommentClient() }, + }; } + } - public MergeRequestDiscussion Resolve(MergeRequestDiscussionResolve resolve) + public MergeRequestDiscussion Resolve(MergeRequestDiscussionResolve resolve) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var discussions = GetMergeRequest().GetDiscussions(); - var discussion = discussions.FirstOrDefault(x => string.Equals(x.Id, resolve.Id, StringComparison.Ordinal)); - if (discussion == null) - throw new GitLabNotFoundException(); - - foreach (var note in discussion.Notes) - { - note.Resolved = true; - } + var discussions = GetMergeRequest().GetDiscussions(); + var discussion = discussions.FirstOrDefault(x => string.Equals(x.Id, resolve.Id, StringComparison.Ordinal)); + if (discussion == null) + throw new GitLabNotFoundException(); - return discussion; + foreach (var note in discussion.Notes) + { + note.Resolved = true; } + + return discussion; } + } - public void Delete(string discussionId, long noteId) + public void Delete(string discussionId, long noteId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var discussions = GetMergeRequest().GetDiscussions(); - var discussion = discussions.FirstOrDefault(x => string.Equals(x.Id, discussionId, StringComparison.Ordinal)); - if (discussion == null) - throw new GitLabNotFoundException(); + var discussions = GetMergeRequest().GetDiscussions(); + var discussion = discussions.FirstOrDefault(x => string.Equals(x.Id, discussionId, StringComparison.Ordinal)); + if (discussion == null) + throw new GitLabNotFoundException(); - var allComments = GetMergeRequest().Comments; - foreach (var discussionNote in discussion.Notes.Where(x => x.Id == noteId)) + var allComments = GetMergeRequest().Comments; + foreach (var discussionNote in discussion.Notes.Where(x => x.Id == noteId)) + { + var note = allComments.FirstOrDefault(x => x.Id == discussionNote.Id); + if (note != null) { - var note = allComments.FirstOrDefault(x => x.Id == discussionNote.Id); - if (note != null) - { - allComments.Remove(note); - } + allComments.Remove(note); } } } diff --git a/NGitLab.Mock/Clients/MilestoneClient.cs b/NGitLab.Mock/Clients/MilestoneClient.cs index d8b0cf04..8ada014d 100644 --- a/NGitLab.Mock/Clients/MilestoneClient.cs +++ b/NGitLab.Mock/Clients/MilestoneClient.cs @@ -6,220 +6,219 @@ using NGitLab.Mock.Clients; using NGitLab.Models; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +internal sealed class MilestoneClient : ClientBase, IMilestoneClient { - internal sealed class MilestoneClient : ClientBase, IMilestoneClient - { - private readonly int _resourceId; + private readonly int _resourceId; - public MilestoneClient(ClientContext context, IIdOrPathAddressable id, MilestoneScope scope) - : base(context) + public MilestoneClient(ClientContext context, IIdOrPathAddressable id, MilestoneScope scope) + : base(context) + { + _resourceId = scope switch { - _resourceId = scope switch - { - MilestoneScope.Groups => Server.AllGroups.FindGroup(id.ValueAsUriParameter()).Id, - MilestoneScope.Projects => Server.AllProjects.FindProject(id.ValueAsUriParameter()).Id, - _ => throw new NotSupportedException($"{scope} milestone is not supported yet."), - }; - Scope = scope; - } + MilestoneScope.Groups => Server.AllGroups.FindGroup(id.ValueAsUriParameter()).Id, + MilestoneScope.Projects => Server.AllProjects.FindProject(id.ValueAsUriParameter()).Id, + _ => throw new NotSupportedException($"{scope} milestone is not supported yet."), + }; + Scope = scope; + } - public Models.Milestone this[int id] + public Models.Milestone this[int id] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return GetMilestone(id, false).ToClientMilestone(); - } + return GetMilestone(id, false).ToClientMilestone(); } } + } - public IEnumerable All => Get(new MilestoneQuery()); + public IEnumerable All => Get(new MilestoneQuery()); - public MilestoneScope Scope { get; } + public MilestoneScope Scope { get; } - public Models.Milestone Activate(int milestoneId) + public Models.Milestone Activate(int milestoneId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var milestone = GetMilestone(milestoneId, true); - milestone.State = MilestoneState.active; - return milestone.ToClientMilestone(); - } + var milestone = GetMilestone(milestoneId, true); + milestone.State = MilestoneState.active; + return milestone.ToClientMilestone(); } + } - public IEnumerable GetMergeRequests(int milestoneId) + public IEnumerable GetMergeRequests(int milestoneId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var milestone = GetMilestone(milestoneId, false); + IEnumerable mergeRequests; + + switch (Scope) { - var milestone = GetMilestone(milestoneId, false); - IEnumerable mergeRequests; - - switch (Scope) - { - case MilestoneScope.Groups: - mergeRequests = milestone.Group.MergeRequests; - break; - case MilestoneScope.Projects: - mergeRequests = milestone.Project.MergeRequests; - break; - default: - throw new NotSupportedException($"{Scope} milestone is not supported yet."); - } - - mergeRequests = mergeRequests.Where(mr => mr.Milestone == milestone); - return mergeRequests.Select(mr => mr.ToMergeRequestClient()); + case MilestoneScope.Groups: + mergeRequests = milestone.Group.MergeRequests; + break; + case MilestoneScope.Projects: + mergeRequests = milestone.Project.MergeRequests; + break; + default: + throw new NotSupportedException($"{Scope} milestone is not supported yet."); } + + mergeRequests = mergeRequests.Where(mr => mr.Milestone == milestone); + return mergeRequests.Select(mr => mr.ToMergeRequestClient()); } + } - public IEnumerable AllInState(Models.MilestoneState state) + public IEnumerable AllInState(Models.MilestoneState state) + { + return Get(new MilestoneQuery { State = state }); + } + + public Models.Milestone Close(int milestoneId) + { + using (Context.BeginOperationScope()) { - return Get(new MilestoneQuery { State = state }); + var milestone = GetMilestone(milestoneId, true); + milestone.State = MilestoneState.closed; + return milestone.ToClientMilestone(); } + } - public Models.Milestone Close(int milestoneId) + public Models.Milestone Create(MilestoneCreate milestone) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var ms = new Milestone { - var milestone = GetMilestone(milestoneId, true); - milestone.State = MilestoneState.closed; - return milestone.ToClientMilestone(); - } - } + Title = milestone.Title, + Description = milestone.Description, + DueDate = string.IsNullOrEmpty(milestone.DueDate) ? DateTimeOffset.UtcNow : DateTimeOffset.Parse(milestone.DueDate), + StartDate = string.IsNullOrEmpty(milestone.StartDate) ? DateTimeOffset.UtcNow : DateTimeOffset.Parse(milestone.StartDate), + }; - public Models.Milestone Create(MilestoneCreate milestone) - { - using (Context.BeginOperationScope()) + switch (Scope) { - var ms = new Milestone - { - Title = milestone.Title, - Description = milestone.Description, - DueDate = string.IsNullOrEmpty(milestone.DueDate) ? DateTimeOffset.UtcNow : DateTimeOffset.Parse(milestone.DueDate), - StartDate = string.IsNullOrEmpty(milestone.StartDate) ? DateTimeOffset.UtcNow : DateTimeOffset.Parse(milestone.StartDate), - }; - - switch (Scope) - { - case MilestoneScope.Groups: - var group = GetGroup(_resourceId, GroupPermission.Edit); - group.Milestones.Add(ms); - break; - case MilestoneScope.Projects: - var project = GetProject(_resourceId, ProjectPermission.Edit); - project.Milestones.Add(ms); - break; - default: - throw new NotSupportedException($"{Scope} milestone is not supported yet."); - } - - return ms.ToClientMilestone(); + case MilestoneScope.Groups: + var group = GetGroup(_resourceId, GroupPermission.Edit); + group.Milestones.Add(ms); + break; + case MilestoneScope.Projects: + var project = GetProject(_resourceId, ProjectPermission.Edit); + project.Milestones.Add(ms); + break; + default: + throw new NotSupportedException($"{Scope} milestone is not supported yet."); } + + return ms.ToClientMilestone(); } + } - public void Delete(int milestoneId) + public void Delete(int milestoneId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var milestone = GetMilestone(milestoneId, true); + switch (Scope) { - var milestone = GetMilestone(milestoneId, true); - switch (Scope) - { - case MilestoneScope.Groups: - milestone.Group.Milestones.Remove(milestone); - break; - case MilestoneScope.Projects: - milestone.Project.Milestones.Remove(milestone); - break; - default: - throw new NotSupportedException($"{Scope} milestone is not supported yet."); - } + case MilestoneScope.Groups: + milestone.Group.Milestones.Remove(milestone); + break; + case MilestoneScope.Projects: + milestone.Project.Milestones.Remove(milestone); + break; + default: + throw new NotSupportedException($"{Scope} milestone is not supported yet."); } } + } - public IEnumerable Get(MilestoneQuery query) + public IEnumerable Get(MilestoneQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + IEnumerable milestones; + + switch (Scope) { - IEnumerable milestones; - - switch (Scope) - { - case MilestoneScope.Groups: - var group = GetGroup(_resourceId, GroupPermission.View); - milestones = group.Milestones; - break; - case MilestoneScope.Projects: - var project = GetProject(_resourceId, ProjectPermission.View); - milestones = project.Milestones; - break; - default: - throw new NotSupportedException($"{Scope} milestone is not supported yet."); - } - - if (query.State != null) - { - milestones = milestones.Where(m => (int)m.State == (int)query.State); - } - - if (!string.IsNullOrEmpty(query.Search)) - { - milestones = milestones.Where(m => m.Title.Contains(query.Search, StringComparison.OrdinalIgnoreCase)); - } - - return milestones.Select(m => m.ToClientMilestone()); + case MilestoneScope.Groups: + var group = GetGroup(_resourceId, GroupPermission.View); + milestones = group.Milestones; + break; + case MilestoneScope.Projects: + var project = GetProject(_resourceId, ProjectPermission.View); + milestones = project.Milestones; + break; + default: + throw new NotSupportedException($"{Scope} milestone is not supported yet."); } - } - public Models.Milestone Update(int milestoneId, MilestoneUpdate milestone) - { - using (Context.BeginOperationScope()) + if (query.State != null) { - var ms = GetMilestone(milestoneId, true); + milestones = milestones.Where(m => (int)m.State == (int)query.State); + } - if (!string.IsNullOrEmpty(milestone.Title)) - { - ms.Title = milestone.Title; - } + if (!string.IsNullOrEmpty(query.Search)) + { + milestones = milestones.Where(m => m.Title.Contains(query.Search, StringComparison.OrdinalIgnoreCase)); + } - if (milestone.Description != null) - { - ms.Description = milestone.Description; - } + return milestones.Select(m => m.ToClientMilestone()); + } + } - if (!string.IsNullOrEmpty(milestone.DueDate)) - { - ms.DueDate = DateTimeOffset.Parse(milestone.DueDate, CultureInfo.InvariantCulture); - } + public Models.Milestone Update(int milestoneId, MilestoneUpdate milestone) + { + using (Context.BeginOperationScope()) + { + var ms = GetMilestone(milestoneId, true); - if (!string.IsNullOrEmpty(milestone.StartDate)) - { - ms.StartDate = DateTimeOffset.Parse(milestone.StartDate, CultureInfo.InvariantCulture); - } + if (!string.IsNullOrEmpty(milestone.Title)) + { + ms.Title = milestone.Title; + } - return ms.ToClientMilestone(); + if (milestone.Description != null) + { + ms.Description = milestone.Description; } - } - private Milestone GetMilestone(int milestoneId, bool editing) - { - Milestone milestone; + if (!string.IsNullOrEmpty(milestone.DueDate)) + { + ms.DueDate = DateTimeOffset.Parse(milestone.DueDate, CultureInfo.InvariantCulture); + } - switch (Scope) + if (!string.IsNullOrEmpty(milestone.StartDate)) { - case MilestoneScope.Groups: - var group = GetGroup(_resourceId, editing ? GroupPermission.Edit : GroupPermission.View); - milestone = group.Milestones.FirstOrDefault(x => x.Id == milestoneId); - break; - case MilestoneScope.Projects: - var project = GetProject(_resourceId, editing ? ProjectPermission.Edit : ProjectPermission.View); - milestone = project.Milestones.FirstOrDefault(x => x.Id == milestoneId); - break; - default: - throw new NotSupportedException($"{Scope} milestone is not supported yet."); + ms.StartDate = DateTimeOffset.Parse(milestone.StartDate, CultureInfo.InvariantCulture); } - return milestone ?? throw new GitLabNotFoundException($"Cannot find milestone with ID {milestoneId}"); + return ms.ToClientMilestone(); + } + } + + private Milestone GetMilestone(int milestoneId, bool editing) + { + Milestone milestone; + + switch (Scope) + { + case MilestoneScope.Groups: + var group = GetGroup(_resourceId, editing ? GroupPermission.Edit : GroupPermission.View); + milestone = group.Milestones.FirstOrDefault(x => x.Id == milestoneId); + break; + case MilestoneScope.Projects: + var project = GetProject(_resourceId, editing ? ProjectPermission.Edit : ProjectPermission.View); + milestone = project.Milestones.FirstOrDefault(x => x.Id == milestoneId); + break; + default: + throw new NotSupportedException($"{Scope} milestone is not supported yet."); } + + return milestone ?? throw new GitLabNotFoundException($"Cannot find milestone with ID {milestoneId}"); } } diff --git a/NGitLab.Mock/Clients/NamespacesClient.cs b/NGitLab.Mock/Clients/NamespacesClient.cs index 307d57a3..9eac6023 100644 --- a/NGitLab.Mock/Clients/NamespacesClient.cs +++ b/NGitLab.Mock/Clients/NamespacesClient.cs @@ -2,24 +2,23 @@ using System.Collections.Generic; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class NamespacesClient : ClientBase, INamespacesClient { - internal sealed class NamespacesClient : ClientBase, INamespacesClient + public NamespacesClient(ClientContext context) + : base(context) { - public NamespacesClient(ClientContext context) - : base(context) - { - } + } - public Namespace this[int id] => throw new NotImplementedException(); + public Namespace this[int id] => throw new NotImplementedException(); - public Namespace this[string fullPath] => throw new NotImplementedException(); + public Namespace this[string fullPath] => throw new NotImplementedException(); - public IEnumerable Accessible => throw new NotImplementedException(); + public IEnumerable Accessible => throw new NotImplementedException(); - public IEnumerable Search(string search) - { - throw new NotImplementedException(); - } + public IEnumerable Search(string search) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/PipelineClient.cs b/NGitLab.Mock/Clients/PipelineClient.cs index 68a0e517..0a7cf0de 100644 --- a/NGitLab.Mock/Clients/PipelineClient.cs +++ b/NGitLab.Mock/Clients/PipelineClient.cs @@ -7,303 +7,302 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients -{ - internal sealed class PipelineClient : ClientBase, IPipelineClient - { - private readonly int _projectId; - private readonly IJobClient _jobClient; - - public PipelineClient(ClientContext context, IJobClient jobClient, ProjectId projectId) - : base(context) - { - _jobClient = jobClient; - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } - - public Models.Pipeline this[int id] - { - get - { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var pipeline = project.Pipelines.GetById(id); - if (pipeline == null) - throw new GitLabNotFoundException(); - - return pipeline.ToPipelineClient(); - } - } - } +namespace NGitLab.Mock.Clients; - public IEnumerable All - { - get - { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.Pipelines.Select(p => p.ToPipelineBasicClient()).ToList(); - } - } - } +internal sealed class PipelineClient : ClientBase, IPipelineClient +{ + private readonly int _projectId; + private readonly IJobClient _jobClient; - public IEnumerable AllJobs => _jobClient.GetJobs(JobScopeMask.All); + public PipelineClient(ClientContext context, IJobClient jobClient, ProjectId projectId) + : base(context) + { + _jobClient = jobClient; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public Models.Pipeline Create(string @ref) + public Models.Pipeline this[int id] + { + get { using (Context.BeginOperationScope()) { var project = GetProject(_projectId, ProjectPermission.View); - var pipeline = project.Pipelines.Add(@ref, JobStatus.Running, Context.User); + var pipeline = project.Pipelines.GetById(id); + if (pipeline == null) + throw new GitLabNotFoundException(); + return pipeline.ToPipelineClient(); } } + } - public Models.Pipeline Create(PipelineCreate createOptions) + public IEnumerable All + { + get { using (Context.BeginOperationScope()) { var project = GetProject(_projectId, ProjectPermission.View); - var pipeline = project.Pipelines.Add(createOptions.Ref, JobStatus.Running, Context.User); - pipeline.Variables = createOptions.Variables.Select(v => new PipelineVariable { Key = v.Key, Value = v.Value }); - return pipeline.ToPipelineClient(); + return project.Pipelines.Select(p => p.ToPipelineBasicClient()).ToList(); } } + } - public Models.Pipeline CreatePipelineWithTrigger(string token, string @ref, Dictionary variables) + public IEnumerable AllJobs => _jobClient.GetJobs(JobScopeMask.All); + + public Models.Pipeline Create(string @ref) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var pipeline = project.Pipelines.Add(@ref, JobStatus.Running, Context.User); - pipeline.Variables = variables.Select(v => new PipelineVariable { Key = v.Key, Value = v.Value }); - pipeline.CiToken = token; - return pipeline.ToPipelineClient(); - } + var project = GetProject(_projectId, ProjectPermission.View); + var pipeline = project.Pipelines.Add(@ref, JobStatus.Running, Context.User); + return pipeline.ToPipelineClient(); } + } - public void Delete(int pipelineId) + public Models.Pipeline Create(PipelineCreate createOptions) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var pipeline = project.Pipelines.GetById(pipelineId); - project.Pipelines.Remove(pipeline); - } + var project = GetProject(_projectId, ProjectPermission.View); + var pipeline = project.Pipelines.Add(createOptions.Ref, JobStatus.Running, Context.User); + pipeline.Variables = createOptions.Variables.Select(v => new PipelineVariable { Key = v.Key, Value = v.Value }); + return pipeline.ToPipelineClient(); } + } - public IEnumerable GetVariables(int pipelineId) + public Models.Pipeline CreatePipelineWithTrigger(string token, string @ref, Dictionary variables) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var pipeline = project.Pipelines.GetById(pipelineId); - return pipeline.Variables; - } + var project = GetProject(_projectId, ProjectPermission.View); + var pipeline = project.Pipelines.Add(@ref, JobStatus.Running, Context.User); + pipeline.Variables = variables.Select(v => new PipelineVariable { Key = v.Key, Value = v.Value }); + pipeline.CiToken = token; + return pipeline.ToPipelineClient(); } + } - public TestReport GetTestReports(int pipelineId) + public void Delete(int pipelineId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var pipeline = project.Pipelines.GetById(pipelineId); - return pipeline.TestReports; - } + var project = GetProject(_projectId, ProjectPermission.View); + var pipeline = project.Pipelines.GetById(pipelineId); + project.Pipelines.Remove(pipeline); } + } - public TestReportSummary GetTestReportsSummary(int pipelineId) + public IEnumerable GetVariables(int pipelineId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var pipeline = project.Pipelines.GetById(pipelineId); - return pipeline.TestReportsSummary; - } + var project = GetProject(_projectId, ProjectPermission.View); + var pipeline = project.Pipelines.GetById(pipelineId); + return pipeline.Variables; } + } - public GitLabCollectionResponse GetBridgesAsync(PipelineBridgeQuery query) + public TestReport GetTestReports(int pipelineId) + { + using (Context.BeginOperationScope()) { - return GitLabCollectionResponse.Create(GetBridges(query)); + var project = GetProject(_projectId, ProjectPermission.View); + var pipeline = project.Pipelines.GetById(pipelineId); + return pipeline.TestReports; } + } - public IEnumerable GetBridges(PipelineBridgeQuery query) + public TestReportSummary GetTestReportsSummary(int pipelineId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = Context.Server.AllProjects.FindById(_projectId); - var bridges = project.Jobs.Where(j => j.Pipeline.Id == query.PipelineId && j.DownstreamPipeline != null).Select(j => j.ToBridgeClient()); - return (query.Scope == null || !query.Scope.Any()) ? bridges : bridges.Where(j => query.Scope.Contains(j.Status.ToString(), StringComparer.Ordinal)); - } + var project = GetProject(_projectId, ProjectPermission.View); + var pipeline = project.Pipelines.GetById(pipelineId); + return pipeline.TestReportsSummary; } + } - public Models.Job[] GetJobs(int pipelineId) + public GitLabCollectionResponse GetBridgesAsync(PipelineBridgeQuery query) + { + return GitLabCollectionResponse.Create(GetBridges(query)); + } + + public IEnumerable GetBridges(PipelineBridgeQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return _jobClient.GetJobs(JobScopeMask.All).Where(p => p.Pipeline.Id == pipelineId).ToArray(); - } + var project = Context.Server.AllProjects.FindById(_projectId); + var bridges = project.Jobs.Where(j => j.Pipeline.Id == query.PipelineId && j.DownstreamPipeline != null).Select(j => j.ToBridgeClient()); + return (query.Scope == null || !query.Scope.Any()) ? bridges : bridges.Where(j => query.Scope.Contains(j.Status.ToString(), StringComparer.Ordinal)); } + } - public IEnumerable GetJobs(PipelineJobQuery query) + public Models.Job[] GetJobs(int pipelineId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var jobs = _jobClient.GetJobs(JobScopeMask.All).Where(j => j.Pipeline.Id == query.PipelineId); - return (query.Scope == null || !query.Scope.Any()) ? jobs : jobs.Where(j => query.Scope.Contains(j.Status.ToString(), StringComparer.Ordinal)); - } + return _jobClient.GetJobs(JobScopeMask.All).Where(p => p.Pipeline.Id == pipelineId).ToArray(); } + } - [Obsolete("Use JobClient.GetJobs() instead")] - public IEnumerable GetJobsInProject(JobScope scope) + public IEnumerable GetJobs(PipelineJobQuery query) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var jobs = _jobClient.GetJobs(JobScopeMask.All).Where(j => j.Pipeline.Id == query.PipelineId); + return (query.Scope == null || !query.Scope.Any()) ? jobs : jobs.Where(j => query.Scope.Contains(j.Status.ToString(), StringComparer.Ordinal)); } + } - public IEnumerable Search(PipelineQuery query) + [Obsolete("Use JobClient.GetJobs() instead")] + public IEnumerable GetJobsInProject(JobScope scope) + { + throw new NotImplementedException(); + } + + public IEnumerable Search(PipelineQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.View); + IEnumerable pipelines = project.Pipelines; + if (query.Sha != null) { - var project = GetProject(_projectId, ProjectPermission.View); - IEnumerable pipelines = project.Pipelines; - if (query.Sha != null) - { - var sha = new Sha1(query.Sha); - pipelines = pipelines.Where(pipeline => pipeline.Sha.Equals(sha)); - } + var sha = new Sha1(query.Sha); + pipelines = pipelines.Where(pipeline => pipeline.Sha.Equals(sha)); + } - if (query.Name != null) - { - pipelines = pipelines.Where(pipeline => string.Equals(pipeline.User.Name, query.Name, StringComparison.Ordinal)); - } + if (query.Name != null) + { + pipelines = pipelines.Where(pipeline => string.Equals(pipeline.User.Name, query.Name, StringComparison.Ordinal)); + } - if (query.Ref != null) - { - pipelines = pipelines.Where(pipeline => string.Equals(pipeline.Ref, query.Ref, StringComparison.Ordinal)); - } + if (query.Ref != null) + { + pipelines = pipelines.Where(pipeline => string.Equals(pipeline.Ref, query.Ref, StringComparison.Ordinal)); + } - if (query.Scope.HasValue) + if (query.Scope.HasValue) + { + if (query.Scope.Value == PipelineScope.tags) { - if (query.Scope.Value == PipelineScope.tags) - { - pipelines = pipelines.Where(p => p.Tag); - } - else if (query.Scope.Value == PipelineScope.branches) - { - pipelines = pipelines.Where(p => !p.Tag); - } - else if (query.Scope.Value == PipelineScope.running) - { - pipelines = pipelines.Where(p => p.Status == JobStatus.Running); - } - else if (query.Scope.Value == PipelineScope.pending) - { - pipelines = pipelines.Where(p => p.Status == JobStatus.Pending); - } - else if (query.Scope.Value == PipelineScope.finished) - { - pipelines = pipelines.Where(p => p.FinishedAt.HasValue); - } - else - { - throw new NotImplementedException(); - } + pipelines = pipelines.Where(p => p.Tag); } - - if (query.Status.HasValue) + else if (query.Scope.Value == PipelineScope.branches) { - pipelines = pipelines.Where(pipeline => pipeline.Status == query.Status); + pipelines = pipelines.Where(p => !p.Tag); } - - if (query.Username != null) + else if (query.Scope.Value == PipelineScope.running) { - pipelines = pipelines.Where(pipeline => string.Equals(pipeline.User.UserName, query.Username, StringComparison.Ordinal)); + pipelines = pipelines.Where(p => p.Status == JobStatus.Running); } - - if (query.YamlErrors.HasValue) + else if (query.Scope.Value == PipelineScope.pending) { - pipelines = pipelines.Where(pipeline => !string.IsNullOrEmpty(pipeline.YamlError)); + pipelines = pipelines.Where(p => p.Status == JobStatus.Pending); } - - if (query.OrderBy.HasValue) + else if (query.Scope.Value == PipelineScope.finished) { - pipelines = query.OrderBy.Value switch - { - PipelineOrderBy.id => QuerySort(pipelines, query.Sort, p => p.Id), - PipelineOrderBy.status => QuerySort(pipelines, query.Sort, p => p.Status), - PipelineOrderBy.@ref => QuerySort(pipelines, query.Sort, p => p.Ref), - PipelineOrderBy.user_id => QuerySort(pipelines, query.Sort, p => p.User.Id), - PipelineOrderBy.updated_at => QuerySort(pipelines, query.Sort, p => p.UpdatedAt), - _ => throw new NotImplementedException(), - }; + pipelines = pipelines.Where(p => p.FinishedAt.HasValue); } else { - pipelines = QuerySort(pipelines, query.Sort, p => p.UpdatedAt); + throw new NotImplementedException(); } + } - return pipelines.Where(p => !p.IsDownStreamPipeline).Select(pipeline => pipeline.ToPipelineBasicClient()).ToList(); + if (query.Status.HasValue) + { + pipelines = pipelines.Where(pipeline => pipeline.Status == query.Status); } - } - private static IEnumerable QuerySort(IEnumerable pipelines, PipelineSort? sort, Func expression) - { - if (!sort.HasValue) - sort = PipelineSort.desc; + if (query.Username != null) + { + pipelines = pipelines.Where(pipeline => string.Equals(pipeline.User.UserName, query.Username, StringComparison.Ordinal)); + } - if (sort.Value == PipelineSort.desc) - return pipelines.OrderByDescending(expression); + if (query.YamlErrors.HasValue) + { + pipelines = pipelines.Where(pipeline => !string.IsNullOrEmpty(pipeline.YamlError)); + } - return pipelines.OrderBy(expression); - } + if (query.OrderBy.HasValue) + { + pipelines = query.OrderBy.Value switch + { + PipelineOrderBy.id => QuerySort(pipelines, query.Sort, p => p.Id), + PipelineOrderBy.status => QuerySort(pipelines, query.Sort, p => p.Status), + PipelineOrderBy.@ref => QuerySort(pipelines, query.Sort, p => p.Ref), + PipelineOrderBy.user_id => QuerySort(pipelines, query.Sort, p => p.User.Id), + PipelineOrderBy.updated_at => QuerySort(pipelines, query.Sort, p => p.UpdatedAt), + _ => throw new NotImplementedException(), + }; + } + else + { + pipelines = QuerySort(pipelines, query.Sort, p => p.UpdatedAt); + } - public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return this[id]; + return pipelines.Where(p => !p.IsDownStreamPipeline).Select(pipeline => pipeline.ToPipelineBasicClient()).ToList(); } + } - public GitLabCollectionResponse GetAllJobsAsync() - { - return GitLabCollectionResponse.Create(AllJobs); - } + private static IEnumerable QuerySort(IEnumerable pipelines, PipelineSort? sort, Func expression) + { + if (!sort.HasValue) + sort = PipelineSort.desc; - public GitLabCollectionResponse GetJobsAsync(PipelineJobQuery query) - { - return GitLabCollectionResponse.Create(GetJobs(query)); - } + if (sort.Value == PipelineSort.desc) + return pipelines.OrderByDescending(expression); - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task CreateAsync(PipelineCreate createOptions, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Create(createOptions); - } + return pipelines.OrderBy(expression); + } - public GitLabCollectionResponse SearchAsync(PipelineQuery query) - { - return GitLabCollectionResponse.Create(Search(query)); - } + public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return this[id]; + } - public GitLabCollectionResponse GetVariablesAsync(int pipelineId) - { - return GitLabCollectionResponse.Create(GetVariables(pipelineId)); - } + public GitLabCollectionResponse GetAllJobsAsync() + { + return GitLabCollectionResponse.Create(AllJobs); + } + + public GitLabCollectionResponse GetJobsAsync(PipelineJobQuery query) + { + return GitLabCollectionResponse.Create(GetJobs(query)); + } + + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task CreateAsync(PipelineCreate createOptions, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Create(createOptions); + } + + public GitLabCollectionResponse SearchAsync(PipelineQuery query) + { + return GitLabCollectionResponse.Create(Search(query)); + } - public Task RetryAsync(int pipelineId, CancellationToken cancellationToken = default) + public GitLabCollectionResponse GetVariablesAsync(int pipelineId) + { + return GitLabCollectionResponse.Create(GetVariables(pipelineId)); + } + + public Task RetryAsync(int pipelineId, CancellationToken cancellationToken = default) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var jobs = _jobClient.GetJobs(JobScopeMask.Failed).Where(j => j.Pipeline.Id == pipelineId); + foreach (var job in jobs) { - var jobs = _jobClient.GetJobs(JobScopeMask.Failed).Where(j => j.Pipeline.Id == pipelineId); - foreach (var job in jobs) - { - _jobClient.RunAction(job.Id, JobAction.Retry); - } - - return Task.FromResult(this[pipelineId]); + _jobClient.RunAction(job.Id, JobAction.Retry); } + + return Task.FromResult(this[pipelineId]); } } } diff --git a/NGitLab.Mock/Clients/ProjectBadgeClient.cs b/NGitLab.Mock/Clients/ProjectBadgeClient.cs index 101a6c93..3539b575 100644 --- a/NGitLab.Mock/Clients/ProjectBadgeClient.cs +++ b/NGitLab.Mock/Clients/ProjectBadgeClient.cs @@ -3,99 +3,98 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ProjectBadgeClient : ClientBase, IProjectBadgeClient { - internal sealed class ProjectBadgeClient : ClientBase, IProjectBadgeClient - { - private readonly int _projectId; + private readonly int _projectId; - public ProjectBadgeClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public ProjectBadgeClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public Models.Badge this[int id] + public Models.Badge this[int id] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var badge = project.Badges.GetById(id); - if (badge == null) - throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in project with id '{_projectId}'"); + var project = GetProject(_projectId, ProjectPermission.View); + var badge = project.Badges.GetById(id); + if (badge == null) + throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in project with id '{_projectId}'"); - return badge.ToBadgeModel(); - } + return badge.ToBadgeModel(); } } + } - public IEnumerable All + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var groupBadges = (project.Group != null) ? GetGroup(project.Group.Id, GroupPermission.View).Badges.Select(badge => badge.ToBadgeModel()) : Array.Empty(); - return groupBadges.Union(project.Badges.Select(badge => badge.ToBadgeModel())).ToList(); - } + var project = GetProject(_projectId, ProjectPermission.View); + var groupBadges = (project.Group != null) ? GetGroup(project.Group.Id, GroupPermission.View).Badges.Select(badge => badge.ToBadgeModel()) : Array.Empty(); + return groupBadges.Union(project.Badges.Select(badge => badge.ToBadgeModel())).ToList(); } } + } - public IEnumerable ProjectsOnly + public IEnumerable ProjectsOnly + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return All.Where(badge => badge.Kind == BadgeKind.Project).ToList(); - } + return All.Where(badge => badge.Kind == BadgeKind.Project).ToList(); } } + } - public Models.Badge Create(BadgeCreate badge) - { - EnsureUserIsAuthenticated(); + public Models.Badge Create(BadgeCreate badge) + { + EnsureUserIsAuthenticated(); - using (Context.BeginOperationScope()) - { - var createdBadge = GetProject(_projectId, ProjectPermission.Edit).Badges.Add(badge.LinkUrl, badge.ImageUrl); - return createdBadge.ToBadgeModel(); - } + using (Context.BeginOperationScope()) + { + var createdBadge = GetProject(_projectId, ProjectPermission.Edit).Badges.Add(badge.LinkUrl, badge.ImageUrl); + return createdBadge.ToBadgeModel(); } + } - public void Delete(int id) - { - EnsureUserIsAuthenticated(); + public void Delete(int id) + { + EnsureUserIsAuthenticated(); - using (Context.BeginOperationScope()) + using (Context.BeginOperationScope()) + { + var badgeToRemove = GetProject(_projectId, ProjectPermission.View).Badges.FirstOrDefault(b => b.Id == id); + if (badgeToRemove == null) { - var badgeToRemove = GetProject(_projectId, ProjectPermission.View).Badges.FirstOrDefault(b => b.Id == id); - if (badgeToRemove == null) - { - throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in project with id '{_projectId}'"); - } - - GetProject(_projectId, ProjectPermission.Edit).Badges.Remove(badgeToRemove); + throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in project with id '{_projectId}'"); } + + GetProject(_projectId, ProjectPermission.Edit).Badges.Remove(badgeToRemove); } + } - public Models.Badge Update(int id, BadgeUpdate badge) + public Models.Badge Update(int id, BadgeUpdate badge) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var badgeToUpdate = GetProject(_projectId, ProjectPermission.Edit).Badges.FirstOrDefault(b => b.Id == id); + if (badgeToUpdate == null) { - var badgeToUpdate = GetProject(_projectId, ProjectPermission.Edit).Badges.FirstOrDefault(b => b.Id == id); - if (badgeToUpdate == null) - { - throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in project with id '{_projectId}'"); - } - - badgeToUpdate.LinkUrl = badge.LinkUrl; - badgeToUpdate.ImageUrl = badge.ImageUrl; - return badgeToUpdate.ToBadgeModel(); + throw new GitLabNotFoundException($"Badge with id '{id}' does not exist in project with id '{_projectId}'"); } + + badgeToUpdate.LinkUrl = badge.LinkUrl; + badgeToUpdate.ImageUrl = badge.ImageUrl; + return badgeToUpdate.ToBadgeModel(); } } } diff --git a/NGitLab.Mock/Clients/ProjectClient.cs b/NGitLab.Mock/Clients/ProjectClient.cs index 5cbcfd5c..9c4740ce 100644 --- a/NGitLab.Mock/Clients/ProjectClient.cs +++ b/NGitLab.Mock/Clients/ProjectClient.cs @@ -8,374 +8,373 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ProjectClient : ClientBase, IProjectClient { - internal sealed class ProjectClient : ClientBase, IProjectClient + public ProjectClient(ClientContext context) + : base(context) { - public ProjectClient(ClientContext context) - : base(context) - { - } + } - public Models.Project this[int id] + public Models.Project this[int id] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(id, ProjectPermission.View); - if (project == null || !project.CanUserViewProject(Context.User)) - throw new GitLabNotFoundException(); + var project = GetProject(id, ProjectPermission.View); + if (project == null || !project.CanUserViewProject(Context.User)) + throw new GitLabNotFoundException(); - return project.ToClientProject(Context.User); - } + return project.ToClientProject(Context.User); } } + } - public Models.Project this[string fullName] + public Models.Project this[string fullName] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(fullName, ProjectPermission.View); - return project.ToClientProject(Context.User); - } + var project = GetProject(fullName, ProjectPermission.View); + return project.ToClientProject(Context.User); } } + } - public IEnumerable Accessible + public IEnumerable Accessible + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Server.AllProjects.Where(project => project.IsUserMember(Context.User)).Select(project => project.ToClientProject(Context.User)).ToList(); - } + return Server.AllProjects.Where(project => project.IsUserMember(Context.User)).Select(project => project.ToClientProject(Context.User)).ToList(); } } + } - public IEnumerable Owned + public IEnumerable Owned + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Server.AllProjects.Where(project => project.IsUserOwner(Context.User)).Select(project => project.ToClientProject(Context.User)).ToList(); - } + return Server.AllProjects.Where(project => project.IsUserOwner(Context.User)).Select(project => project.ToClientProject(Context.User)).ToList(); } } + } - public IEnumerable Visible + public IEnumerable Visible + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Server.AllProjects.Where(project => project.CanUserViewProject(Context.User)).Select(project => project.ToClientProject(Context.User)).ToList(); - } + return Server.AllProjects.Where(project => project.CanUserViewProject(Context.User)).Select(project => project.ToClientProject(Context.User)).ToList(); } } + } - public Models.Project Create(ProjectCreate project) + public Models.Project Create(ProjectCreate project) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var parentGroup = GetParentGroup(project.NamespaceId); + var parentGroup = GetParentGroup(project.NamespaceId); - var newProject = new Project(project.Name) + var newProject = new Project(project.Name) + { + Description = project.Description, + Visibility = project.VisibilityLevel, + Permissions = { - Description = project.Description, - Visibility = project.VisibilityLevel, - Permissions = - { - new Permission(Context.User, AccessLevel.Owner), - }, - }; - - parentGroup.Projects.Add(newProject); - return newProject.ToClientProject(Context.User); - } + new Permission(Context.User, AccessLevel.Owner), + }, + }; + + parentGroup.Projects.Add(newProject); + return newProject.ToClientProject(Context.User); } + } - private Group GetParentGroup(string namespaceId) + private Group GetParentGroup(string namespaceId) + { + Group parentGroup; + if (namespaceId != null) { - Group parentGroup; - if (namespaceId != null) - { - parentGroup = Server.AllGroups.FindGroup(namespaceId); - if (parentGroup == null || !parentGroup.CanUserViewGroup(Context.User)) - throw new GitLabNotFoundException(); - - if (!parentGroup.CanUserAddProject(Context.User)) - throw new GitLabForbiddenException(); - } - else - { - parentGroup = Context.User.Namespace; - } + parentGroup = Server.AllGroups.FindGroup(namespaceId); + if (parentGroup == null || !parentGroup.CanUserViewGroup(Context.User)) + throw new GitLabNotFoundException(); - return parentGroup; + if (!parentGroup.CanUserAddProject(Context.User)) + throw new GitLabForbiddenException(); } - - public void Delete(int id) + else { - using (Context.BeginOperationScope()) - { - var project = GetProject(id, ProjectPermission.Delete); - project.Remove(); - } + parentGroup = Context.User.Namespace; } - public void Archive(int id) + return parentGroup; + } + + public void Delete(int id) + { + using (Context.BeginOperationScope()) { - var project = GetProject(id, ProjectPermission.Edit); - project.Archived = true; + var project = GetProject(id, ProjectPermission.Delete); + project.Remove(); } + } + + public void Archive(int id) + { + var project = GetProject(id, ProjectPermission.Edit); + project.Archived = true; + } - public void Unarchive(int id) + public void Unarchive(int id) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(id, ProjectPermission.Edit); - project.Archived = false; - } + var project = GetProject(id, ProjectPermission.Edit); + project.Archived = false; } + } - public Models.Project Fork(string id, ForkProject forkProject) - { - EnsureUserIsAuthenticated(); + public Models.Project Fork(string id, ForkProject forkProject) + { + EnsureUserIsAuthenticated(); - using (Context.BeginOperationScope()) - { - var project = GetProject(id, ProjectPermission.View); - var group = forkProject.Namespace != null ? GetParentGroup(forkProject.Namespace) : Context.User.Namespace; - var newProject = project.Fork(group, Context.User, forkProject.Name); - return newProject.ToClientProject(Context.User); - } + using (Context.BeginOperationScope()) + { + var project = GetProject(id, ProjectPermission.View); + var group = forkProject.Namespace != null ? GetParentGroup(forkProject.Namespace) : Context.User.Namespace; + var newProject = project.Fork(group, Context.User, forkProject.Name); + return newProject.ToClientProject(Context.User); } + } - public IEnumerable Get(ProjectQuery query) + public IEnumerable Get(ProjectQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + if (query.MinAccessLevel != null + || query.LastActivityAfter != null + || query.Search != null + || query.Statistics is true) { - if (query.MinAccessLevel != null - || query.LastActivityAfter != null - || query.Search != null - || query.Statistics is true) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); + } - var projects = Server.AllProjects; + var projects = Server.AllProjects; - if (query.Archived != null) - { - projects = projects.Where(p => query.Archived == p.Archived); - } + if (query.Archived != null) + { + projects = projects.Where(p => query.Archived == p.Archived); + } - if (query.Visibility != null) - { - projects = projects.Where(p => query.Visibility == p.Visibility); - } + if (query.Visibility != null) + { + projects = projects.Where(p => query.Visibility == p.Visibility); + } - switch (query.Scope) - { - case ProjectQueryScope.Accessible: - projects = projects.Where(p => p.IsUserMember(Context.User)); - break; - case ProjectQueryScope.Owned: - projects = projects.Where(p => p.IsUserOwner(Context.User)); - break; - case ProjectQueryScope.Visible: - projects = projects.Where(p => p.CanUserViewProject(Context.User)); - break; - case ProjectQueryScope.All: - break; - } + switch (query.Scope) + { + case ProjectQueryScope.Accessible: + projects = projects.Where(p => p.IsUserMember(Context.User)); + break; + case ProjectQueryScope.Owned: + projects = projects.Where(p => p.IsUserOwner(Context.User)); + break; + case ProjectQueryScope.Visible: + projects = projects.Where(p => p.CanUserViewProject(Context.User)); + break; + case ProjectQueryScope.All: + break; + } - if (query.Topics.Any()) - { - projects = projects.Where(p => query.Topics.All(t => p.Topics.Contains(t, StringComparer.Ordinal))); - } + if (query.Topics.Any()) + { + projects = projects.Where(p => query.Topics.All(t => p.Topics.Contains(t, StringComparer.Ordinal))); + } - if (query.UserId != null) - { - projects = projects.Where(p => p.IsUserOwner(Context.User)); - } + if (query.UserId != null) + { + projects = projects.Where(p => p.IsUserOwner(Context.User)); + } - if (query.OrderBy is "id") + if (query.OrderBy is "id") + { + if (query.Ascending is null or true) { - if (query.Ascending is null or true) - { - projects = projects.OrderBy(p => p.Id); - } - else - { - projects = projects.OrderByDescending(p => p.Id); - } + projects = projects.OrderBy(p => p.Id); } - else if (query.OrderBy is not null) + else { - throw new NotImplementedException(); + projects = projects.OrderByDescending(p => p.Id); } - - return projects.Select(project => project.ToClientProject(Context.User)).ToList(); } - } - - public Models.Project GetById(int id, SingleProjectQuery query) - { - using (Context.BeginOperationScope()) + else if (query.OrderBy is not null) { - return GetProject(id, ProjectPermission.View).ToClientProject(Context.User); + throw new NotImplementedException(); } - } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task GetByIdAsync(int id, SingleProjectQuery query, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return GetById(id, query); + return projects.Select(project => project.ToClientProject(Context.User)).ToList(); } + } - public async Task GetByNamespacedPathAsync(string path, SingleProjectQuery query = null, CancellationToken cancellationToken = default) + public Models.Project GetById(int id, SingleProjectQuery query) + { + using (Context.BeginOperationScope()) { - await Task.Yield(); - return this[path]; + return GetProject(id, ProjectPermission.View).ToClientProject(Context.User); } + } + + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task GetByIdAsync(int id, SingleProjectQuery query, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return GetById(id, query); + } + + public async Task GetByNamespacedPathAsync(string path, SingleProjectQuery query = null, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return this[path]; + } - public IEnumerable GetForks(string id, ForkedProjectQuery query) + public IEnumerable GetForks(string id, ForkedProjectQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + if (query.Archived != null + || query.Membership != null + || query.MinAccessLevel != null + || query.OrderBy != null + || query.PerPage != null + || query.Search != null + || query.Statistics != null + || query.Visibility != null) { - if (query.Archived != null - || query.Membership != null - || query.MinAccessLevel != null - || query.OrderBy != null - || query.PerPage != null - || query.Search != null - || query.Statistics != null - || query.Visibility != null) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); + } - var upstream = GetProject(id, ProjectPermission.View); - var matches = Server.AllProjects.Where(project => project.ForkedFrom?.Id == upstream.Id); - matches = matches.Where(project => query.Owned == null || query.Owned == project.IsUserOwner(Context.User)); + var upstream = GetProject(id, ProjectPermission.View); + var matches = Server.AllProjects.Where(project => project.ForkedFrom?.Id == upstream.Id); + matches = matches.Where(project => query.Owned == null || query.Owned == project.IsUserOwner(Context.User)); - return matches.Select(project => project.ToClientProject(Context.User)).ToList(); - } + return matches.Select(project => project.ToClientProject(Context.User)).ToList(); } + } - public Dictionary GetLanguages(string id) + public Dictionary GetLanguages(string id) + { + // Basic implementation, the results are not expected to be accurrate + using (Context.BeginOperationScope()) { - // Basic implementation, the results are not expected to be accurrate - using (Context.BeginOperationScope()) + var project = GetProject(id, ProjectPermission.View); + if (project.Repository.IsEmpty) + return new(StringComparer.Ordinal); + + project.Repository.Checkout(project.DefaultBranch); + + var gitFolder = Path.Combine(project.Repository.FullPath, ".git"); + var files = Directory.GetFiles(project.Repository.FullPath, "*", SearchOption.AllDirectories) + .Where(file => !file.StartsWith(gitFolder, StringComparison.Ordinal)) + .ToArray(); + + Dictionary result = new(StringComparer.Ordinal); + AddByExtension("C#", ".cs"); + AddByExtension("HTML", ".html", ".htm"); + AddByExtension("JavaScript", ".js", ".jsx"); + AddByExtension("PowerShell", ".ps1"); + AddByExtension("TypeScript", ".ts", ".tsx"); + return result; + + void AddByExtension(string name, params string[] expectedExtensions) { - var project = GetProject(id, ProjectPermission.View); - if (project.Repository.IsEmpty) - return new(StringComparer.Ordinal); - - project.Repository.Checkout(project.DefaultBranch); - - var gitFolder = Path.Combine(project.Repository.FullPath, ".git"); - var files = Directory.GetFiles(project.Repository.FullPath, "*", SearchOption.AllDirectories) - .Where(file => !file.StartsWith(gitFolder, StringComparison.Ordinal)) - .ToArray(); - - Dictionary result = new(StringComparer.Ordinal); - AddByExtension("C#", ".cs"); - AddByExtension("HTML", ".html", ".htm"); - AddByExtension("JavaScript", ".js", ".jsx"); - AddByExtension("PowerShell", ".ps1"); - AddByExtension("TypeScript", ".ts", ".tsx"); - return result; - - void AddByExtension(string name, params string[] expectedExtensions) + var count = files.Count(file => expectedExtensions.Any(expectedExtension => file.EndsWith(expectedExtension, StringComparison.OrdinalIgnoreCase))); + if (count > 0) { - var count = files.Count(file => expectedExtensions.Any(expectedExtension => file.EndsWith(expectedExtension, StringComparison.OrdinalIgnoreCase))); - if (count > 0) - { - result.Add(name, count / (double)files.Length); - } + result.Add(name, count / (double)files.Length); } } } + } - public Models.Project Update(string id, ProjectUpdate projectUpdate) + public Models.Project Update(string id, ProjectUpdate projectUpdate) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(id, ProjectPermission.Edit); + var project = GetProject(id, ProjectPermission.Edit); - if (projectUpdate.Name != null) - { - project.Name = projectUpdate.Name; - } + if (projectUpdate.Name != null) + { + project.Name = projectUpdate.Name; + } - if (projectUpdate.DefaultBranch != null) - { - project.DefaultBranch = projectUpdate.DefaultBranch; - } + if (projectUpdate.DefaultBranch != null) + { + project.DefaultBranch = projectUpdate.DefaultBranch; + } - if (projectUpdate.Description != null) - { - project.Description = projectUpdate.Description; - } + if (projectUpdate.Description != null) + { + project.Description = projectUpdate.Description; + } - if (projectUpdate.Visibility.HasValue) - { - project.Visibility = projectUpdate.Visibility.Value; - } + if (projectUpdate.Visibility.HasValue) + { + project.Visibility = projectUpdate.Visibility.Value; + } - if (projectUpdate.BuildTimeout.HasValue) - { - project.BuildTimeout = TimeSpan.FromMinutes(projectUpdate.BuildTimeout.Value); - } + if (projectUpdate.BuildTimeout.HasValue) + { + project.BuildTimeout = TimeSpan.FromMinutes(projectUpdate.BuildTimeout.Value); + } - if (projectUpdate.LfsEnabled.HasValue) - { - project.LfsEnabled = projectUpdate.LfsEnabled.Value; - } + if (projectUpdate.LfsEnabled.HasValue) + { + project.LfsEnabled = projectUpdate.LfsEnabled.Value; + } #pragma warning disable CS0618 // Type or member is obsolete - if (projectUpdate.TagList != null) - { - project.Topics = projectUpdate.TagList.Where(t => !string.IsNullOrEmpty(t)).Distinct(StringComparer.Ordinal).ToArray(); - } + if (projectUpdate.TagList != null) + { + project.Topics = projectUpdate.TagList.Where(t => !string.IsNullOrEmpty(t)).Distinct(StringComparer.Ordinal).ToArray(); + } #pragma warning restore CS0618 // Type or member is obsolete - if (projectUpdate.Topics is { Count: > 0 }) - { - project.Topics = projectUpdate.Topics.Where(t => !string.IsNullOrEmpty(t)).Distinct(StringComparer.Ordinal).ToArray(); - } - - return project.ToClientProject(Context.User); + if (projectUpdate.Topics is { Count: > 0 }) + { + project.Topics = projectUpdate.Topics.Where(t => !string.IsNullOrEmpty(t)).Distinct(StringComparer.Ordinal).ToArray(); } - } - public UploadedProjectFile UploadFile(string id, FormDataContent data) - { - throw new NotImplementedException(); + return project.ToClientProject(Context.User); } + } - public GitLabCollectionResponse GetAsync(ProjectQuery query) - { - return GitLabCollectionResponse.Create(Get(query)); - } + public UploadedProjectFile UploadFile(string id, FormDataContent data) + { + throw new NotImplementedException(); + } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task ForkAsync(string id, ForkProject forkProject, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Fork(id, forkProject); - } + public GitLabCollectionResponse GetAsync(ProjectQuery query) + { + return GitLabCollectionResponse.Create(Get(query)); + } - public GitLabCollectionResponse GetForksAsync(string id, ForkedProjectQuery query) - { - return GitLabCollectionResponse.Create(GetForks(id, query)); - } + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task ForkAsync(string id, ForkProject forkProject, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Fork(id, forkProject); + } + + public GitLabCollectionResponse GetForksAsync(string id, ForkedProjectQuery query) + { + return GitLabCollectionResponse.Create(GetForks(id, query)); } } diff --git a/NGitLab.Mock/Clients/ProjectHooksClient.cs b/NGitLab.Mock/Clients/ProjectHooksClient.cs index 7d2cb0c2..a7b730d8 100644 --- a/NGitLab.Mock/Clients/ProjectHooksClient.cs +++ b/NGitLab.Mock/Clients/ProjectHooksClient.cs @@ -2,105 +2,104 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ProjectHooksClient : ClientBase, IProjectHooksClient { - internal sealed class ProjectHooksClient : ClientBase, IProjectHooksClient - { - public int ProjectId { get; } + public int ProjectId { get; } - public ProjectHooksClient(ClientContext context, int projectId) - : base(context) - { - ProjectId = projectId; - } + public ProjectHooksClient(ClientContext context, int projectId) + : base(context) + { + ProjectId = projectId; + } - public IEnumerable All + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var hooks = GetProject(ProjectId, ProjectPermission.Edit).Hooks; - return ToClientProjectHooks(hooks).ToList(); - } + var hooks = GetProject(ProjectId, ProjectPermission.Edit).Hooks; + return ToClientProjectHooks(hooks).ToList(); } } + } - public Models.ProjectHook this[int hookId] + public Models.ProjectHook this[int hookId] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var hook = All.FirstOrDefault(h => h.Id == hookId) ?? throw new GitLabNotFoundException(); - return hook; - } + var hook = All.FirstOrDefault(h => h.Id == hookId) ?? throw new GitLabNotFoundException(); + return hook; } } + } - public Models.ProjectHook Create(ProjectHookUpsert hook) + public Models.ProjectHook Create(ProjectHookUpsert hook) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var projectHook = UpsertToHook(hook); + var projectHook = UpsertToHook(hook); - GetProject(ProjectId, ProjectPermission.Edit).Hooks.Add(projectHook); - return projectHook.ToClientProjectHook(); - } + GetProject(ProjectId, ProjectPermission.Edit).Hooks.Add(projectHook); + return projectHook.ToClientProjectHook(); } + } - public Models.ProjectHook Update(int hookId, ProjectHookUpsert hook) + public Models.ProjectHook Update(int hookId, ProjectHookUpsert hook) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var currentHook = GetProject(ProjectId, ProjectPermission.Edit).Hooks.FirstOrDefault(h => h.Id == hookId) ?? throw new GitLabNotFoundException(); + var currentHook = GetProject(ProjectId, ProjectPermission.Edit).Hooks.FirstOrDefault(h => h.Id == hookId) ?? throw new GitLabNotFoundException(); - currentHook.Url = hook.Url; - currentHook.PushEvents = hook.PushEvents; - currentHook.MergeRequestsEvents = hook.MergeRequestsEvents; - currentHook.IssuesEvents = hook.IssuesEvents; - currentHook.TagPushEvents = hook.TagPushEvents; - currentHook.NoteEvents = hook.NoteEvents; - currentHook.JobEvents = hook.JobEvents; - currentHook.PipelineEvents = hook.PipelineEvents; - currentHook.EnableSslVerification = hook.EnableSslVerification; + currentHook.Url = hook.Url; + currentHook.PushEvents = hook.PushEvents; + currentHook.MergeRequestsEvents = hook.MergeRequestsEvents; + currentHook.IssuesEvents = hook.IssuesEvents; + currentHook.TagPushEvents = hook.TagPushEvents; + currentHook.NoteEvents = hook.NoteEvents; + currentHook.JobEvents = hook.JobEvents; + currentHook.PipelineEvents = hook.PipelineEvents; + currentHook.EnableSslVerification = hook.EnableSslVerification; - return currentHook.ToClientProjectHook(); - } + return currentHook.ToClientProjectHook(); } + } - public void Delete(int hookId) + public void Delete(int hookId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var projectHooks = GetProject(ProjectId, ProjectPermission.Edit).Hooks; - var hook = projectHooks.FirstOrDefault(h => h.Id == hookId) ?? throw new GitLabNotFoundException(); + var projectHooks = GetProject(ProjectId, ProjectPermission.Edit).Hooks; + var hook = projectHooks.FirstOrDefault(h => h.Id == hookId) ?? throw new GitLabNotFoundException(); - projectHooks.Remove(hook); - } + projectHooks.Remove(hook); } + } - private static IEnumerable ToClientProjectHooks(IEnumerable hooks) - { - return hooks.Select(hook => hook.ToClientProjectHook()); - } + private static IEnumerable ToClientProjectHooks(IEnumerable hooks) + { + return hooks.Select(hook => hook.ToClientProjectHook()); + } - private static ProjectHook UpsertToHook(ProjectHookUpsert hook) + private static ProjectHook UpsertToHook(ProjectHookUpsert hook) + { + var hookFromUpsert = new ProjectHook { - var hookFromUpsert = new ProjectHook - { - Url = hook.Url, - PushEvents = hook.PushEvents, - MergeRequestsEvents = hook.MergeRequestsEvents, - IssuesEvents = hook.IssuesEvents, - TagPushEvents = hook.TagPushEvents, - NoteEvents = hook.NoteEvents, - JobEvents = hook.JobEvents, - PipelineEvents = hook.PipelineEvents, - EnableSslVerification = hook.EnableSslVerification, - }; + Url = hook.Url, + PushEvents = hook.PushEvents, + MergeRequestsEvents = hook.MergeRequestsEvents, + IssuesEvents = hook.IssuesEvents, + TagPushEvents = hook.TagPushEvents, + NoteEvents = hook.NoteEvents, + JobEvents = hook.JobEvents, + PipelineEvents = hook.PipelineEvents, + EnableSslVerification = hook.EnableSslVerification, + }; - return hookFromUpsert; - } + return hookFromUpsert; } } diff --git a/NGitLab.Mock/Clients/ProjectIssueNoteClient.cs b/NGitLab.Mock/Clients/ProjectIssueNoteClient.cs index dd9e7a57..847a040a 100644 --- a/NGitLab.Mock/Clients/ProjectIssueNoteClient.cs +++ b/NGitLab.Mock/Clients/ProjectIssueNoteClient.cs @@ -2,88 +2,87 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ProjectIssueNoteClient : ClientBase, IProjectIssueNoteClient { - internal sealed class ProjectIssueNoteClient : ClientBase, IProjectIssueNoteClient + private readonly int _projectId; + + public ProjectIssueNoteClient(ClientContext context, ProjectId projectId) + : base(context) { - private readonly int _projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public ProjectIssueNoteClient(ClientContext context, ProjectId projectId) - : base(context) + public Models.ProjectIssueNote Create(ProjectIssueNoteCreate create) + { + using (Context.BeginOperationScope()) { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + var issue = GetIssue(create.IssueId); - public Models.ProjectIssueNote Create(ProjectIssueNoteCreate create) - { - using (Context.BeginOperationScope()) + var projectIssueNote = new ProjectIssueNote { - var issue = GetIssue(create.IssueId); - - var projectIssueNote = new ProjectIssueNote - { - Body = create.Body, - Confidential = create.Confidential, - Author = Context.User, - }; - issue.Notes.Add(projectIssueNote); - - return projectIssueNote.ToProjectIssueNote(); - } + Body = create.Body, + Confidential = create.Confidential, + Author = Context.User, + }; + issue.Notes.Add(projectIssueNote); + + return projectIssueNote.ToProjectIssueNote(); } + } - public Models.ProjectIssueNote Edit(ProjectIssueNoteEdit edit) + public Models.ProjectIssueNote Edit(ProjectIssueNoteEdit edit) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var note = GetIssueNote(edit.IssueId, edit.NoteId); + var note = GetIssueNote(edit.IssueId, edit.NoteId); - note.Body = edit.Body; + note.Body = edit.Body; - return note.ToProjectIssueNote(); - } + return note.ToProjectIssueNote(); } + } - public IEnumerable ForIssue(int issueIid) + public IEnumerable ForIssue(int issueIid) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return GetIssue(issueIid).Notes.Select(n => n.ToProjectIssueNote()); - } + return GetIssue(issueIid).Notes.Select(n => n.ToProjectIssueNote()); } + } - public Models.ProjectIssueNote Get(int issueIid, int noteId) + public Models.ProjectIssueNote Get(int issueIid, int noteId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return GetIssueNote(issueIid, noteId).ToProjectIssueNote(); - } + return GetIssueNote(issueIid, noteId).ToProjectIssueNote(); } + } - private Issue GetIssue(int issueIid) - { - var project = GetProject(_projectId, ProjectPermission.View); - var issue = project.Issues.FirstOrDefault(iss => iss.Iid == issueIid); - - if (issue == null) - { - throw new GitLabNotFoundException("Issue does not exist."); - } + private Issue GetIssue(int issueIid) + { + var project = GetProject(_projectId, ProjectPermission.View); + var issue = project.Issues.FirstOrDefault(iss => iss.Iid == issueIid); - return issue; + if (issue == null) + { + throw new GitLabNotFoundException("Issue does not exist."); } - private ProjectIssueNote GetIssueNote(int issueIid, int issueNoteId) - { - var issue = GetIssue(issueIid); - var note = issue.Notes.FirstOrDefault(n => n.Id == issueNoteId); + return issue; + } - if (note == null) - { - throw new GitLabNotFoundException("Issue Note does not exist."); - } + private ProjectIssueNote GetIssueNote(int issueIid, int issueNoteId) + { + var issue = GetIssue(issueIid); + var note = issue.Notes.FirstOrDefault(n => n.Id == issueNoteId); - return note; + if (note == null) + { + throw new GitLabNotFoundException("Issue Note does not exist."); } + + return note; } } diff --git a/NGitLab.Mock/Clients/ProjectLevelApprovalRulesClient.cs b/NGitLab.Mock/Clients/ProjectLevelApprovalRulesClient.cs index c8b50c6a..b9c9841f 100644 --- a/NGitLab.Mock/Clients/ProjectLevelApprovalRulesClient.cs +++ b/NGitLab.Mock/Clients/ProjectLevelApprovalRulesClient.cs @@ -2,36 +2,35 @@ using System.Collections.Generic; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ProjectLevelApprovalRulesClient : ClientBase, IProjectLevelApprovalRulesClient { - internal sealed class ProjectLevelApprovalRulesClient : ClientBase, IProjectLevelApprovalRulesClient - { - private readonly int _projectId; + private readonly int _projectId; - public ProjectLevelApprovalRulesClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public ProjectLevelApprovalRulesClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public List GetProjectLevelApprovalRules() - { - throw new NotImplementedException(); - } + public List GetProjectLevelApprovalRules() + { + throw new NotImplementedException(); + } - public ApprovalRule UpdateProjectLevelApprovalRule(int approvalRuleIdToUpdate, ApprovalRuleUpdate approvalRuleUpdate) - { - throw new NotImplementedException(); - } + public ApprovalRule UpdateProjectLevelApprovalRule(int approvalRuleIdToUpdate, ApprovalRuleUpdate approvalRuleUpdate) + { + throw new NotImplementedException(); + } - public ApprovalRule CreateProjectLevelRule(ApprovalRuleCreate approvalRuleCreate) - { - throw new NotImplementedException(); - } + public ApprovalRule CreateProjectLevelRule(ApprovalRuleCreate approvalRuleCreate) + { + throw new NotImplementedException(); + } - public void DeleteProjectLevelRule(int approvalRuleIdToDelete) - { - throw new NotImplementedException(); - } + public void DeleteProjectLevelRule(int approvalRuleIdToDelete) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/ProjectSearchClient.cs b/NGitLab.Mock/Clients/ProjectSearchClient.cs index 8eea7e93..9066f60f 100644 --- a/NGitLab.Mock/Clients/ProjectSearchClient.cs +++ b/NGitLab.Mock/Clients/ProjectSearchClient.cs @@ -1,23 +1,22 @@ using System; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ProjectSearchClient : ClientBase, ISearchClient { - internal sealed class ProjectSearchClient : ClientBase, ISearchClient - { - private readonly ClientContext _context; - private readonly int _projectId; + private readonly ClientContext _context; + private readonly int _projectId; - public ProjectSearchClient(ClientContext context, ProjectId projectId) - : base(context) - { - _context = context; - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public ProjectSearchClient(ClientContext context, ProjectId projectId) + : base(context) + { + _context = context; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public GitLabCollectionResponse GetBlobsAsync(SearchQuery query) - { - throw new NotImplementedException(); - } + public GitLabCollectionResponse GetBlobsAsync(SearchQuery query) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/ProjectVariableClient.cs b/NGitLab.Mock/Clients/ProjectVariableClient.cs index 082f6432..5d66d1d2 100644 --- a/NGitLab.Mock/Clients/ProjectVariableClient.cs +++ b/NGitLab.Mock/Clients/ProjectVariableClient.cs @@ -2,35 +2,34 @@ using System.Collections.Generic; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ProjectVariableClient : ClientBase, IProjectVariableClient { - internal sealed class ProjectVariableClient : ClientBase, IProjectVariableClient - { - private readonly int _projectId; + private readonly int _projectId; - public ProjectVariableClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public ProjectVariableClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public Variable this[string key] => throw new NotImplementedException(); + public Variable this[string key] => throw new NotImplementedException(); - public IEnumerable All => throw new NotImplementedException(); + public IEnumerable All => throw new NotImplementedException(); - public Variable Create(VariableCreate model) - { - throw new NotImplementedException(); - } + public Variable Create(VariableCreate model) + { + throw new NotImplementedException(); + } - public void Delete(string key) - { - throw new NotImplementedException(); - } + public void Delete(string key) + { + throw new NotImplementedException(); + } - public Variable Update(string key, VariableUpdate model) - { - throw new NotImplementedException(); - } + public Variable Update(string key, VariableUpdate model) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/ProtectedBranchClient.cs b/NGitLab.Mock/Clients/ProtectedBranchClient.cs index 66d4761f..93d46482 100644 --- a/NGitLab.Mock/Clients/ProtectedBranchClient.cs +++ b/NGitLab.Mock/Clients/ProtectedBranchClient.cs @@ -2,69 +2,68 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ProtectedBranchClient : ClientBase, IProtectedBranchClient { - internal sealed class ProtectedBranchClient : ClientBase, IProtectedBranchClient + private readonly int _projectId; + + public ProtectedBranchClient(ClientContext context, ProjectId projectId) + : base(context) { - private readonly int _projectId; + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public ProtectedBranchClient(ClientContext context, ProjectId projectId) - : base(context) + public Models.ProtectedBranch GetProtectedBranch(string branchName) + { + using (Context.BeginOperationScope()) { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + var project = GetProject(_projectId, ProjectPermission.Edit); + return project.ProtectedBranches.First(b => b.Name.Equals(branchName, StringComparison.Ordinal)).ToProtectedBranchClient(); } + } - public Models.ProtectedBranch GetProtectedBranch(string branchName) + public Models.ProtectedBranch[] GetProtectedBranches(string search = null) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Edit); - return project.ProtectedBranches.First(b => b.Name.Equals(branchName, StringComparison.Ordinal)).ToProtectedBranchClient(); - } + var project = GetProject(_projectId, ProjectPermission.Edit); + return project.ProtectedBranches + .Where(b => b.Name.Contains(search ?? "", StringComparison.Ordinal)) + .Select(b => b.ToProtectedBranchClient()) + .ToArray(); } + } - public Models.ProtectedBranch[] GetProtectedBranches(string search = null) + public Models.ProtectedBranch ProtectBranch(BranchProtect branchProtect) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.Edit); + var protectedBranch = project.ProtectedBranches.FirstOrDefault(b => b.Name.Equals(branchProtect.BranchName, StringComparison.Ordinal)); + if (protectedBranch == null) { - var project = GetProject(_projectId, ProjectPermission.Edit); - return project.ProtectedBranches - .Where(b => b.Name.Contains(search ?? "", StringComparison.Ordinal)) - .Select(b => b.ToProtectedBranchClient()) - .ToArray(); + protectedBranch = new(); + project.ProtectedBranches.Add(protectedBranch); } - } - - public Models.ProtectedBranch ProtectBranch(BranchProtect branchProtect) - { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Edit); - var protectedBranch = project.ProtectedBranches.FirstOrDefault(b => b.Name.Equals(branchProtect.BranchName, StringComparison.Ordinal)); - if (protectedBranch == null) - { - protectedBranch = new(); - project.ProtectedBranches.Add(protectedBranch); - } - protectedBranch.Name = branchProtect.BranchName; - protectedBranch.AllowForcePush = branchProtect.AllowForcePush; - protectedBranch.CodeOwnerApprovalRequired = branchProtect.CodeOwnerApprovalRequired; + protectedBranch.Name = branchProtect.BranchName; + protectedBranch.AllowForcePush = branchProtect.AllowForcePush; + protectedBranch.CodeOwnerApprovalRequired = branchProtect.CodeOwnerApprovalRequired; - return protectedBranch.ToProtectedBranchClient(); - } + return protectedBranch.ToProtectedBranchClient(); } + } - public void UnprotectBranch(string branchName) + public void UnprotectBranch(string branchName) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.Edit); + var protectedBranch = project.ProtectedBranches.FirstOrDefault(b => b.Name.Equals(branchName, StringComparison.Ordinal)); + if (protectedBranch != null) { - var project = GetProject(_projectId, ProjectPermission.Edit); - var protectedBranch = project.ProtectedBranches.FirstOrDefault(b => b.Name.Equals(branchName, StringComparison.Ordinal)); - if (protectedBranch != null) - { - project.ProtectedBranches.Remove(protectedBranch); - } + project.ProtectedBranches.Remove(protectedBranch); } } } diff --git a/NGitLab.Mock/Clients/ReleaseClient.cs b/NGitLab.Mock/Clients/ReleaseClient.cs index c26595f3..7b585257 100644 --- a/NGitLab.Mock/Clients/ReleaseClient.cs +++ b/NGitLab.Mock/Clients/ReleaseClient.cs @@ -7,137 +7,136 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ReleaseClient : ClientBase, IReleaseClient { - internal sealed class ReleaseClient : ClientBase, IReleaseClient - { - private readonly int _projectId; + private readonly int _projectId; - public ReleaseClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public ReleaseClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public IEnumerable All + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.Releases.Select(r => r.ToReleaseClient()); - } + var project = GetProject(_projectId, ProjectPermission.View); + return project.Releases.Select(r => r.ToReleaseClient()); } } + } - public Models.ReleaseInfo this[string tagName] + public Models.ReleaseInfo this[string tagName] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var release = project.Releases.FirstOrDefault(r => r.TagName.Equals(tagName, StringComparison.Ordinal)); + var project = GetProject(_projectId, ProjectPermission.View); + var release = project.Releases.FirstOrDefault(r => r.TagName.Equals(tagName, StringComparison.Ordinal)); - return release.ToReleaseClient(); - } + return release.ToReleaseClient(); } } + } - public Models.ReleaseInfo Create(ReleaseCreate data) + public Models.ReleaseInfo Create(ReleaseCreate data) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var release = project.Releases.Add(data.TagName, data.Name, data.Ref, data.Description, Context.User); - return release.ToReleaseClient(); - } + var project = GetProject(_projectId, ProjectPermission.Contribute); + var release = project.Releases.Add(data.TagName, data.Name, data.Ref, data.Description, Context.User); + return release.ToReleaseClient(); } + } - public Models.ReleaseInfo Update(ReleaseUpdate data) + public Models.ReleaseInfo Update(ReleaseUpdate data) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.Contribute); + var release = project.Releases.GetByTagName(data.TagName); + if (release == null) { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var release = project.Releases.GetByTagName(data.TagName); - if (release == null) - { - throw new GitLabNotFoundException(); - } - - if (data.Name != null) - { - release.Name = data.Name; - } - - if (data.Description != null) - { - release.Description = data.Description; - } - - if (data.ReleasedAt.HasValue) - { - release.ReleasedAt = data.ReleasedAt.Value; - } + throw new GitLabNotFoundException(); + } - return release.ToReleaseClient(); + if (data.Name != null) + { + release.Name = data.Name; } - } - public void Delete(string tagName) - { - using (Context.BeginOperationScope()) + if (data.Description != null) { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var release = project.Releases.FirstOrDefault(r => r.TagName.Equals(tagName, StringComparison.Ordinal)); - if (release == null) - throw new GitLabNotFoundException(); + release.Description = data.Description; + } - project.Releases.Remove(release); + if (data.ReleasedAt.HasValue) + { + release.ReleasedAt = data.ReleasedAt.Value; } - } - public IReleaseLinkClient ReleaseLinks(string tagName) - { - throw new NotImplementedException(); + return release.ToReleaseClient(); } + } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task CreateAsync(ReleaseCreate data, CancellationToken cancellationToken = default) + public void Delete(string tagName) + { + using (Context.BeginOperationScope()) { - await Task.Yield(); - return Create(data); + var project = GetProject(_projectId, ProjectPermission.Contribute); + var release = project.Releases.FirstOrDefault(r => r.TagName.Equals(tagName, StringComparison.Ordinal)); + if (release == null) + throw new GitLabNotFoundException(); + + project.Releases.Remove(release); } + } + + public IReleaseLinkClient ReleaseLinks(string tagName) + { + throw new NotImplementedException(); + } + + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task CreateAsync(ReleaseCreate data, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Create(data); + } - public GitLabCollectionResponse GetAsync(ReleaseQuery query = null) + public GitLabCollectionResponse GetAsync(ReleaseQuery query = null) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(_projectId, ProjectPermission.View); + var result = project.Releases.AsEnumerable(); + if (query != null) { - var project = GetProject(_projectId, ProjectPermission.View); - var result = project.Releases.AsEnumerable(); - if (query != null) + var orderBy = !string.IsNullOrEmpty(query.OrderBy) && string.Equals(query.OrderBy, "created_at", StringComparison.Ordinal) + ? new Func(r => r.CreatedAt) + : new Func(r => r.ReleasedAt); + + var sortAsc = !string.IsNullOrEmpty(query.Sort) && string.Equals(query.Sort, "asc", StringComparison.Ordinal); + result = sortAsc ? result.OrderBy(orderBy) : result.OrderByDescending(orderBy); + + if (query.Page.HasValue) { - var orderBy = !string.IsNullOrEmpty(query.OrderBy) && string.Equals(query.OrderBy, "created_at", StringComparison.Ordinal) - ? new Func(r => r.CreatedAt) - : new Func(r => r.ReleasedAt); - - var sortAsc = !string.IsNullOrEmpty(query.Sort) && string.Equals(query.Sort, "asc", StringComparison.Ordinal); - result = sortAsc ? result.OrderBy(orderBy) : result.OrderByDescending(orderBy); - - if (query.Page.HasValue) - { - var perPage = query.PerPage ?? 20; - var page = Math.Max(0, query.Page.Value - 1); - result = result.Skip(perPage * page); - } - - if (query.IncludeHtmlDescription == true) - throw new NotImplementedException(); + var perPage = query.PerPage ?? 20; + var page = Math.Max(0, query.Page.Value - 1); + result = result.Skip(perPage * page); } - return GitLabCollectionResponse.Create(result.Select(r => r.ToReleaseClient()).ToArray()); + if (query.IncludeHtmlDescription == true) + throw new NotImplementedException(); } + + return GitLabCollectionResponse.Create(result.Select(r => r.ToReleaseClient()).ToArray()); } } } diff --git a/NGitLab.Mock/Clients/ReleaseLinkClient.cs b/NGitLab.Mock/Clients/ReleaseLinkClient.cs index 6f89286b..469ff781 100644 --- a/NGitLab.Mock/Clients/ReleaseLinkClient.cs +++ b/NGitLab.Mock/Clients/ReleaseLinkClient.cs @@ -2,37 +2,36 @@ using System.Collections.Generic; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class ReleaseLinkClient : ClientBase, IReleaseLinkClient { - internal sealed class ReleaseLinkClient : ClientBase, IReleaseLinkClient + private readonly int _projectId; + private readonly string _tagName; + + public ReleaseLinkClient(ClientContext context, int projectId, string tagName) + : base(context) + { + _projectId = projectId; + _tagName = tagName; + } + + public ReleaseLink this[int id] => throw new NotImplementedException(); + + public IEnumerable All => throw new NotImplementedException(); + + public ReleaseLink Create(ReleaseLinkCreate data) + { + throw new NotImplementedException(); + } + + public void Delete(int id) + { + throw new NotImplementedException(); + } + + public ReleaseLink Update(int id, ReleaseLinkUpdate data) { - private readonly int _projectId; - private readonly string _tagName; - - public ReleaseLinkClient(ClientContext context, int projectId, string tagName) - : base(context) - { - _projectId = projectId; - _tagName = tagName; - } - - public ReleaseLink this[int id] => throw new NotImplementedException(); - - public IEnumerable All => throw new NotImplementedException(); - - public ReleaseLink Create(ReleaseLinkCreate data) - { - throw new NotImplementedException(); - } - - public void Delete(int id) - { - throw new NotImplementedException(); - } - - public ReleaseLink Update(int id, ReleaseLinkUpdate data) - { - throw new NotImplementedException(); - } + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/RepositoryClient.cs b/NGitLab.Mock/Clients/RepositoryClient.cs index 4eb0fe57..d0ecef6f 100644 --- a/NGitLab.Mock/Clients/RepositoryClient.cs +++ b/NGitLab.Mock/Clients/RepositoryClient.cs @@ -5,127 +5,126 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class RepositoryClient : ClientBase, IRepositoryClient { - internal sealed class RepositoryClient : ClientBase, IRepositoryClient - { - private readonly int _projectId; + private readonly int _projectId; - public RepositoryClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public RepositoryClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public ITagClient Tags => new TagClient(Context, _projectId); + public ITagClient Tags => new TagClient(Context, _projectId); - public IFilesClient Files => new FileClient(Context, _projectId); + public IFilesClient Files => new FileClient(Context, _projectId); - public IBranchClient Branches => new BranchClient(Context, _projectId); + public IBranchClient Branches => new BranchClient(Context, _projectId); - public IProjectHooksClient ProjectHooks => new ProjectHooksClient(Context, _projectId); + public IProjectHooksClient ProjectHooks => new ProjectHooksClient(Context, _projectId); - public IContributorClient Contributors => new ContributorClient(Context, _projectId); + public IContributorClient Contributors => new ContributorClient(Context, _projectId); - public IEnumerable Tree + public IEnumerable Tree + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.Repository.GetTree().ToList(); - } + var project = GetProject(_projectId, ProjectPermission.View); + return project.Repository.GetTree().ToList(); } } + } - public IEnumerable Commits + public IEnumerable Commits + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.Repository.GetCommits().Select(commit => ConvertToNGitLabCommit(commit, project)).ToList(); - } + var project = GetProject(_projectId, ProjectPermission.View); + return project.Repository.GetCommits().Select(commit => ConvertToNGitLabCommit(commit, project)).ToList(); } } + } - public IEnumerable GetTree(string path) - { - throw new NotImplementedException(); - } + public IEnumerable GetTree(string path) + { + throw new NotImplementedException(); + } - public IEnumerable GetTree(string path, string @ref, bool recursive) - { - throw new NotImplementedException(); - } + public IEnumerable GetTree(string path, string @ref, bool recursive) + { + throw new NotImplementedException(); + } - public GitLabCollectionResponse GetTreeAsync(RepositoryGetTreeOptions options) - { - return GitLabCollectionResponse.Create(GetTree(options)); - } + public GitLabCollectionResponse GetTreeAsync(RepositoryGetTreeOptions options) + { + return GitLabCollectionResponse.Create(GetTree(options)); + } - public IEnumerable GetTree(RepositoryGetTreeOptions options) + public IEnumerable GetTree(RepositoryGetTreeOptions options) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.Repository.GetTree(options).ToList(); - } + var project = GetProject(_projectId, ProjectPermission.View); + return project.Repository.GetTree(options).ToList(); } + } - public void GetRawBlob(string sha, Action parser) - { - throw new NotImplementedException(); - } + public void GetRawBlob(string sha, Action parser) + { + throw new NotImplementedException(); + } - public void GetArchive(Action parser) - { - throw new NotImplementedException(); - } + public void GetArchive(Action parser) + { + throw new NotImplementedException(); + } - public IEnumerable GetCommits(string refName, int maxResults = 0) + public IEnumerable GetCommits(string refName, int maxResults = 0) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.Repository.GetCommits(refName).Select(commit => ConvertToNGitLabCommit(commit, project)).ToList(); - } + var project = GetProject(_projectId, ProjectPermission.View); + return project.Repository.GetCommits(refName).Select(commit => ConvertToNGitLabCommit(commit, project)).ToList(); } + } - public IEnumerable GetCommits(GetCommitsRequest request) + public IEnumerable GetCommits(GetCommitsRequest request) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - return project.Repository.GetCommits(request).Select(commit => ConvertToNGitLabCommit(commit, project)).ToList(); - } + var project = GetProject(_projectId, ProjectPermission.View); + return project.Repository.GetCommits(request).Select(commit => ConvertToNGitLabCommit(commit, project)).ToList(); } + } - public Commit GetCommit(Sha1 sha) - { - throw new NotImplementedException(); - } + public Commit GetCommit(Sha1 sha) + { + throw new NotImplementedException(); + } - public IEnumerable GetCommitDiff(Sha1 sha) - { - throw new NotImplementedException(); - } + public IEnumerable GetCommitDiff(Sha1 sha) + { + throw new NotImplementedException(); + } - public IEnumerable GetCommitRefs(Sha1 sha, CommitRefType type = CommitRefType.All) - { - throw new NotImplementedException(); - } + public IEnumerable GetCommitRefs(Sha1 sha, CommitRefType type = CommitRefType.All) + { + throw new NotImplementedException(); + } - private static Commit ConvertToNGitLabCommit(LibGit2Sharp.Commit commit, Project project) - { - return commit.ToCommitClient(project); - } + private static Commit ConvertToNGitLabCommit(LibGit2Sharp.Commit commit, Project project) + { + return commit.ToCommitClient(project); + } - public CompareResults Compare(CompareQuery query) - { - throw new NotImplementedException(); - } + public CompareResults Compare(CompareQuery query) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/RunnerClient.cs b/NGitLab.Mock/Clients/RunnerClient.cs index d5a38cad..d1906e38 100644 --- a/NGitLab.Mock/Clients/RunnerClient.cs +++ b/NGitLab.Mock/Clients/RunnerClient.cs @@ -7,193 +7,192 @@ using NGitLab.Mock.Internals; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class RunnerClient : ClientBase, IRunnerClient { - internal sealed class RunnerClient : ClientBase, IRunnerClient + public IEnumerable Accessible { - public IEnumerable Accessible + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return GetOwnedRunners().Select(r => r.ToClientRunner(Context.User)); - } + return GetOwnedRunners().Select(r => r.ToClientRunner(Context.User)); } } + } - public IEnumerable All + public IEnumerable All + { + get { - get + if (!Context.User.IsAdmin) { - if (!Context.User.IsAdmin) - { - throw new GitLabForbiddenException(); - } - - using (Context.BeginOperationScope()) - { - var runners = Server.AllProjects.SelectMany(p => p.RegisteredRunners); - var clientRunners = runners.Select(r => r.ToClientRunner(Context.User)).ToList(); - return clientRunners; - } + throw new GitLabForbiddenException(); } - } - public RunnerClient(ClientContext context) - : base(context) - { - } - - public Models.Runner this[int id] - { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var runner = Accessible.FirstOrDefault(r => r.Id == id) ?? throw new GitLabNotFoundException(); - return runner; - } + var runners = Server.AllProjects.SelectMany(p => p.RegisteredRunners); + var clientRunners = runners.Select(r => r.ToClientRunner(Context.User)).ToList(); + return clientRunners; } } + } - public void Delete(Models.Runner runner) => Delete(runner.Id); + public RunnerClient(ClientContext context) + : base(context) + { + } - public void Delete(int runnerId) + public Models.Runner this[int id] + { + get { using (Context.BeginOperationScope()) { - var projects = Server.AllProjects.Where(p => p.EnabledRunners.Any(r => r.Id == runnerId)); - if (!projects.Any()) - { - throw new GitLabBadRequestException("Runner is not found in any project"); - } - - if (projects.Skip(1).Any()) - { - throw new GitLabBadRequestException("Runner is enabled in multiple projects"); - } - - var project = GetProject(projects.Single().Id, ProjectPermission.Edit); - project.RemoveRunner(runnerId); + var runner = Accessible.FirstOrDefault(r => r.Id == id) ?? throw new GitLabNotFoundException(); + return runner; } } + } + + public void Delete(Models.Runner runner) => Delete(runner.Id); - public Models.Runner Update(int runnerId, RunnerUpdate runnerUpdate) + public void Delete(int runnerId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var projects = Server.AllProjects.Where(p => p.EnabledRunners.Any(r => r.Id == runnerId)); + if (!projects.Any()) { - var runner = this[runnerId] ?? throw new GitLabNotFoundException(); - var runnerOnServer = GetServerRunner(runnerId); - - runnerOnServer.Active = runnerUpdate.Active ?? runnerOnServer.Active; - runnerOnServer.TagList = runnerUpdate.TagList ?? runnerOnServer.TagList; - runnerOnServer.Description = !string.IsNullOrEmpty(runnerUpdate.Description) ? runnerUpdate.Description : runnerOnServer.Description; - runnerOnServer.Locked = runnerUpdate.Locked ?? runnerOnServer.Locked; - runnerOnServer.RunUntagged = runnerUpdate.RunUntagged ?? runnerOnServer.RunUntagged; - - return runner; + throw new GitLabBadRequestException("Runner is not found in any project"); } - } - public IEnumerable OfProject(int projectId) - { - using (Context.BeginOperationScope()) + if (projects.Skip(1).Any()) { - var runnerRefs = GetProject(projectId, ProjectPermission.Edit).EnabledRunners; - return runnerRefs.Select(r => this[r.Id]).ToList(); + throw new GitLabBadRequestException("Runner is enabled in multiple projects"); } - } - public GitLabCollectionResponse OfProjectAsync(int projectId) - { - return GitLabCollectionResponse.Create(OfProject(projectId)); + var project = GetProject(projects.Single().Id, ProjectPermission.Edit); + project.RemoveRunner(runnerId); } + } - public IEnumerable GetJobs(int runnerId, JobScope jobScope) + public Models.Runner Update(int runnerId, RunnerUpdate runnerUpdate) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); - } + var runner = this[runnerId] ?? throw new GitLabNotFoundException(); + var runnerOnServer = GetServerRunner(runnerId); - public IEnumerable GetJobs(int runnerId, JobStatus? status = null) - { - throw new NotImplementedException(); - } + runnerOnServer.Active = runnerUpdate.Active ?? runnerOnServer.Active; + runnerOnServer.TagList = runnerUpdate.TagList ?? runnerOnServer.TagList; + runnerOnServer.Description = !string.IsNullOrEmpty(runnerUpdate.Description) ? runnerUpdate.Description : runnerOnServer.Description; + runnerOnServer.Locked = runnerUpdate.Locked ?? runnerOnServer.Locked; + runnerOnServer.RunUntagged = runnerUpdate.RunUntagged ?? runnerOnServer.RunUntagged; - // Seems like an old method... In the actual code, the method is the same as OfProject. - IEnumerable IRunnerClient.GetAvailableRunners(int projectId) - { - return OfProject(projectId); + return runner; } + } - public IEnumerable GetAllRunnersWithScope(RunnerScope scope) + public IEnumerable OfProject(int projectId) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + var runnerRefs = GetProject(projectId, ProjectPermission.Edit).EnabledRunners; + return runnerRefs.Select(r => this[r.Id]).ToList(); } + } - public Models.Runner EnableRunner(int projectId, RunnerId runnerId) - { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.Edit); - var runner = GetServerRunner(runnerId.Id); + public GitLabCollectionResponse OfProjectAsync(int projectId) + { + return GitLabCollectionResponse.Create(OfProject(projectId)); + } - var runnerReference = new RunnerRef(runner); + public IEnumerable GetJobs(int runnerId, JobScope jobScope) + { + throw new NotImplementedException(); + } - if (project.EnabledRunners.Contains(runnerReference)) - { - throw new GitLabBadRequestException("Runner has already been taken"); - } + public IEnumerable GetJobs(int runnerId, JobStatus? status = null) + { + throw new NotImplementedException(); + } - project.EnabledRunners.Add(runnerReference); - return runner.ToClientRunner(Context.User); - } - } + // Seems like an old method... In the actual code, the method is the same as OfProject. + IEnumerable IRunnerClient.GetAvailableRunners(int projectId) + { + return OfProject(projectId); + } - [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] - public async Task EnableRunnerAsync(int projectId, RunnerId runnerId, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return EnableRunner(projectId, runnerId); - } + public IEnumerable GetAllRunnersWithScope(RunnerScope scope) + { + throw new NotImplementedException(); + } - public void DisableRunner(int projectId, RunnerId runnerId) + public Models.Runner EnableRunner(int projectId, RunnerId runnerId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(projectId, ProjectPermission.Edit); - var runner = GetServerRunner(runnerId.Id); + var project = GetProject(projectId, ProjectPermission.Edit); + var runner = GetServerRunner(runnerId.Id); - if (project.EnabledRunners.All(r => r.Id != runnerId.Id)) - { - throw new GitLabNotFoundException(); - } + var runnerReference = new RunnerRef(runner); - var runnerReference = new RunnerRef(runner); - project.EnabledRunners.Remove(runnerReference); + if (project.EnabledRunners.Contains(runnerReference)) + { + throw new GitLabBadRequestException("Runner has already been taken"); } - } - private IEnumerable GetOwnedRunners() - { - var projects = Server.AllProjects.Where(project => project.CanUserEditProject(Context.User)); - var runners = projects.SelectMany(p => p.RegisteredRunners); - return runners; + project.EnabledRunners.Add(runnerReference); + return runner.ToClientRunner(Context.User); } + } - private Runner GetServerRunner(int id) - { - return GetOwnedRunners().FirstOrDefault(runner => runner.Id == id) ?? throw new GitLabNotFoundException(); - } + [SuppressMessage("Design", "MA0042:Do not use blocking calls in an async method", Justification = "Would be an infinite recursion")] + public async Task EnableRunnerAsync(int projectId, RunnerId runnerId, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return EnableRunner(projectId, runnerId); + } - public Models.Runner Register(RunnerRegister request) + public void DisableRunner(int projectId, RunnerId runnerId) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var project = GetProject(projectId, ProjectPermission.Edit); + var runner = GetServerRunner(runnerId.Id); + + if (project.EnabledRunners.All(r => r.Id != runnerId.Id)) { - var project = Server.AllProjects.SingleOrDefault(p => string.Equals(p.RunnersToken, request.Token, StringComparison.Ordinal)); - var runner = project.AddRunner(null, request.Description, request.Active ?? false, request.Locked ?? true, false, request.RunUntagged ?? false); - return runner.ToClientRunner(Context.User); + throw new GitLabNotFoundException(); } + + var runnerReference = new RunnerRef(runner); + project.EnabledRunners.Remove(runnerReference); + } + } + + private IEnumerable GetOwnedRunners() + { + var projects = Server.AllProjects.Where(project => project.CanUserEditProject(Context.User)); + var runners = projects.SelectMany(p => p.RegisteredRunners); + return runners; + } + + private Runner GetServerRunner(int id) + { + return GetOwnedRunners().FirstOrDefault(runner => runner.Id == id) ?? throw new GitLabNotFoundException(); + } + + public Models.Runner Register(RunnerRegister request) + { + using (Context.BeginOperationScope()) + { + var project = Server.AllProjects.SingleOrDefault(p => string.Equals(p.RunnersToken, request.Token, StringComparison.Ordinal)); + var runner = project.AddRunner(null, request.Description, request.Active ?? false, request.Locked ?? true, false, request.RunUntagged ?? false); + return runner.ToClientRunner(Context.User); } } } diff --git a/NGitLab.Mock/Clients/SnippetClient.cs b/NGitLab.Mock/Clients/SnippetClient.cs index 30fb1aff..b156bc44 100644 --- a/NGitLab.Mock/Clients/SnippetClient.cs +++ b/NGitLab.Mock/Clients/SnippetClient.cs @@ -3,62 +3,61 @@ using System.IO; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class SnippetClient : ClientBase, ISnippetClient { - internal sealed class SnippetClient : ClientBase, ISnippetClient + public SnippetClient(ClientContext context) + : base(context) { - public SnippetClient(ClientContext context) - : base(context) - { - } + } - public IEnumerable All => throw new NotImplementedException(); + public IEnumerable All => throw new NotImplementedException(); - public IEnumerable User => throw new NotImplementedException(); + public IEnumerable User => throw new NotImplementedException(); - public void Create(SnippetCreate snippet) - { - throw new NotImplementedException(); - } + public void Create(SnippetCreate snippet) + { + throw new NotImplementedException(); + } - public void Create(SnippetProjectCreate snippet) - { - throw new NotImplementedException(); - } + public void Create(SnippetProjectCreate snippet) + { + throw new NotImplementedException(); + } - public void Update(SnippetUpdate snippet) - { - throw new NotImplementedException(); - } + public void Update(SnippetUpdate snippet) + { + throw new NotImplementedException(); + } - public void Update(SnippetProjectUpdate snippet) - { - throw new NotImplementedException(); - } + public void Update(SnippetProjectUpdate snippet) + { + throw new NotImplementedException(); + } - public void Delete(int snippetId) - { - throw new NotImplementedException(); - } + public void Delete(int snippetId) + { + throw new NotImplementedException(); + } - public void Delete(int projectId, int snippetId) - { - throw new NotImplementedException(); - } + public void Delete(int projectId, int snippetId) + { + throw new NotImplementedException(); + } - public IEnumerable ForProject(int projectId) - { - throw new NotImplementedException(); - } + public IEnumerable ForProject(int projectId) + { + throw new NotImplementedException(); + } - public Snippet Get(int projectId, int snippetId) - { - throw new NotImplementedException(); - } + public Snippet Get(int projectId, int snippetId) + { + throw new NotImplementedException(); + } - public void GetContent(int projectId, int snippetId, Action parser) - { - throw new NotImplementedException(); - } + public void GetContent(int projectId, int snippetId, Action parser) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/SystemHookClient.cs b/NGitLab.Mock/Clients/SystemHookClient.cs index e19ed33a..f8d8f5df 100644 --- a/NGitLab.Mock/Clients/SystemHookClient.cs +++ b/NGitLab.Mock/Clients/SystemHookClient.cs @@ -3,83 +3,82 @@ using System.Linq; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class SystemHookClient : ClientBase, ISystemHookClient { - internal sealed class SystemHookClient : ClientBase, ISystemHookClient + public SystemHookClient(ClientContext context) + : base(context) { - public SystemHookClient(ClientContext context) - : base(context) - { - } + } - public Models.SystemHook this[int hookId] + public Models.SystemHook this[int hookId] + { + get { - get + AssertIsAdmin(); + using (Context.BeginOperationScope()) { - AssertIsAdmin(); - using (Context.BeginOperationScope()) - { - var result = Server.SystemHooks.FirstOrDefault(hook => hook.Id == hookId); - if (result == null) - throw new GitLabNotFoundException(); - - return result.ToClientSystemHook(); - } - } - } + var result = Server.SystemHooks.FirstOrDefault(hook => hook.Id == hookId); + if (result == null) + throw new GitLabNotFoundException(); - public IEnumerable All - { - get - { - AssertIsAdmin(); - using (Context.BeginOperationScope()) - { - return Server.SystemHooks.Select(hook => hook.ToClientSystemHook()).ToList(); - } + return result.ToClientSystemHook(); } } + } - public Models.SystemHook Create(SystemHookUpsert hook) + public IEnumerable All + { + get { AssertIsAdmin(); using (Context.BeginOperationScope()) { - var newHook = new SystemHook - { - CreatedAt = DateTime.UtcNow, - EnableSslVerification = hook.EnableSslVerification, - MergeRequestsEvents = hook.MergeRequestsEvents, - PushEvents = hook.PushEvents, - TagPushEvents = hook.TagPushEvents, - Url = hook.Url, - RepositoryUpdateEvents = hook.RepositoryUpdateEvents, - }; - Server.SystemHooks.Add(newHook); - - return newHook.ToClientSystemHook(); + return Server.SystemHooks.Select(hook => hook.ToClientSystemHook()).ToList(); } } + } - public void Delete(int hookId) + public Models.SystemHook Create(SystemHookUpsert hook) + { + AssertIsAdmin(); + using (Context.BeginOperationScope()) { - AssertIsAdmin(); - using (Context.BeginOperationScope()) + var newHook = new SystemHook { - var result = Server.SystemHooks.FirstOrDefault(hook => hook.Id == hookId); - if (result == null) - throw new GitLabNotFoundException(); + CreatedAt = DateTime.UtcNow, + EnableSslVerification = hook.EnableSslVerification, + MergeRequestsEvents = hook.MergeRequestsEvents, + PushEvents = hook.PushEvents, + TagPushEvents = hook.TagPushEvents, + Url = hook.Url, + RepositoryUpdateEvents = hook.RepositoryUpdateEvents, + }; + Server.SystemHooks.Add(newHook); - Server.SystemHooks.Remove(result); - } + return newHook.ToClientSystemHook(); } + } - private void AssertIsAdmin() + public void Delete(int hookId) + { + AssertIsAdmin(); + using (Context.BeginOperationScope()) { - if (Context.IsAuthenticated && Context.User.IsAdmin) - return; + var result = Server.SystemHooks.FirstOrDefault(hook => hook.Id == hookId); + if (result == null) + throw new GitLabNotFoundException(); - throw new GitLabException("User must be admin"); + Server.SystemHooks.Remove(result); } } + + private void AssertIsAdmin() + { + if (Context.IsAuthenticated && Context.User.IsAdmin) + return; + + throw new GitLabException("User must be admin"); + } } diff --git a/NGitLab.Mock/Clients/TagClient.cs b/NGitLab.Mock/Clients/TagClient.cs index 78f8fc7a..5f6f978f 100644 --- a/NGitLab.Mock/Clients/TagClient.cs +++ b/NGitLab.Mock/Clients/TagClient.cs @@ -8,95 +8,94 @@ using NGitLab.Models; using Commit = LibGit2Sharp.Commit; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class TagClient : ClientBase, ITagClient { - internal sealed class TagClient : ClientBase, ITagClient - { - private readonly int _projectId; + private readonly int _projectId; - public TagClient(ClientContext context, int projectId) - : base(context) - { - _projectId = projectId; - } + public TagClient(ClientContext context, int projectId) + : base(context) + { + _projectId = projectId; + } - public IEnumerable All + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return GetProject(_projectId, ProjectPermission.View).Repository.GetTags().Select(t => ToTagClient(t)).ToList(); - } + return GetProject(_projectId, ProjectPermission.View).Repository.GetTags().Select(t => ToTagClient(t)).ToList(); } } + } - public Tag Create(TagCreate tag) + public Tag Create(TagCreate tag) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var createdTag = project.Repository.CreateTag(Context.User, tag.Name, tag.Ref, tag.Message, tag.ReleaseDescription); + var project = GetProject(_projectId, ProjectPermission.Contribute); + var createdTag = project.Repository.CreateTag(Context.User, tag.Name, tag.Ref, tag.Message, tag.ReleaseDescription); - return ToTagClient(createdTag); - } + return ToTagClient(createdTag); } + } - public Task GetByNameAsync(string name, CancellationToken cancellationToken = default) + public Task GetByNameAsync(string name, CancellationToken cancellationToken = default) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.View); - var mockTag = project.Repository.GetTags().FirstOrDefault(t => t.FriendlyName.Equals(name, StringComparison.Ordinal)); - if (mockTag is null) - throw new GitLabException() { StatusCode = HttpStatusCode.NotFound }; - return Task.FromResult(ToTagClient(mockTag)); - } + var project = GetProject(_projectId, ProjectPermission.View); + var mockTag = project.Repository.GetTags().FirstOrDefault(t => t.FriendlyName.Equals(name, StringComparison.Ordinal)); + if (mockTag is null) + throw new GitLabException() { StatusCode = HttpStatusCode.NotFound }; + return Task.FromResult(ToTagClient(mockTag)); } + } - public void Delete(string name) + public void Delete(string name) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - project.Repository.DeleteTag(name); - } + var project = GetProject(_projectId, ProjectPermission.Contribute); + project.Repository.DeleteTag(name); } + } - public Tag ToTagClient(LibGit2Sharp.Tag tag) - { - var project = GetProject(_projectId, ProjectPermission.Contribute); - var commit = (Commit)tag.PeeledTarget; + public Tag ToTagClient(LibGit2Sharp.Tag tag) + { + var project = GetProject(_projectId, ProjectPermission.Contribute); + var commit = (Commit)tag.PeeledTarget; - return new Tag + return new Tag + { + Commit = commit.ToCommitInfo(), + Name = tag.FriendlyName, + Release = new Models.ReleaseInfo { - Commit = commit.ToCommitInfo(), - Name = tag.FriendlyName, - Release = new Models.ReleaseInfo - { - Description = project.Releases.GetByTagName(tag.FriendlyName)?.Description, - TagName = tag.FriendlyName, - }, - Message = tag.Annotation?.Message, - }; - } + Description = project.Releases.GetByTagName(tag.FriendlyName)?.Description, + TagName = tag.FriendlyName, + }, + Message = tag.Annotation?.Message, + }; + } - public GitLabCollectionResponse GetAsync(TagQuery query) + public GitLabCollectionResponse GetAsync(TagQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var result = GetProject(_projectId, ProjectPermission.View).Repository.GetTags(); + if (query != null) { - var result = GetProject(_projectId, ProjectPermission.View).Repository.GetTags(); - if (query != null) - { - if (!string.IsNullOrEmpty(query.Sort)) - throw new NotImplementedException(); + if (!string.IsNullOrEmpty(query.Sort)) + throw new NotImplementedException(); - if (!string.IsNullOrEmpty(query.OrderBy)) - throw new NotImplementedException(); - } - - return GitLabCollectionResponse.Create(result.Select(tag => ToTagClient(tag)).ToArray()); + if (!string.IsNullOrEmpty(query.OrderBy)) + throw new NotImplementedException(); } + + return GitLabCollectionResponse.Create(result.Select(tag => ToTagClient(tag)).ToArray()); } } } diff --git a/NGitLab.Mock/Clients/TriggerClient.cs b/NGitLab.Mock/Clients/TriggerClient.cs index 054631e9..a06ae661 100644 --- a/NGitLab.Mock/Clients/TriggerClient.cs +++ b/NGitLab.Mock/Clients/TriggerClient.cs @@ -2,25 +2,24 @@ using System.Collections.Generic; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class TriggerClient : ClientBase, ITriggerClient { - internal sealed class TriggerClient : ClientBase, ITriggerClient - { - private readonly int _projectId; + private readonly int _projectId; - public TriggerClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public TriggerClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public Trigger this[int id] => throw new NotImplementedException(); + public Trigger this[int id] => throw new NotImplementedException(); - public IEnumerable All => throw new NotImplementedException(); + public IEnumerable All => throw new NotImplementedException(); - public Trigger Create(string description) - { - throw new NotImplementedException(); - } + public Trigger Create(string description) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/UserClient.cs b/NGitLab.Mock/Clients/UserClient.cs index 899258a4..138e2e8f 100644 --- a/NGitLab.Mock/Clients/UserClient.cs +++ b/NGitLab.Mock/Clients/UserClient.cs @@ -5,178 +5,177 @@ using System.Threading.Tasks; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class UserClient : ClientBase, IUserClient { - internal sealed class UserClient : ClientBase, IUserClient + public UserClient(ClientContext context) + : base(context) { - public UserClient(ClientContext context) - : base(context) - { - } - - public Models.User this[int id] - { - get - { - using (Context.BeginOperationScope()) - { - return Server.Users.GetById(id)?.ToClientUser() ?? throw new GitLabNotFoundException(); - } - } - } + } - public IEnumerable All + public Models.User this[int id] + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Server.Users.Select(user => user.ToClientUser()).ToList(); - } + return Server.Users.GetById(id)?.ToClientUser() ?? throw new GitLabNotFoundException(); } } + } - public Session Current + public IEnumerable All + { + get { - get + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Context.User?.ToClientSession(); - } + return Server.Users.Select(user => user.ToClientUser()).ToList(); } } + } - public ISshKeyClient CurrentUserSShKeys => throw new NotSupportedException(); - - public Models.User Create(UserUpsert user) + public Session Current + { + get { using (Context.BeginOperationScope()) { - var u = new User(user.Username) - { - Name = user.Name, - Email = user.Email, - }; - - Server.Users.Add(u); - return u.ToClientUser(); + return Context.User?.ToClientSession(); } } + } - public UserToken CreateToken(UserTokenCreate tokenRequest) - { - throw new NotSupportedException(); - } + public ISshKeyClient CurrentUserSShKeys => throw new NotSupportedException(); - public void Delete(int id) + public Models.User Create(UserUpsert user) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var u = new User(user.Username) { - var user = Server.Users.GetById(id); - - if (user == null) - { - throw new GitLabNotFoundException($"User '{id}' is not found. Cannot be deleted"); - } + Name = user.Name, + Email = user.Email, + }; - Server.Users.Remove(user); - } + Server.Users.Add(u); + return u.ToClientUser(); } + } - public void Activate(int id) - { - using (Context.BeginOperationScope()) - { - var user = Server.Users.GetById(id); + public UserToken CreateToken(UserTokenCreate tokenRequest) + { + throw new NotSupportedException(); + } - if (user == null) - { - throw new GitLabNotFoundException($"User '{id}' is not found. Cannot be activated"); - } + public void Delete(int id) + { + using (Context.BeginOperationScope()) + { + var user = Server.Users.GetById(id); - user.State = UserState.active; + if (user == null) + { + throw new GitLabNotFoundException($"User '{id}' is not found. Cannot be deleted"); } + + Server.Users.Remove(user); } + } - public void Deactivate(int id) + public void Activate(int id) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - var user = Server.Users.GetById(id); - - if (user == null) - { - throw new GitLabNotFoundException($"User '{id}' is not found. Cannot be deactivated"); - } + var user = Server.Users.GetById(id); - user.State = UserState.deactivated; + if (user == null) + { + throw new GitLabNotFoundException($"User '{id}' is not found. Cannot be activated"); } + + user.State = UserState.active; } + } - public IEnumerable Get(string username) + public void Deactivate(int id) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var user = Server.Users.GetById(id); + + if (user == null) { - return Server.Users.SearchByUsername(username).Select(user => user.ToClientUser()).ToList(); + throw new GitLabNotFoundException($"User '{id}' is not found. Cannot be deactivated"); } + + user.State = UserState.deactivated; } + } - public IEnumerable Get(UserQuery query) + public IEnumerable Get(string username) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Server.Users.Get(query).Select(user => user.ToClientUser()); - } + return Server.Users.SearchByUsername(username).Select(user => user.ToClientUser()).ToList(); } + } - public IEnumerable Search(string query) + public IEnumerable Get(UserQuery query) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) - { - return Server.Users - .Where(user => string.Equals(user.Email, query, StringComparison.OrdinalIgnoreCase) || string.Equals(user.UserName, query, StringComparison.OrdinalIgnoreCase)) - .Select(user => user.ToClientUser()).ToList(); - } + return Server.Users.Get(query).Select(user => user.ToClientUser()); } + } - public ISshKeyClient SShKeys(int userId) + public IEnumerable Search(string query) + { + using (Context.BeginOperationScope()) { - throw new NotImplementedException(); + return Server.Users + .Where(user => string.Equals(user.Email, query, StringComparison.OrdinalIgnoreCase) || string.Equals(user.UserName, query, StringComparison.OrdinalIgnoreCase)) + .Select(user => user.ToClientUser()).ToList(); } + } - public Models.User Update(int id, UserUpsert userUpsert) + public ISshKeyClient SShKeys(int userId) + { + throw new NotImplementedException(); + } + + public Models.User Update(int id, UserUpsert userUpsert) + { + using (Context.BeginOperationScope()) { - using (Context.BeginOperationScope()) + var user = Server.Users.GetById(id); + if (user != null) { - var user = Server.Users.GetById(id); - if (user != null) - { - user.Name = userUpsert.Name; - user.Email = userUpsert.Email; + user.Name = userUpsert.Name; + user.Email = userUpsert.Email; - return user.ToClientUser(); - } - - throw new GitLabNotFoundException(); + return user.ToClientUser(); } - } - public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default) - { - await Task.Yield(); - return this[id]; + throw new GitLabNotFoundException(); } + } - public async Task GetCurrentUserAsync(CancellationToken cancellationToken = default) - { - await Task.Yield(); - return Current; - } + public async Task GetByIdAsync(int id, CancellationToken cancellationToken = default) + { + await Task.Yield(); + return this[id]; + } - public GitLabCollectionResponse GetLastActivityDatesAsync(DateTimeOffset? from = null) - { - throw new NotImplementedException(); - } + public async Task GetCurrentUserAsync(CancellationToken cancellationToken = default) + { + await Task.Yield(); + return Current; + } + + public GitLabCollectionResponse GetLastActivityDatesAsync(DateTimeOffset? from = null) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Clients/VersionClient.cs b/NGitLab.Mock/Clients/VersionClient.cs index 039438c2..fbb87559 100644 --- a/NGitLab.Mock/Clients/VersionClient.cs +++ b/NGitLab.Mock/Clients/VersionClient.cs @@ -1,17 +1,16 @@ using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class VersionClient : ClientBase, IVersionClient { - internal sealed class VersionClient : ClientBase, IVersionClient + public VersionClient(ClientContext context) + : base(context) { - public VersionClient(ClientContext context) - : base(context) - { - } + } - public GitLabVersion Get() - { - return Server.Version; - } + public GitLabVersion Get() + { + return Server.Version; } } diff --git a/NGitLab.Mock/Clients/WikiClient.cs b/NGitLab.Mock/Clients/WikiClient.cs index 10d3bd66..923d735f 100644 --- a/NGitLab.Mock/Clients/WikiClient.cs +++ b/NGitLab.Mock/Clients/WikiClient.cs @@ -2,35 +2,34 @@ using System.Collections.Generic; using NGitLab.Models; -namespace NGitLab.Mock.Clients +namespace NGitLab.Mock.Clients; + +internal sealed class WikiClient : ClientBase, IWikiClient { - internal sealed class WikiClient : ClientBase, IWikiClient - { - private readonly int _projectId; + private readonly int _projectId; - public WikiClient(ClientContext context, ProjectId projectId) - : base(context) - { - _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; - } + public WikiClient(ClientContext context, ProjectId projectId) + : base(context) + { + _projectId = Server.AllProjects.FindProject(projectId.ValueAsUriParameter()).Id; + } - public WikiPage this[string slug] => throw new NotImplementedException(); + public WikiPage this[string slug] => throw new NotImplementedException(); - public IEnumerable All => throw new NotImplementedException(); + public IEnumerable All => throw new NotImplementedException(); - public WikiPage Create(WikiPageCreate wikiPage) - { - throw new NotImplementedException(); - } + public WikiPage Create(WikiPageCreate wikiPage) + { + throw new NotImplementedException(); + } - public void Delete(string slug) - { - throw new NotImplementedException(); - } + public void Delete(string slug) + { + throw new NotImplementedException(); + } - public WikiPage Update(string slug, WikiPageUpdate wikiPage) - { - throw new NotImplementedException(); - } + public WikiPage Update(string slug, WikiPageUpdate wikiPage) + { + throw new NotImplementedException(); } } diff --git a/NGitLab.Mock/Collection.cs b/NGitLab.Mock/Collection.cs index 153161ac..506c66bb 100644 --- a/NGitLab.Mock/Collection.cs +++ b/NGitLab.Mock/Collection.cs @@ -4,85 +4,84 @@ using System.Collections.Specialized; using System.ComponentModel; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public abstract class Collection : IReadOnlyCollection, INotifyCollectionChanged, INotifyPropertyChanged + where T : GitLabObject { - public abstract class Collection : IReadOnlyCollection, INotifyCollectionChanged, INotifyPropertyChanged - where T : GitLabObject - { - private readonly List _items = new(); + private readonly List _items = new(); - public event NotifyCollectionChangedEventHandler CollectionChanged; + public event NotifyCollectionChangedEventHandler CollectionChanged; - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler PropertyChanged; - protected Collection(GitLabObject parent) - { - Parent = parent ?? throw new ArgumentNullException(nameof(parent)); - } + protected Collection(GitLabObject parent) + { + Parent = parent ?? throw new ArgumentNullException(nameof(parent)); + } - protected GitLabServer Server => Parent.Server; + protected GitLabServer Server => Parent.Server; - protected GitLabObject Parent { get; } + protected GitLabObject Parent { get; } - public int Count => _items.Count; + public int Count => _items.Count; - protected void Clear() - { - _items.Clear(); + protected void Clear() + { + _items.Clear(); - CollectionChanged?.Invoke(this, EventArgsCache.ResetCollectionChanged); - PropertyChanged?.Invoke(this, EventArgsCache.IndexerPropertyChanged); - PropertyChanged?.Invoke(this, EventArgsCache.CountPropertyChanged); - } + CollectionChanged?.Invoke(this, EventArgsCache.ResetCollectionChanged); + PropertyChanged?.Invoke(this, EventArgsCache.IndexerPropertyChanged); + PropertyChanged?.Invoke(this, EventArgsCache.CountPropertyChanged); + } - public IEnumerator GetEnumerator() => _items.GetEnumerator(); + public IEnumerator GetEnumerator() => _items.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public bool Contains(T item) - { - if (item is null) - throw new ArgumentNullException(nameof(item)); + public bool Contains(T item) + { + if (item is null) + throw new ArgumentNullException(nameof(item)); - return _items.Contains(item); - } + return _items.Contains(item); + } - public virtual void Add(T item) - { - if (item is null) - throw new ArgumentNullException(nameof(item)); + public virtual void Add(T item) + { + if (item is null) + throw new ArgumentNullException(nameof(item)); - item.Parent = Parent; - _items.Add(item); + item.Parent = Parent; + _items.Add(item); - CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, _items.Count - 1)); - PropertyChanged?.Invoke(this, EventArgsCache.IndexerPropertyChanged); - PropertyChanged?.Invoke(this, EventArgsCache.CountPropertyChanged); - } + CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, _items.Count - 1)); + PropertyChanged?.Invoke(this, EventArgsCache.IndexerPropertyChanged); + PropertyChanged?.Invoke(this, EventArgsCache.CountPropertyChanged); + } - public bool Remove(T item) - { - if (item is null) - throw new ArgumentNullException(nameof(item)); + public bool Remove(T item) + { + if (item is null) + throw new ArgumentNullException(nameof(item)); - var index = _items.IndexOf(item); - if (index < 0) - return false; + var index = _items.IndexOf(item); + if (index < 0) + return false; - item.Parent = null; - _items.RemoveAt(index); + item.Parent = null; + _items.RemoveAt(index); - CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index)); - PropertyChanged?.Invoke(this, EventArgsCache.IndexerPropertyChanged); - PropertyChanged?.Invoke(this, EventArgsCache.CountPropertyChanged); - return true; - } + CollectionChanged?.Invoke(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index)); + PropertyChanged?.Invoke(this, EventArgsCache.IndexerPropertyChanged); + PropertyChanged?.Invoke(this, EventArgsCache.CountPropertyChanged); + return true; + } - private static class EventArgsCache - { - internal static readonly PropertyChangedEventArgs CountPropertyChanged = new("Count"); - internal static readonly PropertyChangedEventArgs IndexerPropertyChanged = new("Item[]"); - internal static readonly NotifyCollectionChangedEventArgs ResetCollectionChanged = new(NotifyCollectionChangedAction.Reset); - } + private static class EventArgsCache + { + internal static readonly PropertyChangedEventArgs CountPropertyChanged = new("Count"); + internal static readonly PropertyChangedEventArgs IndexerPropertyChanged = new("Item[]"); + internal static readonly NotifyCollectionChangedEventArgs ResetCollectionChanged = new(NotifyCollectionChangedAction.Reset); } } diff --git a/NGitLab.Mock/CommitAction.cs b/NGitLab.Mock/CommitAction.cs index 894f07b9..71af5e82 100644 --- a/NGitLab.Mock/CommitAction.cs +++ b/NGitLab.Mock/CommitAction.cs @@ -1,11 +1,10 @@ -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public enum CommitAction { - public enum CommitAction - { - Create, - Delete, - Move, - Update, - chmod, - } + Create, + Delete, + Move, + Update, + chmod, } diff --git a/NGitLab.Mock/CommitActionCreateHandler.cs b/NGitLab.Mock/CommitActionCreateHandler.cs index 0bd06ceb..622996a7 100644 --- a/NGitLab.Mock/CommitActionCreateHandler.cs +++ b/NGitLab.Mock/CommitActionCreateHandler.cs @@ -2,32 +2,31 @@ using System.IO; using NGitLab.Models; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +internal sealed class CommitActionCreateHandler : ICommitActionHandler { - internal sealed class CommitActionCreateHandler : ICommitActionHandler + public void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository) { - public void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository) - { - if (!Directory.Exists(repoPath)) - throw new DirectoryNotFoundException(); + if (!Directory.Exists(repoPath)) + throw new DirectoryNotFoundException(); - var filePath = Path.Combine(repoPath, action.FilePath); + var filePath = Path.Combine(repoPath, action.FilePath); - if (System.IO.File.Exists(filePath)) - throw new GitLabException("File already exists."); + if (System.IO.File.Exists(filePath)) + throw new GitLabException("File already exists."); - if (string.Equals(action.Encoding, "base64", StringComparison.OrdinalIgnoreCase)) - { - var content = Convert.FromBase64String(action.Content); - System.IO.File.WriteAllBytes(filePath, content); - } - else - { - System.IO.File.WriteAllText(filePath, action.Content); - } - - repository.Index.Add(action.FilePath); - repository.Index.Write(); + if (string.Equals(action.Encoding, "base64", StringComparison.OrdinalIgnoreCase)) + { + var content = Convert.FromBase64String(action.Content); + System.IO.File.WriteAllBytes(filePath, content); } + else + { + System.IO.File.WriteAllText(filePath, action.Content); + } + + repository.Index.Add(action.FilePath); + repository.Index.Write(); } } diff --git a/NGitLab.Mock/CommitActionDeleteHandler.cs b/NGitLab.Mock/CommitActionDeleteHandler.cs index 6fa67963..27b5acf7 100644 --- a/NGitLab.Mock/CommitActionDeleteHandler.cs +++ b/NGitLab.Mock/CommitActionDeleteHandler.cs @@ -1,21 +1,20 @@ using System.IO; using NGitLab.Models; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +internal sealed class CommitActionDeleteHandler : ICommitActionHandler { - internal sealed class CommitActionDeleteHandler : ICommitActionHandler + public void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository) { - public void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository) - { - var fullPath = Path.Combine(repoPath, action.FilePath); + var fullPath = Path.Combine(repoPath, action.FilePath); - if (!System.IO.File.Exists(fullPath)) - throw new FileNotFoundException("Could not find file", fullPath); + if (!System.IO.File.Exists(fullPath)) + throw new FileNotFoundException("Could not find file", fullPath); - System.IO.File.Delete(fullPath); + System.IO.File.Delete(fullPath); - repository.Index.Remove(action.FilePath); - repository.Index.Write(); - } + repository.Index.Remove(action.FilePath); + repository.Index.Write(); } } diff --git a/NGitLab.Mock/CommitActionMoveHandler.cs b/NGitLab.Mock/CommitActionMoveHandler.cs index deae46f7..5de8bd79 100644 --- a/NGitLab.Mock/CommitActionMoveHandler.cs +++ b/NGitLab.Mock/CommitActionMoveHandler.cs @@ -1,22 +1,21 @@ using System.IO; using NGitLab.Models; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +internal sealed class CommitActionMoveHandler : ICommitActionHandler { - internal sealed class CommitActionMoveHandler : ICommitActionHandler + public void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository) { - public void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository) - { - var oldPath = Path.Combine(repoPath, action.PreviousPath); - if (!System.IO.File.Exists(oldPath)) - throw new FileNotFoundException("Could not find file", nameof(oldPath)); + var oldPath = Path.Combine(repoPath, action.PreviousPath); + if (!System.IO.File.Exists(oldPath)) + throw new FileNotFoundException("Could not find file", nameof(oldPath)); - var newPath = Path.Combine(repoPath, action.FilePath); - System.IO.File.Move(oldPath, newPath); + var newPath = Path.Combine(repoPath, action.FilePath); + System.IO.File.Move(oldPath, newPath); - repository.Index.Add(action.FilePath); - repository.Index.Add(action.PreviousPath); - repository.Index.Write(); - } + repository.Index.Add(action.FilePath); + repository.Index.Add(action.PreviousPath); + repository.Index.Write(); } } diff --git a/NGitLab.Mock/CommitActionUpdateHandler.cs b/NGitLab.Mock/CommitActionUpdateHandler.cs index 07f7f97b..3893b3d0 100644 --- a/NGitLab.Mock/CommitActionUpdateHandler.cs +++ b/NGitLab.Mock/CommitActionUpdateHandler.cs @@ -2,32 +2,31 @@ using System.IO; using NGitLab.Models; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +internal sealed class CommitActionUpdateHandler : ICommitActionHandler { - internal sealed class CommitActionUpdateHandler : ICommitActionHandler + public void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository) { - public void Handle(CreateCommitAction action, string repoPath, LibGit2Sharp.Repository repository) - { - if (!Directory.Exists(repoPath)) - throw new DirectoryNotFoundException(); + if (!Directory.Exists(repoPath)) + throw new DirectoryNotFoundException(); - var filePath = Path.Combine(repoPath, action.FilePath); + var filePath = Path.Combine(repoPath, action.FilePath); - if (!System.IO.File.Exists(filePath)) - throw new FileNotFoundException("File does not exist."); + if (!System.IO.File.Exists(filePath)) + throw new FileNotFoundException("File does not exist."); - if (string.Equals(action.Encoding, "base64", StringComparison.OrdinalIgnoreCase)) - { - var content = Convert.FromBase64String(action.Content); - System.IO.File.WriteAllBytes(filePath, content); - } - else - { - System.IO.File.WriteAllText(filePath, action.Content); - } - - repository.Index.Add(action.FilePath); - repository.Index.Write(); + if (string.Equals(action.Encoding, "base64", StringComparison.OrdinalIgnoreCase)) + { + var content = Convert.FromBase64String(action.Content); + System.IO.File.WriteAllBytes(filePath, content); } + else + { + System.IO.File.WriteAllText(filePath, action.Content); + } + + repository.Index.Add(action.FilePath); + repository.Index.Write(); } } diff --git a/NGitLab.Mock/CommitInfo.cs b/NGitLab.Mock/CommitInfo.cs index c4bc3c45..82859e9a 100644 --- a/NGitLab.Mock/CommitInfo.cs +++ b/NGitLab.Mock/CommitInfo.cs @@ -1,9 +1,8 @@ -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public sealed class CommitInfo : GitLabObject { - public sealed class CommitInfo : GitLabObject - { - public string Sha { get; set; } + public string Sha { get; set; } - public string Status { get; set; } - } + public string Status { get; set; } } diff --git a/NGitLab.Mock/CommitInfoCollection.cs b/NGitLab.Mock/CommitInfoCollection.cs index 917457bf..8e50c59e 100644 --- a/NGitLab.Mock/CommitInfoCollection.cs +++ b/NGitLab.Mock/CommitInfoCollection.cs @@ -1,29 +1,28 @@ using System; using System.Linq; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public sealed class CommitInfoCollection : Collection { - public sealed class CommitInfoCollection : Collection + public CommitInfoCollection(GitLabObject parent) + : base(parent) { - public CommitInfoCollection(GitLabObject parent) - : base(parent) - { - } + } - public CommitInfo GetOrAdd(string sha) + public CommitInfo GetOrAdd(string sha) + { + var commitInfo = this.FirstOrDefault(commit => string.Equals(commit.Sha, sha, StringComparison.OrdinalIgnoreCase)); + if (commitInfo == null) { - var commitInfo = this.FirstOrDefault(commit => string.Equals(commit.Sha, sha, StringComparison.OrdinalIgnoreCase)); - if (commitInfo == null) + commitInfo = new CommitInfo { - commitInfo = new CommitInfo - { - Sha = sha, - }; - - Add(commitInfo); - } + Sha = sha, + }; - return commitInfo; + Add(commitInfo); } + + return commitInfo; } } diff --git a/NGitLab.Mock/CommitStatus.cs b/NGitLab.Mock/CommitStatus.cs index a739386c..7ff5b8cb 100644 --- a/NGitLab.Mock/CommitStatus.cs +++ b/NGitLab.Mock/CommitStatus.cs @@ -1,49 +1,48 @@ using NGitLab.Models; -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public sealed class CommitStatus : GitLabObject { - public sealed class CommitStatus : GitLabObject - { - public new Project Parent => (Project)base.Parent; + public new Project Parent => (Project)base.Parent; - public string Sha { get; set; } + public string Sha { get; set; } - public string Status { get; set; } + public string Status { get; set; } - public string Ref { get; set; } + public string Ref { get; set; } - public string Name { get; set; } + public string Name { get; set; } - public string TargetUrl { get; set; } + public string TargetUrl { get; set; } - public string Description { get; set; } + public string Description { get; set; } - public int? Coverage { get; set; } + public int? Coverage { get; set; } - public CommitStatusCreate ToClientCommitStatusCreate() + public CommitStatusCreate ToClientCommitStatusCreate() + { + return new CommitStatusCreate { - return new CommitStatusCreate - { - Name = Name, - TargetUrl = TargetUrl, - Status = Status, - Ref = Ref, - CommitSha = Sha, - Description = Description, - State = Status, - Coverage = Coverage, - }; - } - - public Models.CommitStatus ToClientCommitStatus() + Name = Name, + TargetUrl = TargetUrl, + Status = Status, + Ref = Ref, + CommitSha = Sha, + Description = Description, + State = Status, + Coverage = Coverage, + }; + } + + public Models.CommitStatus ToClientCommitStatus() + { + return new Models.CommitStatus { - return new Models.CommitStatus - { - CommitSha = Sha, - Name = Name, - Ref = Ref, - Status = Status, - }; - } + CommitSha = Sha, + Name = Name, + Ref = Ref, + Status = Status, + }; } } diff --git a/NGitLab.Mock/CommitStatusCollection.cs b/NGitLab.Mock/CommitStatusCollection.cs index fc270446..770b541b 100644 --- a/NGitLab.Mock/CommitStatusCollection.cs +++ b/NGitLab.Mock/CommitStatusCollection.cs @@ -1,10 +1,9 @@ -namespace NGitLab.Mock +namespace NGitLab.Mock; + +public sealed class CommitStatusCollection : Collection { - public sealed class CommitStatusCollection : Collection + public CommitStatusCollection(GitLabObject parent) + : base(parent) { - public CommitStatusCollection(GitLabObject parent) - : base(parent) - { - } } } diff --git a/NGitLab.Mock/Config/ConfigSerializer.cs b/NGitLab.Mock/Config/ConfigSerializer.cs index 89932ac1..b0f5566b 100644 --- a/NGitLab.Mock/Config/ConfigSerializer.cs +++ b/NGitLab.Mock/Config/ConfigSerializer.cs @@ -9,418 +9,417 @@ #pragma warning disable MA0009 // Add regex evaluation timeout -namespace NGitLab.Mock.Config +namespace NGitLab.Mock.Config; + +internal sealed class ConfigSerializer { - internal sealed class ConfigSerializer - { - private static readonly Regex s_variableTemplateRegex = new(@"{{|}}|{[a-zA-Z_][\w\.-]+}", RegexOptions.Compiled); + private static readonly Regex s_variableTemplateRegex = new(@"{{|}}|{[a-zA-Z_][\w\.-]+}", RegexOptions.Compiled); - private readonly Dictionary _configs = new(StringComparer.OrdinalIgnoreCase); - private readonly Dictionary _variables = new(StringComparer.Ordinal); - private readonly Dictionary _resolvedDictionary = new(StringComparer.Ordinal); + private readonly Dictionary _configs = new(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary _variables = new(StringComparer.Ordinal); + private readonly Dictionary _resolvedDictionary = new(StringComparer.Ordinal); - public void DefineVariable(string name, object value) - { - _variables[name] = value; - } + public void DefineVariable(string name, object value) + { + _variables[name] = value; + } - public static string Serialize(GitLabConfig config) + public static string Serialize(GitLabConfig config) + { + var serializer = new SerializerBuilder().DisableAliases().Build(); + return serializer.Serialize(new Dictionary(StringComparer.OrdinalIgnoreCase) { - var serializer = new SerializerBuilder().DisableAliases().Build(); - return serializer.Serialize(new Dictionary(StringComparer.OrdinalIgnoreCase) - { - { "gitlab", config }, - }); - } + { "gitlab", config }, + }); + } - public void Deserialize(string content) + public void Deserialize(string content) + { + var deserializer = new DeserializerBuilder().Build(); + var data = deserializer.Deserialize>(content); + foreach (var config in data) { - var deserializer = new DeserializerBuilder().Build(); - var data = deserializer.Deserialize>(content); - foreach (var config in data) + if (string.Equals(config.Key, "variables", StringComparison.OrdinalIgnoreCase)) { - if (string.Equals(config.Key, "variables", StringComparison.OrdinalIgnoreCase)) - { - if (config.Value is not Dictionary dict) - throw new InvalidOperationException("Variables config is invalid, expected dictionary"); + if (config.Value is not Dictionary dict) + throw new InvalidOperationException("Variables config is invalid, expected dictionary"); - foreach (var pair in dict) - { - if (pair.Key is not string key) - throw new InvalidOperationException("Variables config is invalid, expected keys as string"); - - DefineVariable(key, pair.Value); - } - } - else + foreach (var pair in dict) { - _configs[config.Key] = config.Value; + if (pair.Key is not string key) + throw new InvalidOperationException("Variables config is invalid, expected keys as string"); + + DefineVariable(key, pair.Value); } } + else + { + _configs[config.Key] = config.Value; + } } + } - public bool TryGet(string name, ref T value) - where T : class - { - if (!_configs.TryGetValue(name, out var config)) - return true; - - object v = value; - config = ExpandVariables(config); - if (!TryConvert(typeof(T), config, ref v)) - return false; - - value = (T)v; + public bool TryGet(string name, ref T value) + where T : class + { + if (!_configs.TryGetValue(name, out var config)) return true; - } - private object ExpandVariables(object value) - { - return value == null ? null : ExpandVariables(value, new Stack()); - } + object v = value; + config = ExpandVariables(config); + if (!TryConvert(typeof(T), config, ref v)) + return false; - private object ExpandVariables(object value, Stack stack) - { - if (value is string str) - { - var matches = s_variableTemplateRegex.Matches(str).Cast().ToArray(); - if (matches.Length == 0) - return Environment.ExpandEnvironmentVariables(str); + value = (T)v; + return true; + } - if (matches.Length == 1 && matches[0].Length == str.Length) - return ResolveVariable(str.Trim('{', '}'), stack); + private object ExpandVariables(object value) + { + return value == null ? null : ExpandVariables(value, new Stack()); + } - var bld = new StringBuilder(); - var index = 0; - foreach (var match in matches) - { - if (index < match.Index) - bld.Append(Environment.ExpandEnvironmentVariables(str.Substring(index, match.Index - index))); + private object ExpandVariables(object value, Stack stack) + { + if (value is string str) + { + var matches = s_variableTemplateRegex.Matches(str).Cast().ToArray(); + if (matches.Length == 0) + return Environment.ExpandEnvironmentVariables(str); - if (string.Equals(match.Value, "{{", StringComparison.Ordinal)) - bld.Append('{'); - else if (string.Equals(match.Value, "}}", StringComparison.Ordinal)) - bld.Append('}'); - else - bld.Append(ResolveVariable(match.Value.Trim('{', '}'), stack)); + if (matches.Length == 1 && matches[0].Length == str.Length) + return ResolveVariable(str.Trim('{', '}'), stack); - index = match.Index + match.Length; - } + var bld = new StringBuilder(); + var index = 0; + foreach (var match in matches) + { + if (index < match.Index) + bld.Append(Environment.ExpandEnvironmentVariables(str.Substring(index, match.Index - index))); - if (index < str.Length) - bld.Append(Environment.ExpandEnvironmentVariables(str.Substring(index))); + if (string.Equals(match.Value, "{{", StringComparison.Ordinal)) + bld.Append('{'); + else if (string.Equals(match.Value, "}}", StringComparison.Ordinal)) + bld.Append('}'); + else + bld.Append(ResolveVariable(match.Value.Trim('{', '}'), stack)); - return bld.ToString(); + index = match.Index + match.Length; } - if (value is List list) - { - for (var i = 0; i < list.Count; i++) - { - list[i] = ExpandVariables(list[i], stack); - } + if (index < str.Length) + bld.Append(Environment.ExpandEnvironmentVariables(str.Substring(index))); - return list; - } + return bld.ToString(); + } - if (value is Dictionary dictionary) + if (value is List list) + { + for (var i = 0; i < list.Count; i++) { - foreach (var key in dictionary.Keys.ToArray()) - { - dictionary[key] = ExpandVariables(dictionary[key], stack); - } - - return dictionary; + list[i] = ExpandVariables(list[i], stack); } - return value; + return list; } - private object ResolveVariable(string name, Stack stack) + if (value is Dictionary dictionary) { - if (stack.Contains(name, StringComparer.Ordinal)) - throw new InvalidOperationException($"Cyclic variable resolution of '{name}'"); - - switch (name.ToLowerInvariant()) + foreach (var key in dictionary.Keys.ToArray()) { - case "new_guid": - return Guid.NewGuid().ToString("D"); + dictionary[key] = ExpandVariables(dictionary[key], stack); } - if (_resolvedDictionary.TryGetValue(name, out var value)) - return value; + return dictionary; + } + + return value; + } - if (!_variables.TryGetValue(name, out value)) - throw new InvalidOperationException($"Variable '{name}' not found"); + private object ResolveVariable(string name, Stack stack) + { + if (stack.Contains(name, StringComparer.Ordinal)) + throw new InvalidOperationException($"Cyclic variable resolution of '{name}'"); - stack.Push(name); - value = ExpandVariables(value, stack); - stack.Pop(); - _resolvedDictionary[name] = value; + switch (name.ToLowerInvariant()) + { + case "new_guid": + return Guid.NewGuid().ToString("D"); + } + if (_resolvedDictionary.TryGetValue(name, out var value)) return value; + + if (!_variables.TryGetValue(name, out value)) + throw new InvalidOperationException($"Variable '{name}' not found"); + + stack.Push(name); + value = ExpandVariables(value, stack); + stack.Pop(); + _resolvedDictionary[name] = value; + + return value; + } + + public static bool TryConvert(object valueObj, out T value) + { + object v = null; + if (TryConvert(typeof(T), valueObj, ref v)) + { + value = (T)v; + return true; + } + + value = default; + return false; + } + + public static bool TryConvert(Type type, object valueObj, ref object value) + { + if (type == typeof(object) || type.IsInstanceOfType(valueObj)) + { + value = valueObj; + return true; } - public static bool TryConvert(object valueObj, out T value) + if (type == typeof(bool)) { - object v = null; - if (TryConvert(typeof(T), valueObj, ref v)) + if (valueObj is string valueString && bool.TryParse(string.IsNullOrEmpty(valueString) ? "false" : valueString, out var valueBool)) { - value = (T)v; + value = valueBool; return true; } - value = default; return false; } - public static bool TryConvert(Type type, object valueObj, ref object value) + if (type == typeof(int)) { - if (type == typeof(object) || type.IsInstanceOfType(valueObj)) + if (valueObj is string valueString && int.TryParse(valueString, out var valueInt)) { - value = valueObj; + value = valueInt; return true; } - if (type == typeof(bool)) - { - if (valueObj is string valueString && bool.TryParse(string.IsNullOrEmpty(valueString) ? "false" : valueString, out var valueBool)) - { - value = valueBool; - return true; - } + return false; + } - return false; + if (type == typeof(string)) + { + if (valueObj == null) + { + value = null; + return true; } - if (type == typeof(int)) + if (valueObj is string valueString) { - if (valueObj is string valueString && int.TryParse(valueString, out var valueInt)) - { - value = valueInt; - return true; - } - - return false; + value = valueString; + return true; } - if (type == typeof(string)) + return false; + } + + if (type.IsEnum) + { + if (valueObj is string valueString && TryParseEnum(type, valueString, out var valueEnum)) { - if (valueObj == null) - { - value = null; - return true; - } + value = valueEnum; + return true; + } - if (valueObj is string valueString) - { - value = valueString; - return true; - } + return false; + } - return false; + if (type == typeof(DateTime)) + { + if (valueObj is string valueString && (DateTime.TryParseExact(valueString, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var valueDate) || DateTime.TryParse(valueString, CultureInfo.InvariantCulture, DateTimeStyles.None, out valueDate))) + { + value = valueDate; + return true; } - if (type.IsEnum) - { - if (valueObj is string valueString && TryParseEnum(type, valueString, out var valueEnum)) - { - value = valueEnum; - return true; - } + return false; + } - return false; + if (type == typeof(DateTimeOffset)) + { + if (valueObj is string valueString && (DateTimeOffset.TryParseExact(valueString, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var valueDate) || DateTimeOffset.TryParse(valueString, CultureInfo.InvariantCulture, DateTimeStyles.None, out valueDate))) + { + value = valueDate; + return true; } - if (type == typeof(DateTime)) - { - if (valueObj is string valueString && (DateTime.TryParseExact(valueString, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var valueDate) || DateTime.TryParse(valueString, CultureInfo.InvariantCulture, DateTimeStyles.None, out valueDate))) - { - value = valueDate; - return true; - } + return false; + } - return false; - } + if (valueObj == null) + { + value = null; + return true; + } - if (type == typeof(DateTimeOffset)) + // Nullable + if (type.IsGenericType) + { + var genericArgs = type.GetGenericArguments(); + if (genericArgs.Length == 1 && genericArgs[0].IsValueType) { - if (valueObj is string valueString && (DateTimeOffset.TryParseExact(valueString, "dd/MM/yyyy HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out var valueDate) || DateTimeOffset.TryParse(valueString, CultureInfo.InvariantCulture, DateTimeStyles.None, out valueDate))) - { - value = valueDate; - return true; - } + var nullableType = typeof(Nullable<>).MakeGenericType(genericArgs); + if (!type.IsAssignableFrom(nullableType)) + return false; - return false; - } + object v = null; + if (!TryConvert(genericArgs[0], valueObj, ref v)) + return false; - if (valueObj == null) - { - value = null; + value = Activator.CreateInstance(nullableType, v); return true; } + } - // Nullable - if (type.IsGenericType) + if (value == null && type.IsClass && !type.IsAbstract && !type.IsArray) + { + value = Activator.CreateInstance(type); + } + + var success = false; + if (typeof(IDictionary).IsAssignableFrom(type)) + { + var itf = type.IsInterface && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>) + ? type + : type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary<,>)); + + if (itf != null) { - var genericArgs = type.GetGenericArguments(); - if (genericArgs.Length == 1 && genericArgs[0].IsValueType) + var args = itf.GetGenericArguments(); + if (args.Length != 2 || args[0] != typeof(string) || valueObj is not Dictionary valueDict) + return false; + + var itemType = args[1]; + var dict = value as IDictionary; + if (dict == null) { - var nullableType = typeof(Nullable<>).MakeGenericType(genericArgs); - if (!type.IsAssignableFrom(nullableType)) + var dictType = typeof(Dictionary<,>).MakeGenericType(args); + if (!type.IsAssignableFrom(dictType)) return false; + dict = (IDictionary)Activator.CreateInstance(dictType); + } + + foreach (var key in valueDict.Keys.Select(x => x as string ?? throw new InvalidOperationException($"Not supported key: {x}")).ToArray()) + { object v = null; - if (!TryConvert(genericArgs[0], valueObj, ref v)) + if (!TryConvert(itemType, valueDict[key], ref v)) return false; - value = Activator.CreateInstance(nullableType, v); - return true; + dict[key] = v; } - } - if (value == null && type.IsClass && !type.IsAbstract && !type.IsArray) - { - value = Activator.CreateInstance(type); + value = dict; + success = true; } - - var success = false; - if (typeof(IDictionary).IsAssignableFrom(type)) + } + else if (typeof(IEnumerable).IsAssignableFrom(type)) + { + if (type.IsArray) { - var itf = type.IsInterface && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IDictionary<,>) - ? type - : type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary<,>)); + if (type.GetArrayRank() != 1) + return false; - if (itf != null) + var itemType = type.GetElementType(); + if (itemType == null || valueObj is not List valueArr) + return false; + + var arr = Array.CreateInstance(itemType, valueArr.Count); + for (var i = 0; i < valueArr.Count; i++) { - var args = itf.GetGenericArguments(); - if (args.Length != 2 || args[0] != typeof(string) || valueObj is not Dictionary valueDict) + object v = null; + if (!TryConvert(itemType, valueArr[i], ref v)) return false; - var itemType = args[1]; - var dict = value as IDictionary; - if (dict == null) - { - var dictType = typeof(Dictionary<,>).MakeGenericType(args); - if (!type.IsAssignableFrom(dictType)) - return false; - - dict = (IDictionary)Activator.CreateInstance(dictType); - } + arr.SetValue(v, i); + } - foreach (var key in valueDict.Keys.Select(x => x as string ?? throw new InvalidOperationException($"Not supported key: {x}")).ToArray()) - { - object v = null; - if (!TryConvert(itemType, valueDict[key], ref v)) - return false; + value = arr; + return true; + } - dict[key] = v; - } + var itf = type.IsInterface && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>) + ? type + : type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>)); - value = dict; - success = true; - } - } - else if (typeof(IEnumerable).IsAssignableFrom(type)) + if (itf != null) { - if (type.IsArray) - { - if (type.GetArrayRank() != 1) - return false; + var args = itf.GetGenericArguments(); + if (args.Length != 1 || valueObj is not List valueArr) + return false; - var itemType = type.GetElementType(); - if (itemType == null || valueObj is not List valueArr) + var itemType = args[0]; + var list = value as IList; + if (list == null) + { + var listType = typeof(List<>).MakeGenericType(itemType); + if (!type.IsAssignableFrom(listType)) return false; - var arr = Array.CreateInstance(itemType, valueArr.Count); - for (var i = 0; i < valueArr.Count; i++) - { - object v = null; - if (!TryConvert(itemType, valueArr[i], ref v)) - return false; - - arr.SetValue(v, i); - } - - value = arr; - return true; + list = (IList)Activator.CreateInstance(listType); } - var itf = type.IsInterface && type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>) - ? type - : type.GetInterfaces().FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IList<>)); - - if (itf != null) + foreach (var item in valueArr) { - var args = itf.GetGenericArguments(); - if (args.Length != 1 || valueObj is not List valueArr) + object v = null; + if (!TryConvert(itemType, item, ref v)) return false; - var itemType = args[0]; - var list = value as IList; - if (list == null) - { - var listType = typeof(List<>).MakeGenericType(itemType); - if (!type.IsAssignableFrom(listType)) - return false; - - list = (IList)Activator.CreateInstance(listType); - } - - foreach (var item in valueArr) - { - object v = null; - if (!TryConvert(itemType, item, ref v)) - return false; - - list.Add(v); - } - - value = list; - success = true; + list.Add(v); } - } - if (type.IsClass) - { - if (valueObj is not Dictionary tempDict) - return success; + value = list; + success = true; + } + } - var valueDict = tempDict.ToDictionary(x => (string)x.Key, x => x.Value, StringComparer.OrdinalIgnoreCase); - foreach (var property in type.GetProperties()) - { - if (!valueDict.TryGetValue(property.Name, out var vObj)) - continue; + if (type.IsClass) + { + if (valueObj is not Dictionary tempDict) + return success; - var v = property.GetValue(value); - if (v == null && !property.CanWrite) - return false; + var valueDict = tempDict.ToDictionary(x => (string)x.Key, x => x.Value, StringComparer.OrdinalIgnoreCase); + foreach (var property in type.GetProperties()) + { + if (!valueDict.TryGetValue(property.Name, out var vObj)) + continue; - if (!TryConvert(property.PropertyType, vObj, ref v)) - return false; + var v = property.GetValue(value); + if (v == null && !property.CanWrite) + return false; - if (property.CanWrite) - property.SetValue(value, v); - } + if (!TryConvert(property.PropertyType, vObj, ref v)) + return false; - return true; + if (property.CanWrite) + property.SetValue(value, v); } - return success; + return true; } - private static bool TryParseEnum(Type type, string value, out object result) + return success; + } + + private static bool TryParseEnum(Type type, string value, out object result) + { + try { - try - { - result = Enum.Parse(type, value, ignoreCase: true); - return true; - } - catch - { - result = default; - return false; - } + result = Enum.Parse(type, value, ignoreCase: true); + return true; + } + catch + { + result = default; + return false; } } } diff --git a/NGitLab.Mock/Config/GitLabCollection.cs b/NGitLab.Mock/Config/GitLabCollection.cs index 62b7d355..7a553392 100644 --- a/NGitLab.Mock/Config/GitLabCollection.cs +++ b/NGitLab.Mock/Config/GitLabCollection.cs @@ -1,47 +1,46 @@ using System.Linq; -namespace NGitLab.Mock.Config +namespace NGitLab.Mock.Config; + +public abstract class GitLabCollection : System.Collections.ObjectModel.Collection + where TItem : GitLabObject { - public abstract class GitLabCollection : System.Collections.ObjectModel.Collection - where TItem : GitLabObject + internal readonly object _parent; + + protected internal GitLabCollection(object parent) + { + _parent = parent; + } + + protected override void InsertItem(int index, TItem item) + { + SetItem(item); + base.InsertItem(index, item); + } + + protected override void SetItem(int index, TItem item) { - internal readonly object _parent; - - protected internal GitLabCollection(object parent) - { - _parent = parent; - } - - protected override void InsertItem(int index, TItem item) - { - SetItem(item); - base.InsertItem(index, item); - } - - protected override void SetItem(int index, TItem item) - { - SetItem(item); - base.SetItem(index, item); - } - - internal virtual void SetItem(TItem item) - { - if (item == null) - return; - - item.Parent = _parent; - - if (item.Id == default) - item.Id = Items.Select(x => x.Id).DefaultIfEmpty().Max() + 1; - } + SetItem(item); + base.SetItem(index, item); } - public abstract class GitLabCollection : GitLabCollection - where TItem : GitLabObject + internal virtual void SetItem(TItem item) + { + if (item == null) + return; + + item.Parent = _parent; + + if (item.Id == default) + item.Id = Items.Select(x => x.Id).DefaultIfEmpty().Max() + 1; + } +} + +public abstract class GitLabCollection : GitLabCollection + where TItem : GitLabObject +{ + protected internal GitLabCollection(TParent parent) + : base(parent) { - protected internal GitLabCollection(TParent parent) - : base(parent) - { - } } } diff --git a/NGitLab.Mock/Config/GitLabComment.cs b/NGitLab.Mock/Config/GitLabComment.cs index 47b5cd0f..0f8b0621 100644 --- a/NGitLab.Mock/Config/GitLabComment.cs +++ b/NGitLab.Mock/Config/GitLabComment.cs @@ -1,51 +1,50 @@ using System; -namespace NGitLab.Mock.Config +namespace NGitLab.Mock.Config; + +public class GitLabComment : GitLabObject { - public class GitLabComment : GitLabObject - { - /// - /// Author username (required if default user not defined) - /// - public string Author { get; set; } + /// + /// Author username (required if default user not defined) + /// + public string Author { get; set; } + + public string Message { get; set; } - public string Message { get; set; } + /// + /// Indicates if comment is from GitLab system + /// + public bool System { get; set; } - /// - /// Indicates if comment is from GitLab system - /// - public bool System { get; set; } + public DateTime? CreatedAt { get; set; } - public DateTime? CreatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } - public DateTime? UpdatedAt { get; set; } + /// + /// Comment thread (all comments with same thread are grouped) + /// + public string Thread { get; set; } - /// - /// Comment thread (all comments with same thread are grouped) - /// - public string Thread { get; set; } + /// + /// Indicates if comment is resolvable (only for merge request comments) + /// + public bool Resolvable { get; set; } - /// - /// Indicates if comment is resolvable (only for merge request comments) - /// - public bool Resolvable { get; set; } + /// + /// Indicates if comment is resolved (only for merge request comments and resolvable) + /// + public bool Resolved { get; set; } +} - /// - /// Indicates if comment is resolved (only for merge request comments and resolvable) - /// - public bool Resolved { get; set; } +public class GitLabCommentsCollection : GitLabCollection +{ + internal GitLabCommentsCollection(GitLabIssue parent) + : base(parent) + { } - public class GitLabCommentsCollection : GitLabCollection + internal GitLabCommentsCollection(GitLabMergeRequest parent) + : base(parent) { - internal GitLabCommentsCollection(GitLabIssue parent) - : base(parent) - { - } - - internal GitLabCommentsCollection(GitLabMergeRequest parent) - : base(parent) - { - } } } diff --git a/NGitLab.Mock/Config/GitLabCommit.cs b/NGitLab.Mock/Config/GitLabCommit.cs index 7034142e..fb2eb4db 100644 --- a/NGitLab.Mock/Config/GitLabCommit.cs +++ b/NGitLab.Mock/Config/GitLabCommit.cs @@ -1,62 +1,61 @@ using System.Collections.Generic; -namespace NGitLab.Mock.Config +namespace NGitLab.Mock.Config; + +/// +/// Describe a commit in a GitLab project +/// +public class GitLabCommit : GitLabObject { /// - /// Describe a commit in a GitLab project + /// Author username (required if default user not defined) /// - public class GitLabCommit : GitLabObject - { - /// - /// Author username (required if default user not defined) - /// - public string User { get; set; } - - public string Message { get; set; } - - /// - /// Alias to reference it in pipeline - /// - public string Alias { get; set; } - - /// - /// Files in the repository at this commit - /// - public IList Files { get; } = new List(); - - /// - /// Submodules added at this commit - /// - public IList SubModules { get; } = new List(); - - public IList Tags { get; } = new List(); - - /// - /// Source branch if a checkout or for a merge commit (required for merge commit) - /// - public string SourceBranch { get; set; } - - /// - /// Target branch for a merge commit (required for merge commit) - /// - public string TargetBranch { get; set; } - - /// - /// Branch to checkout before make more operation - /// - public string FromBranch { get; set; } - - /// - /// Indicates if source branch must be deleted after merge - /// - public bool DeleteSourceBranch { get; set; } - } + public string User { get; set; } + + public string Message { get; set; } + + /// + /// Alias to reference it in pipeline + /// + public string Alias { get; set; } + + /// + /// Files in the repository at this commit + /// + public IList Files { get; } = new List(); + + /// + /// Submodules added at this commit + /// + public IList SubModules { get; } = new List(); + + public IList Tags { get; } = new List(); - public class GitLabCommitsCollection : GitLabCollection + /// + /// Source branch if a checkout or for a merge commit (required for merge commit) + /// + public string SourceBranch { get; set; } + + /// + /// Target branch for a merge commit (required for merge commit) + /// + public string TargetBranch { get; set; } + + /// + /// Branch to checkout before make more operation + /// + public string FromBranch { get; set; } + + /// + /// Indicates if source branch must be deleted after merge + /// + public bool DeleteSourceBranch { get; set; } +} + +public class GitLabCommitsCollection : GitLabCollection +{ + internal GitLabCommitsCollection(GitLabProject parent) + : base(parent) { - internal GitLabCommitsCollection(GitLabProject parent) - : base(parent) - { - } } } diff --git a/NGitLab.Mock/Config/GitLabConfig.cs b/NGitLab.Mock/Config/GitLabConfig.cs index debefe77..57776da0 100644 --- a/NGitLab.Mock/Config/GitLabConfig.cs +++ b/NGitLab.Mock/Config/GitLabConfig.cs @@ -1,67 +1,66 @@ using NGitLab.Models; -namespace NGitLab.Mock.Config +namespace NGitLab.Mock.Config; + +/// +/// Describe content of a GitLab server +/// +public class GitLabConfig { - /// - /// Describe content of a GitLab server - /// - public class GitLabConfig + public GitLabConfig() { - public GitLabConfig() - { - Users = new GitLabUsersCollection(this); - Groups = new GitLabGroupsCollection(this); - Projects = new GitLabProjectsCollection(this); - } + Users = new GitLabUsersCollection(this); + Groups = new GitLabGroupsCollection(this); + Projects = new GitLabProjectsCollection(this); + } - /// - /// Server url - /// - public string Url { get; set; } + /// + /// Server url + /// + public string Url { get; set; } - /// - /// User used by default when not specified in extensions methods - /// - public string DefaultUser { get; set; } + /// + /// User used by default when not specified in extensions methods + /// + public string DefaultUser { get; set; } - /// - /// Branch name by default when not specified in extensions methods or deserialize - /// - public string DefaultBranch { get; set; } + /// + /// Branch name by default when not specified in extensions methods or deserialize + /// + public string DefaultBranch { get; set; } - /// - /// Groups and projects default visibility - /// - public VisibilityLevel DefaultVisibility { get; set; } = VisibilityLevel.Internal; + /// + /// Groups and projects default visibility + /// + public VisibilityLevel DefaultVisibility { get; set; } = VisibilityLevel.Internal; - public GitLabUsersCollection Users { get; } + public GitLabUsersCollection Users { get; } - /// - /// Explicit groups - /// - public GitLabGroupsCollection Groups { get; } + /// + /// Explicit groups + /// + public GitLabGroupsCollection Groups { get; } - public GitLabProjectsCollection Projects { get; } + public GitLabProjectsCollection Projects { get; } - /// - /// Serialize config to YAML format - /// - public string Serialize() - { - return ConfigSerializer.Serialize(this); - } + /// + /// Serialize config to YAML format + /// + public string Serialize() + { + return ConfigSerializer.Serialize(this); + } - /// - /// Deserialize YAML content to config - /// - public static GitLabConfig Deserialize(string content) - { - var serializer = new ConfigSerializer(); - serializer.Deserialize(content); - var config = new GitLabConfig(); - return serializer.TryGet("gitlab", ref config) - ? config - : throw new GitLabException("Cannot deserialize YAML config"); - } + /// + /// Deserialize YAML content to config + /// + public static GitLabConfig Deserialize(string content) + { + var serializer = new ConfigSerializer(); + serializer.Deserialize(content); + var config = new GitLabConfig(); + return serializer.TryGet("gitlab", ref config) + ? config + : throw new GitLabException("Cannot deserialize YAML config"); } } diff --git a/NGitLab.Mock/Config/GitLabFileDescriptor.cs b/NGitLab.Mock/Config/GitLabFileDescriptor.cs index 418487b5..29fea54d 100644 --- a/NGitLab.Mock/Config/GitLabFileDescriptor.cs +++ b/NGitLab.Mock/Config/GitLabFileDescriptor.cs @@ -1,18 +1,17 @@ -namespace NGitLab.Mock.Config +namespace NGitLab.Mock.Config; + +/// +/// Describe a file in project repository +/// +public class GitLabFileDescriptor { /// - /// Describe a file in project repository + /// Relative path to file (required) /// - public class GitLabFileDescriptor - { - /// - /// Relative path to file (required) - /// - public string Path { get; set; } + public string Path { get; set; } - /// - /// File content - /// - public string Content { get; set; } - } + /// + /// File content + /// + public string Content { get; set; } } diff --git a/NGitLab.Mock/Config/GitLabGroup.cs b/NGitLab.Mock/Config/GitLabGroup.cs index 06746af5..5aa137f9 100644 --- a/NGitLab.Mock/Config/GitLabGroup.cs +++ b/NGitLab.Mock/Config/GitLabGroup.cs @@ -1,45 +1,44 @@ using NGitLab.Models; -namespace NGitLab.Mock.Config +namespace NGitLab.Mock.Config; + +/// +/// Describe a GitLab group +/// +public class GitLabGroup : GitLabObject { - /// - /// Describe a GitLab group - /// - public class GitLabGroup : GitLabObject + public GitLabGroup() { - public GitLabGroup() - { - Labels = new GitLabLabelsCollection(this); - Permissions = new GitLabPermissionsCollection(this); - Milestones = new GitLabMilestonesCollection(this); - } + Labels = new GitLabLabelsCollection(this); + Permissions = new GitLabPermissionsCollection(this); + Milestones = new GitLabMilestonesCollection(this); + } - /// - /// Name (required) - /// - public string Name { get; set; } + /// + /// Name (required) + /// + public string Name { get; set; } - /// - /// Parent namespace - /// - public string Namespace { get; set; } + /// + /// Parent namespace + /// + public string Namespace { get; set; } - public string Description { get; set; } + public string Description { get; set; } - public VisibilityLevel? Visibility { get; set; } + public VisibilityLevel? Visibility { get; set; } - public GitLabLabelsCollection Labels { get; } + public GitLabLabelsCollection Labels { get; } - public GitLabPermissionsCollection Permissions { get; } + public GitLabPermissionsCollection Permissions { get; } - public GitLabMilestonesCollection Milestones { get; } - } + public GitLabMilestonesCollection Milestones { get; } +} - public class GitLabGroupsCollection : GitLabCollection +public class GitLabGroupsCollection : GitLabCollection +{ + internal GitLabGroupsCollection(GitLabConfig parent) + : base(parent) { - internal GitLabGroupsCollection(GitLabConfig parent) - : base(parent) - { - } } } diff --git a/NGitLab.Mock/Config/GitLabHelpers.cs b/NGitLab.Mock/Config/GitLabHelpers.cs index 3ae2e4c8..5b5b52a1 100644 --- a/NGitLab.Mock/Config/GitLabHelpers.cs +++ b/NGitLab.Mock/Config/GitLabHelpers.cs @@ -11,2006 +11,2005 @@ #pragma warning disable RS0026 // Adding optional parameters to public methods #pragma warning disable RS0037 // Activate nullable values in public API -namespace NGitLab.Mock.Config +namespace NGitLab.Mock.Config; + +public static class GitLabHelpers { - public static class GitLabHelpers + public static GitLabConfig Configure(this GitLabConfig config, Action configure) { - public static GitLabConfig Configure(this GitLabConfig config, Action configure) - { - configure(config); - return config; - } + configure(config); + return config; + } - public static GitLabUser Configure(this GitLabUser user, Action configure) - { - return Configure(user, configure); - } + public static GitLabUser Configure(this GitLabUser user, Action configure) + { + return Configure(user, configure); + } - public static GitLabGroup Configure(this GitLabGroup group, Action configure) - { - return Configure(group, configure); - } + public static GitLabGroup Configure(this GitLabGroup group, Action configure) + { + return Configure(group, configure); + } - public static GitLabProject Configure(this GitLabProject project, Action configure) - { - return Configure(project, configure); - } + public static GitLabProject Configure(this GitLabProject project, Action configure) + { + return Configure(project, configure); + } - public static GitLabCommit Configure(this GitLabCommit commit, Action configure) - { - return Configure(commit, configure); - } + public static GitLabCommit Configure(this GitLabCommit commit, Action configure) + { + return Configure(commit, configure); + } - public static GitLabIssue Configure(this GitLabIssue issue, Action configure) - { - return Configure(issue, configure); - } + public static GitLabIssue Configure(this GitLabIssue issue, Action configure) + { + return Configure(issue, configure); + } - public static GitLabMergeRequest Configure(this GitLabMergeRequest mergeRequest, Action configure) - { - return Configure(mergeRequest, configure); - } + public static GitLabMergeRequest Configure(this GitLabMergeRequest mergeRequest, Action configure) + { + return Configure(mergeRequest, configure); + } - private static T Configure(this T gitLabObject, Action configure) - where T : GitLabObject - { - configure(gitLabObject); - return gitLabObject; - } + private static T Configure(this T gitLabObject, Action configure) + where T : GitLabObject + { + configure(gitLabObject); + return gitLabObject; + } - public static GitLabPipeline Configure(this GitLabPipeline pipeline, Action configure) - { - configure(pipeline); - return pipeline; - } + public static GitLabPipeline Configure(this GitLabPipeline pipeline, Action configure) + { + configure(pipeline); + return pipeline; + } - /// - /// Add a user description in config - /// - /// Config. - /// Username (required) - /// Configuration method - public static GitLabConfig WithUser(this GitLabConfig config, string username, Action configure) + /// + /// Add a user description in config + /// + /// Config. + /// Username (required) + /// Configuration method + public static GitLabConfig WithUser(this GitLabConfig config, string username, Action configure) + { + return Configure(config, _ => { - return Configure(config, _ => + var user = new GitLabUser { - var user = new GitLabUser - { - Username = username ?? throw new ArgumentNullException(nameof(username)), - }; + Username = username ?? throw new ArgumentNullException(nameof(username)), + }; - config.Users.Add(user); - configure(user); - }); - } + config.Users.Add(user); + configure(user); + }); + } - /// - /// Add a user description in config - /// - /// Config. - /// Username (required) - /// Name. - /// Email. - /// Avatar URL. - /// Indicates if user is admin in GitLab server - /// Define as default user for next descriptions - /// Configuration method - public static GitLabConfig WithUser(this GitLabConfig config, string username, string? name = null, string? email = null, string? avatarUrl = null, bool isAdmin = false, bool isDefault = false, Action? configure = null) - { - return WithUser(config, username, user => + /// + /// Add a user description in config + /// + /// Config. + /// Username (required) + /// Name. + /// Email. + /// Avatar URL. + /// Indicates if user is admin in GitLab server + /// Define as default user for next descriptions + /// Configuration method + public static GitLabConfig WithUser(this GitLabConfig config, string username, string? name = null, string? email = null, string? avatarUrl = null, bool isAdmin = false, bool isDefault = false, Action? configure = null) + { + return WithUser(config, username, user => + { + user.Name = name; + user.Email = email; + user.AvatarUrl = avatarUrl; + user.IsAdmin = isAdmin; + if (isDefault) { - user.Name = name; - user.Email = email; - user.AvatarUrl = avatarUrl; - user.IsAdmin = isAdmin; - if (isDefault) - { - user.AsDefaultUser(); - } + user.AsDefaultUser(); + } - configure?.Invoke(user); - }); - } + configure?.Invoke(user); + }); + } - /// - /// Define a user as default for next descriptions - /// - /// User. - public static GitLabUser AsDefaultUser(this GitLabUser user) + /// + /// Define a user as default for next descriptions + /// + /// User. + public static GitLabUser AsDefaultUser(this GitLabUser user) + { + return Configure(user, _ => { - return Configure(user, _ => - { - user.Parent.DefaultUser = user.Username; - }); - } + user.Parent.DefaultUser = user.Username; + }); + } - /// - /// Define a user as default for next descriptions - /// - /// Config. - /// Username. - public static GitLabConfig SetDefaultUser(this GitLabConfig config, string username) + /// + /// Define a user as default for next descriptions + /// + /// Config. + /// Username. + public static GitLabConfig SetDefaultUser(this GitLabConfig config, string username) + { + return Configure(config, _ => { - return Configure(config, _ => - { - config.DefaultUser = username; - }); - } + config.DefaultUser = username; + }); + } - /// - /// Define default branch for next descriptions - /// - /// Config. - /// Branch name. - /// - public static GitLabConfig SetDefaultBranch(this GitLabConfig config, string branchName) + /// + /// Define default branch for next descriptions + /// + /// Config. + /// Branch name. + /// + public static GitLabConfig SetDefaultBranch(this GitLabConfig config, string branchName) + { + return Configure(config, _ => { - return Configure(config, _ => - { - config.DefaultBranch = branchName; - }); - } + config.DefaultBranch = branchName; + }); + } - /// - /// Define default groups and projects visibility - /// - /// Config. - /// Visibility. - /// - public static GitLabConfig SetDefaultVisibility(this GitLabConfig config, VisibilityLevel visibility) + /// + /// Define default groups and projects visibility + /// + /// Config. + /// Visibility. + /// + public static GitLabConfig SetDefaultVisibility(this GitLabConfig config, VisibilityLevel visibility) + { + return Configure(config, _ => { - return Configure(config, _ => - { - config.DefaultVisibility = visibility; - }); - } + config.DefaultVisibility = visibility; + }); + } - /// - /// Add an explicit group description in config - /// - /// Config. - /// Name. - /// Configuration method - public static GitLabConfig WithGroup(this GitLabConfig config, string? name, Action configure) + /// + /// Add an explicit group description in config + /// + /// Config. + /// Name. + /// Configuration method + public static GitLabConfig WithGroup(this GitLabConfig config, string? name, Action configure) + { + return Configure(config, _ => { - return Configure(config, _ => + var group = new GitLabGroup { - var group = new GitLabGroup - { - Name = name ?? Guid.NewGuid().ToString("D"), - }; + Name = name ?? Guid.NewGuid().ToString("D"), + }; - config.Groups.Add(group); - configure(group); - }); - } + config.Groups.Add(group); + configure(group); + }); + } - /// - /// Add an explicit group description in config - /// - /// Config. - /// Name. - /// Explicit ID (config increment) - /// Parent namespace. - /// Description. - /// Visibility. - /// Define default user as maintainer. - /// Configuration method - public static GitLabConfig WithGroup(this GitLabConfig config, string? name = null, int id = default, string? @namespace = null, string? description = null, VisibilityLevel? visibility = null, bool addDefaultUserAsMaintainer = false, Action? configure = null) - { - return WithGroup(config, name, group => - { - if (id != default) - group.Id = id; + /// + /// Add an explicit group description in config + /// + /// Config. + /// Name. + /// Explicit ID (config increment) + /// Parent namespace. + /// Description. + /// Visibility. + /// Define default user as maintainer. + /// Configuration method + public static GitLabConfig WithGroup(this GitLabConfig config, string? name = null, int id = default, string? @namespace = null, string? description = null, VisibilityLevel? visibility = null, bool addDefaultUserAsMaintainer = false, Action? configure = null) + { + return WithGroup(config, name, group => + { + if (id != default) + group.Id = id; - group.Namespace = @namespace; - group.Description = description; - group.Visibility = visibility; + group.Namespace = @namespace; + group.Description = description; + group.Visibility = visibility; - if (addDefaultUserAsMaintainer) - { - if (string.IsNullOrEmpty(group.Parent.DefaultUser)) - throw new InvalidOperationException("Default user not configured"); + if (addDefaultUserAsMaintainer) + { + if (string.IsNullOrEmpty(group.Parent.DefaultUser)) + throw new InvalidOperationException("Default user not configured"); - WithUserPermission(group, group.Parent.DefaultUser, AccessLevel.Maintainer); - } + WithUserPermission(group, group.Parent.DefaultUser, AccessLevel.Maintainer); + } - configure?.Invoke(group); - }); - } + configure?.Invoke(group); + }); + } - /// - /// Add a project description in config - /// - /// Config. - /// Name. - /// Configuration method - public static GitLabConfig WithProject(this GitLabConfig config, string? name, Action configure) + /// + /// Add a project description in config + /// + /// Config. + /// Name. + /// Configuration method + public static GitLabConfig WithProject(this GitLabConfig config, string? name, Action configure) + { + return Configure(config, _ => { - return Configure(config, _ => + var project = new GitLabProject { - var project = new GitLabProject - { - Name = name, - }; + Name = name, + }; - config.Projects.Add(project); - configure(project); - }); - } + config.Projects.Add(project); + configure(project); + }); + } - /// - /// Add a project description in config - /// - /// Config. - /// Name. - /// Explicit ID (config increment) - /// Group fullname. - /// Description. - /// Repository default branch. - /// Visibility. - /// Indicates if an initial commit is added. - /// Define default user as maintainer. - /// Path where to clone repository after server resolving - /// Parameters passed to clone command - /// Configuration method - public static GitLabConfig WithProject(this GitLabConfig config, string? name = null, int id = default, string? @namespace = null, string? description = null, - string? defaultBranch = null, VisibilityLevel visibility = VisibilityLevel.Internal, bool initialCommit = false, - bool addDefaultUserAsMaintainer = false, string? clonePath = null, string? cloneParameters = null, Action? configure = null) - { - return WithProject(config, name, project => - { - if (id != default) - project.Id = id; + /// + /// Add a project description in config + /// + /// Config. + /// Name. + /// Explicit ID (config increment) + /// Group fullname. + /// Description. + /// Repository default branch. + /// Visibility. + /// Indicates if an initial commit is added. + /// Define default user as maintainer. + /// Path where to clone repository after server resolving + /// Parameters passed to clone command + /// Configuration method + public static GitLabConfig WithProject(this GitLabConfig config, string? name = null, int id = default, string? @namespace = null, string? description = null, + string? defaultBranch = null, VisibilityLevel visibility = VisibilityLevel.Internal, bool initialCommit = false, + bool addDefaultUserAsMaintainer = false, string? clonePath = null, string? cloneParameters = null, Action? configure = null) + { + return WithProject(config, name, project => + { + if (id != default) + project.Id = id; - project.Namespace = @namespace; - project.Description = description; - project.DefaultBranch = defaultBranch ?? config.DefaultBranch ?? "main"; - project.Visibility = visibility; - project.ClonePath = clonePath; - project.CloneParameters = cloneParameters; + project.Namespace = @namespace; + project.Description = description; + project.DefaultBranch = defaultBranch ?? config.DefaultBranch ?? "main"; + project.Visibility = visibility; + project.ClonePath = clonePath; + project.CloneParameters = cloneParameters; - if (initialCommit) + if (initialCommit) + { + WithCommit(project, "Initial commit", user: null, commit => { - WithCommit(project, "Initial commit", user: null, commit => - { - WithFile(commit, "README.md", $"# {name}{Environment.NewLine}"); - }); - } + WithFile(commit, "README.md", $"# {name}{Environment.NewLine}"); + }); + } - if (addDefaultUserAsMaintainer) - { - if (string.IsNullOrEmpty(project.Parent.DefaultUser)) - throw new InvalidOperationException("Default user not configured"); + if (addDefaultUserAsMaintainer) + { + if (string.IsNullOrEmpty(project.Parent.DefaultUser)) + throw new InvalidOperationException("Default user not configured"); - WithUserPermission(project, project.Parent.DefaultUser, AccessLevel.Maintainer); - } + WithUserPermission(project, project.Parent.DefaultUser, AccessLevel.Maintainer); + } - configure?.Invoke(project); - }); - } + configure?.Invoke(project); + }); + } - /// - /// Add a group description in group - /// - /// Group. - /// Name (required) - /// Color in RGB hex format (example: #A1F8C3) - /// Description. - public static GitLabGroup WithLabel(this GitLabGroup group, string name, string? color = null, string? description = null) + /// + /// Add a group description in group + /// + /// Group. + /// Name (required) + /// Color in RGB hex format (example: #A1F8C3) + /// Description. + public static GitLabGroup WithLabel(this GitLabGroup group, string name, string? color = null, string? description = null) + { + return Configure(group, _ => { - return Configure(group, _ => + var label = new GitLabLabel { - var label = new GitLabLabel - { - Name = name ?? throw new ArgumentNullException(nameof(name)), - Color = color, - Description = description, - }; + Name = name ?? throw new ArgumentNullException(nameof(name)), + Color = color, + Description = description, + }; - group.Labels.Add(label); - }); - } + group.Labels.Add(label); + }); + } - /// - /// Add a label description in project - /// - /// Project. - /// Name (required) - /// Color in RGB hex format (example: #A1F8C3) - /// Description. - public static GitLabProject WithLabel(this GitLabProject project, string name, string? color = null, string? description = null) + /// + /// Add a label description in project + /// + /// Project. + /// Name (required) + /// Color in RGB hex format (example: #A1F8C3) + /// Description. + public static GitLabProject WithLabel(this GitLabProject project, string name, string? color = null, string? description = null) + { + return Configure(project, _ => { - return Configure(project, _ => + var label = new GitLabLabel { - var label = new GitLabLabel - { - Name = name ?? throw new ArgumentNullException(nameof(name)), - Color = color, - Description = description, - }; + Name = name ?? throw new ArgumentNullException(nameof(name)), + Color = color, + Description = description, + }; - project.Labels.Add(label); - }); - } + project.Labels.Add(label); + }); + } - /// - /// Add a commit description in project - /// - /// Project. - /// Message (required) - /// Author username (required if default user not defined) - /// Configuration method - public static GitLabProject WithCommit(this GitLabProject project, string? message, string? user, Action configure) + /// + /// Add a commit description in project + /// + /// Project. + /// Message (required) + /// Author username (required if default user not defined) + /// Configuration method + public static GitLabProject WithCommit(this GitLabProject project, string? message, string? user, Action configure) + { + return Configure(project, _ => { - return Configure(project, _ => + var commit = new GitLabCommit { - var commit = new GitLabCommit - { - Message = message, - User = user, - }; + Message = message, + User = user, + }; - project.Commits.Add(commit); - configure(commit); - }); - } + project.Commits.Add(commit); + configure(commit); + }); + } - /// - /// Add a commit description in project - /// - /// Project. - /// Message (required) - /// Author username (required if default user not defined) - /// Source branch (required if checkout or merge) - /// Target branch (required if merge) - /// From branch - /// Tags. - /// Alias to reference it in pipeline. - /// Configuration method - public static GitLabProject WithCommit(this GitLabProject project, string? message = null, string? user = null, string? sourceBranch = null, string? targetBranch = null, string? fromBranch = null, IEnumerable? tags = null, string? alias = null, Action? configure = null) - { - return WithCommit(project, message, user, commit => + /// + /// Add a commit description in project + /// + /// Project. + /// Message (required) + /// Author username (required if default user not defined) + /// Source branch (required if checkout or merge) + /// Target branch (required if merge) + /// From branch + /// Tags. + /// Alias to reference it in pipeline. + /// Configuration method + public static GitLabProject WithCommit(this GitLabProject project, string? message = null, string? user = null, string? sourceBranch = null, string? targetBranch = null, string? fromBranch = null, IEnumerable? tags = null, string? alias = null, Action? configure = null) + { + return WithCommit(project, message, user, commit => + { + commit.SourceBranch = sourceBranch; + commit.TargetBranch = targetBranch; + commit.FromBranch = fromBranch; + commit.Alias = alias; + if (tags != null) { - commit.SourceBranch = sourceBranch; - commit.TargetBranch = targetBranch; - commit.FromBranch = fromBranch; - commit.Alias = alias; - if (tags != null) + foreach (var tag in tags) { - foreach (var tag in tags) - { - commit.Tags.Add(tag); - } + commit.Tags.Add(tag); } + } - configure?.Invoke(commit); - }); - } + configure?.Invoke(commit); + }); + } - /// - /// Add a merge commit in project - /// - /// Project. - /// Source branch (required) - /// Target branch - /// Author username (required if default user not defined) - /// Indicates if source branch must be deleted after merge. - /// Tags. - /// Configuration method - public static GitLabProject WithMergeCommit(this GitLabProject project, string sourceBranch, string? targetBranch = null, string? user = null, bool deleteSourceBranch = false, IEnumerable? tags = null, Action? configure = null) - { - return WithCommit(project, $"Merge '{sourceBranch}' into '{targetBranch ?? project.DefaultBranch}'", user, commit => + /// + /// Add a merge commit in project + /// + /// Project. + /// Source branch (required) + /// Target branch + /// Author username (required if default user not defined) + /// Indicates if source branch must be deleted after merge. + /// Tags. + /// Configuration method + public static GitLabProject WithMergeCommit(this GitLabProject project, string sourceBranch, string? targetBranch = null, string? user = null, bool deleteSourceBranch = false, IEnumerable? tags = null, Action? configure = null) + { + return WithCommit(project, $"Merge '{sourceBranch}' into '{targetBranch ?? project.DefaultBranch}'", user, commit => + { + commit.SourceBranch = sourceBranch ?? throw new ArgumentNullException(nameof(sourceBranch)); + commit.TargetBranch = targetBranch ?? project.DefaultBranch; + commit.DeleteSourceBranch = deleteSourceBranch; + if (tags != null) { - commit.SourceBranch = sourceBranch ?? throw new ArgumentNullException(nameof(sourceBranch)); - commit.TargetBranch = targetBranch ?? project.DefaultBranch; - commit.DeleteSourceBranch = deleteSourceBranch; - if (tags != null) + foreach (var tag in tags) { - foreach (var tag in tags) - { - commit.Tags.Add(tag); - } + commit.Tags.Add(tag); } + } - configure?.Invoke(commit); - }); - } + configure?.Invoke(commit); + }); + } - /// - /// Add a tag description in commit - /// - /// Commit. - /// Name (required) - public static GitLabCommit WithTag(this GitLabCommit commit, string name) + /// + /// Add a tag description in commit + /// + /// Commit. + /// Name (required) + public static GitLabCommit WithTag(this GitLabCommit commit, string name) + { + return Configure(commit, _ => { - return Configure(commit, _ => - { - commit.Tags.Add(name ?? throw new ArgumentNullException(nameof(name))); - }); - } + commit.Tags.Add(name ?? throw new ArgumentNullException(nameof(name))); + }); + } - /// - /// Add a file description in commit - /// - /// Commit. - /// Relative path (required) - /// File Content - public static GitLabCommit WithFile(this GitLabCommit commit, string relativePath, string content = "") + /// + /// Add a file description in commit + /// + /// Commit. + /// Relative path (required) + /// File Content + public static GitLabCommit WithFile(this GitLabCommit commit, string relativePath, string content = "") + { + return Configure(commit, _ => { - return Configure(commit, _ => + commit.Files.Add(new GitLabFileDescriptor { - commit.Files.Add(new GitLabFileDescriptor - { - Path = relativePath ?? throw new ArgumentNullException(nameof(relativePath)), - Content = content, - }); + Path = relativePath ?? throw new ArgumentNullException(nameof(relativePath)), + Content = content, }); - } + }); + } - /// - /// Add a submodule in commit - /// - public static GitLabCommit WithSubModule(this GitLabCommit commit, string projectName) + /// + /// Add a submodule in commit + /// + public static GitLabCommit WithSubModule(this GitLabCommit commit, string projectName) + { + return Configure(commit, _ => { - return Configure(commit, _ => + commit.SubModules.Add(new GitLabSubModuleDescriptor { - commit.SubModules.Add(new GitLabSubModuleDescriptor - { - ProjectName = projectName, - }); + ProjectName = projectName, }); - } + }); + } - /// - /// Add an issue description in project - /// - /// Project. - /// Title. - /// Author username (required if default user not defined) - /// Configuration method - public static GitLabProject WithIssue(this GitLabProject project, string? title, string? author, Action configure) + /// + /// Add an issue description in project + /// + /// Project. + /// Title. + /// Author username (required if default user not defined) + /// Configuration method + public static GitLabProject WithIssue(this GitLabProject project, string? title, string? author, Action configure) + { + return Configure(project, _ => { - return Configure(project, _ => + var issue = new GitLabIssue { - var issue = new GitLabIssue - { - Title = title, - Author = author, - }; + Title = title, + Author = author, + }; - project.Issues.Add(issue); - configure(issue); - }); - } + project.Issues.Add(issue); + configure(issue); + }); + } + + /// + /// Add an issue description in project + /// + /// Project. + /// Title. + /// Explicit ID (project increment) + /// Description. + /// Author username (required if default user nor defined) + /// Assignee username (allow multiple separated by ',') + /// Milestone title (create it if not exists) + /// Creation date time. + /// Update date time. + /// Close date time. + /// Labels names. + /// Configuration method + public static GitLabProject WithIssue(this GitLabProject project, string? title = null, int id = default, string? description = null, string? author = null, string? assignee = null, string? milestone = null, DateTime? createdAt = null, DateTime? updatedAt = null, DateTime? closedAt = null, IEnumerable? labels = null, Action? configure = null) + { + return WithIssue(project, title, author, issue => + { + if (id != default) + issue.Id = id; - /// - /// Add an issue description in project - /// - /// Project. - /// Title. - /// Explicit ID (project increment) - /// Description. - /// Author username (required if default user nor defined) - /// Assignee username (allow multiple separated by ',') - /// Milestone title (create it if not exists) - /// Creation date time. - /// Update date time. - /// Close date time. - /// Labels names. - /// Configuration method - public static GitLabProject WithIssue(this GitLabProject project, string? title = null, int id = default, string? description = null, string? author = null, string? assignee = null, string? milestone = null, DateTime? createdAt = null, DateTime? updatedAt = null, DateTime? closedAt = null, IEnumerable? labels = null, Action? configure = null) - { - return WithIssue(project, title, author, issue => + issue.Description = description; + issue.Assignee = assignee; + issue.Milestone = milestone; + issue.CreatedAt = createdAt; + issue.UpdatedAt = updatedAt; + issue.ClosedAt = closedAt; + if (labels != null) { - if (id != default) - issue.Id = id; - - issue.Description = description; - issue.Assignee = assignee; - issue.Milestone = milestone; - issue.CreatedAt = createdAt; - issue.UpdatedAt = updatedAt; - issue.ClosedAt = closedAt; - if (labels != null) + foreach (var label in labels) { - foreach (var label in labels) - { - WithLabel(issue, label); - } + WithLabel(issue, label); } + } - configure?.Invoke(issue); - }); - } + configure?.Invoke(issue); + }); + } - public static GitLabProject WithRelease(this GitLabProject project, string author, string tagName, DateTime? createdAt = null, DateTime? releasedAt = null) + public static GitLabProject WithRelease(this GitLabProject project, string author, string tagName, DateTime? createdAt = null, DateTime? releasedAt = null) + { + return Configure(project, _ => { - return Configure(project, _ => + var date = DateTime.UtcNow; + var release = new GitLabReleaseInfo { - var date = DateTime.UtcNow; - var release = new GitLabReleaseInfo - { - Author = author, - TagName = tagName, - CreatedAt = createdAt ?? date, - ReleasedAt = releasedAt ?? date, - }; + Author = author, + TagName = tagName, + CreatedAt = createdAt ?? date, + ReleasedAt = releasedAt ?? date, + }; - project.Releases.Add(release); - }); - } + project.Releases.Add(release); + }); + } - /// - /// Add label in issue (create it if not exists) - /// - /// Issue. - /// Label name (required) - public static GitLabIssue WithLabel(this GitLabIssue issue, string label) + /// + /// Add label in issue (create it if not exists) + /// + /// Issue. + /// Label name (required) + public static GitLabIssue WithLabel(this GitLabIssue issue, string label) + { + return Configure(issue, _ => { - return Configure(issue, _ => - { - issue.Labels.Add(label ?? throw new ArgumentNullException(nameof(label))); - }); - } + issue.Labels.Add(label ?? throw new ArgumentNullException(nameof(label))); + }); + } - /// - /// Add merge request description in project - /// - /// Project. - /// Source branch. - /// Title. - /// Author username (required if default user not defined) - /// Configuration method - public static GitLabProject WithMergeRequest(this GitLabProject project, string? sourceBranch, string? title, string? author, Action configure) - { - return Configure(project, _ => + /// + /// Add merge request description in project + /// + /// Project. + /// Source branch. + /// Title. + /// Author username (required if default user not defined) + /// Configuration method + public static GitLabProject WithMergeRequest(this GitLabProject project, string? sourceBranch, string? title, string? author, Action configure) + { + return Configure(project, _ => + { + var mergeRequest = new GitLabMergeRequest { - var mergeRequest = new GitLabMergeRequest - { - Title = title, - Author = author, - SourceBranch = sourceBranch, - TargetBranch = project.DefaultBranch, - }; - - project.MergeRequests.Add(mergeRequest); - configure(mergeRequest); - }); - } + Title = title, + Author = author, + SourceBranch = sourceBranch, + TargetBranch = project.DefaultBranch, + }; + + project.MergeRequests.Add(mergeRequest); + configure(mergeRequest); + }); + } - /// - /// Add merge request description in project - /// - /// Project. - /// Source branch (required) - /// Title. - /// Explicit ID (project increment) - /// Target branch (use default branch if null) - /// Description. - /// Author username (required if default user not defined) - /// Assignee username. - /// Creation date time. - /// Update date time. - /// Close date time. - /// Merge date time. - /// Approvers usernames. - /// Labels names. - /// Milestone name. - /// Configuration method - public static GitLabProject WithMergeRequest(this GitLabProject project, string? sourceBranch = null, string? title = null, int id = default, string? targetBranch = null, string? description = null, string? author = null, string? assignee = null, DateTime? createdAt = null, DateTime? updatedAt = null, DateTime? closedAt = null, DateTime? mergedAt = null, IEnumerable? approvers = null, IEnumerable? labels = null, string? milestone = null, Action? configure = null) - { - return WithMergeRequest(project, sourceBranch, title, author, mergeRequest => + /// + /// Add merge request description in project + /// + /// Project. + /// Source branch (required) + /// Title. + /// Explicit ID (project increment) + /// Target branch (use default branch if null) + /// Description. + /// Author username (required if default user not defined) + /// Assignee username. + /// Creation date time. + /// Update date time. + /// Close date time. + /// Merge date time. + /// Approvers usernames. + /// Labels names. + /// Milestone name. + /// Configuration method + public static GitLabProject WithMergeRequest(this GitLabProject project, string? sourceBranch = null, string? title = null, int id = default, string? targetBranch = null, string? description = null, string? author = null, string? assignee = null, DateTime? createdAt = null, DateTime? updatedAt = null, DateTime? closedAt = null, DateTime? mergedAt = null, IEnumerable? approvers = null, IEnumerable? labels = null, string? milestone = null, Action? configure = null) + { + return WithMergeRequest(project, sourceBranch, title, author, mergeRequest => + { + if (id != default) + mergeRequest.Id = id; + + mergeRequest.Description = description; + mergeRequest.Assignee = assignee; + mergeRequest.TargetBranch = targetBranch; + mergeRequest.CreatedAt = createdAt; + mergeRequest.UpdatedAt = updatedAt; + mergeRequest.ClosedAt = closedAt; + mergeRequest.MergedAt = mergedAt; + mergeRequest.Milestone = milestone; + + if (labels != null) { - if (id != default) - mergeRequest.Id = id; - - mergeRequest.Description = description; - mergeRequest.Assignee = assignee; - mergeRequest.TargetBranch = targetBranch; - mergeRequest.CreatedAt = createdAt; - mergeRequest.UpdatedAt = updatedAt; - mergeRequest.ClosedAt = closedAt; - mergeRequest.MergedAt = mergedAt; - mergeRequest.Milestone = milestone; - - if (labels != null) + foreach (var label in labels) { - foreach (var label in labels) - { - WithLabel(mergeRequest, label); - } + WithLabel(mergeRequest, label); } + } - if (approvers != null) + if (approvers != null) + { + foreach (var approver in approvers) { - foreach (var approver in approvers) - { - WithApprover(mergeRequest, approver); - } + WithApprover(mergeRequest, approver); } + } - configure?.Invoke(mergeRequest); - }); - } + configure?.Invoke(mergeRequest); + }); + } - /// - /// Add label in merge request (create it if not exists) - /// - /// Merge request. - /// Label name (required) - public static GitLabMergeRequest WithLabel(this GitLabMergeRequest mergeRequest, string label) + /// + /// Add label in merge request (create it if not exists) + /// + /// Merge request. + /// Label name (required) + public static GitLabMergeRequest WithLabel(this GitLabMergeRequest mergeRequest, string label) + { + return Configure(mergeRequest, _ => { - return Configure(mergeRequest, _ => - { - mergeRequest.Labels.Add(label ?? throw new ArgumentNullException(nameof(label))); - }); - } + mergeRequest.Labels.Add(label ?? throw new ArgumentNullException(nameof(label))); + }); + } - /// - /// Add approver in merge request - /// - /// Merge request. - /// Approver username (required) - public static GitLabMergeRequest WithApprover(this GitLabMergeRequest mergeRequest, string approver) + /// + /// Add approver in merge request + /// + /// Merge request. + /// Approver username (required) + public static GitLabMergeRequest WithApprover(this GitLabMergeRequest mergeRequest, string approver) + { + return Configure(mergeRequest, _ => { - return Configure(mergeRequest, _ => - { - mergeRequest.Approvers.Add(approver ?? throw new ArgumentNullException(nameof(approver))); - }); - } + mergeRequest.Approvers.Add(approver ?? throw new ArgumentNullException(nameof(approver))); + }); + } - /// - /// Add user permission in group - /// - /// Group. - /// Username (required) - /// Access level (required) - public static GitLabGroup WithUserPermission(this GitLabGroup group, string user, AccessLevel level) + /// + /// Add user permission in group + /// + /// Group. + /// Username (required) + /// Access level (required) + public static GitLabGroup WithUserPermission(this GitLabGroup group, string user, AccessLevel level) + { + return Configure(group, _ => { - return Configure(group, _ => + var permission = new GitLabPermission { - var permission = new GitLabPermission - { - User = user ?? throw new ArgumentNullException(nameof(user)), - Level = level, - }; + User = user ?? throw new ArgumentNullException(nameof(user)), + Level = level, + }; - group.Permissions.Add(permission); - }); - } + group.Permissions.Add(permission); + }); + } - /// - /// Add user permission in project - /// - /// Project. - /// Username (required) - /// Access level (required) - public static GitLabProject WithUserPermission(this GitLabProject project, string user, AccessLevel level) + /// + /// Add user permission in project + /// + /// Project. + /// Username (required) + /// Access level (required) + public static GitLabProject WithUserPermission(this GitLabProject project, string user, AccessLevel level) + { + return Configure(project, _ => { - return Configure(project, _ => + var permission = new GitLabPermission { - var permission = new GitLabPermission - { - User = user ?? throw new ArgumentNullException(nameof(user)), - Level = level, - }; + User = user ?? throw new ArgumentNullException(nameof(user)), + Level = level, + }; - project.Permissions.Add(permission); - }); - } + project.Permissions.Add(permission); + }); + } - /// - /// Add group permission in group - /// - /// Group. - /// Group fullname (required) - /// Access level (required) - public static GitLabGroup WithGroupPermission(this GitLabGroup grp, string groupName, AccessLevel level) + /// + /// Add group permission in group + /// + /// Group. + /// Group fullname (required) + /// Access level (required) + public static GitLabGroup WithGroupPermission(this GitLabGroup grp, string groupName, AccessLevel level) + { + return Configure(grp, _ => { - return Configure(grp, _ => + var permission = new GitLabPermission { - var permission = new GitLabPermission - { - Group = groupName ?? throw new ArgumentNullException(nameof(groupName)), - Level = level, - }; + Group = groupName ?? throw new ArgumentNullException(nameof(groupName)), + Level = level, + }; - grp.Permissions.Add(permission); - }); - } + grp.Permissions.Add(permission); + }); + } - /// - /// Add group permission in project - /// - /// Project. - /// Group fullname (required) - /// Access level (required) - public static GitLabProject WithGroupPermission(this GitLabProject project, string groupName, AccessLevel level) + /// + /// Add group permission in project + /// + /// Project. + /// Group fullname (required) + /// Access level (required) + public static GitLabProject WithGroupPermission(this GitLabProject project, string groupName, AccessLevel level) + { + return Configure(project, _ => { - return Configure(project, _ => + var permission = new GitLabPermission { - var permission = new GitLabPermission - { - Group = groupName ?? throw new ArgumentNullException(nameof(groupName)), - Level = level, - }; + Group = groupName ?? throw new ArgumentNullException(nameof(groupName)), + Level = level, + }; - project.Permissions.Add(permission); - }); - } + project.Permissions.Add(permission); + }); + } - /// - /// Add milestone in group - /// - /// Group. - /// Title (required) - /// Configuration method - public static GitLabGroup WithMilestone(this GitLabGroup group, string title, Action configure) + /// + /// Add milestone in group + /// + /// Group. + /// Title (required) + /// Configuration method + public static GitLabGroup WithMilestone(this GitLabGroup group, string title, Action configure) + { + return Configure(group, _ => { - return Configure(group, _ => + var milestone = new GitLabMilestone { - var milestone = new GitLabMilestone - { - Title = title ?? throw new ArgumentNullException(nameof(title)), - }; + Title = title ?? throw new ArgumentNullException(nameof(title)), + }; - group.Milestones.Add(milestone); - configure(milestone); - }); - } + group.Milestones.Add(milestone); + configure(milestone); + }); + } - /// - /// Add milestone in group - /// - /// Group. - /// Title (required) - /// Explicit ID (config increment) - /// Description. - /// Due date time. - /// Start date time. - /// Creation date time. - /// Update date time. - /// Close date time. - /// Configuration method - public static GitLabGroup WithMilestone(this GitLabGroup group, string title, int id = default, string? description = null, DateTime? dueDate = null, DateTime? startDate = null, DateTime? createdAt = null, DateTime? updatedAt = null, DateTime? closedAt = null, Action? configure = null) - { - return WithMilestone(group, title, milestone => - { - if (id != default) - milestone.Id = id; + /// + /// Add milestone in group + /// + /// Group. + /// Title (required) + /// Explicit ID (config increment) + /// Description. + /// Due date time. + /// Start date time. + /// Creation date time. + /// Update date time. + /// Close date time. + /// Configuration method + public static GitLabGroup WithMilestone(this GitLabGroup group, string title, int id = default, string? description = null, DateTime? dueDate = null, DateTime? startDate = null, DateTime? createdAt = null, DateTime? updatedAt = null, DateTime? closedAt = null, Action? configure = null) + { + return WithMilestone(group, title, milestone => + { + if (id != default) + milestone.Id = id; - milestone.Description = description; - milestone.DueDate = dueDate; - milestone.StartDate = startDate; - milestone.CreatedAt = createdAt; - milestone.UpdatedAt = updatedAt; - milestone.ClosedAt = closedAt; + milestone.Description = description; + milestone.DueDate = dueDate; + milestone.StartDate = startDate; + milestone.CreatedAt = createdAt; + milestone.UpdatedAt = updatedAt; + milestone.ClosedAt = closedAt; - configure?.Invoke(milestone); - }); - } + configure?.Invoke(milestone); + }); + } - /// - /// Add milestone in project - /// - /// Project. - /// Title (required) - /// Configuration method - public static GitLabProject WithMilestone(this GitLabProject project, string title, Action configure) + /// + /// Add milestone in project + /// + /// Project. + /// Title (required) + /// Configuration method + public static GitLabProject WithMilestone(this GitLabProject project, string title, Action configure) + { + return Configure(project, _ => { - return Configure(project, _ => + var milestone = new GitLabMilestone { - var milestone = new GitLabMilestone - { - Title = title ?? throw new ArgumentNullException(nameof(title)), - }; + Title = title ?? throw new ArgumentNullException(nameof(title)), + }; - project.Milestones.Add(milestone); - configure(milestone); - }); - } + project.Milestones.Add(milestone); + configure(milestone); + }); + } - /// - /// Add milestone in project - /// - /// Project. - /// Title (required) - /// Explicit ID (config increment) - /// Description. - /// Due date time. - /// Start date time. - /// Creation date time. - /// Update date time. - /// Close date time. - /// Configuration method - public static GitLabProject WithMilestone(this GitLabProject project, string title, int id = default, string? description = null, DateTime? dueDate = null, DateTime? startDate = null, DateTime? createdAt = null, DateTime? updatedAt = null, DateTime? closedAt = null, Action? configure = null) - { - return WithMilestone(project, title, milestone => - { - if (id != default) - milestone.Id = id; + /// + /// Add milestone in project + /// + /// Project. + /// Title (required) + /// Explicit ID (config increment) + /// Description. + /// Due date time. + /// Start date time. + /// Creation date time. + /// Update date time. + /// Close date time. + /// Configuration method + public static GitLabProject WithMilestone(this GitLabProject project, string title, int id = default, string? description = null, DateTime? dueDate = null, DateTime? startDate = null, DateTime? createdAt = null, DateTime? updatedAt = null, DateTime? closedAt = null, Action? configure = null) + { + return WithMilestone(project, title, milestone => + { + if (id != default) + milestone.Id = id; - milestone.Description = description; - milestone.DueDate = dueDate; - milestone.StartDate = startDate; - milestone.CreatedAt = createdAt; - milestone.UpdatedAt = updatedAt; - milestone.ClosedAt = closedAt; + milestone.Description = description; + milestone.DueDate = dueDate; + milestone.StartDate = startDate; + milestone.CreatedAt = createdAt; + milestone.UpdatedAt = updatedAt; + milestone.ClosedAt = closedAt; - configure?.Invoke(milestone); - }); - } + configure?.Invoke(milestone); + }); + } - /// - /// Add comment in issue - /// - /// Issue. - /// Message. - /// Configuration method - public static GitLabIssue WithComment(this GitLabIssue issue, string? message, Action configure) - { - return WithComment(issue, message, configure); - } + /// + /// Add comment in issue + /// + /// Issue. + /// Message. + /// Configuration method + public static GitLabIssue WithComment(this GitLabIssue issue, string? message, Action configure) + { + return WithComment(issue, message, configure); + } - /// - /// Add comment in merge request - /// - /// Merge request. - /// Message. - /// Configuration method - public static GitLabMergeRequest WithComment(this GitLabMergeRequest mergeRequest, string? message, Action configure) - { - return WithComment(mergeRequest, message, configure); - } + /// + /// Add comment in merge request + /// + /// Merge request. + /// Message. + /// Configuration method + public static GitLabMergeRequest WithComment(this GitLabMergeRequest mergeRequest, string? message, Action configure) + { + return WithComment(mergeRequest, message, configure); + } - private static T WithComment(this T obj, string? message, Action configure) - where T : GitLabObject + private static T WithComment(this T obj, string? message, Action configure) + where T : GitLabObject + { + return Configure(obj, _ => { - return Configure(obj, _ => + var comment = new GitLabComment { - var comment = new GitLabComment - { - Message = message, - }; + Message = message, + }; - switch (obj) - { - case GitLabIssue issue: - issue.Comments.Add(comment); - break; - case GitLabMergeRequest mergeRequest: - mergeRequest.Comments.Add(comment); - break; - default: - throw new InvalidOperationException($"Cannot add comment in {typeof(T).Name}"); - } + switch (obj) + { + case GitLabIssue issue: + issue.Comments.Add(comment); + break; + case GitLabMergeRequest mergeRequest: + mergeRequest.Comments.Add(comment); + break; + default: + throw new InvalidOperationException($"Cannot add comment in {typeof(T).Name}"); + } - configure(comment); - }); - } + configure(comment); + }); + } - /// - /// Add comment in issue - /// - /// Issue. - /// Message (required) - /// Explicit ID (issue increment) - /// Author username (required if default user not defined) - /// Indicates if comment is from GitLab system. - /// Creation date time. - /// Update date time. - /// Comment thread (all comments with same thread are grouped) - /// Indicates if comment is resolvable. - /// Indicates if comment is resolved. - /// Configuration method - public static GitLabIssue WithComment(this GitLabIssue issue, string? message = null, int id = default, string? author = null, bool system = false, DateTime? createdAt = null, DateTime? updatedAt = null, string? thread = null, bool resolvable = false, bool resolved = false, Action? configure = null) - { - return WithComment(issue, message, id, author, system, createdAt, updatedAt, thread, resolvable, resolved, configure); - } + /// + /// Add comment in issue + /// + /// Issue. + /// Message (required) + /// Explicit ID (issue increment) + /// Author username (required if default user not defined) + /// Indicates if comment is from GitLab system. + /// Creation date time. + /// Update date time. + /// Comment thread (all comments with same thread are grouped) + /// Indicates if comment is resolvable. + /// Indicates if comment is resolved. + /// Configuration method + public static GitLabIssue WithComment(this GitLabIssue issue, string? message = null, int id = default, string? author = null, bool system = false, DateTime? createdAt = null, DateTime? updatedAt = null, string? thread = null, bool resolvable = false, bool resolved = false, Action? configure = null) + { + return WithComment(issue, message, id, author, system, createdAt, updatedAt, thread, resolvable, resolved, configure); + } - /// - /// Add comment in issue - /// - /// Merge request. - /// Message (required) - /// Explicit ID (merge request increment) - /// Author username (required if default user not defined) - /// Indicates if comment is from GitLab system. - /// Creation date time. - /// Update date time. - /// Comment thread (all comments with same thread are grouped) - /// Indicates if comment is resolvable. - /// Indicates if comment is resolved. - /// Configuration method - public static GitLabMergeRequest WithComment(this GitLabMergeRequest mergeRequest, string? message = null, int id = default, string? author = null, bool system = false, DateTime? createdAt = null, DateTime? updatedAt = null, string? thread = null, bool resolvable = false, bool resolved = false, Action? configure = null) - { - return WithComment(mergeRequest, message, id, author, system, createdAt, updatedAt, thread, resolvable, resolved, configure); - } + /// + /// Add comment in issue + /// + /// Merge request. + /// Message (required) + /// Explicit ID (merge request increment) + /// Author username (required if default user not defined) + /// Indicates if comment is from GitLab system. + /// Creation date time. + /// Update date time. + /// Comment thread (all comments with same thread are grouped) + /// Indicates if comment is resolvable. + /// Indicates if comment is resolved. + /// Configuration method + public static GitLabMergeRequest WithComment(this GitLabMergeRequest mergeRequest, string? message = null, int id = default, string? author = null, bool system = false, DateTime? createdAt = null, DateTime? updatedAt = null, string? thread = null, bool resolvable = false, bool resolved = false, Action? configure = null) + { + return WithComment(mergeRequest, message, id, author, system, createdAt, updatedAt, thread, resolvable, resolved, configure); + } - private static T WithComment(this T obj, string? message, int id = default, string? author = null, bool system = false, DateTime? createdAt = null, DateTime? updatedAt = null, string? thread = null, bool resolvable = false, bool resolved = false, Action? configure = null) - where T : GitLabObject + private static T WithComment(this T obj, string? message, int id = default, string? author = null, bool system = false, DateTime? createdAt = null, DateTime? updatedAt = null, string? thread = null, bool resolvable = false, bool resolved = false, Action? configure = null) + where T : GitLabObject + { + return WithComment(obj, message, comment => { - return WithComment(obj, message, comment => - { - if (id != default) - comment.Id = id; - - comment.Author = author; - comment.System = system; - comment.CreatedAt = createdAt; - comment.UpdatedAt = updatedAt; - comment.Thread = thread; - comment.Resolvable = resolvable; - comment.Resolved = resolved; - - configure?.Invoke(comment); - }); - } + if (id != default) + comment.Id = id; - /// - /// Add commit mention comment in issue - /// - /// Issue. - /// Message. - /// Inner HTML. - /// Explicit ID (issue increment) - /// Author username (required if default user not defined) - /// Creation date time. - /// Update date time. - public static GitLabIssue WithSystemComment(this GitLabIssue issue, string? message = null, string? innerHtml = null, int id = default, string? author = null, DateTime? createdAt = null, DateTime? updatedAt = null) - { - return WithSystemComment(issue, message, innerHtml, id, author, createdAt, updatedAt); - } + comment.Author = author; + comment.System = system; + comment.CreatedAt = createdAt; + comment.UpdatedAt = updatedAt; + comment.Thread = thread; + comment.Resolvable = resolvable; + comment.Resolved = resolved; - /// - /// Add commit mention comment in merge request - /// - /// Merge request. - /// Message. - /// Inner HTML. - /// Explicit ID (merge request increment) - /// Author username (required if default user not defined) - /// Creation date time. - /// Update date time. - public static GitLabMergeRequest WithSystemComment(this GitLabMergeRequest mergeRequest, string? message = null, string? innerHtml = null, int id = default, string? author = null, DateTime? createdAt = null, DateTime? updatedAt = null) - { - return WithSystemComment(mergeRequest, message, innerHtml, id, author, createdAt, updatedAt); - } + configure?.Invoke(comment); + }); + } - private static T WithSystemComment(this T obj, string? message, string? innerHtml, int id, string? author, DateTime? createdAt, DateTime? updatedAt) - where T : GitLabObject - { - var body = innerHtml == null ? message : $"{message}\n\n{innerHtml}"; - return WithComment(obj, body, id: id, author: author, system: true, createdAt: createdAt, updatedAt: updatedAt); - } + /// + /// Add commit mention comment in issue + /// + /// Issue. + /// Message. + /// Inner HTML. + /// Explicit ID (issue increment) + /// Author username (required if default user not defined) + /// Creation date time. + /// Update date time. + public static GitLabIssue WithSystemComment(this GitLabIssue issue, string? message = null, string? innerHtml = null, int id = default, string? author = null, DateTime? createdAt = null, DateTime? updatedAt = null) + { + return WithSystemComment(issue, message, innerHtml, id, author, createdAt, updatedAt); + } - /// - /// Add pipeline in project - /// - /// Project. - /// Commit alias reference. - /// Configuration method - public static GitLabProject WithPipeline(this GitLabProject project, string @ref, Action configure) - { - return Configure(project, _ => - { - var pipeline = new GitLabPipeline(project) - { - Commit = @ref ?? throw new ArgumentNullException(nameof(@ref)), - }; + /// + /// Add commit mention comment in merge request + /// + /// Merge request. + /// Message. + /// Inner HTML. + /// Explicit ID (merge request increment) + /// Author username (required if default user not defined) + /// Creation date time. + /// Update date time. + public static GitLabMergeRequest WithSystemComment(this GitLabMergeRequest mergeRequest, string? message = null, string? innerHtml = null, int id = default, string? author = null, DateTime? createdAt = null, DateTime? updatedAt = null) + { + return WithSystemComment(mergeRequest, message, innerHtml, id, author, createdAt, updatedAt); + } - project.Pipelines.Add(pipeline); - configure(pipeline); - }); - } + private static T WithSystemComment(this T obj, string? message, string? innerHtml, int id, string? author, DateTime? createdAt, DateTime? updatedAt) + where T : GitLabObject + { + var body = innerHtml == null ? message : $"{message}\n\n{innerHtml}"; + return WithComment(obj, body, id: id, author: author, system: true, createdAt: createdAt, updatedAt: updatedAt); + } - /// - /// Add job in pipeline - /// - /// Pipeline. - /// Name. - /// Stage (build by default) - /// Status (Manual by default) - /// Creation date time. - /// Start date time. - /// Finish date time. - /// Indicates if failure is allowed. - /// Downstream pipeline. - /// Configuration method - public static GitLabPipeline WithJob(this GitLabPipeline pipeline, string? name = null, string? stage = null, JobStatus status = JobStatus.Unknown, DateTime? createdAt = null, DateTime? startedAt = null, DateTime? finishedAt = null, bool allowFailure = false, GitLabPipeline? downstreamPipeline = null, Action? configure = null) - { - return Configure(pipeline, _ => + /// + /// Add pipeline in project + /// + /// Project. + /// Commit alias reference. + /// Configuration method + public static GitLabProject WithPipeline(this GitLabProject project, string @ref, Action configure) + { + return Configure(project, _ => + { + var pipeline = new GitLabPipeline(project) { - if (pipeline.Parent == null) - throw new InvalidOperationException($"Parent project not set on pipeline {pipeline}"); + Commit = @ref ?? throw new ArgumentNullException(nameof(@ref)), + }; - var job = new GitLabJob - { - Name = name, - Stage = stage, - Status = status, - CreatedAt = createdAt, - StartedAt = startedAt, - FinishedAt = finishedAt, - AllowFailure = allowFailure, - DownstreamPipeline = downstreamPipeline, - }; - - pipeline.Jobs.Add(job); - configure?.Invoke(job); - }); - } + project.Pipelines.Add(pipeline); + configure(pipeline); + }); + } - /// - /// Create and fill server from config - /// - /// Config. - public static GitLabServer BuildServer(this GitLabConfig config) + /// + /// Add job in pipeline + /// + /// Pipeline. + /// Name. + /// Stage (build by default) + /// Status (Manual by default) + /// Creation date time. + /// Start date time. + /// Finish date time. + /// Indicates if failure is allowed. + /// Downstream pipeline. + /// Configuration method + public static GitLabPipeline WithJob(this GitLabPipeline pipeline, string? name = null, string? stage = null, JobStatus status = JobStatus.Unknown, DateTime? createdAt = null, DateTime? startedAt = null, DateTime? finishedAt = null, bool allowFailure = false, GitLabPipeline? downstreamPipeline = null, Action? configure = null) + { + return Configure(pipeline, _ => { - var server = CreateServer(config); - foreach (var user in config.Users) - { - CreateUser(server, user); - } - - foreach (var group in config.Groups.OrderBy(x => - string.IsNullOrEmpty(x.Namespace) ? x.Name : $"{x.Namespace}/{x.Name}", StringComparer.Ordinal)) - { - CreateGroup(server, group); - } + if (pipeline.Parent == null) + throw new InvalidOperationException($"Parent project not set on pipeline {pipeline}"); - foreach (var project in config.Projects) + var job = new GitLabJob { - CreateProject(server, project); - } + Name = name, + Stage = stage, + Status = status, + CreatedAt = createdAt, + StartedAt = startedAt, + FinishedAt = finishedAt, + AllowFailure = allowFailure, + DownstreamPipeline = downstreamPipeline, + }; - return server; - } + pipeline.Jobs.Add(job); + configure?.Invoke(job); + }); + } - /// - /// Create client from config - /// - /// Config. - /// Username that use client (if not defined, use default user or the first in the list) - public static IGitLabClient BuildClient(this GitLabConfig config, string? username = null) + /// + /// Create and fill server from config + /// + /// Config. + public static GitLabServer BuildServer(this GitLabConfig config) + { + var server = CreateServer(config); + foreach (var user in config.Users) { - return CreateClient(BuildServer(config), username ?? config.DefaultUser ?? config.Users.FirstOrDefault()?.Username ?? throw new InvalidOperationException("No user configured")); + CreateUser(server, user); } - /// - /// Create client from server - /// - /// Server. - /// Username that use client (if not defined, use the first in the list) - public static IGitLabClient CreateClient(this GitLabServer server, string? username = null) + foreach (var group in config.Groups.OrderBy(x => + string.IsNullOrEmpty(x.Namespace) ? x.Name : $"{x.Namespace}/{x.Name}", StringComparer.Ordinal)) { - username ??= server.Users.FirstOrDefault()?.UserName ?? throw new InvalidOperationException("No user configured"); - return server.CreateClient(server.Users.First(x => string.Equals(x.UserName, username, StringComparison.Ordinal))); + CreateGroup(server, group); } - /// - /// Create config from server - /// - /// Server. - public static GitLabConfig ToConfig(this GitLabServer server) + foreach (var project in config.Projects) { - var config = new GitLabConfig(); - foreach (var user in server.Users) - { - config.Users.Add(ToConfig(user)); - } + CreateProject(server, project); + } - foreach (var group in server.AllGroups.Where(x => !x.IsUserNamespace)) - { - config.Groups.Add(ToConfig(group)); - } + return server; + } - foreach (var project in server.AllProjects) - { - config.Projects.Add(ToConfig(project)); - } + /// + /// Create client from config + /// + /// Config. + /// Username that use client (if not defined, use default user or the first in the list) + public static IGitLabClient BuildClient(this GitLabConfig config, string? username = null) + { + return CreateClient(BuildServer(config), username ?? config.DefaultUser ?? config.Users.FirstOrDefault()?.Username ?? throw new InvalidOperationException("No user configured")); + } - return config; - } + /// + /// Create client from server + /// + /// Server. + /// Username that use client (if not defined, use the first in the list) + public static IGitLabClient CreateClient(this GitLabServer server, string? username = null) + { + username ??= server.Users.FirstOrDefault()?.UserName ?? throw new InvalidOperationException("No user configured"); + return server.CreateClient(server.Users.First(x => string.Equals(x.UserName, username, StringComparison.Ordinal))); + } - private static GitLabServer CreateServer(GitLabConfig config) + /// + /// Create config from server + /// + /// Server. + public static GitLabConfig ToConfig(this GitLabServer server) + { + var config = new GitLabConfig(); + foreach (var user in server.Users) { - return new GitLabServer - { - DefaultBranchName = config.DefaultBranch ?? "main", - DefaultForkVisibilityLevel = config.DefaultVisibility, - Url = new Uri(config.Url ?? Path.GetTempPath()), - }; + config.Users.Add(ToConfig(user)); } - private static void CreateUser(GitLabServer server, GitLabUser user) + foreach (var group in server.AllGroups.Where(x => !x.IsUserNamespace)) { - server.Users.Add(new User(user.Username ?? throw new ArgumentException(@"user.Username == null", nameof(user))) - { - Id = user.Id, - Name = user.Name ?? user.Username, - Email = user.Email ?? $"{user.Username}@example.com", - AvatarUrl = user.AvatarUrl, - IsAdmin = user.IsAdmin, - }); + config.Groups.Add(ToConfig(group)); } - private static void CreateGroup(GitLabServer server, GitLabGroup group) + foreach (var project in server.AllProjects) { - var grp = new Group(group.Name ?? throw new ArgumentException(@"group.Name == null", nameof(group))) - { - Id = group.Id, - Description = group.Description, - Visibility = group.Visibility ?? group.Parent.DefaultVisibility, - }; - - if (string.IsNullOrEmpty(group.Namespace)) - { - server.Groups.Add(grp); - } - else - { - var parent = GetOrCreateGroup(server, group.Namespace); - parent.Groups.Add(grp); - } - - foreach (var label in group.Labels) - { - CreateLabel(grp, label); - } - - foreach (var permission in group.Permissions) - { - CreatePermission(server, grp, permission); - } - - foreach (var milestone in group.Milestones) - { - CreateMilestone(grp, milestone); - } + config.Projects.Add(ToConfig(project)); } - private static void CreateProject(GitLabServer server, GitLabProject project) - { - var prj = new Project(project.Name ?? Guid.NewGuid().ToString("D")) - { - Id = project.Id, - Description = project.Description, - DefaultBranch = project.DefaultBranch ?? server.DefaultBranchName, - Visibility = project.Visibility ?? project.Parent.DefaultVisibility, - ForkingAccessLevel = project.ForkingAccessLevel, - }; - - var group = GetOrCreateGroup(server, project.Namespace ?? Guid.NewGuid().ToString("D")); - group.Projects.Add(prj); - - var aliases = new Dictionary(StringComparer.Ordinal); - foreach (var commit in project.Commits) - { - var cmt = CreateCommit(server, prj, commit); - if (!string.IsNullOrEmpty(commit.Alias)) - aliases[commit.Alias] = cmt; - } - - foreach (var label in project.Labels) - { - CreateLabel(prj, label); - } - - foreach (var milestone in project.Milestones) - { - CreateMilestone(prj, milestone); - } - - foreach (var issue in project.Issues) - { - CreateIssue(server, prj, issue); - } - - foreach (var release in project.Releases) - { - CreateRelease(server, prj, release); - } - - for (var i = 0; i < project.MergeRequests.Count; i++) - { - var mergeRequest = project.MergeRequests[i]; - var maxCreatedAt = project.MergeRequests - .Skip(i + 1) - .SelectMany(x => new[] { x.CreatedAt ?? default, x.UpdatedAt ?? default, x.MergedAt ?? default, x.ClosedAt ?? default } - .Concat(x.Comments.SelectMany(c => new[] { c.CreatedAt ?? default, c.UpdatedAt ?? default }))) - .Where(x => x != default) - .DefaultIfEmpty(DateTime.UtcNow).Min(); - - CreateMergeRequest(server, prj, mergeRequest, maxCreatedAt); - } - - foreach (var permission in project.Permissions) - { - CreatePermission(server, prj, permission); - } - - foreach (var pipeline in project.Pipelines) - { - CreatePipeline(server, prj, pipeline, aliases); - } - - if (!string.IsNullOrEmpty(project.ClonePath)) - { - var folderPath = Path.GetDirectoryName(Path.GetFullPath(project.ClonePath)); - if (!Directory.Exists(folderPath)) - Directory.CreateDirectory(folderPath!); - - // libgit2sharp cannot clone with an other folder name - using var process = new Process - { - StartInfo = new ProcessStartInfo - { - FileName = "git", - Arguments = $"-c protocol.file.allow=always clone {project.CloneParameters} \"{prj.SshUrl}\" \"{Path.GetFileName(project.ClonePath)}\" --recursive", - RedirectStandardError = true, - UseShellExecute = false, - WorkingDirectory = folderPath, - }, - }; - - process.Start(); - process.WaitForExit(); - if (process.ExitCode != 0) - { - var error = process.StandardError.ReadToEnd(); - throw new GitLabException($"Cannot clone '{prj.PathWithNamespace}' in '{project.ClonePath}': {error}"); - } - } - } + return config; + } - private static void CreateRelease(GitLabServer server, Project project, GitLabReleaseInfo gitLabRelease) + private static GitLabServer CreateServer(GitLabConfig config) + { + return new GitLabServer { - var user = GetOrCreateUser(server, gitLabRelease.Author); - var release = new ReleaseInfo - { - Author = new UserRef(user), - TagName = gitLabRelease.TagName, - CreatedAt = gitLabRelease.CreatedAt, - ReleasedAt = gitLabRelease.ReleasedAt, - }; + DefaultBranchName = config.DefaultBranch ?? "main", + DefaultForkVisibilityLevel = config.DefaultVisibility, + Url = new Uri(config.Url ?? Path.GetTempPath()), + }; + } - project.Releases.Add(release); - } + private static void CreateUser(GitLabServer server, GitLabUser user) + { + server.Users.Add(new User(user.Username ?? throw new ArgumentException(@"user.Username == null", nameof(user))) + { + Id = user.Id, + Name = user.Name ?? user.Username, + Email = user.Email ?? $"{user.Username}@example.com", + AvatarUrl = user.AvatarUrl, + IsAdmin = user.IsAdmin, + }); + } - private static Commit CreateCommit(GitLabServer server, Project prj, GitLabCommit commit) + private static void CreateGroup(GitLabServer server, GitLabGroup group) + { + var grp = new Group(group.Name ?? throw new ArgumentException(@"group.Name == null", nameof(group))) { - var username = commit.User ?? commit.Parent.Parent.DefaultUser ?? throw new InvalidOperationException("Default user is required when author not set"); - var user = GetOrCreateUser(server, username); - var targetBranch = commit.TargetBranch; - Commit cmt; - if (!string.IsNullOrEmpty(commit.FromBranch)) - { - prj.Repository.Checkout(commit.FromBranch); - } - - if (string.IsNullOrEmpty(targetBranch)) - { - var branchExists = string.IsNullOrEmpty(commit.SourceBranch) || prj.Repository.GetAllBranches().Any(x => string.Equals(x.FriendlyName, commit.SourceBranch, StringComparison.Ordinal)); - if (!branchExists) - prj.Repository.CreateBranch(commit.SourceBranch); - - var files = commit.Files.Count == 0 - ? new List() { File.CreateFromText("test.txt", Guid.NewGuid().ToString()) } - : commit.Files.Select(x => File.CreateFromText(x.Path, x.Content ?? string.Empty)).ToList(); - - var submodules = CreateSubModules(server, prj, commit); - - cmt = prj.Repository.Commit(user, commit.Message ?? Guid.NewGuid().ToString("D"), commit.SourceBranch, files, submodules); - } - else - { - cmt = prj.Repository.Merge(user, commit.SourceBranch, targetBranch); - if (commit.DeleteSourceBranch) - prj.Repository.RemoveBranch(commit.SourceBranch); - } - - foreach (var tag in commit.Tags) - { - prj.Repository.CreateTag(tag); - } - - return cmt; - } + Id = group.Id, + Description = group.Description, + Visibility = group.Visibility ?? group.Parent.DefaultVisibility, + }; - private static IEnumerable CreateSubModules(GitLabServer server, Project prj, GitLabCommit commit) + if (string.IsNullOrEmpty(group.Namespace)) { - List submodules = new(); - foreach (var submodule in commit.SubModules) - { - var subModuleProject = server.AllProjects.FirstOrDefault(x => - x.Name.Equals(submodule.ProjectName, StringComparison.OrdinalIgnoreCase)); - if (subModuleProject is null) - { - throw new GitLabException($"Project {submodule.ProjectName} can't be found."); - } - - if (!subModuleProject.Repository.GetCommits().Any()) - { - throw new GitLabException("Project added as a module must have least one commit."); - } - - using var process = Process.Start( - new ProcessStartInfo("git", $"-c protocol.file.allow=always submodule add \"{subModuleProject.SshUrl}\" \"{subModuleProject.Name}\"") - { - RedirectStandardError = true, - UseShellExecute = false, - WorkingDirectory = prj.Repository.FullPath, - }); - - process.WaitForExit(); - if (process.ExitCode != 0) - { - var error = process.StandardError.ReadToEnd(); - throw new GitLabException($"Cannot add submodule: {error}"); - } - - submodules.Add(subModuleProject.Name); - } - - return submodules; + server.Groups.Add(grp); } - - private static void CreateLabel(Group group, GitLabLabel label) + else { - group.Labels.Add(new Label - { - Name = label.Name ?? throw new ArgumentException(@"label.Name == null", nameof(label)), - Color = label.Color ?? "#d9534f", - Description = label.Description, - }); + var parent = GetOrCreateGroup(server, group.Namespace); + parent.Groups.Add(grp); } - private static void CreateLabel(Project project, GitLabLabel label) + foreach (var label in group.Labels) { - project.Labels.Add(new Label - { - Name = label.Name ?? throw new ArgumentException(@"label.Name == null", nameof(label)), - Color = label.Color ?? "#d9534f", - Description = label.Description, - }); + CreateLabel(grp, label); } - private static void CreateLabel(Project project, string label) + foreach (var permission in group.Permissions) { - var model = project.Labels.Concat(GetLabels(project.Group)).FirstOrDefault(x => string.Equals(x.Name, label, StringComparison.Ordinal)); - if (model == null) - project.Labels.Add(label); - - static IEnumerable