Commit 978c6380 authored by Schakko's avatar Schakko Committed by Greg Messner
Browse files

Add GitLab's (very limited) time tracking API (#81)

parent e0bb05fa
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<groupId>org.gitlab4j</groupId> <groupId>org.gitlab4j</groupId>
<artifactId>gitlab4j-api</artifactId> <artifactId>gitlab4j-api</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>4.5.1-SNAPSHOT</version> <version>4.5.2-SNAPSHOT</version>
<name>GitLab API Java Client</name> <name>GitLab API Java Client</name>
<description>GitLab API for Java (gitlab4j-api) provides a full featured Java API for working with GitLab repositories via the GitLab REST API</description> <description>GitLab API for Java (gitlab4j-api) provides a full featured Java API for working with GitLab repositories via the GitLab REST API</description>
<url>http://www.messners.com/#gitlab4j-api/gitlab4j-api.html</url> <url>http://www.messners.com/#gitlab4j-api/gitlab4j-api.html</url>
......
...@@ -31,6 +31,7 @@ import javax.ws.rs.core.Response; ...@@ -31,6 +31,7 @@ import javax.ws.rs.core.Response;
import org.gitlab4j.api.GitLabApi.ApiVersion; import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Issue; import org.gitlab4j.api.models.Issue;
import org.gitlab4j.api.models.TimeStats;
/** /**
* This class provides an entry point to all the GitLab API project calls. * This class provides an entry point to all the GitLab API project calls.
...@@ -293,4 +294,126 @@ public class IssuesApi extends AbstractApi implements Constants { ...@@ -293,4 +294,126 @@ public class IssuesApi extends AbstractApi implements Constants {
Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT); Response.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT);
delete(expectedStatus, getDefaultPerPageParam(), "projects", projectId, "issues", issueIid); delete(expectedStatus, getDefaultPerPageParam(), "projects", projectId, "issues", issueIid);
} }
/**
* Sets an estimated time of work in this issue
*
* POST /projects/:id/issues/:issue_iid/time_estimate
*
* @param projectId the project ID to delete the issue from
* @param issueIid the internal ID of a project's issue
* @param duration Human readable format, e.g. 3h30m
* @throws GitLabApiException if any exception occurs
*/
public TimeStats estimateTime(Integer projectId, Integer issueIid, String duration) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
if (issueIid == null) {
throw new RuntimeException("issue IID cannot be null");
}
GitLabApiForm formData = new GitLabApiForm()
.withParam("duration", duration, true);
Response response = post(Response.Status.CREATED, formData.asMap(), "projects", projectId, "issues", issueIid, "time_estimate");
return (response.readEntity(TimeStats.class));
}
/**
* Resets the estimated time for this issue to 0 seconds.
*
* POST /projects/:id/issues/:issue_iid/reset_time_estimate
*
* @param projectId the project ID to delete the issue from
* @param issueIid the internal ID of a project's issue
* @throws GitLabApiException if any exception occurs
*/
public TimeStats resetEstimatedTime(Integer projectId, Integer issueIid) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
if (issueIid == null) {
throw new RuntimeException("issue IID cannot be null");
}
Response response = post(Response.Status.OK, new GitLabApiForm().asMap(), "projects", projectId, "issues", issueIid, "reset_time_estimate");
return (response.readEntity(TimeStats.class));
}
/**
* Adds spent time for this issue
*
* POST /projects/:id/issues/:issue_iid/add_spent_time
*
* @param projectId the project ID to delete the issue from
* @param issueIid the internal ID of a project's issue
* @param duration Human readable format, e.g. 3h30m
* @throws GitLabApiException if any exception occurs
*/
public TimeStats addSpentTime(Integer projectId, Integer issueIid, String duration) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
if (issueIid == null) {
throw new RuntimeException("issue IID cannot be null");
}
GitLabApiForm formData = new GitLabApiForm()
.withParam("duration", duration, true);
Response response = post(Response.Status.CREATED, formData.asMap(), "projects", projectId, "issues", issueIid, "add_spent_time");
return (response.readEntity(TimeStats.class));
}
/**
* Resets the total spent time for this issue to 0 seconds.
*
* POST /projects/:id/issues/:issue_iid/reset_spent_time
*
* @param projectId
* @param issueIId
* @throws GitLabApiException
*/
public TimeStats resetSpentTime(Integer projectId, Integer issueIid) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
if (issueIid == null) {
throw new RuntimeException("issue IID cannot be null");
}
Response response = post(Response.Status.OK, new GitLabApiForm().asMap(), "projects", projectId, "issues", issueIid, "reset_spent_time");
return (response.readEntity(TimeStats.class));
}
/**
* Get time tracking stats
*
* GET /projects/:id/issues/:issue_iid/time_stats
*
* @param projectId
* @param issueIId
* @throws GitLabApiException
*/
public TimeStats getTimeTrackingStats(Integer projectId, Integer issueIid) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
if (issueIid == null) {
throw new RuntimeException("issue IID cannot be null");
}
Response response = get(Response.Status.OK, new GitLabApiForm().asMap(), "projects", projectId, "issues", issueIid, "time_stats");
return (response.readEntity(TimeStats.class));
}
} }
...@@ -38,6 +38,7 @@ import org.gitlab4j.api.Constants.IssueState; ...@@ -38,6 +38,7 @@ import org.gitlab4j.api.Constants.IssueState;
import org.gitlab4j.api.GitLabApi.ApiVersion; import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Issue; import org.gitlab4j.api.models.Issue;
import org.gitlab4j.api.models.Project; import org.gitlab4j.api.models.Project;
import org.gitlab4j.api.models.TimeStats;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Before; import org.junit.Before;
import org.junit.BeforeClass; import org.junit.BeforeClass;
...@@ -215,4 +216,72 @@ public class TestIssuesApi { ...@@ -215,4 +216,72 @@ public class TestIssuesApi {
assertEquals(Response.Status.NOT_FOUND.getStatusCode(), gle.getHttpStatus()); assertEquals(Response.Status.NOT_FOUND.getStatusCode(), gle.getHttpStatus());
} }
} }
/**
* Simplify creation of issues
* @return
* @throws GitLabApiException
*/
private Issue ensureIssue() throws GitLabApiException {
Integer projectId = testProject.getId();
String title = getUniqueTitle();
Issue issue = gitLabApi.getIssuesApi().createIssue(projectId, title, ISSUE_DESCRIPTION);
return issue;
}
@Test
public void testGetTimeTrackingStats() throws GitLabApiException {
Issue issue = ensureIssue();
TimeStats timeStats = gitLabApi.getIssuesApi().getTimeTrackingStats(issue.getProjectId(), issue.getIid());
assertEquals(new Integer(0), timeStats.getTimeEstimate());
assertEquals(new Integer(0), timeStats.getTotalTimeSpent());
}
/**
* Expect the given {@link TimeStats} object to have the values
* @param timeStats
* @param timeEstimate
* @param totalTimeSpent
*/
private void assertTimeStats(TimeStats timeStats, int timeEstimate, int totalTimeSpent) {
assertEquals(new Integer(timeEstimate), timeStats.getTimeEstimate());
assertEquals(new Integer(totalTimeSpent), timeStats.getTotalTimeSpent());
}
@Test
public void testEstimateTime() throws GitLabApiException {
Issue issue = ensureIssue();
TimeStats timeStats = gitLabApi.getIssuesApi().estimateTime(issue.getProjectId(), issue.getIid(), "1h");
assertTimeStats(timeStats, (60 /* seconds */ * 60 /* minutes */), 0);
}
@Test
public void testResetEstimatedTime() throws GitLabApiException {
Issue issue = ensureIssue();
gitLabApi.getIssuesApi().estimateTime(issue.getProjectId(), issue.getIid(), "1h");
TimeStats timeStats = gitLabApi.getIssuesApi().resetEstimatedTime(issue.getProjectId(), issue.getIid());
assertTimeStats(timeStats, 0, 0);
}
@Test
public void testAddSpentTime() throws GitLabApiException {
Issue issue = ensureIssue();
TimeStats timeStats = gitLabApi.getIssuesApi().addSpentTime(issue.getProjectId(), issue.getIid(), "1h");
assertTimeStats(timeStats, 0, (60 /* seconds */ * 60 /* minutes */));
}
@Test
public void testResetSpentTime() throws GitLabApiException {
Issue issue = ensureIssue();
gitLabApi.getIssuesApi().addSpentTime(issue.getProjectId(), issue.getIid(), "1h");
TimeStats timeStats = gitLabApi.getIssuesApi().resetSpentTime(issue.getProjectId(), issue.getIid());
assertTimeStats(timeStats, 0, 0);
}
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment