registration = Map.of(
+ "clientId", "bad-date-" + UUID.randomUUID(),
+ "clientName", "Bad Date Client",
+ "redirectUris", List.of(),
+ "grantTypes", List.of(),
+ "registeredAt", "not-a-date",
+ "clientData", Map.of()
+ );
+
+ RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(registration)
+ .when()
+ .post("/api/v1/mcp-clients")
+ .then()
+ .statusCode(400);
+ }
+
+ @Test
+ void testListWithNegativePageReturns400() {
+ RestAssured.given()
+ .when()
+ .queryParam("page", -1)
+ .queryParam("pageSize", 10)
+ .get("/api/v1/mcp-clients")
+ .then()
+ .statusCode(400);
+ }
+
+ @Test
+ void testListWithZeroPageSizeReturns400() {
+ RestAssured.given()
+ .when()
+ .queryParam("page", 0)
+ .queryParam("pageSize", 0)
+ .get("/api/v1/mcp-clients")
+ .then()
+ .statusCode(400);
+ }
+
+ @Test
+ void testDeleteClient() {
+ String clientId = "del-" + UUID.randomUUID();
+ createdClientIds.add(clientId);
+
+ RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(buildRegistration(clientId, "Delete Me"))
+ .when()
+ .post("/api/v1/mcp-clients")
+ .then()
+ .statusCode(201);
+
+ RestAssured.given()
+ .when()
+ .delete("/api/v1/mcp-clients/" + clientId)
+ .then()
+ .statusCode(204);
+
+ RestAssured.given()
+ .when()
+ .get("/api/v1/mcp-clients/" + clientId)
+ .then()
+ .statusCode(404);
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/NewRpmReportRestTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/NewRpmReportRestTest.java
similarity index 96%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/rest/NewRpmReportRestTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/NewRpmReportRestTest.java
index 56458a80..a64bbdeb 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/NewRpmReportRestTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/NewRpmReportRestTest.java
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-package com.redhat.ecosystemappeng.morpheus.rest;
+package com.redhat.ecosystemappeng.exploitiq.rest;
import java.util.HashMap;
import java.util.Map;
@@ -21,8 +21,8 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import com.redhat.ecosystemappeng.morpheus.exception.CveIdValidationException;
-import com.redhat.ecosystemappeng.morpheus.model.morpheus.PipelineMode;
+import com.redhat.ecosystemappeng.exploitiq.exception.CveIdValidationException;
+import com.redhat.ecosystemappeng.exploitiq.model.exploitiq.PipelineMode;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ProductEndpointRestTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ProductEndpointRestTest.java
similarity index 99%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ProductEndpointRestTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ProductEndpointRestTest.java
index 66ae49f9..7d77f23f 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ProductEndpointRestTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ProductEndpointRestTest.java
@@ -1,4 +1,4 @@
-package com.redhat.ecosystemappeng.morpheus.rest;
+package com.redhat.ecosystemappeng.exploitiq.rest;
import static org.hamcrest.Matchers.*;
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ReportEndpointFailedRestTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ReportEndpointFailedRestTest.java
similarity index 97%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ReportEndpointFailedRestTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ReportEndpointFailedRestTest.java
index d7a42e2c..5f0510fc 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ReportEndpointFailedRestTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ReportEndpointFailedRestTest.java
@@ -1,4 +1,4 @@
-package com.redhat.ecosystemappeng.morpheus.rest;
+package com.redhat.ecosystemappeng.exploitiq.rest;
import static org.hamcrest.Matchers.*;
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ReportListInputTypeRestTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ReportListInputTypeRestTest.java
similarity index 99%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ReportListInputTypeRestTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ReportListInputTypeRestTest.java
index b812dabd..cff1543a 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/ReportListInputTypeRestTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/ReportListInputTypeRestTest.java
@@ -1,4 +1,4 @@
-package com.redhat.ecosystemappeng.morpheus.rest;
+package com.redhat.ecosystemappeng.exploitiq.rest;
import static org.hamcrest.Matchers.equalTo;
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/RestApiTestFixture.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/RestApiTestFixture.java
similarity index 90%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/rest/RestApiTestFixture.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/RestApiTestFixture.java
index c8ef7f9f..7d323175 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/RestApiTestFixture.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/RestApiTestFixture.java
@@ -1,4 +1,4 @@
-package com.redhat.ecosystemappeng.morpheus.rest;
+package com.redhat.ecosystemappeng.exploitiq.rest;
import java.time.Duration;
import java.util.List;
@@ -15,15 +15,15 @@
*
* Optional remote base URL for RestAssured: Quarkus config key
* {@value #CONFIG_KEY_EXTERNAL_BASE_URL} (e.g. set in {@code src/test/resources/application.properties}
- * as {@code %test.morpheus.rest-test.external-base-url} or on the Maven command line as
- * {@code -Dmorpheus.rest-test.external-base-url=http://localhost:8080}). When unset or blank,
+ * as {@code %test.exploit-iq.rest-test.external-base-url} or on the Maven command line as
+ * {@code -Dexploit-iq.rest-test.external-base-url=http://localhost:8080}). When unset or blank,
* {@link #configureRestAssuredIfExternal()} does nothing so Quarkus keeps the default in-process test URL.
*/
public final class RestApiTestFixture {
/** Quarkus / MicroProfile config key for RestAssured base URI during REST tests. */
- public static final String CONFIG_KEY_EXTERNAL_BASE_URL = "morpheus.rest-test.external-base-url";
- public static final String CONFIG_KEY_SPDX_TIMEOUT = "morpheus.rest-test.spdx-timeout";
+ public static final String CONFIG_KEY_EXTERNAL_BASE_URL = "exploit-iq.rest-test.external-base-url";
+ public static final String CONFIG_KEY_SPDX_TIMEOUT = "exploit-iq.rest-test.spdx-timeout";
private static final Duration DEFAULT_SPDX_TIMEOUT = Duration.ofMinutes(10);
private RestApiTestFixture() {
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadCycloneDxRestTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadCycloneDxRestTest.java
similarity index 99%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadCycloneDxRestTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadCycloneDxRestTest.java
index 8d2e8da7..036a0765 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadCycloneDxRestTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadCycloneDxRestTest.java
@@ -1,4 +1,4 @@
-package com.redhat.ecosystemappeng.morpheus.rest;
+package com.redhat.ecosystemappeng.exploitiq.rest;
import static org.hamcrest.Matchers.*;
diff --git a/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadSpdxMockedSyftRestTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadSpdxMockedSyftRestTest.java
new file mode 100644
index 00000000..a2edaf41
--- /dev/null
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadSpdxMockedSyftRestTest.java
@@ -0,0 +1,89 @@
+package com.redhat.ecosystemappeng.exploitiq.rest;
+
+import static org.hamcrest.Matchers.*;
+
+import java.io.File;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.redhat.ecosystemappeng.exploitiq.model.ParsedCycloneDx;
+import com.redhat.ecosystemappeng.exploitiq.service.GenerateSbomService;
+
+import io.quarkus.test.InjectMock;
+import io.quarkus.test.junit.QuarkusTest;
+import io.restassured.RestAssured;
+import io.restassured.http.ContentType;
+
+/**
+ * SPDX upload tests that mock {@link GenerateSbomService} to avoid real syft/registry calls.
+ */
+@QuarkusTest
+public class UploadSpdxMockedSyftRestTest {
+
+ private static final String SPDX_WITH_UNSUPPORTED = "src/test/resources/devservices/spdx-sboms/spdx-with-unsupported-component.json";
+ private static final String CYCLONEDX_FIXTURE = "src/test/resources/devservices/cyclonedx-sboms/nmstate-rhel8-operator.json";
+ private static final String TEST_VULN_ID = "CVE-2021-4238";
+
+ @InjectMock
+ GenerateSbomService generateSbomService;
+
+ @BeforeEach
+ void setUp() throws Exception {
+ RestApiTestFixture.configureRestAssuredIfExternal();
+
+ ObjectMapper mapper = new ObjectMapper();
+ JsonNode sbomJson = mapper.readTree(new File(CYCLONEDX_FIXTURE));
+ JsonNode component = sbomJson.get("metadata").get("component");
+
+ ParsedCycloneDx mockSbom = new ParsedCycloneDx(
+ sbomJson,
+ component.get("name").asText(),
+ component.has("version") ? component.get("version").asText() : null,
+ component.has("description") ? component.get("description").asText() : null,
+ component.has("type") ? component.get("type").asText() : null,
+ component.has("purl") ? component.get("purl").asText() : null,
+ component.has("bom-ref") ? component.get("bom-ref").asText() : null);
+
+ Mockito.when(generateSbomService.generate(Mockito.anyString()))
+ .thenReturn(mockSbom);
+ }
+
+ @Test
+ void testUpload_SpdxWithUnsupportedComponent_RecordsInSubmissionFailures() {
+ File sbomFile = new File(SPDX_WITH_UNSUPPORTED);
+
+ String productId = RestAssured.given()
+ .contentType(ContentType.MULTIPART)
+ .multiPart("cveId", TEST_VULN_ID)
+ .multiPart("file", sbomFile)
+ .when()
+ .post("/api/v1/products/upload-spdx")
+ .then()
+ .statusCode(202)
+ .contentType(ContentType.JSON)
+ .body("productId", notNullValue())
+ .extract()
+ .path("productId");
+
+ Assertions.assertNotNull(productId, "Product ID should not be null");
+ RestApiTestFixture.awaitSpdxProductProcessingComplete(productId);
+
+ RestAssured.given()
+ .when()
+ .get("/api/v1/products/" + productId)
+ .then()
+ .statusCode(200)
+ .contentType(ContentType.JSON)
+ .body("data.submittedCount", equalTo(2))
+ .body("data.submissionFailures", notNullValue())
+ .body("data.submissionFailures", hasSize(1))
+ .body("data.submissionFailures[0].name", equalTo("maven-lib"))
+ .body("data.submissionFailures[0].version", equalTo("2.0"))
+ .body("data.submissionFailures[0].error", containsString("Expects a container image purl with format pkg:oci/name@sha256:hash?repository_url=...&tag=..."));
+ }
+}
\ No newline at end of file
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadSpdxRestTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadSpdxRestTest.java
similarity index 97%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadSpdxRestTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadSpdxRestTest.java
index 62eacc71..aaf6b399 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadSpdxRestTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/rest/UploadSpdxRestTest.java
@@ -1,4 +1,4 @@
-package com.redhat.ecosystemappeng.morpheus.rest;
+package com.redhat.ecosystemappeng.exploitiq.rest;
import static org.hamcrest.Matchers.*;
@@ -8,7 +8,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import com.redhat.ecosystemappeng.morpheus.service.SpdxParsingService;
+import com.redhat.ecosystemappeng.exploitiq.service.SpdxParsingService;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
@@ -36,7 +36,7 @@ void restAssuredBase() {
private static final int GITOPS_119_EXPECTED_SUBMISSION_FAILURE_COUNT = 1;
/**
- * Successful Morpheus-backed reports after async processing:
+ * Successful exploit-iq-backed reports after async processing:
* {@link #GITOPS_119_EXPECTED_SUBMITTED_COUNT} submitted =
* {@link #GITOPS_119_EXPECTED_REPORT_COUNT} reports + {@link #GITOPS_119_EXPECTED_SUBMISSION_FAILURE_COUNT} failure(s).
*/
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/service/ReportServiceCredentialInjectionOrderTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/service/ReportServiceCredentialInjectionOrderTest.java
similarity index 90%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/service/ReportServiceCredentialInjectionOrderTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/service/ReportServiceCredentialInjectionOrderTest.java
index 8850c0d5..62015c8f 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/service/ReportServiceCredentialInjectionOrderTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/service/ReportServiceCredentialInjectionOrderTest.java
@@ -1,13 +1,13 @@
-package com.redhat.ecosystemappeng.morpheus.service;
+package com.redhat.ecosystemappeng.exploitiq.service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.redhat.ecosystemappeng.morpheus.model.ParsedCycloneDx;
-import com.redhat.ecosystemappeng.morpheus.model.Product;
-import com.redhat.ecosystemappeng.morpheus.model.ReportData;
-import com.redhat.ecosystemappeng.morpheus.model.ReportRequestId;
-import com.redhat.ecosystemappeng.morpheus.repository.ProductRepositoryService;
+import com.redhat.ecosystemappeng.exploitiq.model.ParsedCycloneDx;
+import com.redhat.ecosystemappeng.exploitiq.model.Product;
+import com.redhat.ecosystemappeng.exploitiq.model.ReportData;
+import com.redhat.ecosystemappeng.exploitiq.model.ReportRequestId;
+import com.redhat.ecosystemappeng.exploitiq.repository.ProductRepositoryService;
import io.quarkus.test.InjectMock;
import io.quarkus.test.component.QuarkusComponentTest;
import jakarta.inject.Inject;
@@ -80,7 +80,7 @@ void submitCycloneDx_injectsCredentialBeforeSave() throws Exception {
inOrder.verify(productRepository).save(any(Product.class), any());
inOrder.verify(reportService).submit(any(), any(JsonNode.class));
}, "credentialId must be injected BEFORE saveReport() and submit(), " +
- "otherwise it is not persisted in MongoDB and not included in the Morpheus payload");
+ "otherwise it is not persisted in MongoDB and not included in the ExploitIQ payload");
}
@Test
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/service/ReportServiceMetadataKeysTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/service/ReportServiceMetadataKeysTest.java
similarity index 97%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/service/ReportServiceMetadataKeysTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/service/ReportServiceMetadataKeysTest.java
index 1c549bb3..e8a0d714 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/service/ReportServiceMetadataKeysTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/service/ReportServiceMetadataKeysTest.java
@@ -1,4 +1,4 @@
-package com.redhat.ecosystemappeng.morpheus.service;
+package com.redhat.ecosystemappeng.exploitiq.service;
import static org.junit.jupiter.api.Assertions.*;
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/service/SpdxParsingServiceTest.java b/src/test/java/com/redhat/ecosystemappeng/exploitiq/service/SpdxParsingServiceTest.java
similarity index 94%
rename from src/test/java/com/redhat/ecosystemappeng/morpheus/service/SpdxParsingServiceTest.java
rename to src/test/java/com/redhat/ecosystemappeng/exploitiq/service/SpdxParsingServiceTest.java
index 64034b0c..9a84eb1c 100644
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/service/SpdxParsingServiceTest.java
+++ b/src/test/java/com/redhat/ecosystemappeng/exploitiq/service/SpdxParsingServiceTest.java
@@ -1,4 +1,4 @@
-package com.redhat.ecosystemappeng.morpheus.service;
+package com.redhat.ecosystemappeng.exploitiq.service;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -8,7 +8,7 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.redhat.ecosystemappeng.morpheus.exception.SbomValidationException;
+import com.redhat.ecosystemappeng.exploitiq.exception.SbomValidationException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/McpClientEndpointRestTest.java b/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/McpClientEndpointRestTest.java
deleted file mode 100644
index 85ee1f0a..00000000
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/McpClientEndpointRestTest.java
+++ /dev/null
@@ -1,360 +0,0 @@
-package com.redhat.ecosystemappeng.morpheus.rest;
-
-import static org.hamcrest.Matchers.*;
-
-import java.time.Instant;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import io.restassured.http.ContentType;
-
-@QuarkusTest
-public class McpClientEndpointRestTest {
-
- private final List createdClientIds = new ArrayList<>();
-
- @BeforeEach
- void restAssuredBase() {
- RestApiTestFixture.configureRestAssuredIfExternal();
- }
-
- @AfterEach
- void cleanupClients() {
- for (String clientId : createdClientIds) {
- try {
- RestAssured.given()
- .when()
- .delete("/api/v1/mcp-clients/" + clientId);
- } catch (Exception ignored) {
- }
- }
- createdClientIds.clear();
- }
-
- private Map buildRegistration(String clientId, String clientName) {
- return Map.of(
- "clientId", clientId,
- "clientName", clientName,
- "redirectUris", List.of("http://localhost:3000/callback"),
- "grantTypes", List.of("authorization_code"),
- "registeredAt", Instant.now().toString(),
- "clientData", Map.of("scope", "openid", "token_endpoint_auth_method", "client_secret_post")
- );
- }
-
- @Test
- void testRegisterAndGetClient() {
- String clientId = "test-" + UUID.randomUUID();
- createdClientIds.add(clientId);
- Map registration = buildRegistration(clientId, "Test Client");
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(201)
- .contentType(ContentType.JSON)
- .body("clientId", equalTo(clientId))
- .body("clientName", equalTo("Test Client"))
- .body("redirectUris", hasItem("http://localhost:3000/callback"))
- .body("grantTypes", hasItem("authorization_code"));
-
- RestAssured.given()
- .when()
- .get("/api/v1/mcp-clients/" + clientId)
- .then()
- .statusCode(200)
- .contentType(ContentType.JSON)
- .body("clientId", equalTo(clientId))
- .body("clientName", equalTo("Test Client"))
- .body("clientData.scope", equalTo("openid"));
- }
-
- @Test
- void testRegisterDuplicateReturns409() {
- String clientId = "dup-" + UUID.randomUUID();
- createdClientIds.add(clientId);
- Map registration = buildRegistration(clientId, "Dup Client");
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(201);
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(409)
- .body("error", containsString("already exists"));
- }
-
- @Test
- void testRegisterWithMissingClientIdReturns400() {
- Map registration = Map.of(
- "clientName", "Bad Client",
- "redirectUris", List.of(),
- "grantTypes", List.of(),
- "registeredAt", Instant.now().toString(),
- "clientData", Map.of()
- );
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(400);
- }
-
- @Test
- void testGetNonExistentClientReturns404() {
- RestAssured.given()
- .when()
- .get("/api/v1/mcp-clients/nonexistent-client-" + UUID.randomUUID())
- .then()
- .statusCode(404)
- .body("error", containsString("not found"));
- }
-
- @Test
- void testDeleteNonExistentClientReturns404() {
- RestAssured.given()
- .when()
- .delete("/api/v1/mcp-clients/nonexistent-client-" + UUID.randomUUID())
- .then()
- .statusCode(404)
- .body("error", containsString("not found"));
- }
-
- @Test
- void testListClients() {
- String clientId1 = "list-a-" + UUID.randomUUID();
- String clientId2 = "list-b-" + UUID.randomUUID();
- createdClientIds.add(clientId1);
- createdClientIds.add(clientId2);
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(buildRegistration(clientId1, "List Client A"))
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(201);
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(buildRegistration(clientId2, "List Client B"))
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(201);
-
- RestAssured.given()
- .when()
- .queryParam("page", 0)
- .queryParam("pageSize", 100)
- .get("/api/v1/mcp-clients")
- .then()
- .statusCode(200)
- .contentType(ContentType.JSON)
- .header("X-Total-Elements", notNullValue())
- .body("clientId", hasItems(clientId1, clientId2));
- }
-
- @Test
- void testListClientsPagination() {
- String clientId1 = "page-a-" + UUID.randomUUID();
- String clientId2 = "page-b-" + UUID.randomUUID();
- createdClientIds.add(clientId1);
- createdClientIds.add(clientId2);
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(buildRegistration(clientId1, "Page Client A"))
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(201);
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(buildRegistration(clientId2, "Page Client B"))
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(201);
-
- RestAssured.given()
- .when()
- .queryParam("page", 0)
- .queryParam("pageSize", 1)
- .get("/api/v1/mcp-clients")
- .then()
- .statusCode(200)
- .header("X-Total-Elements", notNullValue())
- .header("X-Total-Pages", notNullValue())
- .body("size()", equalTo(1));
- }
-
- @Test
- void testRegisterWithBlankClientIdReturns400() {
- Map registration = Map.of(
- "clientId", " ",
- "clientName", "Blank Id Client",
- "redirectUris", List.of(),
- "grantTypes", List.of(),
- "registeredAt", Instant.now().toString(),
- "clientData", Map.of()
- );
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(400);
- }
-
- @Test
- void testRegisterWithMissingClientNameReturns400() {
- Map registration = Map.of(
- "clientId", "no-name-" + UUID.randomUUID(),
- "redirectUris", List.of(),
- "grantTypes", List.of(),
- "registeredAt", Instant.now().toString(),
- "clientData", Map.of()
- );
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(400);
- }
-
- @Test
- void testRegisterWithMissingRegisteredAtReturns400() {
- Map registration = Map.of(
- "clientId", "no-date-" + UUID.randomUUID(),
- "clientName", "No Date Client",
- "redirectUris", List.of(),
- "grantTypes", List.of(),
- "clientData", Map.of()
- );
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(400);
- }
-
- @Test
- void testRegisterWithMissingClientDataReturns400() {
- Map registration = Map.of(
- "clientId", "no-data-" + UUID.randomUUID(),
- "clientName", "No Data Client",
- "redirectUris", List.of(),
- "grantTypes", List.of(),
- "registeredAt", Instant.now().toString()
- );
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(400);
- }
-
- @Test
- void testRegisterWithMalformedRegisteredAtReturns400() {
- Map registration = Map.of(
- "clientId", "bad-date-" + UUID.randomUUID(),
- "clientName", "Bad Date Client",
- "redirectUris", List.of(),
- "grantTypes", List.of(),
- "registeredAt", "not-a-date",
- "clientData", Map.of()
- );
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(registration)
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(400);
- }
-
- @Test
- void testListWithNegativePageReturns400() {
- RestAssured.given()
- .when()
- .queryParam("page", -1)
- .queryParam("pageSize", 10)
- .get("/api/v1/mcp-clients")
- .then()
- .statusCode(400);
- }
-
- @Test
- void testListWithZeroPageSizeReturns400() {
- RestAssured.given()
- .when()
- .queryParam("page", 0)
- .queryParam("pageSize", 0)
- .get("/api/v1/mcp-clients")
- .then()
- .statusCode(400);
- }
-
- @Test
- void testDeleteClient() {
- String clientId = "del-" + UUID.randomUUID();
- createdClientIds.add(clientId);
-
- RestAssured.given()
- .contentType(ContentType.JSON)
- .body(buildRegistration(clientId, "Delete Me"))
- .when()
- .post("/api/v1/mcp-clients")
- .then()
- .statusCode(201);
-
- RestAssured.given()
- .when()
- .delete("/api/v1/mcp-clients/" + clientId)
- .then()
- .statusCode(204);
-
- RestAssured.given()
- .when()
- .get("/api/v1/mcp-clients/" + clientId)
- .then()
- .statusCode(404);
- }
-}
diff --git a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadSpdxMockedSyftRestTest.java b/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadSpdxMockedSyftRestTest.java
deleted file mode 100644
index f8542cd3..00000000
--- a/src/test/java/com/redhat/ecosystemappeng/morpheus/rest/UploadSpdxMockedSyftRestTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-package com.redhat.ecosystemappeng.morpheus.rest;
-
-import static org.hamcrest.Matchers.*;
-
-import java.io.File;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.redhat.ecosystemappeng.morpheus.model.ParsedCycloneDx;
-import com.redhat.ecosystemappeng.morpheus.service.GenerateSbomService;
-
-import io.quarkus.test.InjectMock;
-import io.quarkus.test.junit.QuarkusTest;
-import io.restassured.RestAssured;
-import io.restassured.http.ContentType;
-
-/**
- * SPDX upload tests that mock {@link GenerateSbomService} to avoid real syft/registry calls.
- */
-@QuarkusTest
-public class UploadSpdxMockedSyftRestTest {
-
- private static final String SPDX_WITH_UNSUPPORTED = "src/test/resources/devservices/spdx-sboms/spdx-with-unsupported-component.json";
- private static final String CYCLONEDX_FIXTURE = "src/test/resources/devservices/cyclonedx-sboms/nmstate-rhel8-operator.json";
- private static final String TEST_VULN_ID = "CVE-2021-4238";
-
- @InjectMock
- GenerateSbomService generateSbomService;
-
- @BeforeEach
- void setUp() throws Exception {
- RestApiTestFixture.configureRestAssuredIfExternal();
-
- ObjectMapper mapper = new ObjectMapper();
- JsonNode sbomJson = mapper.readTree(new File(CYCLONEDX_FIXTURE));
- JsonNode component = sbomJson.get("metadata").get("component");
-
- ParsedCycloneDx mockSbom = new ParsedCycloneDx(
- sbomJson,
- component.get("name").asText(),
- component.has("version") ? component.get("version").asText() : null,
- component.has("description") ? component.get("description").asText() : null,
- component.has("type") ? component.get("type").asText() : null,
- component.has("purl") ? component.get("purl").asText() : null,
- component.has("bom-ref") ? component.get("bom-ref").asText() : null);
-
- Mockito.when(generateSbomService.generate(Mockito.anyString()))
- .thenReturn(mockSbom);
- }
-
- @Test
- void testUpload_SpdxWithUnsupportedComponent_RecordsInSubmissionFailures() {
- File sbomFile = new File(SPDX_WITH_UNSUPPORTED);
-
- String productId = RestAssured.given()
- .contentType(ContentType.MULTIPART)
- .multiPart("cveId", TEST_VULN_ID)
- .multiPart("file", sbomFile)
- .when()
- .post("/api/v1/products/upload-spdx")
- .then()
- .statusCode(202)
- .contentType(ContentType.JSON)
- .body("productId", notNullValue())
- .extract()
- .path("productId");
-
- Assertions.assertNotNull(productId, "Product ID should not be null");
- RestApiTestFixture.awaitSpdxProductProcessingComplete(productId);
-
- RestAssured.given()
- .when()
- .get("/api/v1/products/" + productId)
- .then()
- .statusCode(200)
- .contentType(ContentType.JSON)
- .body("data.submittedCount", equalTo(2))
- .body("data.submissionFailures", notNullValue())
- .body("data.submissionFailures", hasSize(1))
- .body("data.submissionFailures[0].name", equalTo("maven-lib"))
- .body("data.submissionFailures[0].version", equalTo("2.0"))
- .body("data.submissionFailures[0].error", containsString("Expects a container image purl with format pkg:oci/name@sha256:hash?repository_url=...&tag=..."));
- }
-}
diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties
index df7c228b..316dc1cb 100644
--- a/src/test/resources/application.properties
+++ b/src/test/resources/application.properties
@@ -1,22 +1,22 @@
# In-process REST tests (@QuarkusTest): Mongo Dev Services, seed data, auth off (see RoleMappingAugmentor).
# Optional: point REST tests at a running app (RestAssured base URI). Example:
-# %test.morpheus.rest-test.external-base-url=http://localhost:8080
-# Or: mvn test -Dmorpheus.rest-test.external-base-url=http://localhost:8080
+# %test.exploit-iq.rest-test.external-base-url=http://localhost:8080
+# Or: mvn test -Dexploit-iq.rest-test.external-base-url=http://localhost:8080
# No OTLP collector in tests — disable default OTLP export (avoids VertxGrpcSender → localhost:4317 warnings).
%test.quarkus.otel.exporter.otlp.enabled=false
-%test.morpheus.database.init.enabled=true
+%test.exploit-iq.database.init.enabled=true
%test.NAMESPACE=exploit-iq
%test.quarkus.oidc.enabled=false
-%test.morpheus.credential-store.encryption-key=dev-test-key-must-be-32bytes-long!
+%test.exploit-iq.credential-store.encryption-key=dev-test-key-must-be-32bytes-long!
%test.quarkus.quinoa.enabled=false
%test.quarkus.mongodb.devservices.image-name=docker.io/mongodb/mongodb-community-server:8.0.3-ubi8
%test.quarkus.wiremock.devservices.reload=true
%test.quarkus.wiremock.devservices.files-mapping=src/test/resources/devservices/wiremock
# WireMock dev service logs full request/response bodies at INFO; raise level to avoid huge test logs.
%test.quarkus.log.category."io.quarkiverse.wiremock.devservice.WireMockServer".level=ERROR
-# Morpheus REST client → WireMock (no real agent in @QuarkusTest); stub is mappings/morpheus-generate.json
-%test.quarkus.rest-client.morpheus.url=http://localhost:${quarkus.wiremock.devservices.port}/generate
+# ExploitIQ REST client → WireMock (no real agent in @QuarkusTest); stub is mappings/exploit-iq-generate.json
+%test.quarkus.rest-client.exploit-iq.url=http://localhost:${quarkus.wiremock.devservices.port}/generate
# GitHub REST client → WireMock (stub mappings/github.json matches /repos/.../languages like api.github.com)
%test.quarkus.rest-client.github.url=http://localhost:${quarkus.wiremock.devservices.port}
-# Default timeout for async SPDX processing wait in REST tests.
-%test.morpheus.rest-test.spdx-timeout=10m
+# Default timeout for async SPDX processing wait in REST tests (test-only config, not part of exploit-iq namespace).
+%test.test.rest.spdx-timeout=10m
diff --git a/src/test/resources/devservices/reports/test-sbom-report-3-report-2.json b/src/test/resources/devservices/reports/test-sbom-report-3-report-2.json
index be2b51ab..5ca4603b 100644
--- a/src/test/resources/devservices/reports/test-sbom-report-3-report-2.json
+++ b/src/test/resources/devservices/reports/test-sbom-report-3-report-2.json
@@ -2928,8 +2928,8 @@
},
"info": {
"vdb": {
- "code_vdb_path": "/morpheus-data/vdbs/code/9bd0c29c6857086b",
- "doc_vdb_path": "/morpheus-data/vdbs/doc/beed003ae65a070d"
+ "code_vdb_path": "/exploit-iq-data/vdbs/code/9bd0c29c6857086b",
+ "doc_vdb_path": "/exploit-iq-data/vdbs/doc/beed003ae65a070d"
},
"intel": [
{
diff --git a/src/test/resources/devservices/reports/test-sbom-report-5-report-2.json b/src/test/resources/devservices/reports/test-sbom-report-5-report-2.json
index 2c1b882a..d4464629 100644
--- a/src/test/resources/devservices/reports/test-sbom-report-5-report-2.json
+++ b/src/test/resources/devservices/reports/test-sbom-report-5-report-2.json
@@ -2763,8 +2763,8 @@
},
"info": {
"vdb": {
- "code_vdb_path": "/morpheus-data/vdbs/code/1c72f35adf7fbae9",
- "doc_vdb_path": "/morpheus-data/vdbs/doc/b9103c68ee4af680"
+ "code_vdb_path": "/exploit-iq-data/vdbs/code/1c72f35adf7fbae9",
+ "doc_vdb_path": "/exploit-iq-data/vdbs/doc/b9103c68ee4af680"
},
"intel": [
{
diff --git a/src/test/resources/devservices/reports/test-sbom-report-6-report-2.json b/src/test/resources/devservices/reports/test-sbom-report-6-report-2.json
index e6d5961e..12495a1e 100644
--- a/src/test/resources/devservices/reports/test-sbom-report-6-report-2.json
+++ b/src/test/resources/devservices/reports/test-sbom-report-6-report-2.json
@@ -2671,7 +2671,7 @@
"metadata": {
"product_id": "product-6",
"user": "vbelouso@redhat.com",
- "source": "morpheus-parser",
+ "source": "exploit-iq-parser",
"batch_id": "mp-10i7ly",
"requested_at": "2025-01-20T14:46:58.335Z",
"submitted_at": "2025-01-20T15:46:58.335583Z",
diff --git a/src/test/resources/devservices/reports/test-sbom-report-7-report-1.json b/src/test/resources/devservices/reports/test-sbom-report-7-report-1.json
index 146b9a1f..5a8d6451 100644
--- a/src/test/resources/devservices/reports/test-sbom-report-7-report-1.json
+++ b/src/test/resources/devservices/reports/test-sbom-report-7-report-1.json
@@ -5,7 +5,7 @@
"metadata": {
"product_id": "product-7",
"user": "vbelouso@redhat.com",
- "source": "morpheus-parser",
+ "source": "exploit-iq-parser",
"batch_id": "mp-10i7ly",
"requested_at": "2025-01-20T14:46:58.335Z",
"submitted_at": "2025-01-20T15:46:58.335583Z",
@@ -2130,8 +2130,8 @@
},
"info": {
"vdb": {
- "code_vdb_path": "/morpheus-data/vdbs/code/234dc59bcd709aad",
- "doc_vdb_path": "/morpheus-data/vdbs/doc/d12523272b4cfe13"
+ "code_vdb_path": "/exploit-iq-data/vdbs/code/234dc59bcd709aad",
+ "doc_vdb_path": "/exploit-iq-data/vdbs/doc/d12523272b4cfe13"
},
"intel": [
{
diff --git a/src/test/resources/devservices/reports/test-sbom-report-7-report-2.json b/src/test/resources/devservices/reports/test-sbom-report-7-report-2.json
index 16820b77..cd19fcc1 100644
--- a/src/test/resources/devservices/reports/test-sbom-report-7-report-2.json
+++ b/src/test/resources/devservices/reports/test-sbom-report-7-report-2.json
@@ -5,7 +5,7 @@
"metadata": {
"product_id": "product-7",
"user": "vbelouso@redhat.com",
- "source": "morpheus-parser",
+ "source": "exploit-iq-parser",
"batch_id": "mp-10i7ly",
"requested_at": "2025-01-20T14:46:58.335Z",
"submitted_at": "2025-01-20T15:46:58.335583Z",
@@ -2130,8 +2130,8 @@
},
"info": {
"vdb": {
- "code_vdb_path": "/morpheus-data/vdbs/code/234dc59bcd709aad",
- "doc_vdb_path": "/morpheus-data/vdbs/doc/d12523272b4cfe13"
+ "code_vdb_path": "/exploit-iq-data/vdbs/code/234dc59bcd709aad",
+ "doc_vdb_path": "/exploit-iq-data/vdbs/doc/d12523272b4cfe13"
},
"intel": [
{
diff --git a/src/test/resources/devservices/reports/test-sbom-report-8-report-2.json b/src/test/resources/devservices/reports/test-sbom-report-8-report-2.json
index 3565fa8a..f43c59a0 100644
--- a/src/test/resources/devservices/reports/test-sbom-report-8-report-2.json
+++ b/src/test/resources/devservices/reports/test-sbom-report-8-report-2.json
@@ -2900,7 +2900,7 @@
"metadata": {
"product_id": "product-8",
"user": "vbelouso@redhat.com",
- "source": "morpheus-parser",
+ "source": "exploit-iq-parser",
"batch_id": "mp-i3mtoj",
"requested_at": "2025-01-20T14:46:58.335Z",
"submitted_at": "2025-01-20T15:46:58.335583Z",
diff --git a/src/test/resources/devservices/reports/test-sbom-report-9-report-1.json b/src/test/resources/devservices/reports/test-sbom-report-9-report-1.json
index c419cada..3e353eb0 100644
--- a/src/test/resources/devservices/reports/test-sbom-report-9-report-1.json
+++ b/src/test/resources/devservices/reports/test-sbom-report-9-report-1.json
@@ -3043,7 +3043,7 @@
"metadata": {
"product_id": "product-9",
"user": "vbelouso@redhat.com",
- "source": "morpheus-parser",
+ "source": "exploit-iq-parser",
"batch_id": "mp-dnxbrn",
"requested_at": "2025-01-20T14:46:58.335Z",
"submitted_at": "2025-01-20T15:46:58.335583Z",
diff --git a/src/test/resources/devservices/wiremock/mappings/morpheus-generate.json b/src/test/resources/devservices/wiremock/mappings/exploit-iq-generate.json
similarity index 100%
rename from src/test/resources/devservices/wiremock/mappings/morpheus-generate.json
rename to src/test/resources/devservices/wiremock/mappings/exploit-iq-generate.json