Commit 0ebaceea authored by Greg Messner's avatar Greg Messner
Browse files

Initial check-in (#69)

parent 73f3502f
/*
* The MIT License (MIT)
*
* Copyright (c) 2017 Greg Messner <greg@messners.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.gitlab4j.api;
import java.util.Date;
import java.util.List;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Issue;
/**
* This class provides an entry point to all the GitLab API project calls.
*/
public class IssuesApi extends AbstractApi implements Constants {
public IssuesApi(GitLabApi gitLabApi) {
super(gitLabApi);
}
/**
* Get all issues the authenticated user has access to. Only returns issues created by the current user. Only returns the first page
*
* GET /issues
*
* @return a list of user's issues
* @throws GitLabApiException if any exception occurs
*/
public List<Issue> getIssues() throws GitLabApiException {
return (getIssues(1, getDefaultPerPage()));
}
/**
* Get all issues the authenticated user has access to using the specified page and per page setting. Only returns issues created by the current user.
*
* GET /issues
*
* @param page the page to get
* @param perPage the number of issues per page
* @return the list of issues in the specified range
* @throws GitLabApiException if any exception occurs
*/
public List<Issue> getIssues(int page, int perPage) throws GitLabApiException {
Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "issues");
return (response.readEntity(new GenericType<List<Issue>>() {}));
}
/**
* Get a Pager of all issues the authenticated user has access to. Only returns issues created by the current user.
*
* GET /issues
*r
* @param itemsPerPage the number of issues per page
* @return the list of issues in the specified range
* @throws GitLabApiException if any exception occurs
*/
public Pager<Issue> getIssues(int itemsPerPage) throws GitLabApiException {
return (new Pager<Issue>(this, Issue.class, itemsPerPage, null, "issues"));
}
/**
* Get a list of project's issues. Only returns the first page
*
* GET /projects/:id/issues
*
* @param projectId the project ID to get the issues for
* @return a list of project's issues
* @throws GitLabApiException if any exception occurs
*/
public List<Issue> getIssues(Integer projectId) throws GitLabApiException {
return (getIssues(projectId, 1, getDefaultPerPage()));
}
/**
* Get a list of project's issues using the specified page and per page settings.
*
* GET /projects/:id/issues
*
* @param projectId the project ID to get the issues for
* @param page the page to get
* @param perPage the number of issues per page
* @return the list of issues in the specified range
* @throws GitLabApiException if any exception occurs
*/
public List<Issue> getIssues(Integer projectId, int page, int perPage) throws GitLabApiException {
Response response = get(Response.Status.OK, getPageQueryParams(page, perPage), "projects", projectId, "issues");
return (response.readEntity(new GenericType<List<Issue>>() {}));
}
/**
* Get a Pager of project's issues.
*
* GET /projects/:id/issues
*
* @param projectId the project ID to get the issues for
* @param itemsPerPage the number of issues per page
* @return the list of issues in the specified range
* @throws GitLabApiException if any exception occurs
*/
public Pager<Issue> getIssues(Integer projectId, int itemsPerPage) throws GitLabApiException {
return (new Pager<Issue>(this, Issue.class, itemsPerPage, null, "projects", projectId, "issues"));
}
/**
* Get a single project issue.
*
* GET /projects/:id/issues/:issue_iid
*
* @param projectId the project ID to get the issue for
* @param issueId the internal ID of a project's issue
* @return the specified Issue instance
* @throws GitLabApiException if any exception occurs
*/
public Issue getIssue(Integer projectId, Integer issueId) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
Response response = get(Response.Status.OK, getDefaultPerPageParam(), "projects", projectId, "issues", issueId);
return (response.readEntity(Issue.class));
}
/**
* Create an issue for the project.
*
* POST /projects/:id/issues
*
* @param projectId the ID of the project owned by the authenticated user, required
* @param title the title of an issue, required
* @param description the description of an issue, optional
* @return an instance of Issue
* @throws GitLabApiException if any exception occurs
*/
public Issue createIssue(Integer projectId, String title, String description) throws GitLabApiException {
return (createIssue(projectId, title, description, null, null, null, null, null, null, null, null));
}
/**
* Create an issue for the project.
*
* POST /projects/:id/issues
*
* @param projectId the ID of the project owned by the authenticated user, required
* @param title the issue title of an issue, required
* @param description the description of an issue, optional
* @param confidential set the issue to be confidential, default is false, optional
* @param assigneeIds the IDs of the users to assign issue, optional
* @param milestoneId the ID of a milestone to assign issue, optional
* @param labels comma-separated label names for an issue, optional
* @param createdAt the date the issue was created at, optional
* @param dueDate the due date, optional
* @param mergeRequestToResolveId the IID of a merge request in which to resolve all issues. This will fill the issue with a default
* description and mark all discussions as resolved. When passing a description or title, these values will take precedence over the default values. Optional
* @param discussionToResolveId the ID of a discussion to resolve. This will fill in the issue with a default description and mark the discussion as resolved.
* Use in combination with merge_request_to_resolve_discussions_of. Optional
* @return an instance of Issue
* @throws GitLabApiException if any exception occurs
*/
public Issue createIssue(Integer projectId, String title, String description, Boolean confidential, List<Integer> assigneeIds, Integer milestoneId, String labels,
Date createdAt, Date dueDate, Integer mergeRequestToResolveId, Integer discussionToResolveId) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("projectId cannot be null");
}
GitLabApiForm formData = new GitLabApiForm()
.withParam("title", title, true)
.withParam("description", description)
.withParam("confidential", confidential)
.withParam("assignee_ids", assigneeIds)
.withParam("milestone_id", milestoneId)
.withParam("labels", labels)
.withParam("created_at", createdAt)
.withParam("due_date", dueDate)
.withParam("merge_request_to_resolve_discussions_of", mergeRequestToResolveId)
.withParam("discussion_to_resolve", discussionToResolveId);
Response response = post(Response.Status.CREATED, formData, "projects", projectId, "issues");
return (response.readEntity(Issue.class));
}
/**
* Closes an existing project issue.
*
* PUT /projects/:id/issues/:issue_iid
*
* @param projectId the ID of the project owned by the authenticated user, required
* @param issueIid the issue IID to update, required
* @return an instance of the updated Issue
* @throws GitLabApiException if any exception occurs
*/
public Issue closeIssue(Integer projectId, Integer issueIid) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("project ID cannot be null");
}
if (issueIid == null) {
throw new RuntimeException("issue IID cannot be null");
}
GitLabApiForm formData = new GitLabApiForm().withParam("state_event", StateEvent.CLOSE);
Response response = put(Response.Status.OK, formData.asMap(), "projects", projectId, "issues", issueIid);
return (response.readEntity(Issue.class));
}
/**
* Updates an existing project issue. This call can also be used to mark an issue as closed.
*
* PUT /projects/:id/issues/:issue_iid
*
* @param projectId the ID of the project owned by the authenticated user, required
* @param issueIid the issue IID to update, required
* @param title the title of an issue, optional
* @param description the description of an issue, optional
* @param confidential set the issue to be confidential, default is false, optional
* @param assigneeIds the IDs of the users to assign issue, optional
* @param milestoneId the ID of a milestone to assign issue, optional
* @param labels comma-separated label names for an issue, optional
* @param stateEvent the state event of an issue. Set close to close the issue and reopen to reopen it, optional
* @param updatedAt sets the updated date, requires admin or project owner rights, optional
* @param dueDate the due date, optional
* @return an instance of the updated Issue
* @throws GitLabApiException if any exception occurs
*/
public Issue updateIssue(Integer projectId, Integer issueIid, String title, String description, Boolean confidential, List<Integer> assigneeIds,
Integer milestoneId, String labels, StateEvent stateEvent, Date updatedAt, Date dueDate) throws GitLabApiException {
if (projectId == null) {
throw new RuntimeException("project ID cannot be null");
}
if (issueIid == null) {
throw new RuntimeException("issue IID cannot be null");
}
GitLabApiForm formData = new GitLabApiForm()
.withParam("title", title, true)
.withParam("description", description)
.withParam("confidential", confidential)
.withParam("assignee_ids", assigneeIds)
.withParam("milestone_id", milestoneId)
.withParam("labels", labels)
.withParam("state_event", stateEvent)
.withParam("updated_at", updatedAt)
.withParam("due_date", dueDate);
Response response = put(Response.Status.OK, formData.asMap(), "projects", projectId, "issues", issueIid);
return (response.readEntity(Issue.class));
}
/**
* Delete an issue.
*
* DELETE /projects/:id/issues/:issue_iid
*
* @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 void deleteIssue(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.Status expectedStatus = (isApiVersion(ApiVersion.V3) ? Response.Status.OK : Response.Status.NO_CONTENT);
delete(expectedStatus, getDefaultPerPageParam(), "projects", projectId, "issues", issueIid);
}
}
package org.gitlab4j.api.models;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class TimeStats {
private Integer timeEstimate;
private Integer totalTimeSpent;
private String humanTimeEstimate;
private String humanTotalTimeSpent;
public Integer getTimeEstimate() {
return timeEstimate;
}
public void setTimeEstimate(Integer timeEstimate) {
this.timeEstimate = timeEstimate;
}
public Integer getTotalTimeSpent() {
return totalTimeSpent;
}
public void setTotalTimeSpent(Integer totalTimeSpent) {
this.totalTimeSpent = totalTimeSpent;
}
public String getHumanTimeEstimate() {
return humanTimeEstimate;
}
public void setHumanTimeEstimate(String humanTimeEstimate) {
this.humanTimeEstimate = humanTimeEstimate;
}
public String getHumanTotalTimeSpent() {
return humanTotalTimeSpent;
}
public void setHumanTotalTimeSpent(String humanTotalTimeSpent) {
this.humanTotalTimeSpent = humanTotalTimeSpent;
}
}
/*
* The MIT License (MIT)
*
* Copyright (c) 2017 Greg Messner <greg@messners.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package org.gitlab4j.api;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
import java.util.List;
import java.util.Random;
import javax.ws.rs.core.Response;
import org.gitlab4j.api.Constants.IssueState;
import org.gitlab4j.api.GitLabApi.ApiVersion;
import org.gitlab4j.api.models.Issue;
import org.gitlab4j.api.models.Project;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* In order for these tests to run you must set the following properties in ~/test-gitlab4j.properties
*
* TEST_NAMESPACE
* TEST_PROJECT_NAME
* TEST_HOST_URL
* TEST_PRIVATE_TOKEN
*
* If any of the above are NULL, all tests in this class will be skipped.
*/
public class TestIssuesApi {
// The following needs to be set to your test repository
private static final String TEST_NAMESPACE;
private static final String TEST_PROJECT_NAME;
private static final String TEST_HOST_URL;
private static final String TEST_PRIVATE_TOKEN;
static {
TEST_NAMESPACE = TestUtils.getProperty("TEST_NAMESPACE");
TEST_PROJECT_NAME = TestUtils.getProperty("TEST_PROJECT_NAME");
TEST_HOST_URL = TestUtils.getProperty("TEST_HOST_URL");
TEST_PRIVATE_TOKEN = TestUtils.getProperty("TEST_PRIVATE_TOKEN");
}
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.";
private static Random randomNumberGenerator = new Random();
public TestIssuesApi() {
super();
}
@BeforeClass
public static void setup() {
String problems = "";
if (TEST_NAMESPACE == null || TEST_NAMESPACE.trim().length() == 0) {
problems += "TEST_NAMESPACE cannot be empty\n";
}
if (TEST_HOST_URL == null || TEST_HOST_URL.trim().length() == 0) {
problems += "TEST_HOST_URL cannot be empty\n";
}
if (TEST_PRIVATE_TOKEN == null || TEST_PRIVATE_TOKEN.trim().length() == 0) {
problems += "TEST_PRIVATE_TOKEN cannot be empty\n";
}
if (problems.isEmpty()) {
gitLabApi = new GitLabApi(ApiVersion.V4, TEST_HOST_URL, TEST_PRIVATE_TOKEN);
try {
testProject = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME);
} catch (GitLabApiException gle) {
}
} else {
System.err.print(problems);
}
deleteAllTestIssues();
}
@Before
public void beforeMethod() {
assumeTrue(gitLabApi != null);
}
@AfterClass
public static void teardown() throws GitLabApiException {
deleteAllTestIssues();
}
private static void deleteAllTestIssues() {
if (gitLabApi != null) {
try {
List<Issue> issues = gitLabApi.getIssuesApi().getIssues(testProject.getId());
if (issues != null) {
for (Issue issue : issues) {
if (issue.getTitle().startsWith(ISSUE_TITLE)) {
gitLabApi.getIssuesApi().deleteIssue(testProject.getId(), issue.getIid());
}
}
}
} catch (GitLabApiException ignore) {}
}
}
private static String getUniqueTitle() {
return (ISSUE_TITLE + " - " + (randomNumberGenerator.nextInt() + 1));
}
@Test
public void testGetIssue() throws GitLabApiException {
assertNotNull(testProject);
Integer projectId = testProject.getId();
Issue issue = gitLabApi.getIssuesApi().createIssue(projectId, getUniqueTitle(), ISSUE_DESCRIPTION);
Issue foundIssue = gitLabApi.getIssuesApi().getIssue(projectId, issue.getIid());
assertNotNull(foundIssue);
assertEquals(issue.getIid(), foundIssue.getIid());
}
@Test
public void testGetIssues() throws GitLabApiException {
assertNotNull(testProject);
Integer projectId = testProject.getId();
Issue issue = gitLabApi.getIssuesApi().createIssue(projectId, getUniqueTitle(), ISSUE_DESCRIPTION);
List<Issue> issues = gitLabApi.getIssuesApi().getIssues(projectId);
assertNotNull(issues);
// Make sure the issue just created is returned
boolean found = false;
for (Issue item : issues) {
if (item.getId().equals(issue.getId())) {
found = true;
break;
}
}
assertTrue(found);
}
@Test
public void testCreateIssue() throws GitLabApiException {
assertNotNull(testProject);
Integer projectId = testProject.getId();
String title = getUniqueTitle();
Issue issue = gitLabApi.getIssuesApi().createIssue(projectId, title, ISSUE_DESCRIPTION);
assertNotNull(issue);
assertEquals(title, issue.getTitle());
assertEquals(ISSUE_DESCRIPTION, issue.getDescription());
assertEquals(IssueState.OPENED, issue.getState());
}
@Test
public void testCloseIssueJustCreated() throws GitLabApiException {
assertNotNull(testProject);
Integer projectId = testProject.getId();
Issue issue = gitLabApi.getIssuesApi().createIssue(projectId, getUniqueTitle(), ISSUE_DESCRIPTION);
Issue closedIssue = gitLabApi.getIssuesApi().closeIssue(projectId, issue.getIid());
assertNotNull(closedIssue);
assertEquals(IssueState.CLOSED, closedIssue.getState());
assertEquals(issue.getId(), closedIssue.getId());
}
@Test
public void testDeleteIssue() throws GitLabApiException {
assertNotNull(testProject);
Integer projectId = testProject.getId();
Issue issue = gitLabApi.getIssuesApi().createIssue(projectId, getUniqueTitle(), ISSUE_DESCRIPTION);
gitLabApi.getIssuesApi().deleteIssue(projectId, issue.getIid());
try {
issue = gitLabApi.getIssuesApi().getIssue(projectId, issue.getIid());
assertNull(issue);
} catch (GitLabApiException gle) {
assertEquals(Response.Status.NOT_FOUND.getStatusCode(), gle.getHttpStatus());
}
}
}
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