Skip to content

Commit 93d63ac

Browse files
authored
Extend issue with task status info (#121)
1 parent 6f13050 commit 93d63ac

File tree

6 files changed

+108
-1
lines changed

6 files changed

+108
-1
lines changed

src/GitLabApiClient/Internal/Queries/IssuesQueryBuilder.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,13 @@ protected override void BuildCore(IssuesQueryOptions options)
2525

2626
if (options.AuthorId.HasValue)
2727
Add("author_id", options.AuthorId.Value);
28+
else if (!string.IsNullOrWhiteSpace(options.AuthorUsername))
29+
Add("author_username", options.AuthorUsername);
2830

2931
if (options.AssigneeId.HasValue)
3032
Add("assignee_id", options.AssigneeId.Value);
33+
else if (options.AssigneeUsername.Any())
34+
Add("assignee_username", options.AssigneeUsername);
3135

3236
Add(options.IssueIds);
3337

src/GitLabApiClient/Models/Issues/Requests/IssuesQueryOptions.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,22 @@ internal IssuesQueryOptions() { }
3939
/// </summary>
4040
public int? AuthorId { get; set; }
4141

42+
/// <summary>
43+
/// Return issues created by the given username. Similar to <see cref="AuthorId"/> and mutually exclusive with <see cref="AuthorId"/>.
44+
/// </summary>
45+
public string AuthorUsername { get; set; }
46+
4247
/// <summary>
4348
/// Return issues assigned to the given user id (Introduced in GitLab 9.5).
4449
/// </summary>
4550
public int? AssigneeId { get; set; }
4651

52+
/// <summary>
53+
/// Return issues assigned to the given username. Similar to <see cref="AssigneeId"/> and mutually exclusive with <see cref="AuthorId"/>.
54+
/// In CE version <see cref="AuthorUsername"/> list should only contain a single value or an invalid param error will be returned otherwise.
55+
/// </summary>
56+
public IList<string> AssigneeUsername { get; set; } = new List<string>();
57+
4758
/// <summary>
4859
/// Return only the issues having the given iid.
4960
/// </summary>

src/GitLabApiClient/Models/Issues/Responses/Issue.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,8 @@ public sealed class Issue : ModifiableObject
5757

5858
[JsonProperty("time_stats")]
5959
public IssueTimeStatistic TimeStats { get; set; }
60+
61+
[JsonProperty("task_completion_status")]
62+
public IssueTaskCompletionStatus TaskCompletionStatus { get; set; }
6063
}
6164
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using Newtonsoft.Json;
2+
3+
namespace GitLabApiClient.Models.Issues.Responses
4+
{
5+
public class IssueTaskCompletionStatus
6+
{
7+
[JsonProperty("count")]
8+
public int Count { get; set; }
9+
10+
[JsonProperty("completed_count")]
11+
public int Completed { get; set; }
12+
}
13+
}

test/GitLabApiClient.Test/Internal/Queries/IssuesQueryBuilderTest.cs

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using FluentAssertions;
34
using GitLabApiClient.Internal.Queries;
45
using GitLabApiClient.Models;
@@ -33,7 +34,9 @@ public void NonDefaultQueryBuilt()
3334
CreatedBefore = new DateTime(1991, 12, 12, 2, 2, 2),
3435
UpdatedAfter = new DateTime(1991, 4, 4, 4, 4, 4),
3536
UpdatedBefore = new DateTime(1991, 5, 5, 5, 5, 5),
36-
IsConfidential = true
37+
IsConfidential = true,
38+
AuthorUsername = "user_1",
39+
AssigneeUsername = new List<string> { "user_1", "user_2" }
3740
});
3841

3942
query.Should().BeEquivalentTo("https://gitlab.com/api/v4/issues?" +
@@ -53,5 +56,51 @@ public void NonDefaultQueryBuilt()
5356
"updated_before=1991-05-05T05%3a05%3a05.0000000&" +
5457
"updated_after=1991-04-04T04%3a04%3a04.0000000");
5558
}
59+
60+
[Fact]
61+
public void NonDefaultQueryBuiltWithUserNames()
62+
{
63+
var sut = new IssuesQueryBuilder();
64+
65+
string query = sut.Build(
66+
"https://gitlab.com/api/v4/issues",
67+
new IssuesQueryOptions
68+
{
69+
State = IssueState.Opened,
70+
Labels = { "label1", "label2" },
71+
MilestoneTitle = "milestone1",
72+
Scope = Scope.All,
73+
AuthorId = null,
74+
AssigneeId = null,
75+
IssueIds = { 3, 4 },
76+
Order = IssuesOrder.UpdatedAt,
77+
SortOrder = SortOrder.Ascending,
78+
Filter = "filter",
79+
CreatedAfter = new DateTime(1991, 11, 11, 1, 1, 1),
80+
CreatedBefore = new DateTime(1991, 12, 12, 2, 2, 2),
81+
UpdatedAfter = new DateTime(1991, 4, 4, 4, 4, 4),
82+
UpdatedBefore = new DateTime(1991, 5, 5, 5, 5, 5),
83+
IsConfidential = true,
84+
AuthorUsername = "user_1",
85+
AssigneeUsername = new List<string> { "user_1", "user_2" }
86+
});
87+
88+
query.Should().BeEquivalentTo("https://gitlab.com/api/v4/issues?" +
89+
"state=opened&" +
90+
"labels=label1%2Clabel2&" +
91+
"milestone=milestone1&" +
92+
"scope=all&" +
93+
"author_username=user_1&" +
94+
"assignee_username=user_1%2Cuser_2&" +
95+
"iids%5B%5D=3&iids%5B%5D=4&" +
96+
"order_by=updated_at&" +
97+
"sort=asc&" +
98+
"search=filter&" +
99+
"confidential=true&" +
100+
"created_before=1991-12-12T02%3a02%3a02.0000000&" +
101+
"created_after=1991-11-11T01%3a01%3a01.0000000&" +
102+
"updated_before=1991-05-05T05%3a05%3a05.0000000&" +
103+
"updated_after=1991-04-04T04%3a04%3a04.0000000");
104+
}
56105
}
57106
}

test/GitLabApiClient.Test/IssuesClientTest.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,5 +163,32 @@ public async Task CreatedIssueNoteCanBeUpdated()
163163
updatedIssueNote.Should().Match<Note>(n =>
164164
n.Body == "comment22");
165165
}
166+
167+
[Fact]
168+
public async Task CreateIssueWithTasks()
169+
{
170+
//arrange
171+
string title = Guid.NewGuid().ToString();
172+
await _sut.CreateAsync(TestProjectTextId, new CreateIssueRequest(title)
173+
{
174+
Description = @"Description1
175+
- [ ] Task 1
176+
- [ ] Task 2
177+
- [x] Task 3
178+
"
179+
});
180+
181+
//act
182+
var listedIssues = await _sut.GetAllAsync(projectId: TestProjectTextId, options: o => o.Filter = title);
183+
184+
//assert
185+
listedIssues.Single().Should().Match<Issue>(i =>
186+
i.ProjectId == TestProjectTextId &&
187+
i.Title == title &&
188+
i.TaskCompletionStatus != null &&
189+
i.TaskCompletionStatus.Count == 3 &&
190+
i.TaskCompletionStatus.Completed == 1 &&
191+
i.TimeStats != null);
192+
}
166193
}
167194
}

0 commit comments

Comments
 (0)