From 948c8a29f5a8dc05ac2912202a3057d1a25d54df Mon Sep 17 00:00:00 2001 From: Jeremie Bresson Date: Mon, 6 Mar 2023 16:31:55 +0100 Subject: [PATCH 1/3] Add ExternalStatusCheckApi Fixes #919 --- .../gitlab4j/api/ExternalStatusCheckApi.java | 275 ++++++++++++++++++ src/main/java/org/gitlab4j/api/GitLabApi.java | 21 ++ .../api/models/ExternalStatusCheck.java | 59 ++++ .../ExternalStatusCheckProtectedBranch.java | 71 +++++ .../api/models/ExternalStatusCheckResult.java | 39 +++ .../api/models/ExternalStatusCheckStatus.java | 73 +++++ .../api/TestExternalStatusCheckApi.java | 101 +++++++ .../org/gitlab4j/api/TestGitLabApiBeans.java | 21 ++ .../api/external-status-check-result.json | 82 ++++++ .../api/external-status-check-statuses.json | 14 + .../gitlab4j/api/external-status-checks.json | 18 ++ 11 files changed, 774 insertions(+) create mode 100644 src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java create mode 100644 src/main/java/org/gitlab4j/api/models/ExternalStatusCheck.java create mode 100644 src/main/java/org/gitlab4j/api/models/ExternalStatusCheckProtectedBranch.java create mode 100644 src/main/java/org/gitlab4j/api/models/ExternalStatusCheckResult.java create mode 100644 src/main/java/org/gitlab4j/api/models/ExternalStatusCheckStatus.java create mode 100644 src/test/java/org/gitlab4j/api/TestExternalStatusCheckApi.java create mode 100644 src/test/resources/org/gitlab4j/api/external-status-check-result.json create mode 100644 src/test/resources/org/gitlab4j/api/external-status-check-statuses.json create mode 100644 src/test/resources/org/gitlab4j/api/external-status-checks.json diff --git a/src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java b/src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java new file mode 100644 index 000000000..9098c7c10 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java @@ -0,0 +1,275 @@ +package org.gitlab4j.api; + +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.ws.rs.core.Form; +import javax.ws.rs.core.Response; + +import org.gitlab4j.api.models.ExternalStatusCheck; +import org.gitlab4j.api.models.ExternalStatusCheckProtectedBranch; +import org.gitlab4j.api.models.ExternalStatusCheckResult; +import org.gitlab4j.api.models.ExternalStatusCheckStatus; +import org.gitlab4j.api.models.ExternalStatusCheckStatus.Status; + +/** + * This class implements the client side API for the GitLab external status checks. + * See External Status Checks API for more information. + */ +public class ExternalStatusCheckApi extends AbstractApi { + + public ExternalStatusCheckApi(GitLabApi gitLabApi) { + super(gitLabApi); + } + + /** + * Gets a list of all external status checks for a given project. + * + *
GitLab Endpoint: GET /projects/:id/external_status_checks
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @return a List of ExternalStatusCheck + * @throws GitLabApiException if any exception occurs + */ + public List getExternalStatusChecks(Object projectIdOrPath) throws GitLabApiException { + return (getExternalStatusChecks(projectIdOrPath, getDefaultPerPage()).all()); + } + + /** + * Gets a Pager of all external status checks for a given project. + * + *
GitLab Endpoint: GET /projects/:id/external_status_checks
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param itemsPerPage the number of ExternalStatusCheck instances that will be fetched per page + * @return the Pager of ExternalStatusCheck instances + * @throws GitLabApiException if any exception occurs + */ + public Pager getExternalStatusChecks(Object projectIdOrPath, int itemsPerPage) throws GitLabApiException { + return (new Pager(this, ExternalStatusCheck.class, itemsPerPage, null, + "projects", getProjectIdOrPath(projectIdOrPath), "external_status_checks")); + } + + /** + * Gets a Stream of all external status checks for a given project. + * + *
GitLab Endpoint: GET /projects/:id/external_status_checks
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @return a Stream of ExternalStatusCheck + * @throws GitLabApiException if any exception occurs + */ + public Stream getExternalStatusChecksStream(Object projectIdOrPath) throws GitLabApiException { + return (getExternalStatusChecks(projectIdOrPath, getDefaultPerPage()).stream()); + } + + /** + * Creates a new external status check. + * + *
GitLab Endpoint: POST /projects/:id/external_status_checks
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param name Display name of external status check (required) + * @param externalUrl URL of external status check resource (optional) + * @param protectedBranchIds IDs of protected branches to scope the rule by (optional) + * @return an ExternalStatusCheck instance containing info on the newly created externalStatusCheck + * @throws GitLabApiException if any exception occurs + */ + public ExternalStatusCheck createExternalStatusCheck(Object projectIdOrPath, String name, String externalUrl, List protectedBranchIds) throws GitLabApiException { + Form formData = new GitLabApiForm() + .withParam("name", name, true) + .withParam("external_url", externalUrl, true) + .withParam("protected_branch_ids", protectedBranchIds); + Response response = post(Response.Status.CREATED, formData.asMap(), + "projects", getProjectIdOrPath(projectIdOrPath), "external_status_checks"); + return (response.readEntity(ExternalStatusCheck.class)); + } + + /** + * Creates a new external status check using the information contained in the provided ExternalStatusCheck instance. Only the following + * fields from the ExternalStatusCheck instance are used: + *

+     *      name - Display name of external status check (required)
+     *      external url - URL of external status check resource (required)
+     *      protected branches - the id of the protected branches (optional)
+     * 
+ * + *
GitLab Endpoint: POST /projects/:id/external_status_checks
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param externalStatusCheck the ExternalStatusCheck instance with information for the new external status check + * @return an ExternalStatusCheck instance containing info on the newly created externalStatusCheck + * @throws GitLabApiException if any exception occurs + */ + public ExternalStatusCheck createExternalStatusCheck(Object projectIdOrPath, ExternalStatusCheck externalStatusCheck) throws GitLabApiException { + List protectedBranchIds; + if(externalStatusCheck.getProtectedBranches() == null) { + protectedBranchIds = null; + } else { + protectedBranchIds = externalStatusCheck.getProtectedBranches().stream().map(ExternalStatusCheckProtectedBranch::getId).collect(Collectors.toList()); + } + Form formData = new GitLabApiForm() + .withParam("name", externalStatusCheck.getName(), true) + .withParam("external_url", externalStatusCheck.getExternalUrl(), true) + .withParam("protected_branch_ids", protectedBranchIds); + Response response = post(Response.Status.CREATED, formData.asMap(), + "projects", getProjectIdOrPath(projectIdOrPath), "external_status_checks"); + return (response.readEntity(ExternalStatusCheck.class)); + } + + /** + * Updates an existing external status check. + * + *
GitLab Endpoint: PUT /projects/:id/external_status_checks/:check_id
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param checkId ID of an external status check to update (required) + * @param name Display name of external status check (optional) + * @param externalUrl URL of external status check resource (optional) + * @param protectedBranchIds IDs of protected branches to scope the rule by (optional) + * @return an ExternalStatusCheck instance containing info on the newly created ExternalStatusCheck + * @throws GitLabApiException if any exception occurs + */ + public ExternalStatusCheck updateExternalStatusCheck(Object projectIdOrPath, Long checkId, String name, String externalUrl, List protectedBranchIds) throws GitLabApiException { + Form formData = new GitLabApiForm() + .withParam("name", name) + .withParam("external_url", externalUrl) + .withParam("protected_branch_ids", protectedBranchIds); + Response response = put(Response.Status.OK, formData.asMap(), + "projects", getProjectIdOrPath(projectIdOrPath), "external_status_checks", checkId); + return (response.readEntity(ExternalStatusCheck.class)); + } + + /** + * Updates an external status check using the information contained in the provided ExternalStatusCheck instance. Only the following + * fields from the ExternalStatusCheck instance are used: + *

+     *      id - the id of the external status check (required)
+     *      name - Display name of external status check (optional)
+     *      external url - URL of external status check resource (optional)
+     *      protected branches - the id of the protected branches (optional)
+     * 
+ *
GitLab Endpoint: PUT /projects/:id/external_status_checks/:check_id
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param externalStatusCheck the ExternalStatusCheck instance with update information + * @return an ExternalStatusCheck instance containing info on the updated ExternalStatusCheck + * @throws GitLabApiException if any exception occurs + */ + public ExternalStatusCheck updateExternalStatusCheck(Object projectIdOrPath, ExternalStatusCheck externalStatusCheck) throws GitLabApiException { + if (externalStatusCheck == null || externalStatusCheck.getId() == null) { + throw new GitLabApiException("the specified external status check is null or has no id"); + } + List protectedBranchIds = getProtectedBranchIds(externalStatusCheck); + Form formData = new GitLabApiForm() + .withParam("name", externalStatusCheck.getName()) + .withParam("external_url", externalStatusCheck.getExternalUrl()) + .withParam("protected_branch_ids", protectedBranchIds); + Response response = put(Response.Status.OK, formData.asMap(), + "projects", getProjectIdOrPath(projectIdOrPath), "external_status_checks", externalStatusCheck.getId()); + return (response.readEntity(ExternalStatusCheck.class)); + } + + private List getProtectedBranchIds(ExternalStatusCheck externalStatusCheck) { + if(externalStatusCheck.getProtectedBranches() == null) { + return null; + } + return externalStatusCheck.getProtectedBranches().stream().map(ExternalStatusCheckProtectedBranch::getId).collect(Collectors.toList()); + } + + /** + * Deletes an external status check. + * + *
GitLab Endpoint: DELETE /projects/:id/external_status_checks/:check_id
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param checkId ID of an external status check + * @throws GitLabApiException if any exception occurs + */ + public void deleteExternalStatusCheck(Object projectIdOrPath, Long checkId) throws GitLabApiException { + delete(Response.Status.NO_CONTENT, null, "projects", getProjectIdOrPath(projectIdOrPath), "external_status_checks", checkId); + } + + /** + * Gets a list of all statuses of the external status checks for a given merge request. + * + *
GitLab Endpoint: GET /projects/:id/merge_requests/:merge_request_iid/status_checks
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param mergeRequestIid the merge request IID to get the statuses + * @return a List of ExternalStatusCheckStatus + * @throws GitLabApiException if any exception occurs + */ + public List getExternalStatusCheckStatuses(Object projectIdOrPath, Long mergeRequestIid) throws GitLabApiException { + return (getExternalStatusCheckStatuses(projectIdOrPath, mergeRequestIid, getDefaultPerPage()).all()); + } + + /** + * Gets a Pager of all statuses of the external status checks for a given merge request. + * + *
GitLab Endpoint: GET /projects/:id/merge_requests/:merge_request_iid/status_checks
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param mergeRequestIid the merge request IID to get the statuses + * @param itemsPerPage the number of ExternalStatusCheckStatus instances that will be fetched per page + * @return the Pager of ExternalStatusCheckStatus instances + * @throws GitLabApiException if any exception occurs + */ + public Pager getExternalStatusCheckStatuses(Object projectIdOrPath, Long mergeRequestIid, int itemsPerPage) throws GitLabApiException { + return (new Pager(this, ExternalStatusCheckStatus.class, itemsPerPage, null, + "projects", getProjectIdOrPath(projectIdOrPath), "merge_requests", mergeRequestIid, "status_checks")); + } + + /** + * Gets a Stream of all statuses of the external status checks for a given merge request. + * + *
GitLab Endpoint: GET /projects/:id/merge_requests/:merge_request_iid/status_checks
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param mergeRequestIid the merge request IID to get the statuses + * @return a Stream of ExternalStatusCheckStatus + * @throws GitLabApiException if any exception occurs + */ + public Stream getExternalStatusCheckStatusesStream(Object projectIdOrPath, Long mergeRequestIid) throws GitLabApiException { + return (getExternalStatusCheckStatuses(projectIdOrPath, mergeRequestIid, getDefaultPerPage()).stream()); + } + + /** + * Set the status of an external status check for a given merge request. + * + *
GitLab Endpoint: PUT /projects/:id/external_status_checks/:check_id
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param mergeRequestIid the merge request IID to get the statuses + * @param sha the commit SHA to set the status for (required) + * @param externalStatusCheckId ID of an external status check (required) + * @param status the status to set (optional) + * @return an ExternalStatusCheckResult instance containing info on the newly created status + * @throws GitLabApiException if any exception occurs + */ + public ExternalStatusCheckResult setStatusOfExternalStatusCheck(Object projectIdOrPath, Long mergeRequestIid, String sha, Long externalStatusCheckId, Status status) throws GitLabApiException { + Form formData = new GitLabApiForm() + .withParam("sha", sha) + .withParam("external_status_check_id", externalStatusCheckId) + .withParam("status", status); + Response response = post(Response.Status.CREATED, formData.asMap(), + "projects", getProjectIdOrPath(projectIdOrPath), "merge_requests", mergeRequestIid, "status_check_responses"); + return (response.readEntity(ExternalStatusCheckResult.class)); + } + + /** + * Retry the specified failed external status check for a single merge request. Even though the merge request hasn’t changed, this endpoint resends the current state of merge request to the defined external service. + * + *
GitLab Endpoint: POST /projects/:id/merge_requests/:merge_request_iid/status_checks/:external_status_check_id/retry
+ * + * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path + * @param mergeRequestIid the merge request IID to get the statuses + * @param externalStatusCheckId ID of an external status check + * @throws GitLabApiException if any exception occurs + */ + public void retryExternalStatusCheck(Object projectIdOrPath, Long mergeRequestIid, Long externalStatusCheckId) throws GitLabApiException { + post(Response.Status.ACCEPTED, (Form)null, "projects", getProjectIdOrPath(projectIdOrPath), "merge_requests", mergeRequestIid, "status_checks", externalStatusCheckId, "retry"); + } + +} diff --git a/src/main/java/org/gitlab4j/api/GitLabApi.java b/src/main/java/org/gitlab4j/api/GitLabApi.java index 051b73674..ecc65d3d1 100644 --- a/src/main/java/org/gitlab4j/api/GitLabApi.java +++ b/src/main/java/org/gitlab4j/api/GitLabApi.java @@ -64,6 +64,7 @@ public String getApiNamespace() { private EnvironmentsApi environmentsApi; private EpicsApi epicsApi; private EventsApi eventsApi; + private ExternalStatusCheckApi externalStatusCheckApi; private GroupApi groupApi; private HealthCheckApi healthCheckApi; private ImportExportApi importExportApi; @@ -1087,6 +1088,26 @@ public EventsApi getEventsApi() { return (eventsApi); } + /** + * Gets the ExternalStatusCheckApi instance owned by this GitLabApi instance. The ExternalStatusCheckApi is used + * to perform all the external status checks related API calls. + * + * @return the ExternalStatusCheckApi instance owned by this GitLabApi instance + */ + public ExternalStatusCheckApi getExternalStatusCheckApi() { + + if (externalStatusCheckApi == null) { + synchronized (this) { + if (externalStatusCheckApi == null) { + externalStatusCheckApi = new ExternalStatusCheckApi(this); + } + } + } + + return (externalStatusCheckApi); + } + + /** * Gets the GroupApi instance owned by this GitLabApi instance. The GroupApi is used * to perform all group related API calls. diff --git a/src/main/java/org/gitlab4j/api/models/ExternalStatusCheck.java b/src/main/java/org/gitlab4j/api/models/ExternalStatusCheck.java new file mode 100644 index 000000000..3d90d6827 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ExternalStatusCheck.java @@ -0,0 +1,59 @@ +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; + +import java.util.List; + +public class ExternalStatusCheck { + + private Long id; + private String name; + private Long projectId; + private String externalUrl; + private List protectedBranches; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Long getProjectId() { + return projectId; + } + + public void setProjectId(Long projectId) { + this.projectId = projectId; + } + + public String getExternalUrl() { + return externalUrl; + } + + public void setExternalUrl(String externalUrl) { + this.externalUrl = externalUrl; + } + + public List getProtectedBranches() { + return protectedBranches; + } + + public void setProtectedBranches(List protectedBranches) { + this.protectedBranches = protectedBranches; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckProtectedBranch.java b/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckProtectedBranch.java new file mode 100644 index 000000000..6f0d9fcc4 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckProtectedBranch.java @@ -0,0 +1,71 @@ + +package org.gitlab4j.api.models; + +import java.util.Date; +import java.util.List; + +import org.gitlab4j.api.utils.JacksonJson; + +public class ExternalStatusCheckProtectedBranch { + + private Long id; + private Long projectId; + private String name; + private Date createdAt; + private Date updatedAt; + private Boolean codeOwnerApprovalRequired; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + + public Long getProjectId() { + return projectId; + } + + public void setProjectId(Long projectId) { + this.projectId = projectId; + } + + public String getName() { + return this.name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public Boolean getCodeOwnerApprovalRequired() { + return codeOwnerApprovalRequired; + } + + public void setCodeOwnerApprovalRequired(Boolean codeOwnerApprovalRequired) { + this.codeOwnerApprovalRequired = codeOwnerApprovalRequired; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckResult.java b/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckResult.java new file mode 100644 index 000000000..4a8ea927b --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckResult.java @@ -0,0 +1,39 @@ +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; + +public class ExternalStatusCheckResult { + + private Long id; + private MergeRequest mergeRequest; + private ExternalStatusCheck externalStatusCheck; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public MergeRequest getMergeRequest() { + return mergeRequest; + } + + public void setMergeRequest(MergeRequest mergeRequest) { + this.mergeRequest = mergeRequest; + } + + public ExternalStatusCheck getExternalStatusCheck() { + return externalStatusCheck; + } + + public void setExternalStatusCheck(ExternalStatusCheck externalStatusCheck) { + this.externalStatusCheck = externalStatusCheck; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckStatus.java b/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckStatus.java new file mode 100644 index 000000000..c1e858243 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/models/ExternalStatusCheckStatus.java @@ -0,0 +1,73 @@ +package org.gitlab4j.api.models; + +import org.gitlab4j.api.utils.JacksonJson; +import org.gitlab4j.api.utils.JacksonJsonEnumHelper; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +public class ExternalStatusCheckStatus { + + private Long id; + private String name; + private String externalUrl; + private Status status; + + public enum Status { + PASSED, FAILED, PENDING; + + private static JacksonJsonEnumHelper enumHelper = new JacksonJsonEnumHelper<>(Status.class); + + @JsonCreator + public static Status forValue(String value) { + return enumHelper.forValue(value); + } + + @JsonValue + public String toValue() { + return (enumHelper.toString(this)); + } + + @Override + public String toString() { + return (enumHelper.toString(this)); + } + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getExternalUrl() { + return externalUrl; + } + + public void setExternalUrl(String externalUrl) { + this.externalUrl = externalUrl; + } + + public Status getStatus() { + return status; + } + + public void setStatus(Status status) { + this.status = status; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/test/java/org/gitlab4j/api/TestExternalStatusCheckApi.java b/src/test/java/org/gitlab4j/api/TestExternalStatusCheckApi.java new file mode 100644 index 000000000..7b118e22a --- /dev/null +++ b/src/test/java/org/gitlab4j/api/TestExternalStatusCheckApi.java @@ -0,0 +1,101 @@ +package org.gitlab4j.api; + +import static org.gitlab4j.api.JsonUtils.compareJson; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.openMocks; + +import java.io.IOException; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.ws.rs.core.MultivaluedMap; + +import org.gitlab4j.api.models.ExternalStatusCheck; +import org.gitlab4j.api.models.ExternalStatusCheckStatus; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; + +public class TestExternalStatusCheckApi implements Constants { + + @Mock private GitLabApi gitLabApi; + @Mock private GitLabApiClient gitLabApiClient; + @Captor private ArgumentCaptor> attributeCaptor; + private MockResponse response; + + @BeforeEach + public void setUp() throws Exception { + openMocks(this); + } + + @Test + public void testGetExternalStatusChecks() throws Exception { + initGetExternalStatusChecks(); + List result = new ExternalStatusCheckApi(gitLabApi).getExternalStatusChecks(6L); + assertNotNull(result); + assertTrue(compareJson(result, "external-status-checks.json")); + } + + @Test + public void testGetExternalStatusChecksByPager() throws Exception { + initGetExternalStatusChecks(); + Pager pager = new ExternalStatusCheckApi(gitLabApi).getExternalStatusChecks(6L, 20); + assertNotNull(pager); + assertTrue(compareJson(pager.all(), "external-status-checks.json")); + } + + @Test + public void testGetExternalStatusChecksByStream() throws Exception { + initGetExternalStatusChecks(); + Stream stream = new ExternalStatusCheckApi(gitLabApi).getExternalStatusChecksStream(6L); + assertNotNull(stream); + List list = stream.collect(Collectors.toList()); + assertTrue(compareJson(list, "external-status-checks.json")); + } + + private void initGetExternalStatusChecks() throws Exception, IOException { + response = new MockResponse(ExternalStatusCheck.class, null, "external-status-checks.json"); + when(gitLabApi.getApiClient()).thenReturn(gitLabApiClient); + when(gitLabApiClient.validateSecretToken(any())).thenReturn(true); + when(gitLabApiClient.get(attributeCaptor.capture(), Mockito.any())).thenReturn(response); + } + + @Test + public void testGetExternalStatusCheckStatuses() throws Exception { + initGetExternalStatusCheckStatuses(); + List result = new ExternalStatusCheckApi(gitLabApi).getExternalStatusCheckStatuses(6L, 23L); + assertNotNull(result); + assertTrue(compareJson(result, "external-status-check-statuses.json")); + } + + @Test + public void testGetExternalStatusCheckStatusesByPager() throws Exception { + initGetExternalStatusCheckStatuses(); + Pager pager = new ExternalStatusCheckApi(gitLabApi).getExternalStatusCheckStatuses(6L, 23L, 20); + assertNotNull(pager); + assertTrue(compareJson(pager.all(), "external-status-check-statuses.json")); + } + + @Test + public void testGetExternalStatusCheckStatusesByStream() throws Exception { + initGetExternalStatusCheckStatuses(); + Stream stream = new ExternalStatusCheckApi(gitLabApi).getExternalStatusCheckStatusesStream(6L, 23L); + assertNotNull(stream); + List list = stream.collect(Collectors.toList()); + assertTrue(compareJson(list, "external-status-check-statuses.json")); + } + + private void initGetExternalStatusCheckStatuses() throws Exception, IOException { + response = new MockResponse(ExternalStatusCheckStatus.class, null, "external-status-check-statuses.json"); + when(gitLabApi.getApiClient()).thenReturn(gitLabApiClient); + when(gitLabApiClient.validateSecretToken(any())).thenReturn(true); + when(gitLabApiClient.get(attributeCaptor.capture(), Mockito.any())).thenReturn(response); + } +} diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java index 77a3c424a..12a10656a 100644 --- a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java +++ b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java @@ -62,6 +62,9 @@ import org.gitlab4j.api.models.EpicIssue; import org.gitlab4j.api.models.Event; import org.gitlab4j.api.models.ExportStatus; +import org.gitlab4j.api.models.ExternalStatusCheck; +import org.gitlab4j.api.models.ExternalStatusCheckResult; +import org.gitlab4j.api.models.ExternalStatusCheckStatus; import org.gitlab4j.api.models.FileUpload; import org.gitlab4j.api.models.GpgSignature; import org.gitlab4j.api.models.Group; @@ -266,6 +269,24 @@ public void testExportStatus() throws Exception { assertTrue(compareJson(exportStatus, "export-status.json")); } + @Test + public void testExternalStatusChecks() throws Exception { + List externalStatusChecks = unmarshalResourceList(ExternalStatusCheck.class, "external-status-checks.json"); + assertTrue(compareJson(externalStatusChecks, "external-status-checks.json")); + } + + @Test + public void testExternalStatusCheckResult() throws Exception { + ExternalStatusCheckResult externalStatusCheckResult = unmarshalResource(ExternalStatusCheckResult.class, "external-status-check-result.json"); + assertTrue(compareJson(externalStatusCheckResult, "external-status-check-result.json")); + } + + @Test + public void testExternalStatusCheckStatuses() throws Exception { + List externalStatusCheckStatuses = unmarshalResourceList(ExternalStatusCheckStatus.class, "external-status-check-statuses.json"); + assertTrue(compareJson(externalStatusCheckStatuses, "external-status-check-statuses.json")); + } + @Test public void testFileUpload() throws Exception { FileUpload fileUpload = unmarshalResource(FileUpload.class, "file-upload.json"); diff --git a/src/test/resources/org/gitlab4j/api/external-status-check-result.json b/src/test/resources/org/gitlab4j/api/external-status-check-result.json new file mode 100644 index 000000000..4f7745272 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/external-status-check-result.json @@ -0,0 +1,82 @@ +{ + "id": 4, + "merge_request": { + "id": 7495, + "iid": 19, + "project_id": 7, + "title": "Update readme", + "description": "This is a test", + "state": "opened", + "created_at": "2023-02-18T09:02:29.978Z", + "updated_at": "2023-02-18T09:02:29.978Z", + "target_branch": "main/2.0.x", + "source_branch": "patch-1", + "user_notes_count": 0, + "upvotes": 0, + "downvotes": 0, + "author": { + "id": 1, + "name": "root", + "username": "root", + "state": "active", + "avatar_url": "https://www.gravatar.com/avatar/00afb8fb6ab07c3ee3e9c1f38777e2f4?s=80&d=identicon", + "web_url": "http://localhost:3000/root" + }, + "assignees": [{ + "id": 7, + "name": "Pamella Huel", + "username": "arnita", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a2f5c6fcef64c9c69cb8779cb292be1b?s=80&d=identicon", + "web_url": "http://localhost:3001/arnita" + }], + "assignee": { + "id": 7, + "name": "Pamella Huel", + "username": "arnita", + "state": "active", + "avatar_url": "http://www.gravatar.com/avatar/a2f5c6fcef64c9c69cb8779cb292be1b?s=80&d=identicon", + "web_url": "http://localhost:3001/arnita" + }, + "reviewers": [], + "source_project_id": 7, + "target_project_id": 7, + "labels": [], + "work_in_progress": false, + "merge_when_pipeline_succeeds": false, + "merge_status": "can_be_merged", + "sha": "3704ece21a11fc92a0a86cdec0df16a5b304a4ed", + "force_remove_source_branch": true, + "references": { + "short": "!19", + "relative": "!19", + "full": "my-group/my-project!19" + }, + "web_url": "http://localhost:3001/my-group/my-project/-/merge_requests/19", + "time_stats": { + "time_estimate": 0, + "total_time_spent": 0 + }, + "squash": false, + "task_completion_status": { + "count": 0, + "completed_count": 0 + }, + "has_conflicts": false, + "blocking_discussions_resolved": true, + "subscribed": false, + "changes_count": "1", + "diff_refs": { + "base_sha": "8f46dbb86b44b0c59e4cdb411a22f5f38e92d546", + "head_sha": "3704ece21a11fc92a0a86cdec0df16a5b304a4ed", + "start_sha": "8f46dbb86b44b0c59e4cdb411a22f5f38e92d546" + } + }, + "external_status_check": { + "id": 2, + "name": "a_test", + "project_id": 7, + "external_url": "https://gitlab.com/example/test.json", + "protected_branches": [] + } +} diff --git a/src/test/resources/org/gitlab4j/api/external-status-check-statuses.json b/src/test/resources/org/gitlab4j/api/external-status-check-statuses.json new file mode 100644 index 000000000..f0babbb7b --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/external-status-check-statuses.json @@ -0,0 +1,14 @@ +[ + { + "id": 2, + "name": "a_test", + "external_url": "https://example.com/734a9960", + "status": "failed" + }, + { + "id": 3, + "name": "name", + "external_url": "https://example.io/7ce5d28c7f65", + "status": "pending" + } +] diff --git a/src/test/resources/org/gitlab4j/api/external-status-checks.json b/src/test/resources/org/gitlab4j/api/external-status-checks.json new file mode 100644 index 000000000..b4a4f9173 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/external-status-checks.json @@ -0,0 +1,18 @@ +[ + { + "id": 1, + "name": "Compliance Check", + "project_id": 6, + "external_url": "https://gitlab.com/example/test.json", + "protected_branches": [ + { + "id": 14, + "project_id": 6, + "name": "master", + "created_at": "2020-10-12T14:04:50.787Z", + "updated_at": "2020-10-12T14:04:50.787Z", + "code_owner_approval_required": false + } + ] + } +] From 825bdc8a5deb820bea053b0340665b5d5268064e Mon Sep 17 00:00:00 2001 From: Jeremie Bresson Date: Wed, 15 Mar 2023 11:36:10 +0100 Subject: [PATCH 2/3] Add ExternalStatusCheckEvent --- .../api/webhook/EventExternalStatusCheck.java | 39 ++++++ .../api/webhook/ExternalStatusCheckEvent.java | 107 +++++++++++++++ .../org/gitlab4j/api/TestGitLabApiBeans.java | 7 + .../api/external-status-check-event.json | 122 ++++++++++++++++++ 4 files changed, 275 insertions(+) create mode 100644 src/main/java/org/gitlab4j/api/webhook/EventExternalStatusCheck.java create mode 100644 src/main/java/org/gitlab4j/api/webhook/ExternalStatusCheckEvent.java create mode 100644 src/test/resources/org/gitlab4j/api/external-status-check-event.json diff --git a/src/main/java/org/gitlab4j/api/webhook/EventExternalStatusCheck.java b/src/main/java/org/gitlab4j/api/webhook/EventExternalStatusCheck.java new file mode 100644 index 000000000..16feb98b1 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/webhook/EventExternalStatusCheck.java @@ -0,0 +1,39 @@ +package org.gitlab4j.api.webhook; + +import org.gitlab4j.api.utils.JacksonJson; + +public class EventExternalStatusCheck { + + private Long id; + private String name; + private String externalUrl; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getExternalUrl() { + return externalUrl; + } + + public void setExternalUrl(String externalUrl) { + this.externalUrl = externalUrl; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/main/java/org/gitlab4j/api/webhook/ExternalStatusCheckEvent.java b/src/main/java/org/gitlab4j/api/webhook/ExternalStatusCheckEvent.java new file mode 100644 index 000000000..785df9430 --- /dev/null +++ b/src/main/java/org/gitlab4j/api/webhook/ExternalStatusCheckEvent.java @@ -0,0 +1,107 @@ +package org.gitlab4j.api.webhook; + +import java.util.List; + +import org.gitlab4j.api.models.Assignee; +import org.gitlab4j.api.models.User; +import org.gitlab4j.api.utils.JacksonJson; +import org.gitlab4j.api.webhook.MergeRequestEvent.ObjectAttributes; + +public class ExternalStatusCheckEvent { + + private String objectKind; + private String eventType; + private User user; + private EventProject project; + private EventRepository repository; + private ObjectAttributes objectAttributes; + private List labels; + private MergeRequestChanges changes; + private List assignees; + private EventExternalStatusCheck externalApprovalRule; + + public String getObjectKind() { + return objectKind; + } + + public void setObjectKind(String objectKind) { + this.objectKind = objectKind; + } + + public String getEventType() { + return eventType; + } + + public void setEventType(String eventType) { + this.eventType = eventType; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public EventProject getProject() { + return project; + } + + public void setProject(EventProject project) { + this.project = project; + } + + public EventRepository getRepository() { + return repository; + } + + public void setRepository(EventRepository repository) { + this.repository = repository; + } + + public ObjectAttributes getObjectAttributes() { + return this.objectAttributes; + } + + public void setObjectAttributes(ObjectAttributes objectAttributes) { + this.objectAttributes = objectAttributes; + } + + public List getLabels() { + return labels; + } + + public void setLabels(List labels) { + this.labels = labels; + } + + public MergeRequestChanges getChanges() { + return changes; + } + + public void setChanges(MergeRequestChanges changes) { + this.changes = changes; + } + + public List getAssignees() { + return assignees; + } + + public void setAssignees(List assignees) { + this.assignees = assignees; + } + + public EventExternalStatusCheck getExternalApprovalRule() { + return externalApprovalRule; + } + + public void setExternalApprovalRule(EventExternalStatusCheck externalApprovalRule) { + this.externalApprovalRule = externalApprovalRule; + } + + @Override + public String toString() { + return (JacksonJson.toJsonString(this)); + } +} diff --git a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java index 12a10656a..e57743850 100644 --- a/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java +++ b/src/test/java/org/gitlab4j/api/TestGitLabApiBeans.java @@ -115,6 +115,7 @@ import org.gitlab4j.api.models.Variable; import org.gitlab4j.api.services.JiraService; import org.gitlab4j.api.services.SlackService; +import org.gitlab4j.api.webhook.ExternalStatusCheckEvent; import org.junit.jupiter.api.Test; import com.fasterxml.jackson.databind.JsonNode; @@ -275,6 +276,12 @@ public void testExternalStatusChecks() throws Exception { assertTrue(compareJson(externalStatusChecks, "external-status-checks.json")); } + @Test + public void testExternalStatusCheckEvent() throws Exception { + ExternalStatusCheckEvent externalStatusCheckEvent = unmarshalResource(ExternalStatusCheckEvent.class, "external-status-check-event.json"); + assertTrue(compareJson(externalStatusCheckEvent, "external-status-check-event.json")); + } + @Test public void testExternalStatusCheckResult() throws Exception { ExternalStatusCheckResult externalStatusCheckResult = unmarshalResource(ExternalStatusCheckResult.class, "external-status-check-result.json"); diff --git a/src/test/resources/org/gitlab4j/api/external-status-check-event.json b/src/test/resources/org/gitlab4j/api/external-status-check-event.json new file mode 100644 index 000000000..2e09b8fd5 --- /dev/null +++ b/src/test/resources/org/gitlab4j/api/external-status-check-event.json @@ -0,0 +1,122 @@ +{ + "object_kind": "merge_request", + "event_type": "merge_request", + "user": { + "id": 37, + "name": "John Smith", + "username": "jsmith", + "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/37/avatar.png", + "email": "[REDACTED]" + }, + "project": { + "id": 499, + "name": "a_project", + "web_url": "https://gitlab.example.com/a_group/a_project", + "git_ssh_url": "git@gitshell.example.com:a_group/a_project.git", + "git_http_url": "https://gitlab.example.com/a_group/a_project.git", + "namespace": "Sandbox", + "visibility_level": 0, + "path_with_namespace": "a_group/a_project", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.example.com/a_group/a_project", + "url": "git@gitshell.example.com:a_group/a_project.git", + "ssh_url": "git@gitshell.example.com:a_group/a_project.git", + "http_url": "https://gitlab.example.com/a_group/a_project.git" + }, + "object_attributes": { + "assignee_id": 37, + "author_id": 37, + "created_at": "2023-03-14T12:50:14Z", + "description": "A description", + "id": 8440, + "iid": 20, + "merge_params": { + "force_remove_source_branch": "1" + }, + "merge_status": "preparing", + "merge_when_pipeline_succeeds": false, + "source_branch": "patch-2", + "source_project_id": 499, + "target_branch": "main", + "target_project_id": 499, + "time_estimate": 0, + "title": "Update readme.adoc Test", + "updated_at": "2023-03-14T12:50:14Z", + "url": "https://gitlab.example.com/a_group/a_project/-/merge_requests/20", + "source": { + "id": 499, + "name": "a_project", + "web_url": "https://gitlab.example.com/a_group/a_project", + "git_ssh_url": "git@gitshell.example.com:a_group/a_project.git", + "git_http_url": "https://gitlab.example.com/a_group/a_project.git", + "namespace": "Sandbox", + "visibility_level": 0, + "path_with_namespace": "a_group/a_project", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.example.com/a_group/a_project", + "url": "git@gitshell.example.com:a_group/a_project.git", + "ssh_url": "git@gitshell.example.com:a_group/a_project.git", + "http_url": "https://gitlab.example.com/a_group/a_project.git" + }, + "target": { + "id": 499, + "name": "a_project", + "web_url": "https://gitlab.example.com/a_group/a_project", + "git_ssh_url": "git@gitshell.example.com:a_group/a_project.git", + "git_http_url": "https://gitlab.example.com/a_group/a_project.git", + "namespace": "Sandbox", + "visibility_level": 0, + "path_with_namespace": "a_group/a_project", + "default_branch": "main", + "ci_config_path": "", + "homepage": "https://gitlab.example.com/a_group/a_project", + "url": "git@gitshell.example.com:a_group/a_project.git", + "ssh_url": "git@gitshell.example.com:a_group/a_project.git", + "http_url": "https://gitlab.example.com/a_group/a_project.git" + }, + "last_commit": { + "id": "93bcabc3d474e18a8c744139be0d2dea45ebb3a3", + "message": "Update readme.adoc", + "timestamp": "2023-03-14T12:49:55Z", + "url": "https://gitlab.example.com/a_group/a_project/-/commit/93bcabc3d474e18a8c744139be0d2dea45ebb3a3", + "author": { + "name": "John Smith", + "email": "jsmith@example.com" + } + }, + "work_in_progress": false, + "total_time_spent": 0, + "assignee_ids": [ + 37 + ], + "state": "opened", + "action": "open" + }, + "changes": { + "merge_status": { + "previous": "unchecked", + "current": "preparing" + } + }, + "repository": { + "name": "a_project", + "url": "git@gitshell.example.com:a_group/a_project.git", + "homepage": "https://gitlab.example.com/a_group/a_project" + }, + "assignees": [ + { + "id": 37, + "name": "John Smith", + "username": "jsmith", + "avatar_url": "https://gitlab.example.com/uploads/-/system/user/avatar/37/avatar.png", + "email": "[REDACTED]" + } + ], + "external_approval_rule": { + "id": 2, + "name": "a_test", + "external_url": "https://external.io/a-check" + } +} \ No newline at end of file From dfdc498cac329d0627419de1886e990dbff141f1 Mon Sep 17 00:00:00 2001 From: Jeremie Bresson Date: Wed, 15 Mar 2023 18:04:33 +0100 Subject: [PATCH 3/3] Fix javadoc --- src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java b/src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java index 9098c7c10..e0d04a26d 100644 --- a/src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java +++ b/src/main/java/org/gitlab4j/api/ExternalStatusCheckApi.java @@ -238,7 +238,7 @@ public Stream getExternalStatusCheckStatusesStream(Ob /** * Set the status of an external status check for a given merge request. * - *
GitLab Endpoint: PUT /projects/:id/external_status_checks/:check_id
+ *
GitLab Endpoint: POST /projects/:id/merge_requests/:merge_request_iid/status_check_responses
* * @param projectIdOrPath id, path of the project, or a Project instance holding the project ID or path * @param mergeRequestIid the merge request IID to get the statuses