diff --git a/spec/openapi.yaml b/spec/openapi.yaml index ef79efff1ff3b892a2cbf5d7c409dadda2c1a3fd..a902e0a27c9a72d9c33a6b56efa51b9e67d0f7ef 100644 --- a/spec/openapi.yaml +++ b/spec/openapi.yaml @@ -93,6 +93,47 @@ paths: 500: description: Error while processing data + /reports/gitlab/private-projects: + parameters: + - name: status + in: query + description: the project's current status - active/deleted + required: false + schema: + type: string + - name: since + in: query + description: Starting date range for project creation date - yyyy-MM-dd + required: false + schema: + type: string + - name: until + in: query + description: Ending date range for project creation date - yyyy-MM-dd + required: false + schema: + type: string + get: + tags: + - Private project event report + summary: Gitlab private project event report + description: Returns list of private project events using desired filters + responses: + 200: + description: Success + content: + application/json: + schema: + $ref: "#/components/schemas/PrivateProjectEvents" + 400: + description: Bad Request - invalid non-null prams + content: + application/json: + schema: + $ref: "#/components/schemas/Error" + 500: + description: Error while processing request + components: schemas: NullableString: @@ -334,3 +375,55 @@ components: - 'null' - string description: The old path with namespace, only used in 'project_rename' hooks + + PrivateProjectEvents: + type: array + items: + $ref: "#/components/schemas/PrivateProjectEvent" + + PrivateProjectEvent: + type: object + properties: + composite_id: + $ref: "#/components/schemas/EventCompositeId" + parent_project: + type: + - integer + - "null" + description: the parent project if it exists. Indicates this project is a fork + creation_date: + type: string + description: The project creation date + deletion_date: + type: + - string + - "null" + description: the project deletion date if it was deleted + + EventCompositeId: + type: object + properties: + user_id: + type: integer + description: the project creator's GitLab id + project_id: + type: integer + description: The project GitLab id + project_path: + type: string + description: the project's path with namespace + + Error: + type: object + properties: + status_code: + type: integer + description: HTTP response code + message: + type: string + description: Message containing error information + url: + type: + - string + - "null" + description: The URL diff --git a/src/main/java/org/eclipsefoundation/git/eca/config/LocalDateParamConverterProvider.java b/src/main/java/org/eclipsefoundation/git/eca/config/LocalDateParamConverterProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..0b80f951fb15b40c6212a3bf9d9f1cd523a8c40c --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/config/LocalDateParamConverterProvider.java @@ -0,0 +1,51 @@ +/********************************************************************* +* Copyright (c) 2022 Eclipse Foundation. +* +* This program and the accompanying materials are made +* available under the terms of the Eclipse Public License 2.0 +* which is available at https://www.eclipse.org/legal/epl-2.0/ +* +* Author: Zachary Sabourin <zachary.sabourin@eclipse-foundation.org> +* +* SPDX-License-Identifier: EPL-2.0 +**********************************************************************/ +package org.eclipsefoundation.git.eca.config; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.time.LocalDate; + +import javax.ws.rs.BadRequestException; +import javax.ws.rs.ext.ParamConverter; +import javax.ws.rs.ext.ParamConverterProvider; +import javax.ws.rs.ext.Provider; + +@Provider +public class LocalDateParamConverterProvider implements ParamConverterProvider { + + @SuppressWarnings("unchecked") + @Override + public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType, Annotation[] annotations) { + if (rawType.isAssignableFrom(LocalDate.class)) { + return (ParamConverter<T>) new LocalDateParamConverter(); + } + return null; + } + + public static class LocalDateParamConverter implements ParamConverter<LocalDate> { + + @Override + public LocalDate fromString(String date) { + try { + return LocalDate.parse(date.trim()); + } catch (Exception e) { + throw new BadRequestException(String.format("Invalid parameter: %s", date)); + } + } + + @Override + public String toString(LocalDate date) { + return date.toString(); + } + } +} diff --git a/src/main/java/org/eclipsefoundation/git/eca/dto/PrivateProjectEvent.java b/src/main/java/org/eclipsefoundation/git/eca/dto/PrivateProjectEvent.java index d9e1600ca95638b3b92393a9cf00218b855d8d61..58983fac27a96b28d273484405022f4abf51155e 100644 --- a/src/main/java/org/eclipsefoundation/git/eca/dto/PrivateProjectEvent.java +++ b/src/main/java/org/eclipsefoundation/git/eca/dto/PrivateProjectEvent.java @@ -12,7 +12,9 @@ package org.eclipsefoundation.git.eca.dto; import java.io.Serializable; +import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.util.List; import java.util.stream.Collectors; @@ -199,6 +201,39 @@ public class PrivateProjectEvent extends BareNode { new Object[] { Integer.valueOf(parentProject) })); } + String active = params.getFirst(GitEcaParameterNames.STATUS_ACTIVE.getName()); + if (StringUtils.isNotBlank(active)) { + statement.addClause( + new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".deletionDate IS NULL", + new Object[] {})); + } + + String deleted = params.getFirst(GitEcaParameterNames.STATUS_DELETED.getName()); + if (StringUtils.isNotBlank(deleted)) { + statement.addClause( + new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".deletionDate IS NOT NULL", + new Object[] {})); + } + + String since = params.getFirst(GitEcaParameterNames.SINCE.getName()); + String until = params.getFirst(GitEcaParameterNames.UNTIL.getName()); + + // Get date range or only one time filter + if (StringUtils.isNotBlank(since) && StringUtils.isNotBlank(until)) { + statement.addClause( + new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".creationDate BETWEEN ? AND ?", + new Object[] { LocalDateTime.of(LocalDate.parse(since), LocalTime.of(0, 0)), + LocalDateTime.of(LocalDate.parse(until), LocalTime.of(23, 59)) })); + } else if (StringUtils.isNotBlank(since)) { + statement.addClause( + new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".creationDate > ?", + new Object[] { LocalDateTime.of(LocalDate.parse(since), LocalTime.of(0, 0)) })); + } else if (StringUtils.isNotBlank(until)) { + statement.addClause( + new ParameterizedSQLStatement.Clause(TABLE.getAlias() + ".creationDate < ?", + new Object[] { LocalDateTime.of(LocalDate.parse(until), LocalTime.of(23, 59)) })); + } + return statement; } diff --git a/src/main/java/org/eclipsefoundation/git/eca/namespace/GitEcaParameterNames.java b/src/main/java/org/eclipsefoundation/git/eca/namespace/GitEcaParameterNames.java index 425b21b2cff007dfa7a37841472a992cfb8af5b6..e75ca1706576d3a16a2a60ce6fa950c393d65b8d 100644 --- a/src/main/java/org/eclipsefoundation/git/eca/namespace/GitEcaParameterNames.java +++ b/src/main/java/org/eclipsefoundation/git/eca/namespace/GitEcaParameterNames.java @@ -31,6 +31,10 @@ public final class GitEcaParameterNames implements UrlParameterNamespace { public static final String USER_ID_RAW = "user_id"; public static final String PROJECT_PATH_RAW = "project_path"; public static final String PARENT_PROJECT_RAW = "parent_project"; + public static final String STATUS_ACTIVE_RAW = "active"; + public static final String STATUS_DELETED_RAW = "deleted"; + public static final String SINCE_RAW = "since"; + public static final String UNTIL_RAW = "until"; public static final UrlParameter COMMIT_ID = new UrlParameter(COMMIT_ID_RAW); public static final UrlParameter SHA = new UrlParameter(SHA_RAW); public static final UrlParameter SHAS = new UrlParameter(SHAS_RAW); @@ -42,11 +46,15 @@ public final class GitEcaParameterNames implements UrlParameterNamespace { public static final UrlParameter USER_ID = new UrlParameter(USER_ID_RAW); public static final UrlParameter PROJECT_PATH = new UrlParameter(PROJECT_PATH_RAW); public static final UrlParameter PARENT_PROJECT = new UrlParameter(PARENT_PROJECT_RAW); + public static final UrlParameter STATUS_ACTIVE = new UrlParameter(STATUS_ACTIVE_RAW); + public static final UrlParameter STATUS_DELETED = new UrlParameter(STATUS_DELETED_RAW); + public static final UrlParameter SINCE = new UrlParameter(SINCE_RAW); + public static final UrlParameter UNTIL = new UrlParameter(UNTIL_RAW); @Override public List<UrlParameter> getParameters() { return Arrays.asList(COMMIT_ID, SHA, SHAS, PROJECT_ID, PROJECT_IDS, NOT_IN_PROJECT_IDS, REPO_URL, - FINGERPRINT, USER_ID, PROJECT_PATH, PARENT_PROJECT); + FINGERPRINT, USER_ID, PROJECT_PATH, PARENT_PROJECT, STATUS_ACTIVE, STATUS_DELETED, SINCE, UNTIL); } } diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/ReportsResource.java b/src/main/java/org/eclipsefoundation/git/eca/resource/ReportsResource.java new file mode 100644 index 0000000000000000000000000000000000000000..ad153d39b1e764b23101be97c218f586895349b3 --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/resource/ReportsResource.java @@ -0,0 +1,58 @@ +/********************************************************************* +* Copyright (c) 2022 Eclipse Foundation. +* +* This program and the accompanying materials are made +* available under the terms of the Eclipse Public License 2.0 +* which is available at https://www.eclipse.org/legal/epl-2.0/ +* +* Author: Zachary Sabourin <zachary.sabourin@eclipse-foundation.org> +* +* SPDX-License-Identifier: EPL-2.0 +**********************************************************************/ +package org.eclipsefoundation.git.eca.resource; + +import java.time.LocalDate; + +import javax.inject.Inject; +import javax.ws.rs.BadRequestException; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +import org.apache.commons.lang3.StringUtils; +import org.eclipsefoundation.core.model.RequestWrapper; +import org.eclipsefoundation.git.eca.namespace.GitEcaParameterNames; +import org.eclipsefoundation.git.eca.service.ReportsService; + +@Path("/reports") +public class ReportsResource { + + @Inject + RequestWrapper wrap; + @Inject + ReportsService reportsService; + + @GET + @Path("/gitlab/private-projects") + public Response getPrivateProjectEvents(@QueryParam("status") String status, @QueryParam("since") LocalDate since, + @QueryParam("until") LocalDate until) { + + if (StringUtils.isNotBlank(status) && !isValidStatus(status)) { + throw new BadRequestException(String.format("Invalid 'status' parameter: %s", status)); + } + + return Response.ok(reportsService.getPrivateProjectEvents(wrap, status, since, until)).build(); + } + + /** + * Validates the status as one of "active" or "deleted" + * + * @param status the desired status + * @return true if valid, false if not + */ + private boolean isValidStatus(String status) { + return status.equalsIgnoreCase(GitEcaParameterNames.STATUS_ACTIVE.getName()) + || status.equalsIgnoreCase(GitEcaParameterNames.STATUS_DELETED.getName()); + } +} diff --git a/src/main/java/org/eclipsefoundation/git/eca/resource/mapper/BadRequestMapper.java b/src/main/java/org/eclipsefoundation/git/eca/resource/mapper/BadRequestMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..7a276b81af1c1d94f3457ef9212f51180b2edd67 --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/resource/mapper/BadRequestMapper.java @@ -0,0 +1,37 @@ +/********************************************************************* +* Copyright (c) 2022 Eclipse Foundation. +* +* This program and the accompanying materials are made +* available under the terms of the Eclipse Public License 2.0 +* which is available at https://www.eclipse.org/legal/epl-2.0/ +* +* Author: Zachary Sabourin <zachary.sabourin@eclipse-foundation.org> +* +* SPDX-License-Identifier: EPL-2.0 +**********************************************************************/ +package org.eclipsefoundation.git.eca.resource.mapper; + +import javax.ws.rs.BadRequestException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +import org.eclipsefoundation.core.model.Error; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Creates human legible error responses in the case of BadRequestExceptions. + */ +@Provider +public class BadRequestMapper implements ExceptionMapper<BadRequestException> { + + private static final Logger LOGGER = LoggerFactory.getLogger(BadRequestMapper.class); + + @Override + public Response toResponse(BadRequestException exception) { + LOGGER.error(exception.getMessage()); + return new Error(Status.BAD_REQUEST, exception.getMessage()).asResponse(); + } +} diff --git a/src/main/java/org/eclipsefoundation/git/eca/service/ReportsService.java b/src/main/java/org/eclipsefoundation/git/eca/service/ReportsService.java new file mode 100644 index 0000000000000000000000000000000000000000..97e7a68ba5d3fe2be9be9f036c8615c8706e2595 --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/service/ReportsService.java @@ -0,0 +1,38 @@ +/********************************************************************* +* Copyright (c) 2022 Eclipse Foundation. +* +* This program and the accompanying materials are made +* available under the terms of the Eclipse Public License 2.0 +* which is available at https://www.eclipse.org/legal/epl-2.0/ +* +* Author: Zachary Sabourin <zachary.sabourin@eclipse-foundation.org> +* +* SPDX-License-Identifier: EPL-2.0 +**********************************************************************/ +package org.eclipsefoundation.git.eca.service; + +import java.time.LocalDate; +import java.util.List; + +import org.eclipsefoundation.core.model.RequestWrapper; +import org.eclipsefoundation.git.eca.dto.PrivateProjectEvent; + +/** + * This interface provides the means to get list of desired entities from the DB + * using desired filters. + */ +public interface ReportsService { + + /** + * Fetches a filtered list of PrivateProjectEvents from the DB using the desired + * parameters. Can be filtered by active/deleted status, and by date range + * + * @param wrap The request wrapper + * @param status The current project status + * @param since The starting range + * @param until The ending range + * @return A List of PrivateProjectEvent entities + */ + public List<PrivateProjectEvent> getPrivateProjectEvents(RequestWrapper wrap, String status, LocalDate since, + LocalDate until); +} diff --git a/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultReportsService.java b/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultReportsService.java new file mode 100644 index 0000000000000000000000000000000000000000..47a3434d710a393448055710af004fbaf958fcee --- /dev/null +++ b/src/main/java/org/eclipsefoundation/git/eca/service/impl/DefaultReportsService.java @@ -0,0 +1,73 @@ +/********************************************************************* +* Copyright (c) 2022 Eclipse Foundation. +* +* This program and the accompanying materials are made +* available under the terms of the Eclipse Public License 2.0 +* which is available at https://www.eclipse.org/legal/epl-2.0/ +* +* Author: Zachary Sabourin <zachary.sabourin@eclipse-foundation.org> +* +* SPDX-License-Identifier: EPL-2.0 +**********************************************************************/ +package org.eclipsefoundation.git.eca.service.impl; + +import java.time.LocalDate; +import java.util.Collections; +import java.util.List; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.core.MultivaluedMap; + +import org.apache.commons.lang3.StringUtils; +import org.eclipsefoundation.core.model.RequestWrapper; +import org.eclipsefoundation.git.eca.dto.PrivateProjectEvent; +import org.eclipsefoundation.git.eca.namespace.GitEcaParameterNames; +import org.eclipsefoundation.git.eca.service.ReportsService; +import org.eclipsefoundation.persistence.dao.PersistenceDao; +import org.eclipsefoundation.persistence.model.RDBMSQuery; +import org.eclipsefoundation.persistence.service.FilterService; +import org.jboss.resteasy.specimpl.MultivaluedMapImpl; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class DefaultReportsService implements ReportsService { + + private static final Logger LOGGER = LoggerFactory.getLogger(DefaultReportsService.class); + + @Inject + PersistenceDao dao; + @Inject + FilterService filters; + + @Override + public List<PrivateProjectEvent> getPrivateProjectEvents(RequestWrapper wrap, String status, LocalDate since, LocalDate until) { + + MultivaluedMap<String, String> params = new MultivaluedMapImpl<>(); + + if (StringUtils.isNotBlank(status)) { + if (status.equalsIgnoreCase(GitEcaParameterNames.STATUS_ACTIVE.getName())) { + params.add(GitEcaParameterNames.STATUS_ACTIVE.getName(), status); + } else { + params.add(GitEcaParameterNames.STATUS_DELETED.getName(), status); + } + } + if (since != null) { + params.add(GitEcaParameterNames.SINCE.getName(), since.toString()); + } + if (until != null) { + params.add(GitEcaParameterNames.UNTIL.getName(), until.toString()); + } + + List<PrivateProjectEvent> results = dao + .get(new RDBMSQuery<>(wrap, filters.get(PrivateProjectEvent.class), params)); + if (results == null) { + LOGGER.error("Error retrieving PrivateProjectEvents from the DB using params: {}", params); + return Collections.emptyList(); + } + + return results; + } + +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 4c362c0043718c1185e6ae4845393406d7776d1e..7f1acfd66b080cc69610fbd6ae489cbbd7eb00d0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -38,5 +38,7 @@ quarkus.cache.caffeine."record".expire-after-write=${quarkus.cache.caffeine."def eclipse.mail.allowlist=noreply@github.com,49699333+dependabot[bot]@users.noreply.github.com %dev.eclipse.cache.resource.enabled=true %dev.eclipse.optional-resources.enabled=true +%dev.eclipse.scheduled.private-project.enabled=false + #%dev.quarkus.log.level=DEBUG #quarkus.log.category."org.eclipsefoundation".level=DEBUG \ No newline at end of file diff --git a/src/test/java/org/eclipsefoundation/git/eca/resource/ReportsResourceTest.java b/src/test/java/org/eclipsefoundation/git/eca/resource/ReportsResourceTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3e96bd0067cbd5fc03e02044ed93ed43ffecdac0 --- /dev/null +++ b/src/test/java/org/eclipsefoundation/git/eca/resource/ReportsResourceTest.java @@ -0,0 +1,209 @@ +/********************************************************************* +* Copyright (c) 2022 Eclipse Foundation. +* +* This program and the accompanying materials are made +* available under the terms of the Eclipse Public License 2.0 +* which is available at https://www.eclipse.org/legal/epl-2.0/ +* +* Author: Zachary Sabourin <zachary.sabourin@eclipse-foundation.org> +* +* SPDX-License-Identifier: EPL-2.0 +**********************************************************************/ +package org.eclipsefoundation.git.eca.resource; + +import org.eclipsefoundation.git.eca.namespace.GitEcaParameterNames; +import org.eclipsefoundation.git.eca.test.namespaces.SchemaNamespaceHelper; +import org.eclipsefoundation.testing.helpers.TestCaseHelper; +import org.eclipsefoundation.testing.templates.RestAssuredTemplates; +import org.eclipsefoundation.testing.templates.RestAssuredTemplates.EndpointTestCase; +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; + +@QuarkusTest +class ReportsResourceTest { + public static final String REPORTS_BASE_URL = "/reports"; + public static final String REPORTS_PROJECTS_URL = REPORTS_BASE_URL + "/gitlab/private-projects"; + public static final String REPORTS_PROJECTS_STATUS_URL = REPORTS_PROJECTS_URL + "?status={status}"; + public static final String REPORTS_PROJECTS_UNTIL_URL = REPORTS_PROJECTS_URL + "?until={date}"; + public static final String REPORTS_PROJECTS_SINCE_URL = REPORTS_PROJECTS_URL + "?since={date}"; + public static final String REPORTS_PROJECTS_RANGE_URL = REPORTS_PROJECTS_URL + "?since={start}&until={end}"; + + public static final EndpointTestCase GET_REPORT_SUCCESS_CASE = TestCaseHelper + .buildSuccessCase(REPORTS_PROJECTS_URL, new String[] {}, + SchemaNamespaceHelper.PRIVATE_PROJECT_EVENTS_SCHEMA_PATH); + + public static final EndpointTestCase GET_REPORT_ACTIVE_SUCCESS_CASE = TestCaseHelper.buildSuccessCase( + REPORTS_PROJECTS_STATUS_URL, new String[] { GitEcaParameterNames.STATUS_ACTIVE.getName() }, + SchemaNamespaceHelper.PRIVATE_PROJECT_EVENTS_SCHEMA_PATH); + + public static final EndpointTestCase GET_REPORT_DELETED_SUCCESS_CASE = TestCaseHelper.buildSuccessCase( + REPORTS_PROJECTS_STATUS_URL, new String[] { GitEcaParameterNames.STATUS_DELETED.getName() }, + SchemaNamespaceHelper.PRIVATE_PROJECT_EVENTS_SCHEMA_PATH); + + public static final EndpointTestCase GET_REPORT_SINCE_SUCCESS_CASE = TestCaseHelper.buildSuccessCase( + REPORTS_PROJECTS_SINCE_URL, new String[] { "2022-11-11" }, + SchemaNamespaceHelper.PRIVATE_PROJECT_EVENTS_SCHEMA_PATH); + + public static final EndpointTestCase GET_REPORT_UNTIL_SUCCESS_CASE = TestCaseHelper.buildSuccessCase( + REPORTS_PROJECTS_UNTIL_URL, new String[] { "2022-11-15" }, + SchemaNamespaceHelper.PRIVATE_PROJECT_EVENTS_SCHEMA_PATH); + + public static final EndpointTestCase GET_REPORT_RANGE_SUCCESS_CASE = TestCaseHelper.buildSuccessCase( + REPORTS_PROJECTS_RANGE_URL, new String[] { "2022-11-15", "2022-11-15" }, + SchemaNamespaceHelper.PRIVATE_PROJECT_EVENTS_SCHEMA_PATH); + + public static final EndpointTestCase GET_REPORT_BAD_STATUS_CASE = TestCaseHelper.buildBadRequestCase( + REPORTS_PROJECTS_STATUS_URL, new String[] { "nope" }, SchemaNamespaceHelper.ERROR_SCHEMA_PATH); + + public static final EndpointTestCase GET_REPORT_BAD_UNTIL_CASE = TestCaseHelper.buildBadRequestCase( + REPORTS_PROJECTS_UNTIL_URL, new String[] { "nope" }, SchemaNamespaceHelper.ERROR_SCHEMA_PATH); + + public static final EndpointTestCase GET_REPORT_BAD_SINCE_CASE = TestCaseHelper.buildBadRequestCase( + REPORTS_PROJECTS_SINCE_URL, new String[] { "nope" }, SchemaNamespaceHelper.ERROR_SCHEMA_PATH); + + /* + * GET /reports/webhooks/gitlab/system + */ + @Test + void getPrivProjReport_success() { + RestAssuredTemplates.testGet(GET_REPORT_SUCCESS_CASE); + } + + @Test + void getPrivProjReport_success_validateSchema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_SUCCESS_CASE); + } + + @Test + void getPrivProjReport_success_validateResponseFormat() { + RestAssuredTemplates.testGet_validateResponseFormat(GET_REPORT_SUCCESS_CASE); + } + + @Test + void getPrivProjReport_failure_invalidRequestFormat() { + RestAssuredTemplates.testGet( + TestCaseHelper.buildInvalidFormatCase(REPORTS_PROJECTS_URL, new String[] {}, ContentType.TEXT)); + } + + /* + * GET /reports/webhooks/gitlab/system?status=active + */ + @Test + void getPrivProjReportActive_success() { + RestAssuredTemplates.testGet(GET_REPORT_ACTIVE_SUCCESS_CASE); + } + + @Test + void getPrivProjReportActive_success_validateSchema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_ACTIVE_SUCCESS_CASE); + } + + @Test + void getPrivProjReportActive_success_validateResponseFormat() { + RestAssuredTemplates.testGet_validateResponseFormat(GET_REPORT_ACTIVE_SUCCESS_CASE); + } + + @Test + void getPrivProjReportStatus_failure_invalidStatus() { + RestAssuredTemplates.testGet(GET_REPORT_BAD_STATUS_CASE); + } + + @Test + void getPrivProjReportStatus_failure_invalidStatus_validate_schema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_BAD_STATUS_CASE); + } + + /* + * GET /reports/webhooks/gitlab/system?status=deleted + */ + @Test + void getPrivProjReportDeleted_success() { + RestAssuredTemplates.testGet(GET_REPORT_DELETED_SUCCESS_CASE); + } + + @Test + void getPrivProjReportDeleted_success_validateSchema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_DELETED_SUCCESS_CASE); + } + + @Test + void getPrivProjReportDeleted_success_validateResponseFormat() { + RestAssuredTemplates.testGet_validateResponseFormat(GET_REPORT_DELETED_SUCCESS_CASE); + } + + /* + * GET /reports/webhooks/gitlab/system?since={date} + */ + @Test + void getPrivProjReportSince_success() { + RestAssuredTemplates.testGet(GET_REPORT_SINCE_SUCCESS_CASE); + } + + @Test + void getPrivProjReportSince_success_validateSchema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_SINCE_SUCCESS_CASE); + } + + @Test + void getPrivProjReportSince_success_validateResponseFormat() { + RestAssuredTemplates.testGet_validateResponseFormat(GET_REPORT_SINCE_SUCCESS_CASE); + } + + @Test + void getPrivProjReportSince_failure_invalidStatus() { + RestAssuredTemplates.testGet(GET_REPORT_BAD_SINCE_CASE); + } + + @Test + void getPrivProjReportSince_failure_invalidStatus_validate_schema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_BAD_SINCE_CASE); + } + + /* + * GET /reports/webhooks/gitlab/system?until={date} + */ + @Test + void getPrivProjReportUntil_success() { + RestAssuredTemplates.testGet(GET_REPORT_UNTIL_SUCCESS_CASE); + } + + @Test + void getPrivProjReportUntil_success_validateSchema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_UNTIL_SUCCESS_CASE); + } + + @Test + void getPrivProjReportUntil_success_validateResponseFormat() { + RestAssuredTemplates.testGet_validateResponseFormat(GET_REPORT_UNTIL_SUCCESS_CASE); + } + + @Test + void getPrivProjReportUntil_failure_invalidStatus() { + RestAssuredTemplates.testGet(GET_REPORT_BAD_UNTIL_CASE); + } + + @Test + void getPrivProjReportSUntil_failure_invalidStatus_validate_schema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_BAD_UNTIL_CASE); + } + + /* + * GET /reports/webhooks/gitlab/system?since={date}&until={date} + */ + @Test + void getPrivProjReportRange_success() { + RestAssuredTemplates.testGet(GET_REPORT_RANGE_SUCCESS_CASE); + } + + @Test + void getPrivProjReportRange_success_validateSchema() { + RestAssuredTemplates.testGet_validateSchema(GET_REPORT_RANGE_SUCCESS_CASE); + } + + @Test + void getPrivProjReportRange_success_validateResponseFormat() { + RestAssuredTemplates.testGet_validateResponseFormat(GET_REPORT_RANGE_SUCCESS_CASE); + } +} diff --git a/src/test/java/org/eclipsefoundation/git/eca/test/namespaces/SchemaNamespaceHelper.java b/src/test/java/org/eclipsefoundation/git/eca/test/namespaces/SchemaNamespaceHelper.java index 1b42e1e0b179e515c1b66dcc878d93e375e172ef..6bf874f9d757abd6baec2af53ecff7d31c05bf48 100644 --- a/src/test/java/org/eclipsefoundation/git/eca/test/namespaces/SchemaNamespaceHelper.java +++ b/src/test/java/org/eclipsefoundation/git/eca/test/namespaces/SchemaNamespaceHelper.java @@ -12,10 +12,18 @@ package org.eclipsefoundation.git.eca.test.namespaces; public final class SchemaNamespaceHelper { - public static final String BASE_SCHEMAS_PATH = "schemas/"; - public static final String BASE_SCHEMAS_PATH_SUFFIX = "-schema.json"; - public static final String VALIDATION_REQUEST_SCHEMA_PATH = BASE_SCHEMAS_PATH + "validation-request" - + BASE_SCHEMAS_PATH_SUFFIX; - public static final String VALIDATION_RESPONSE_SCHEMA_PATH = BASE_SCHEMAS_PATH + "validation-response" - + BASE_SCHEMAS_PATH_SUFFIX; + public static final String BASE_SCHEMAS_PATH = "schemas/"; + public static final String BASE_SCHEMAS_PATH_SUFFIX = "-schema.json"; + + public static final String VALIDATION_REQUEST_SCHEMA_PATH = BASE_SCHEMAS_PATH + "validation-request" + + BASE_SCHEMAS_PATH_SUFFIX; + public static final String VALIDATION_RESPONSE_SCHEMA_PATH = BASE_SCHEMAS_PATH + "validation-response" + + BASE_SCHEMAS_PATH_SUFFIX; + + public static final String PRIVATE_PROJECT_EVENT_SCHEMA_PATH = BASE_SCHEMAS_PATH + "private-project-event" + + BASE_SCHEMAS_PATH_SUFFIX; + public static final String PRIVATE_PROJECT_EVENTS_SCHEMA_PATH = BASE_SCHEMAS_PATH + "private-project-events" + + BASE_SCHEMAS_PATH_SUFFIX; + + public static final String ERROR_SCHEMA_PATH = BASE_SCHEMAS_PATH + "error" + BASE_SCHEMAS_PATH_SUFFIX; } diff --git a/src/test/resources/database/default/V1.0.0__default.sql b/src/test/resources/database/default/V1.0.0__default.sql index cf889fb32190e0fa52c008600b9d53290075e01b..398aa5159250311a7dd2f581cea3a38e052e7487 100644 --- a/src/test/resources/database/default/V1.0.0__default.sql +++ b/src/test/resources/database/default/V1.0.0__default.sql @@ -31,4 +31,16 @@ CREATE TABLE `CommitValidationStatusGrouping` ( `commit_id` bigint NOT NULL, PRIMARY KEY (`commit_id`,`fingerprint`) ); -INSERT INTO CommitValidationStatusGrouping(fingerprint, commit_id) VALUES('957706b0f31e0ccfc5287c0ebc62dc79', 1); \ No newline at end of file +INSERT INTO CommitValidationStatusGrouping(fingerprint, commit_id) VALUES('957706b0f31e0ccfc5287c0ebc62dc79', 1); + +CREATE TABLE PrivateProjectEvent ( + userId int NOT NULL, + projectId int NOT NULL, + projectPath varchar(255) NOT NULL, + parentProject int DEFAULT NULL, + creationDate datetime NOT NULL, + deletionDate datetime DEFAULT NULL, + PRIMARY KEY (userId, projectId, projectPath) +); +INSERT INTO PrivateProjectEvent(userId, projectId, projectPath, creationDate) VALUES(1, 133, 'eclipse/test/project', '2022-11-11T12:00:00.000'); +INSERT INTO PrivateProjectEvent(userId, projectId, projectPath, parentProject, creationDate, deletionDate) VALUES(1, 150, 'eclipse/test/project/fork', 133, '2022-11-15T12:00:00.000', '2022-11-20T12:00:00.000'); \ No newline at end of file