diff --git a/src/main/java/org/acme/service/v3/ProductServiceV3.java b/src/main/java/org/acme/service/v3/ProductServiceV3.java index 5d44e42..953fdaa 100644 --- a/src/main/java/org/acme/service/v3/ProductServiceV3.java +++ b/src/main/java/org/acme/service/v3/ProductServiceV3.java @@ -7,6 +7,7 @@ import jakarta.transaction.Transactional; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.util.List; @@ -56,7 +57,11 @@ public List getAll() { */ public ProductEntity getBySku(String sku) { return repository.findBySku(sku) - .orElseThrow(() -> new NotFoundException("Product not found: " + sku)); + .orElseThrow(() -> new NotFoundException( + Response.status(Response.Status.NOT_FOUND) + .entity("Product not found: " + sku) + .type(MediaType.TEXT_PLAIN_TYPE) + .build())); } /** @@ -76,8 +81,10 @@ public ProductEntity create(ProductEntity product) { // Since Repository returns Optional, we check presence. if (repository.findBySku(product.getSku()).isPresent()) { throw new WebApplicationException( - "Product with this SKU already exists", - Response.Status.CONFLICT); + Response.status(Response.Status.CONFLICT) + .entity("Product SKU already exists: " + product.getSku()) + .type(MediaType.TEXT_PLAIN_TYPE) + .build()); } return repository.persist(product); } diff --git a/src/main/java/org/acme/service/v4/ProductServiceV4.java b/src/main/java/org/acme/service/v4/ProductServiceV4.java index e9a19c9..08b9226 100644 --- a/src/main/java/org/acme/service/v4/ProductServiceV4.java +++ b/src/main/java/org/acme/service/v4/ProductServiceV4.java @@ -10,6 +10,7 @@ import jakarta.transaction.Transactional; import jakarta.ws.rs.NotFoundException; import jakarta.ws.rs.WebApplicationException; +import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.util.List; @@ -52,7 +53,11 @@ public List getAll() { public ProductDTO getBySku(String sku) { return repository.findBySku(sku) .map(ProductMapper::toDto) - .orElseThrow(() -> new NotFoundException("Product with SKU " + sku + " not found")); + .orElseThrow(() -> new NotFoundException( + Response.status(Response.Status.NOT_FOUND) + .entity("Product not found: " + sku) + .type(MediaType.TEXT_PLAIN_TYPE) + .build())); } /** @@ -72,8 +77,10 @@ public ProductDTO create(CreateProductRequest request) { // Step 2: Check persistence integrity if (repository.findBySku(entity.getSku()).isPresent()) { throw new WebApplicationException( - "Product with this SKU already exists", - Response.Status.CONFLICT); + Response.status(Response.Status.CONFLICT) + .entity("Product SKU already exists: " + entity.getSku()) + .type(MediaType.TEXT_PLAIN_TYPE) + .build()); } // Step 3: Persist and Return DTO @@ -90,7 +97,11 @@ public void delete(String sku) { .ifPresentOrElse( repository::delete, () -> { - throw new NotFoundException("Product SKU " + sku + " not found"); + throw new NotFoundException( + Response.status(Response.Status.NOT_FOUND) + .entity("Product not found: " + sku) + .type(MediaType.TEXT_PLAIN_TYPE) + .build()); }); } diff --git a/src/test/java/org/acme/api/cucumber/steps/Hooks.java b/src/test/java/org/acme/api/cucumber/steps/Hooks.java deleted file mode 100644 index 5d5168d..0000000 --- a/src/test/java/org/acme/api/cucumber/steps/Hooks.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.acme.api.cucumber.steps; - -import io.cucumber.java.Before; -import jakarta.enterprise.context.Dependent; -import jakarta.inject.Inject; -import org.acme.api.cucumber.VersionContext; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -@Dependent -public class Hooks { - private static final Logger LOGGER = LoggerFactory.getLogger(Hooks.class); - - @Inject - VersionContext versionContext; - - @Before("@v1") - public void setV1() { - LOGGER.info("Setting API Version to v1 based on tag"); - versionContext.setVersion("v1"); - } - - @Before("@v2") - public void setV2() { - LOGGER.info("Setting API Version to v2 based on tag"); - versionContext.setVersion("v2"); - } - - @Before("@v3") - public void setV3() { - LOGGER.info("Setting API Version to v3 based on tag"); - versionContext.setVersion("v3"); - } - - @Before("@v4") - public void setV4() { - LOGGER.info("Setting API Version to v4 based on tag"); - versionContext.setVersion("v4"); - } - - @Before("@v5") - public void setV5() { - LOGGER.info("Setting API Version to v5 based on tag"); - versionContext.setVersion("v5"); - } -} diff --git a/src/test/java/org/acme/api/cucumber/v1/CatalogV1AcceptanceIT.java b/src/test/java/org/acme/api/cucumber/v1/CatalogV1AcceptanceIT.java index 52e487a..045bfb9 100644 --- a/src/test/java/org/acme/api/cucumber/v1/CatalogV1AcceptanceIT.java +++ b/src/test/java/org/acme/api/cucumber/v1/CatalogV1AcceptanceIT.java @@ -6,6 +6,9 @@ import io.quarkiverse.cucumber.CucumberOptions; @QuarkusTestResource(PostgreSqlTestResource.class) -@CucumberOptions(features = "classpath:features/v1", glue = "org.acme.api.cucumber.steps") +@CucumberOptions(features = "classpath:features/v1", glue = { + "org.acme.api.cucumber.steps", + "org.acme.api.cucumber.v1" +}) public class CatalogV1AcceptanceIT extends CucumberQuarkusTest { } diff --git a/src/test/java/org/acme/api/cucumber/v1/V1VersionHook.java b/src/test/java/org/acme/api/cucumber/v1/V1VersionHook.java new file mode 100644 index 0000000..bf2e8bf --- /dev/null +++ b/src/test/java/org/acme/api/cucumber/v1/V1VersionHook.java @@ -0,0 +1,27 @@ +package org.acme.api.cucumber.v1; + +import io.cucumber.java.Before; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import org.acme.api.cucumber.VersionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Pins the API version to v1 for every scenario of {@code CatalogV1AcceptanceIT}. + * Being part of this IT class's glue only, it runs deterministically before each + * of its scenarios and is the single place that sets the version for this class. + */ +@Dependent +public class V1VersionHook { + private static final Logger LOGGER = LoggerFactory.getLogger(V1VersionHook.class); + + @Inject + VersionContext versionContext; + + @Before + public void pinVersion() { + LOGGER.info("Setting API Version to v1 for this acceptance test class"); + versionContext.setVersion("v1"); + } +} diff --git a/src/test/java/org/acme/api/cucumber/v2/CatalogV2AcceptanceIT.java b/src/test/java/org/acme/api/cucumber/v2/CatalogV2AcceptanceIT.java index a8a2aaf..a53f911 100644 --- a/src/test/java/org/acme/api/cucumber/v2/CatalogV2AcceptanceIT.java +++ b/src/test/java/org/acme/api/cucumber/v2/CatalogV2AcceptanceIT.java @@ -7,6 +7,9 @@ import io.quarkiverse.cucumber.CucumberOptions; @QuarkusTestResource(PostgreSqlTestResource.class) -@CucumberOptions(features = "classpath:features/v2", glue = "org.acme.api.cucumber.steps") +@CucumberOptions(features = "classpath:features/v2", glue = { + "org.acme.api.cucumber.steps", + "org.acme.api.cucumber.v2" +}) public class CatalogV2AcceptanceIT extends CucumberQuarkusTest { } diff --git a/src/test/java/org/acme/api/cucumber/v2/V2VersionHook.java b/src/test/java/org/acme/api/cucumber/v2/V2VersionHook.java new file mode 100644 index 0000000..673bfb6 --- /dev/null +++ b/src/test/java/org/acme/api/cucumber/v2/V2VersionHook.java @@ -0,0 +1,27 @@ +package org.acme.api.cucumber.v2; + +import io.cucumber.java.Before; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import org.acme.api.cucumber.VersionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Pins the API version to v2 for every scenario of {@code CatalogV2AcceptanceIT}. + * Being part of this IT class's glue only, it runs deterministically before each + * of its scenarios and is the single place that sets the version for this class. + */ +@Dependent +public class V2VersionHook { + private static final Logger LOGGER = LoggerFactory.getLogger(V2VersionHook.class); + + @Inject + VersionContext versionContext; + + @Before + public void pinVersion() { + LOGGER.info("Setting API Version to v2 for this acceptance test class"); + versionContext.setVersion("v2"); + } +} diff --git a/src/test/java/org/acme/api/cucumber/v3/CatalogV3AcceptanceIT.java b/src/test/java/org/acme/api/cucumber/v3/CatalogV3AcceptanceIT.java index 3666f60..f1d32d4 100644 --- a/src/test/java/org/acme/api/cucumber/v3/CatalogV3AcceptanceIT.java +++ b/src/test/java/org/acme/api/cucumber/v3/CatalogV3AcceptanceIT.java @@ -9,6 +9,9 @@ @CucumberOptions(features = { "classpath:features/catalog", "classpath:features/v3" -}, tags = "@v3", glue = "org.acme.api.cucumber.steps") +}, tags = "@v3", glue = { + "org.acme.api.cucumber.steps", + "org.acme.api.cucumber.v3" +}) public class CatalogV3AcceptanceIT extends CucumberQuarkusTest { } diff --git a/src/test/java/org/acme/api/cucumber/v3/V3VersionHook.java b/src/test/java/org/acme/api/cucumber/v3/V3VersionHook.java new file mode 100644 index 0000000..b1234ae --- /dev/null +++ b/src/test/java/org/acme/api/cucumber/v3/V3VersionHook.java @@ -0,0 +1,27 @@ +package org.acme.api.cucumber.v3; + +import io.cucumber.java.Before; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import org.acme.api.cucumber.VersionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Pins the API version to v3 for every scenario of {@code CatalogV3AcceptanceIT}. + * Being part of this IT class's glue only, it runs deterministically before each + * of its scenarios and is the single place that sets the version for this class. + */ +@Dependent +public class V3VersionHook { + private static final Logger LOGGER = LoggerFactory.getLogger(V3VersionHook.class); + + @Inject + VersionContext versionContext; + + @Before + public void pinVersion() { + LOGGER.info("Setting API Version to v3 for this acceptance test class"); + versionContext.setVersion("v3"); + } +} diff --git a/src/test/java/org/acme/api/cucumber/v4/CatalogV4AcceptanceIT.java b/src/test/java/org/acme/api/cucumber/v4/CatalogV4AcceptanceIT.java index e7ae977..a500c66 100644 --- a/src/test/java/org/acme/api/cucumber/v4/CatalogV4AcceptanceIT.java +++ b/src/test/java/org/acme/api/cucumber/v4/CatalogV4AcceptanceIT.java @@ -9,6 +9,9 @@ @CucumberOptions(features = { "classpath:features/catalog", "classpath:features/v4" -}, tags = "@v4", glue = "org.acme.api.cucumber.steps") +}, tags = "@v4", glue = { + "org.acme.api.cucumber.steps", + "org.acme.api.cucumber.v4" +}) public class CatalogV4AcceptanceIT extends CucumberQuarkusTest { } diff --git a/src/test/java/org/acme/api/cucumber/v4/V4VersionHook.java b/src/test/java/org/acme/api/cucumber/v4/V4VersionHook.java new file mode 100644 index 0000000..9d9ec98 --- /dev/null +++ b/src/test/java/org/acme/api/cucumber/v4/V4VersionHook.java @@ -0,0 +1,27 @@ +package org.acme.api.cucumber.v4; + +import io.cucumber.java.Before; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import org.acme.api.cucumber.VersionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Pins the API version to v4 for every scenario of {@code CatalogV4AcceptanceIT}. + * Being part of this IT class's glue only, it runs deterministically before each + * of its scenarios and is the single place that sets the version for this class. + */ +@Dependent +public class V4VersionHook { + private static final Logger LOGGER = LoggerFactory.getLogger(V4VersionHook.class); + + @Inject + VersionContext versionContext; + + @Before + public void pinVersion() { + LOGGER.info("Setting API Version to v4 for this acceptance test class"); + versionContext.setVersion("v4"); + } +} diff --git a/src/test/java/org/acme/api/cucumber/v5/CatalogV5AcceptanceIT.java b/src/test/java/org/acme/api/cucumber/v5/CatalogV5AcceptanceIT.java index a3743db..be952d6 100644 --- a/src/test/java/org/acme/api/cucumber/v5/CatalogV5AcceptanceIT.java +++ b/src/test/java/org/acme/api/cucumber/v5/CatalogV5AcceptanceIT.java @@ -9,6 +9,9 @@ @CucumberOptions(features = { "classpath:features/catalog", "classpath:features/v5" -}, tags = "@v5", glue = "org.acme.api.cucumber.steps") +}, tags = "@v5", glue = { + "org.acme.api.cucumber.steps", + "org.acme.api.cucumber.v5" +}) public class CatalogV5AcceptanceIT extends CucumberQuarkusTest { } diff --git a/src/test/java/org/acme/api/cucumber/v5/V5VersionHook.java b/src/test/java/org/acme/api/cucumber/v5/V5VersionHook.java new file mode 100644 index 0000000..8fb10b6 --- /dev/null +++ b/src/test/java/org/acme/api/cucumber/v5/V5VersionHook.java @@ -0,0 +1,27 @@ +package org.acme.api.cucumber.v5; + +import io.cucumber.java.Before; +import jakarta.enterprise.context.Dependent; +import jakarta.inject.Inject; +import org.acme.api.cucumber.VersionContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Pins the API version to v5 for every scenario of {@code CatalogV5AcceptanceIT}. + * Being part of this IT class's glue only, it runs deterministically before each + * of its scenarios and is the single place that sets the version for this class. + */ +@Dependent +public class V5VersionHook { + private static final Logger LOGGER = LoggerFactory.getLogger(V5VersionHook.class); + + @Inject + VersionContext versionContext; + + @Before + public void pinVersion() { + LOGGER.info("Setting API Version to v5 for this acceptance test class"); + versionContext.setVersion("v5"); + } +}