Skip to content

Commit f93aeec

Browse files
authored
Fix Epic Issue link association (#969)
* Fix Epic Issue link association Fixes #729 * Change return type
1 parent 7606448 commit f93aeec

File tree

4 files changed

+155
-28
lines changed

4 files changed

+155
-28
lines changed

src/main/java/org/gitlab4j/api/EpicsApi.java

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import org.gitlab4j.api.models.Epic;
1313
import org.gitlab4j.api.models.EpicIssue;
14+
import org.gitlab4j.api.models.EpicIssueLink;
1415

1516
/**
1617
* This class implements the client side API for the GitLab Epics and Epic Issues API calls.
@@ -347,10 +348,10 @@ public void deleteEpic(Object groupIdOrPath, Long epicIid) throws GitLabApiExcep
347348
*
348349
* @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path
349350
* @param epicIid the IID of the epic to get issues for
350-
* @return a list of all epic issues belonging to the specified epic
351+
* @return a list of all issues belonging to the specified epic
351352
* @throws GitLabApiException if any exception occurs
352353
*/
353-
public List<Epic> getEpicIssues(Object groupIdOrPath, Long epicIid) throws GitLabApiException {
354+
public List<EpicIssue> getEpicIssues(Object groupIdOrPath, Long epicIid) throws GitLabApiException {
354355
return (getEpicIssues(groupIdOrPath, epicIid, getDefaultPerPage()).all());
355356
}
356357

@@ -364,12 +365,12 @@ public List<Epic> getEpicIssues(Object groupIdOrPath, Long epicIid) throws GitLa
364365
* @param epicIid the IID of the epic to get issues for
365366
* @param page the page to get
366367
* @param perPage the number of issues per page
367-
* @return a list of all epic issues belonging to the specified epic in the specified range
368+
* @return a list of all issues belonging to the specified epic in the specified range
368369
* @throws GitLabApiException if any exception occurs
369370
*/
370-
public List<Epic> getEpicIssues(Object groupIdOrPath, Long epicIid, int page, int perPage) throws GitLabApiException {
371+
public List<EpicIssue> getEpicIssues(Object groupIdOrPath, Long epicIid, int page, int perPage) throws GitLabApiException {
371372
Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues");
372-
return (response.readEntity(new GenericType<List<Epic>>() { }));
373+
return (response.readEntity(new GenericType<List<EpicIssue>>() { }));
373374
}
374375

375376
/**
@@ -380,11 +381,11 @@ public List<Epic> getEpicIssues(Object groupIdOrPath, Long epicIid, int page, in
380381
* @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path
381382
* @param epicIid the IID of the epic to get issues for
382383
* @param itemsPerPage the number of issues per page
383-
* @return the Pager of all epic issues belonging to the specified epic
384+
* @return the Pager of all issues belonging to the specified epic
384385
* @throws GitLabApiException if any exception occurs
385386
*/
386-
public Pager<Epic> getEpicIssues(Object groupIdOrPath, Long epicIid, int itemsPerPage) throws GitLabApiException {
387-
return (new Pager<Epic>(this, Epic.class, itemsPerPage, null, "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues"));
387+
public Pager<EpicIssue> getEpicIssues(Object groupIdOrPath, Long epicIid, int itemsPerPage) throws GitLabApiException {
388+
return (new Pager<EpicIssue>(this, EpicIssue.class, itemsPerPage, null, "groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues"));
388389
}
389390

390391
/**
@@ -394,10 +395,10 @@ public Pager<Epic> getEpicIssues(Object groupIdOrPath, Long epicIid, int itemsPe
394395
*
395396
* @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path
396397
* @param epicIid the IID of the epic to get issues for
397-
* @return a Stream of all epic issues belonging to the specified epic
398+
* @return a Stream of all issues belonging to the specified epic
398399
* @throws GitLabApiException if any exception occurs
399400
*/
400-
public Stream<Epic> getEpicIssuesStream(Object groupIdOrPath, Long epicIid) throws GitLabApiException {
401+
public Stream<EpicIssue> getEpicIssuesStream(Object groupIdOrPath, Long epicIid) throws GitLabApiException {
401402
return (getEpicIssues(groupIdOrPath, epicIid, getDefaultPerPage()).stream());
402403
}
403404

@@ -409,52 +410,52 @@ public Stream<Epic> getEpicIssuesStream(Object groupIdOrPath, Long epicIid) thro
409410
*
410411
* @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path
411412
* @param epicIid the Epic IID to assign the issue to
412-
* @param issueIid the issue IID of the issue to assign to the epic
413+
* @param issueId the issue ID of the issue to assign to the epic
413414
* @return an EpicIssue instance containing info on the newly assigned epic issue
414415
* @throws GitLabApiException if any exception occurs
415416
*/
416-
public EpicIssue assignIssue(Object groupIdOrPath, Long epicIid, Long issueIid) throws GitLabApiException {
417+
public EpicIssue assignIssue(Object groupIdOrPath, Long epicIid, Long issueId) throws GitLabApiException {
417418
Response response = post(Response.Status.CREATED, (Form)null,
418-
"groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues", issueIid);
419+
"groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues", issueId);
419420
return (response.readEntity(EpicIssue.class));
420421
}
421422

422423
/**
423424
* Remove an epic - issue association.
424425
*
425-
* <pre><code>GitLab Endpoint: DELETE /groups/:id/epics/:epic_iid/issues/:issue_id</code></pre>
426+
* <pre><code>GitLab Endpoint: DELETE /groups/:id/epics/:epic_iid/issues/:epic_issue_id</code></pre>
426427
*
427428
* @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path
428429
* @param epicIid the Epic IID to remove the issue from
429-
* @param issueIid the issue IID of the issue to remove from the epic
430-
* @return an EpicIssue instance containing info on the removed issue
430+
* @param epicIssueId the ID of the "issue - epic" association of the issue to remove from the epic
431+
* @return an EpicIssueLink instance containing info on the removed issue
431432
* @throws GitLabApiException if any exception occurs
432433
*/
433-
public EpicIssue removeIssue(Object groupIdOrPath, Long epicIid, Long issueIid) throws GitLabApiException {
434+
public EpicIssueLink removeIssue(Object groupIdOrPath, Long epicIid, Long epicIssueId) throws GitLabApiException {
434435
Response response = delete(Response.Status.OK, null,
435-
"groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues", issueIid);
436-
return (response.readEntity(EpicIssue.class));
436+
"groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues", epicIssueId);
437+
return (response.readEntity(EpicIssueLink.class));
437438
}
438439

439440
/**
440441
* Updates an epic - issue association.
441442
*
442-
* <pre><code>GitLab Endpoint: PUT /groups/:id/epics/:epic_iid/issues/:issue_id</code></pre>
443+
* <pre><code>GitLab Endpoint: PUT /groups/:id/epics/:epic_iid/issues/:epic_issue_id</code></pre>
443444
*
444445
* @param groupIdOrPath the group ID, path of the group, or a Group instance holding the group ID or path
445446
* @param epicIid the Epic IID that the issue is assigned to
446-
* @param issueIid the issue IID to update
447-
* @param moveBeforeId the ID of the issue - epic association that should be placed before the link in the question (optional)
448-
* @param moveAfterId the ID of the issue - epic association that should be placed after the link in the question (optional)
449-
* @return an EpicIssue instance containing info on the newly assigned epic issue
447+
* @param epicIssueId the ID of the "issue - epic" association
448+
* @param moveBeforeId the ID of the "issue - epic" association that should be placed before the link in the question (optional)
449+
* @param moveAfterId the ID of the "issue - epic" association that should be placed after the link in the question (optional)
450+
* @return a list of all issues belonging to the specified epic
450451
* @throws GitLabApiException if any exception occurs
451452
*/
452-
public EpicIssue updateIssue(Object groupIdOrPath, Long epicIid, Long issueIid, Long moveBeforeId, Long moveAfterId) throws GitLabApiException {
453+
public List<EpicIssue> updateIssue(Object groupIdOrPath, Long epicIid, Long epicIssueId, Long moveBeforeId, Long moveAfterId) throws GitLabApiException {
453454
GitLabApiForm form = new GitLabApiForm()
454455
.withParam("move_before_id", moveBeforeId)
455456
.withParam("move_after_id", moveAfterId);
456-
Response response = post(Response.Status.OK, form,
457-
"groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues", issueIid);
458-
return (response.readEntity(EpicIssue.class));
457+
Response response = put(Response.Status.OK, form,
458+
"groups", getGroupIdOrPath(groupIdOrPath), "epics", epicIid, "issues", epicIssueId);
459+
return response.readEntity(new GenericType<List<EpicIssue>>() {});
459460
}
460461
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
package org.gitlab4j.api.models;
3+
4+
import org.gitlab4j.api.utils.JacksonJson;
5+
6+
public class EpicIssueLink {
7+
8+
private Long id;
9+
private Integer relativePosition;
10+
private Epic epic;
11+
private Issue issue;
12+
13+
public Long getId() {
14+
return id;
15+
}
16+
17+
public void setId(Long epicIssueId) {
18+
this.id = epicIssueId;
19+
}
20+
21+
public Integer getRelativePosition() {
22+
return relativePosition;
23+
}
24+
25+
public void setRelativePosition(Integer relativePosition) {
26+
this.relativePosition = relativePosition;
27+
}
28+
29+
public Epic getEpic() {
30+
return epic;
31+
}
32+
33+
public void setEpic(Epic epic) {
34+
this.epic = epic;
35+
}
36+
37+
public Issue getIssue() {
38+
return issue;
39+
}
40+
41+
public void setIssue(Issue issue) {
42+
this.issue = issue;
43+
}
44+
45+
@Override
46+
public String toString() {
47+
return (JacksonJson.toJsonString(this));
48+
}
49+
}

src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.gitlab4j.api.models.Environment;
6161
import org.gitlab4j.api.models.Epic;
6262
import org.gitlab4j.api.models.EpicIssue;
63+
import org.gitlab4j.api.models.EpicIssueLink;
6364
import org.gitlab4j.api.models.Event;
6465
import org.gitlab4j.api.models.ExportStatus;
6566
import org.gitlab4j.api.models.ExternalStatusCheck;
@@ -254,6 +255,12 @@ public void testEpicIssue() throws Exception {
254255
assertTrue(compareJson(epicIssue, "epic-issue.json"));
255256
}
256257

258+
@Test
259+
public void testEpicIssueLink() throws Exception {
260+
EpicIssueLink epicIssueLink = unmarshalResource(EpicIssueLink.class, "epic-issue-link.json");
261+
assertTrue(compareJson(epicIssueLink, "epic-issue-link.json"));
262+
}
263+
257264
@Test
258265
public void testEvent() throws Exception {
259266
Event event = unmarshalResource(Event.class, "event.json");
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
{
2+
"id": 237,
3+
"relative_position": -1026,
4+
"epic": {
5+
"id": 25,
6+
"iid": 1,
7+
"color": "#1068bf",
8+
"group_id": 139,
9+
"title": "Test group Epic",
10+
"description": "",
11+
"author": {
12+
"id": 1,
13+
"username": "pipin",
14+
"name": "Pip",
15+
"state": "active",
16+
"avatar_url": "http://www.gravatar.com/avatar/5224fd70153710e92fb8bcf79ac29d67?s=80&d=identicon",
17+
"web_url": "https://gitlab.example.com/pipin"
18+
},
19+
"state": "opened",
20+
"web_url": "https://gitlab.example.com/groups/my/test-group/-/epics/1",
21+
"references": {
22+
"short": "&1",
23+
"relative": "&1",
24+
"full": "my/test-group&1"
25+
},
26+
"reference": "my/test-group&1",
27+
"created_at": "2022-08-23T13:50:08.507Z",
28+
"updated_at": "2023-04-27T13:36:34.636Z",
29+
"labels": [],
30+
"upvotes": 0,
31+
"downvotes": 0,
32+
"_links": {
33+
"self": "https://gitlab.example.com/api/v4/groups/139/epics/1",
34+
"epic_issues": "https://gitlab.example.com/api/v4/groups/139/epics/1/issues",
35+
"group": "https://gitlab.example.com/api/v4/groups/139" }
36+
},
37+
"issue": {
38+
"id": 1106,
39+
"iid": 9,
40+
"project_id": 58,
41+
"title": "a title",
42+
"description": "a description",
43+
"state": "opened",
44+
"created_at": "2022-09-12T07:30:09.431Z",
45+
"updated_at": "2023-04-27T13:36:34.703Z",
46+
"labels": [],
47+
"assignees": [],
48+
"author": {
49+
"id": 1,
50+
"username": "pipin",
51+
"name": "Pip",
52+
"state": "active",
53+
"avatar_url": "http://www.gravatar.com/avatar/5224fd70153710e92fb8bcf79ac29d67?s=80&d=identicon",
54+
"web_url": "https://gitlab.example.com/pipin"
55+
},
56+
"user_notes_count": 0,
57+
"merge_requests_count": 1,
58+
"upvotes": 0,
59+
"downvotes": 0,
60+
"web_url": "https://gitlab.example.com/my/test-group/a-project/-/issues/9",
61+
"time_stats": {
62+
"time_estimate": 0,
63+
"total_time_spent": 0
64+
},
65+
"task_completion_status": {
66+
"count": 0,
67+
"completed_count": 0
68+
}
69+
}
70+
}

0 commit comments

Comments
 (0)