diff --git a/pom.xml b/pom.xml
index b98eaac..cb6ca19 100644
--- a/pom.xml
+++ b/pom.xml
@@ -47,6 +47,25 @@
org.jetbrains.kotlin
kotlin-stdlib
+
+
+ io.cucumber
+ cucumber-spring
+ 7.23.0
+
+
+
+ io.cucumber
+ cucumber-junit-platform-engine
+ 7.23.0
+ test
+
+
+
+ io.cucumber
+ cucumber-java
+ 7.23.0
+
org.springframework.boot
diff --git a/src/main/kotlin/com/example/copilotdemo/services/ProductsService.kt b/src/main/kotlin/com/example/copilotdemo/services/ProductsService.kt
index 537c2f5..f8c1f34 100644
--- a/src/main/kotlin/com/example/copilotdemo/services/ProductsService.kt
+++ b/src/main/kotlin/com/example/copilotdemo/services/ProductsService.kt
@@ -30,6 +30,14 @@ class ProductsService {
val total: Int
)
+
+ /**
+ * Retrieves a paginated list of products and the total count from the external DummyJSON API.
+ *
+ * @param start The starting index (number of products to skip).
+ * @param size The number of products to retrieve.
+ * @return [ProductsResult] containing the list of products and the total count.
+ */
fun getProductsAndTotal(start: Int, size: Int): ProductsResult {
if (start < 0 || size < 1) return ProductsResult(emptyList(), 0)
val url = UriComponentsBuilder.fromUriString(baseUrl)
@@ -37,6 +45,7 @@ class ProductsService {
.queryParam("limit", size)
.toUriString()
val response = restTemplate.getForObject(url, DummyJsonResponse::class.java)
+
val products = response?.products?.map {
Product(
id = it.id.toLong(),
@@ -50,4 +59,48 @@ class ProductsService {
val total = response?.total ?: 0
return ProductsResult(products, total)
}
+
+ /**
+ * Fetches all products from the external API in batches of 20.
+ * @return ProductsResult containing all products and the total count.
+ */
+ fun getAllProductsInBatches(): ProductsResult {
+ val batchSize = 20
+ val firstBatch = getProductsAndTotal(0, batchSize)
+ val total = firstBatch.total
+ val allProducts = mutableListOf()
+ allProducts.addAll(firstBatch.products)
+ var fetched = firstBatch.products.size
+ while (fetched < total) {
+ val batch = getProductsAndTotal(fetched, batchSize)
+ allProducts.addAll(batch.products)
+ fetched += batch.products.size
+ if (batch.products.isEmpty()) break // safety check
+ }
+ return ProductsResult(allProducts, total)
+ }
+
+
+
}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/kotlin/com/example/copilotdemo/controllers/ProductsControllerTest.kt b/src/test/kotlin/com/example/copilotdemo/controllers/ProductsControllerTest.kt
index 164c22a..c99a2bc 100644
--- a/src/test/kotlin/com/example/copilotdemo/controllers/ProductsControllerTest.kt
+++ b/src/test/kotlin/com/example/copilotdemo/controllers/ProductsControllerTest.kt
@@ -16,6 +16,7 @@ import org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPat
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import org.springframework.web.client.RestTemplate
+@Suppress("SpringJavaInjectionPointsAutowiringInspection")
@SpringBootTest
@AutoConfigureMockMvc
class ProductsControllerTest {
@@ -56,6 +57,18 @@ class ProductsControllerTest {
.andReturn()
}
+ // write a test case to handle empty response from the service
+ @Test
+ fun `should return empty products when service returns no products`() {
+ val dummyResponse = ProductsService.DummyJsonResponse(products = emptyList(), total = 0)
+ Mockito.`when`(
+ restTemplate.getForObject(Mockito.anyString(), Mockito.eq(ProductsService.DummyJsonResponse::class.java))
+ ).thenReturn(dummyResponse)
+ mockMvc.perform(get("/api/v1/products?start=0&size=10").accept(MediaType.APPLICATION_JSON))
+ .andExpect(status().isOk)
+ .andExpect(jsonPath("$.products").isEmpty)
+ .andExpect(jsonPath("$.total").value(0))
+ }
}