From 79b831c767453e4ce48d0a53d8dcd2f91951e37b Mon Sep 17 00:00:00 2001 From: t0m4uk1991 Date: Fri, 13 Aug 2021 18:13:25 +0300 Subject: [PATCH] Add ability to read resource state events for Issues --- src/main/java/org/gitlab4j/api/GitLabApi.java | 20 ++++ .../gitlab4j/api/ResourceStateEventsApi.java | 65 +++++++++++++ .../org/gitlab4j/api/models/IssueEvent.java | 93 +++++++++++++++++++ .../java/org/gitlab4j/api/TestIssuesApi.java | 2 +- .../api/TestResourceStateEventsApi.java | 76 +++++++++++++++ 5 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/gitlab4j/api/ResourceStateEventsApi.java create mode 100644 src/main/java/org/gitlab4j/api/models/IssueEvent.java create mode 100644 src/test/java/org/gitlab4j/api/TestResourceStateEventsApi.java diff --git a/src/main/java/org/gitlab4j/api/GitLabApi.java b/src/main/java/org/gitlab4j/api/GitLabApi.java index e3e931fce..aa19398f5 100644 --- a/src/main/java/org/gitlab4j/api/GitLabApi.java +++ b/src/main/java/org/gitlab4j/api/GitLabApi.java @@ -85,6 +85,7 @@ public String getApiNamespace() { private RepositoryApi repositoryApi; private RepositoryFileApi repositoryFileApi; private ResourceLabelEventsApi resourceLabelEventsApi; + private ResourceStateEventsApi resourceStateEventsApi; private RunnersApi runnersApi; private SearchApi searchApi; private ServicesApi servicesApi; @@ -1488,6 +1489,25 @@ public ResourceLabelEventsApi getResourceLabelEventsApi() { return (resourceLabelEventsApi); } + /** + * Gets the ResourceStateEventsApi instance owned by this GitLabApi instance. The ResourceStateEventsApi + * is used to perform all Resource State Events related API calls. + * + * @return the ResourceStateEventsApi instance owned by this GitLabApi instance + */ + public ResourceStateEventsApi getResourceStateEventsApi() { + + if (resourceStateEventsApi == null) { + synchronized (this) { + if (resourceStateEventsApi == null) { + resourceStateEventsApi = new ResourceStateEventsApi(this); + } + } + } + + return (resourceStateEventsApi); + } + /** * Gets the RunnersApi instance owned by this GitLabApi instance. The RunnersApi is used * to perform all Runner related API calls. diff --git a/src/main/java/org/gitlab4j/api/ResourceStateEventsApi.java b/src/main/java/org/gitlab4j/api/ResourceStateEventsApi.java new file mode 100644 index 000000000..ff4c42a59 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/ResourceStateEventsApi.java @@ -0,0 +1,65 @@ +package org.gitlab4j.api; + +import org.gitlab4j.api.models.IssueEvent; +import org.gitlab4j.api.models.LabelEvent; + +import javax.ws.rs.core.Response; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; + + +/** + * This class provides an entry point to all the GitLab Resource state events API + * @see Resource state events API at GitLab + */ +public class ResourceStateEventsApi extends AbstractApi { + + public ResourceStateEventsApi(GitLabApi gitLabApi) { + super(gitLabApi); + } + + /** + * Gets a list of all state events for a single issue. + * + *
GitLab Endpoint: GET /projects/:id/issues/:issue_iid/resource_state_events
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param issueIid the IID of the issue + * @return a List of IssueEvent for the specified issue + * @throws GitLabApiException if any exception occurs + */ + public List getIssueStateEvents(Object projectIdOrPath, Integer issueIid) throws GitLabApiException { + return (getIssueStateEvents(projectIdOrPath, issueIid, getDefaultPerPage()).all()); + } + + /** + * Gets a Pager of all state events for a single issue. + * + *
GitLab Endpoint: GET /projects/:id/issues/:issue_iid/resource_state_events
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param issueIid the IID of the issue + * @param itemsPerPage the number of LabelEvent instances that will be fetched per page + * @return the Pager of IssueEvent instances for the specified issue IID + * @throws GitLabApiException if any exception occurs + */ + public Pager getIssueStateEvents(Object projectIdOrPath, Integer issueIid, int itemsPerPage) throws GitLabApiException { + return (new Pager(this, IssueEvent.class, itemsPerPage, null, + "projects", getProjectIdOrPath(projectIdOrPath), "issues", issueIid, "resource_state_events")); + } + + /** + * Gets a Stream of all state events for a single issue. + * + *
GitLab Endpoint: GET /projects/:id/issues/:issue_iid/resource_state_events
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param issueIid the IID of the issue + * @return a Stream of IssueEvent for the specified issue + * @throws GitLabApiException if any exception occurs + */ + public Stream getIssueStateEventsStream(Object projectIdOrPath, Integer issueIid) throws GitLabApiException { + return (getIssueStateEvents(projectIdOrPath, issueIid, getDefaultPerPage()).stream()); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/IssueEvent.java b/src/main/java/org/gitlab4j/api/models/IssueEvent.java new file mode 100644 index 000000000..142621b81 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/IssueEvent.java @@ -0,0 +1,93 @@ +package org.gitlab4j.api.models; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; +import org.gitlab4j.api.utils.JacksonJson; +import org.gitlab4j.api.utils.JacksonJsonEnumHelper; + +public class IssueEvent { + /** Enum to use for specifying the state events resource type. */ + public enum ResourceType { + + ISSUE; + + private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(ResourceType.class, + true, true); + + @JsonCreator + public static ResourceType forValue(String value) { + return enumHelper.forValue(value); + } + + @JsonValue + public String toValue() { + return (enumHelper.toString(this)); + } + + @Override + public String toString() { + return (enumHelper.toString(this)); + } + } + + private int id; + private User user; + private String createdAt; + private ResourceType resourceType; + private int resourceId; + private String state; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public String getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(String createdAt) { + this.createdAt = createdAt; + } + + public ResourceType getResourceType() { + return resourceType; + } + + public void setResourceType(ResourceType resourceType) { + this.resourceType = resourceType; + } + + public int getResourceId() { + return resourceId; + } + + public void setResourceId(int resourceId) { + this.resourceId = resourceId; + } + + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/test/java/org/gitlab4j/api/TestIssuesApi.java b/src/test/java/org/gitlab4j/api/TestIssuesApi.java index 434769e66..d42146859 100644 --- a/src/test/java/org/gitlab4j/api/TestIssuesApi.java +++ b/src/test/java/org/gitlab4j/api/TestIssuesApi.java @@ -101,7 +101,7 @@ public static void teardown() throws GitLabApiException { deleteAllTestIssues(); } - private static void deleteAllTestIssues() { + public static void deleteAllTestIssues() { if (gitLabApi != null) { try { diff --git a/src/test/java/org/gitlab4j/api/TestResourceStateEventsApi.java b/src/test/java/org/gitlab4j/api/TestResourceStateEventsApi.java new file mode 100644 index 000000000..745f68e76 --- /dev/null +++ b/src/test/java/org/gitlab4j/api/TestResourceStateEventsApi.java @@ -0,0 +1,76 @@ +package org.gitlab4j.api; + +import org.gitlab4j.api.models.Issue; +import org.gitlab4j.api.models.IssueEvent; +import org.gitlab4j.api.models.Project; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import java.util.List; + +import static org.gitlab4j.api.TestIssuesApi.deleteAllTestIssues; +import static org.junit.Assert.*; + +@Category(IntegrationTest.class) +public class TestResourceStateEventsApi extends AbstractIntegrationTest { + + private static GitLabApi gitLabApi; + private static Project testProject; + + private static final String ISSUE_TITLE = "Test Issue Title"; + private static final String ISSUE_DESCRIPTION = "This is a really nice description, not."; + + public TestResourceStateEventsApi() { + super(); + } + + @BeforeClass + public static void setup() { + gitLabApi = baseTestSetup(); + testProject = getTestProject(); + } + + @AfterClass + public static void teardown() { + deleteAllTestIssues(); + } + + @Test + public void testGetCloseReopenIssueEvents() throws GitLabApiException { + Integer projectId = testProject.getId(); + Issue issue = gitLabApi.getIssuesApi().createIssue(projectId, ISSUE_TITLE, ISSUE_DESCRIPTION); + + Issue closedIssue = gitLabApi.getIssuesApi().closeIssue(projectId, issue.getIid()); + assertEquals(closedIssue.getState(), Constants.IssueState.CLOSED); + + List issueEvents = gitLabApi.getResourceStateEventsApi().getIssueStateEvents(projectId, issue.getIid()); + assertNotNull(issueEvents); + assertEquals(1, issueEvents.size()); + + assertEquals(1, issueEvents.stream() + .filter(issueEvent -> issueEvent.getState().equals(Constants.IssueState.CLOSED.toValue())) + .count()); + + Issue reopenedIssue = gitLabApi.getIssuesApi() + .updateIssue(projectId, + issue.getIid(), + null, null, null, null, null, null, + Constants.StateEvent.REOPEN, + null, null); + assertEquals(Constants.IssueState.OPENED.toValue(), reopenedIssue.getState().toValue()); + + issueEvents = gitLabApi.getResourceStateEventsApi().getIssueStateEvents(projectId, issue.getIid()); + assertNotNull(issueEvents); + assertEquals(2, issueEvents.size()); + + assertEquals(1, issueEvents.stream() + .filter(issueEvent -> issueEvent.getState().equals(Constants.IssueState.CLOSED.toValue())) + .count()); + assertEquals(1, issueEvents.stream() + .filter(issueEvent -> issueEvent.getState().equals(Constants.IssueState.REOPENED.toValue())) + .count()); + } + +}