diff --git a/src/main/java/org/gitlab4j/api/NotificationSettingsApi.java b/src/main/java/org/gitlab4j/api/NotificationSettingsApi.java new file mode 100644 index 0000000000000000000000000000000000000000..e03dd0a82d2b04040d598b36ef7c9d221e9c4e4c --- /dev/null +++ b/src/main/java/org/gitlab4j/api/NotificationSettingsApi.java @@ -0,0 +1,161 @@ +package org.gitlab4j.api; + +import javax.ws.rs.core.Response; + +import org.gitlab4j.api.models.NotificationSettings; +import org.gitlab4j.api.models.NotificationSettings.Events; + +public class NotificationSettingsApi extends AbstractApi { + + public NotificationSettingsApi(GitLabApi gitLabApi) { + super(gitLabApi); + } + + /** + * Get the global notification settings. + * + * GET /notification_settings + * + * @return a NotificationSettings instance containing the global notification settings + * @throws GitLabApiException if any exception occurs + */ + public NotificationSettings getGlobalNotificationSettings() throws GitLabApiException { + Response response = get(Response.Status.OK, null, "notification_settings"); + return (response.readEntity(NotificationSettings.class)); + } + + /** + * Update the global notification settings. + * + * PUT /notification_settings + * + * @param settings a NotificationSettings instance with the new settings + * @return a NotificationSettings instance containing the updated global notification settings + * @throws GitLabApiException if any exception occurs + */ + public NotificationSettings updateGlobalNotificationSettings(NotificationSettings settings) throws GitLabApiException { + + GitLabApiForm formData = new GitLabApiForm() + .withParam("level", settings.getLevel()) + .withParam("email", settings.getEmail()); + + Events events = settings.getEvents(); + if (events != null) { + formData.withParam("new_note", events.getNewNote()) + .withParam("new_issuee", events.getNewIssue()) + .withParam("reopen_issuee", events.getReopenIssue()) + .withParam("close_issuee", events.getCloseIssue()) + .withParam("reassign_issuee", events.getReassignIssue()) + .withParam("new_merge_requeste", events.getNewMergeRequest()) + .withParam("reopen_merge_requeste", events.getReopenMergeRequest()) + .withParam("close_merge_requeste", events.getCloseMergeRequest()) + .withParam("reassign_merge_requeste", events.getReassignMergeRequest()) + .withParam("merge_merge_requeste", events.getMergeMergeRequest()) + .withParam("failed_pipelinee", events.getFailedPipeline()) + .withParam("success_pipelinee", events.getSuccessPipeline()); + } + + Response response = put(Response.Status.OK, formData.asMap(), "notification_settings"); + return (response.readEntity(NotificationSettings.class)); + } + + /** + * Get the notification settings for a group. + * + * GET /groups/:id/notification_settings + * + * @param groupId the group ID to get the notification settings for + * @return a NotificationSettings instance containing the specified group's notification settings + * @throws GitLabApiException if any exception occurs + */ + public NotificationSettings getGroupNotificationSettings(int groupId) throws GitLabApiException { + Response response = get(Response.Status.OK, null, "groups", groupId, "notification_settings"); + return (response.readEntity(NotificationSettings.class)); + } + + /** + * Update the notification settings for a group + * + * PUT /groups/:id/notification_settings + * + * @param groupId the group ID to update the notification settings for + * @param settings a NotificationSettings instance with the new settings + * @return a NotificationSettings instance containing the updated group notification settings + * @throws GitLabApiException if any exception occurs + */ + public NotificationSettings updateGroupNotificationSettings(int groupId, NotificationSettings settings) throws GitLabApiException { + + GitLabApiForm formData = new GitLabApiForm() + .withParam("level", settings.getLevel()) + .withParam("email", settings.getEmail()); + + Events events = settings.getEvents(); + if (events != null) { + formData.withParam("new_note", events.getNewNote()) + .withParam("new_issuee", events.getNewIssue()) + .withParam("reopen_issuee", events.getReopenIssue()) + .withParam("close_issuee", events.getCloseIssue()) + .withParam("reassign_issuee", events.getReassignIssue()) + .withParam("new_merge_requeste", events.getNewMergeRequest()) + .withParam("reopen_merge_requeste", events.getReopenMergeRequest()) + .withParam("close_merge_requeste", events.getCloseMergeRequest()) + .withParam("reassign_merge_requeste", events.getReassignMergeRequest()) + .withParam("merge_merge_requeste", events.getMergeMergeRequest()) + .withParam("failed_pipelinee", events.getFailedPipeline()) + .withParam("success_pipelinee", events.getSuccessPipeline()); + } + + Response response = put(Response.Status.OK, formData.asMap(), "groups", groupId, "notification_settings"); + return (response.readEntity(NotificationSettings.class)); + } + + /** + * Get the notification settings for a project. + * + * GET /projects/:id/notification_settings + * + * @param projectId the project ID to get the notification settings for + * @return a NotificationSettings instance containing the specified project's notification settings + * @throws GitLabApiException if any exception occurs + */ + public NotificationSettings getProjectNotificationSettings(int projectId) throws GitLabApiException { + Response response = get(Response.Status.OK, null, "projects", projectId, "notification_settings"); + return (response.readEntity(NotificationSettings.class)); + } + + /** + * Update the notification settings for a project + * + * PUT /projects/:id/notification_settings + * + * @param projectId the project ID to update the notification settings for + * @param settings a NotificationSettings instance with the new settings + * @return a NotificationSettings instance containing the updated project notification settings + * @throws GitLabApiException if any exception occurs + */ + public NotificationSettings updateProjectNotificationSettings(int projectId, NotificationSettings settings) throws GitLabApiException { + + GitLabApiForm formData = new GitLabApiForm() + .withParam("level", settings.getLevel()) + .withParam("email", settings.getEmail()); + + Events events = settings.getEvents(); + if (events != null) { + formData.withParam("new_note", events.getNewNote()) + .withParam("new_issuee", events.getNewIssue()) + .withParam("reopen_issuee", events.getReopenIssue()) + .withParam("close_issuee", events.getCloseIssue()) + .withParam("reassign_issuee", events.getReassignIssue()) + .withParam("new_merge_requeste", events.getNewMergeRequest()) + .withParam("reopen_merge_requeste", events.getReopenMergeRequest()) + .withParam("close_merge_requeste", events.getCloseMergeRequest()) + .withParam("reassign_merge_requeste", events.getReassignMergeRequest()) + .withParam("merge_merge_requeste", events.getMergeMergeRequest()) + .withParam("failed_pipelinee", events.getFailedPipeline()) + .withParam("success_pipelinee", events.getSuccessPipeline()); + } + + Response response = put(Response.Status.OK, formData.asMap(), "projects", projectId, "notification_settings"); + return (response.readEntity(NotificationSettings.class)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/NotificationSettings.java b/src/main/java/org/gitlab4j/api/models/NotificationSettings.java new file mode 100644 index 0000000000000000000000000000000000000000..4a4189c3164271df9feb6ebbfe1b611083236ae6 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/NotificationSettings.java @@ -0,0 +1,178 @@ +package org.gitlab4j.api.models; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import org.gitlab4j.api.utils.JacksonJsonEnumHelper; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class NotificationSettings { + + /** Notification level */ + public static enum Level { + + DISABLED, PARTICIPATING, WATCH, GLOBAL, MENTION, CUSTOM; + + private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(Level.class); + + @JsonCreator + public static Level forValue(String value) { + return enumHelper.forValue(value); + } + + @JsonValue + public String toValue() { + return (enumHelper.toString(this)); + } + + @Override + public String toString() { + return (enumHelper.toString(this)); + } + } + + public static class Events { + + private Boolean newNote; + private Boolean newIssue; + private Boolean reopenIssue; + private Boolean closeIssue; + private Boolean reassignIssue; + private Boolean newMergeRequest; + private Boolean reopenMergeRequest; + private Boolean closeMergeRequest; + private Boolean reassignMergeRequest; + private Boolean mergeMergeRequest; + private Boolean failedPipeline; + private Boolean successPipeline; + + public Boolean getNewNote() { + return newNote; + } + + public void setNewNote(Boolean newNote) { + this.newNote = newNote; + } + + public Boolean getNewIssue() { + return newIssue; + } + + public void setNewIssue(Boolean newIssue) { + this.newIssue = newIssue; + } + + public Boolean getReopenIssue() { + return reopenIssue; + } + + public void setReopenIssue(Boolean reopenIssue) { + this.reopenIssue = reopenIssue; + } + + public Boolean getCloseIssue() { + return closeIssue; + } + + public void setCloseIssue(Boolean closeIssue) { + this.closeIssue = closeIssue; + } + + public Boolean getReassignIssue() { + return reassignIssue; + } + + public void setReassignIssue(Boolean reassignIssue) { + this.reassignIssue = reassignIssue; + } + + public Boolean getNewMergeRequest() { + return newMergeRequest; + } + + public void setNewMergeRequest(Boolean newMergeRequest) { + this.newMergeRequest = newMergeRequest; + } + + public Boolean getReopenMergeRequest() { + return reopenMergeRequest; + } + + public void setReopenMergeRequest(Boolean reopenMergeRequest) { + this.reopenMergeRequest = reopenMergeRequest; + } + + public Boolean getCloseMergeRequest() { + return closeMergeRequest; + } + + public void setCloseMergeRequest(Boolean closeMergeRequest) { + this.closeMergeRequest = closeMergeRequest; + } + + public Boolean getReassignMergeRequest() { + return reassignMergeRequest; + } + + public void setReassignMergeRequest(Boolean reassignMergeRequest) { + this.reassignMergeRequest = reassignMergeRequest; + } + + public Boolean getMergeMergeRequest() { + return mergeMergeRequest; + } + + public void setMergeMergeRequest(Boolean mergeMergeRequest) { + this.mergeMergeRequest = mergeMergeRequest; + } + + public Boolean getFailedPipeline() { + return failedPipeline; + } + + public void setFailedPipeline(Boolean failedPipeline) { + this.failedPipeline = failedPipeline; + } + + public Boolean getSuccessPipeline() { + return successPipeline; + } + + public void setSuccessPipeline(Boolean successPipeline) { + this.successPipeline = successPipeline; + } + } + + private Level level; + private String email; + private Events events; + + public Level getLevel() { + return level; + } + + public void setLevel(Level level) { + this.level = level; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Events getEvents() { + return events; + } + + public void setEvents(Events events) { + this.events = events; + } +} \ No newline at end of file diff --git a/src/test/java/org/gitlab4j/api/TestNotificationSettingsApi.java b/src/test/java/org/gitlab4j/api/TestNotificationSettingsApi.java new file mode 100644 index 0000000000000000000000000000000000000000..ef428268a040008749334525db92fce6c595cdfc --- /dev/null +++ b/src/test/java/org/gitlab4j/api/TestNotificationSettingsApi.java @@ -0,0 +1,117 @@ +package org.gitlab4j.api; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assume.assumeTrue; + +import java.util.List; + +import org.gitlab4j.api.GitLabApi.ApiVersion; +import org.gitlab4j.api.models.Group; +import org.gitlab4j.api.models.NotificationSettings; +import org.gitlab4j.api.models.Project; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.FixMethodOrder; +import org.junit.Test; +import org.junit.runners.MethodSorters; + +/** +* In order for these tests to run you must set the following properties in test-gitlab4j.properties + * + * TEST_NAMESPACE + * TEST_PROJECT_NAME + * TEST_GROUP + * TEST_HOST_URL + * TEST_PRIVATE_TOKEN + * + * If any of the above are NULL, all tests in this class will be skipped. + */ +@FixMethodOrder(MethodSorters.NAME_ASCENDING) +public class TestNotificationSettingsApi { + + // The following needs to be set to your test repository + private static final String TEST_PROJECT_NAME; + private static final String TEST_NAMESPACE; + private static final String TEST_GROUP; + 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_GROUP = TestUtils.getProperty("TEST_GROUP"); + TEST_HOST_URL = TestUtils.getProperty("TEST_HOST_URL"); + TEST_PRIVATE_TOKEN = TestUtils.getProperty("TEST_PRIVATE_TOKEN"); + } + + private static GitLabApi gitLabApi; + + public TestNotificationSettingsApi() { + 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_PROJECT_NAME == null || TEST_PROJECT_NAME.trim().length() == 0) { + problems += "TEST_PROJECT_NAME 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); + } else { + System.err.print(problems); + } + } + + @Before + public void beforeMethod() { + assumeTrue(gitLabApi != null); + } + + @Test + public void testGlobalNotificationSettings() throws GitLabApiException { + NotificationSettings settings = gitLabApi.getNotificationSettingsApi().getGlobalNotificationSettings(); + assertNotNull(settings); + } + + @Test + public void testSetGlobalNotificationSettings() throws GitLabApiException { + NotificationSettings settings = new NotificationSettings(); + settings.setLevel(NotificationSettings.Level.DISABLED); + NotificationSettings newSettings = gitLabApi.getNotificationSettingsApi().updateGlobalNotificationSettings(settings); + assertNotNull(newSettings); + assertEquals(NotificationSettings.Level.DISABLED, newSettings.getLevel()); + } + + @Test + public void testGroupNotificationSettings() throws GitLabApiException { + List groups = gitLabApi.getGroupApi().getGroups(TEST_GROUP); + assertNotNull(groups); + assertFalse(groups.isEmpty()); + NotificationSettings settings = gitLabApi.getNotificationSettingsApi().getGroupNotificationSettings(groups.get(0).getId()); + assertNotNull(settings); + } + + @Test + public void testProjectNotificationSettings() throws GitLabApiException { + Project project = gitLabApi.getProjectApi().getProject(TEST_NAMESPACE, TEST_PROJECT_NAME); + assertNotNull(project); + NotificationSettings settings = gitLabApi.getNotificationSettingsApi().getProjectNotificationSettings(project.getId()); + assertNotNull(settings); + } +} diff --git a/src/test/resources/org/gitlab4j/api/notification-settings.json b/src/test/resources/org/gitlab4j/api/notification-settings.json new file mode 100644 index 0000000000000000000000000000000000000000..22ac53996ad2f31937da530e7e4ad5e302cd175a --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/notification-settings.json @@ -0,0 +1,17 @@ +{ + "level": "custom", + "events": { + "new_note": true, + "new_issue": false, + "reopen_issue": false, + "close_issue": false, + "reassign_issue": false, + "new_merge_request": false, + "reopen_merge_request": false, + "close_merge_request": false, + "reassign_merge_request": false, + "merge_merge_request": false, + "failed_pipeline": false, + "success_pipeline": false + } +} \ No newline at end of file