Skip to content

Commit

Permalink
Add ResourceEvents for merge requests (#547)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
phdesroUbi authored Oct 24, 2023
1 parent 5346942 commit dee78df
Show file tree
Hide file tree
Showing 9 changed files with 379 additions and 111 deletions.
122 changes: 122 additions & 0 deletions NGitLab.Mock.Tests/MergeRequestsMockTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
105 changes: 2 additions & 103 deletions NGitLab.Mock/Clients/IssueClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -451,106 +451,5 @@ private IEnumerable<Issue> FilterByQuery(IEnumerable<Issue> 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",
});
}
}
}
80 changes: 73 additions & 7 deletions NGitLab.Mock/Clients/MergeRequestClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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);
}
}
}
Expand Down Expand Up @@ -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();
}
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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();
Expand All @@ -681,5 +714,38 @@ public IMergeRequestDiscussionClient Discussions(int mergeRequestIid)

return new MergeRequestDiscussionClient(Context, _projectId.GetValueOrDefault(), mergeRequestIid);
}

public GitLabCollectionResponse<Models.ResourceLabelEvent> 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<Models.ResourceMilestoneEvent> 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<Models.ResourceStateEvent> 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()));
}
}
}
}
Loading

0 comments on commit dee78df

Please sign in to comment.