Skip to content

Commit 1c5d956

Browse files
authored
Merge pull request #740 from Nektion/master
Add ability to read resource state events for Issues
2 parents c996b1b + 297502d commit 1c5d956

File tree

5 files changed

+255
-1
lines changed

5 files changed

+255
-1
lines changed

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public String getApiNamespace() {
8585
private RepositoryApi repositoryApi;
8686
private RepositoryFileApi repositoryFileApi;
8787
private ResourceLabelEventsApi resourceLabelEventsApi;
88+
private ResourceStateEventsApi resourceStateEventsApi;
8889
private RunnersApi runnersApi;
8990
private SearchApi searchApi;
9091
private ServicesApi servicesApi;
@@ -1488,6 +1489,25 @@ public ResourceLabelEventsApi getResourceLabelEventsApi() {
14881489
return (resourceLabelEventsApi);
14891490
}
14901491

1492+
/**
1493+
* Gets the ResourceStateEventsApi instance owned by this GitLabApi instance. The ResourceStateEventsApi
1494+
* is used to perform all Resource State Events related API calls.
1495+
*
1496+
* @return the ResourceStateEventsApi instance owned by this GitLabApi instance
1497+
*/
1498+
public ResourceStateEventsApi getResourceStateEventsApi() {
1499+
1500+
if (resourceStateEventsApi == null) {
1501+
synchronized (this) {
1502+
if (resourceStateEventsApi == null) {
1503+
resourceStateEventsApi = new ResourceStateEventsApi(this);
1504+
}
1505+
}
1506+
}
1507+
1508+
return (resourceStateEventsApi);
1509+
}
1510+
14911511
/**
14921512
* Gets the RunnersApi instance owned by this GitLabApi instance. The RunnersApi is used
14931513
* to perform all Runner related API calls.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package org.gitlab4j.api;
2+
3+
import org.gitlab4j.api.models.IssueEvent;
4+
import org.gitlab4j.api.models.LabelEvent;
5+
6+
import javax.ws.rs.core.Response;
7+
import java.util.List;
8+
import java.util.Optional;
9+
import java.util.stream.Stream;
10+
11+
12+
/**
13+
* This class provides an entry point to all the GitLab Resource state events API
14+
* @see <a href="https://docs.gitlab.com/ce/api/resource_state_events.html">Resource state events API at GitLab</a>
15+
*/
16+
public class ResourceStateEventsApi extends AbstractApi {
17+
18+
public ResourceStateEventsApi(GitLabApi gitLabApi) {
19+
super(gitLabApi);
20+
}
21+
22+
/**
23+
* Gets a list of all state events for a single issue.
24+
*
25+
* <pre><code>GitLab Endpoint: GET /projects/:id/issues/:issue_iid/resource_state_events</code></pre>
26+
*
27+
* @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path
28+
* @param issueIid the IID of the issue
29+
* @return a List of IssueEvent for the specified issue
30+
* @throws GitLabApiException if any exception occurs
31+
*/
32+
public List<IssueEvent> getIssueStateEvents(Object projectIdOrPath, Integer issueIid) throws GitLabApiException {
33+
return (getIssueStateEvents(projectIdOrPath, issueIid, getDefaultPerPage()).all());
34+
}
35+
36+
/**
37+
* Gets a Pager of all state events for a single issue.
38+
*
39+
* <pre><code>GitLab Endpoint: GET /projects/:id/issues/:issue_iid/resource_state_events</code></pre>
40+
*
41+
* @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path
42+
* @param issueIid the IID of the issue
43+
* @param itemsPerPage the number of LabelEvent instances that will be fetched per page
44+
* @return the Pager of IssueEvent instances for the specified issue IID
45+
* @throws GitLabApiException if any exception occurs
46+
*/
47+
public Pager<IssueEvent> getIssueStateEvents(Object projectIdOrPath, Integer issueIid, int itemsPerPage) throws GitLabApiException {
48+
return (new Pager<IssueEvent>(this, IssueEvent.class, itemsPerPage, null,
49+
"projects", getProjectIdOrPath(projectIdOrPath), "issues", issueIid, "resource_state_events"));
50+
}
51+
52+
/**
53+
* Gets a Stream of all state events for a single issue.
54+
*
55+
* <pre><code>GitLab Endpoint: GET /projects/:id/issues/:issue_iid/resource_state_events</code></pre>
56+
*
57+
* @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path
58+
* @param issueIid the IID of the issue
59+
* @return a Stream of IssueEvent for the specified issue
60+
* @throws GitLabApiException if any exception occurs
61+
*/
62+
public Stream<IssueEvent> getIssueStateEventsStream(Object projectIdOrPath, Integer issueIid) throws GitLabApiException {
63+
return (getIssueStateEvents(projectIdOrPath, issueIid, getDefaultPerPage()).stream());
64+
}
65+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
package org.gitlab4j.api.models;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonValue;
5+
import org.gitlab4j.api.utils.JacksonJson;
6+
import org.gitlab4j.api.utils.JacksonJsonEnumHelper;
7+
8+
public class IssueEvent {
9+
/** Enum to use for specifying the state events resource type. */
10+
public enum ResourceType {
11+
12+
ISSUE;
13+
14+
private static JacksonJsonEnumHelper<ResourceType> enumHelper = new JacksonJsonEnumHelper<>(ResourceType.class,
15+
true, true);
16+
17+
@JsonCreator
18+
public static ResourceType forValue(String value) {
19+
return enumHelper.forValue(value);
20+
}
21+
22+
@JsonValue
23+
public String toValue() {
24+
return (enumHelper.toString(this));
25+
}
26+
27+
@Override
28+
public String toString() {
29+
return (enumHelper.toString(this));
30+
}
31+
}
32+
33+
private int id;
34+
private User user;
35+
private String createdAt;
36+
private ResourceType resourceType;
37+
private int resourceId;
38+
private String state;
39+
40+
public int getId() {
41+
return id;
42+
}
43+
44+
public void setId(int id) {
45+
this.id = id;
46+
}
47+
48+
public User getUser() {
49+
return user;
50+
}
51+
52+
public void setUser(User user) {
53+
this.user = user;
54+
}
55+
56+
public String getCreatedAt() {
57+
return createdAt;
58+
}
59+
60+
public void setCreatedAt(String createdAt) {
61+
this.createdAt = createdAt;
62+
}
63+
64+
public ResourceType getResourceType() {
65+
return resourceType;
66+
}
67+
68+
public void setResourceType(ResourceType resourceType) {
69+
this.resourceType = resourceType;
70+
}
71+
72+
public int getResourceId() {
73+
return resourceId;
74+
}
75+
76+
public void setResourceId(int resourceId) {
77+
this.resourceId = resourceId;
78+
}
79+
80+
public String getState() {
81+
return state;
82+
}
83+
84+
public void setState(String state) {
85+
this.state = state;
86+
}
87+
88+
89+
@Override
90+
public String toString() {
91+
return (JacksonJson.toJsonString(this));
92+
}
93+
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public static void teardown() throws GitLabApiException {
101101
deleteAllTestIssues();
102102
}
103103

104-
private static void deleteAllTestIssues() {
104+
public static void deleteAllTestIssues() {
105105

106106
if (gitLabApi != null) {
107107
try {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package org.gitlab4j.api;
2+
3+
import org.gitlab4j.api.models.Issue;
4+
import org.gitlab4j.api.models.IssueEvent;
5+
import org.gitlab4j.api.models.Project;
6+
import org.junit.AfterClass;
7+
import org.junit.BeforeClass;
8+
import org.junit.Test;
9+
import org.junit.experimental.categories.Category;
10+
11+
import java.util.List;
12+
13+
import static org.gitlab4j.api.TestIssuesApi.deleteAllTestIssues;
14+
import static org.junit.Assert.*;
15+
16+
@Category(IntegrationTest.class)
17+
public class TestResourceStateEventsApi extends AbstractIntegrationTest {
18+
19+
private static GitLabApi gitLabApi;
20+
private static Project testProject;
21+
22+
private static final String ISSUE_TITLE = "Test Issue Title";
23+
private static final String ISSUE_DESCRIPTION = "This is a really nice description, not.";
24+
25+
public TestResourceStateEventsApi() {
26+
super();
27+
}
28+
29+
@BeforeClass
30+
public static void setup() {
31+
gitLabApi = baseTestSetup();
32+
testProject = getTestProject();
33+
}
34+
35+
@AfterClass
36+
public static void teardown() {
37+
deleteAllTestIssues();
38+
}
39+
40+
@Test
41+
public void testGetCloseReopenIssueEvents() throws GitLabApiException {
42+
Integer projectId = testProject.getId();
43+
Issue issue = gitLabApi.getIssuesApi().createIssue(projectId, ISSUE_TITLE, ISSUE_DESCRIPTION);
44+
45+
Issue closedIssue = gitLabApi.getIssuesApi().closeIssue(projectId, issue.getIid());
46+
assertEquals(closedIssue.getState(), Constants.IssueState.CLOSED);
47+
48+
List<IssueEvent> issueEvents = gitLabApi.getResourceStateEventsApi().getIssueStateEvents(projectId, issue.getIid());
49+
assertNotNull(issueEvents);
50+
assertEquals(1, issueEvents.size());
51+
52+
assertEquals(1, issueEvents.stream()
53+
.filter(issueEvent -> issueEvent.getState().equals(Constants.IssueState.CLOSED.toValue()))
54+
.count());
55+
56+
Issue reopenedIssue = gitLabApi.getIssuesApi()
57+
.updateIssue(projectId,
58+
issue.getIid(),
59+
null, null, null, null, null, null,
60+
Constants.StateEvent.REOPEN,
61+
null, null);
62+
assertEquals(Constants.IssueState.OPENED.toValue(), reopenedIssue.getState().toValue());
63+
64+
issueEvents = gitLabApi.getResourceStateEventsApi().getIssueStateEvents(projectId, issue.getIid());
65+
assertNotNull(issueEvents);
66+
assertEquals(2, issueEvents.size());
67+
68+
assertEquals(1, issueEvents.stream()
69+
.filter(issueEvent -> issueEvent.getState().equals(Constants.IssueState.CLOSED.toValue()))
70+
.count());
71+
assertEquals(1, issueEvents.stream()
72+
.filter(issueEvent -> issueEvent.getState().equals(Constants.IssueState.REOPENED.toValue()))
73+
.count());
74+
}
75+
76+
}

0 commit comments

Comments
 (0)