Skip to content

Commit

Permalink
Merge pull request #53 from znsio/correlated_example_values
Browse files Browse the repository at this point in the history
Correlated example values
  • Loading branch information
harikrishnan83 authored Aug 17, 2024
2 parents a6690de + a8ae993 commit d7ba447
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 30 deletions.
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ dependencies {
implementation 'javax.validation:validation-api:2.0.1.Final'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation('io.specmatic:junit5-support:2.0.10')
testImplementation('io.specmatic:specmatic-kafka:0.22.9-TRIAL')
testApi 'io.specmatic:junit5-support:2.0.12'
testImplementation('io.specmatic:specmatic-kafka:0.22.9-TRIAL')
testImplementation(
'org.assertj:assertj-core:3.24.2',
'org.junit.jupiter:junit-jupiter-api:5.10.1'
Expand Down
5 changes: 5 additions & 0 deletions specmatic.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@ sources:
consumes:
- io/specmatic/examples/store/openapi/api_order_v3.yaml
- io/specmatic/examples/store/asyncapi/kafka.yaml

examples:
- "src/test/resources/bff"

test:
resiliencyTests:
enable: all

report:
formatters:
- type: text
Expand Down
6 changes: 6 additions & 0 deletions src/main/kotlin/com/component/orders/backend/OrderService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.springframework.http.MediaType
import org.springframework.http.client.SimpleClientHttpRequestFactory
import org.springframework.stereotype.Service
import org.springframework.web.client.RestTemplate
import java.lang.IllegalStateException
import java.util.*

@Service
Expand Down Expand Up @@ -91,6 +92,11 @@ class OrderService(private val jacksonObjectMapper: ObjectMapper) {
requestFactory.setReadTimeout(4000)
restTemplate.setRequestFactory(requestFactory)
val response = restTemplate.getForEntity(apiUrl, List::class.java)
(response.body as List<*>).any { (it as Map<String, *>)["type"] != type }.let {
if (it) {
throw IllegalStateException("Product type mismatch")
}
}
return response.body.take(1).map {
val product = it as Map<*, *>
Product(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class GlobalExceptionHandler {
fun handleGenericException(ex: Exception): ResponseEntity<ErrorResponse> {
val badRequest = when (ex) {
is ResourceAccessException -> HttpStatus.SERVICE_UNAVAILABLE
is IllegalStateException -> HttpStatus.INTERNAL_SERVER_ERROR
is NoResourceFoundException -> HttpStatus.NOT_FOUND
else -> HttpStatus.BAD_REQUEST
}
Expand Down
13 changes: 8 additions & 5 deletions src/test/kotlin/com/component/orders/ApiTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ApiTests {

@Test
fun `should search for available products`() {
val expectation = File("src/test/resources/stub_products_200.json").readText()
val expectation = File("src/test/resources/domain_service/stub_products_200.json").readText()
setExpectations(expectation)

val url = "http://localhost:8080/findAvailableProducts?type=gadget"
Expand All @@ -75,15 +75,18 @@ class ApiTests {

assert(response.statusCode == HttpStatus.OK)

val expectedResponse = expectation.toMap()["http-response"] as Map<String, Any>
val expectedResponseBody = expectedResponse["body"] as List<Map<String, Any>>
val actualResponseBody = response.body as List<Map<String, Any>>
assertThat(actualResponseBody).isEqualTo(expectedResponseBody)
val expectedProduct = mapOf("name" to "iPhone", "type" to "gadget", "id" to 10)
val actualProduct = actualResponseBody.single()

assertThat(actualProduct["name"]).isEqualTo(expectedProduct["name"])
assertThat(actualProduct["type"]).isEqualTo(expectedProduct["type"])
assertThat(actualProduct["id"]).isEqualTo(expectedProduct["id"])
}

@Test
fun `should return 503 (SERVICE_UNAVAILABLE) status if backend service is down`() {
val expectation = File("src/test/resources/stub timeout.json").readText()
val expectation = File("src/test/resources/domain_service/stub_timeout.json").readText()
setExpectations(expectation)
val url = "http://localhost:8080/findAvailableProducts?type=other"
val headers = HttpHeaders().apply {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ContractTests : SpecmaticContractTest {
private const val KAFKA_MOCK_PORT = 9092
private const val ACTUATOR_MAPPINGS_ENDPOINT =
"http://$APPLICATION_HOST:$APPLICATION_PORT/actuator/mappings"
private const val EXPECTED_NUMBER_OF_MESSAGES = 2
private const val EXPECTED_NUMBER_OF_MESSAGES = 4

@JvmStatic
@BeforeAll
Expand All @@ -34,7 +34,7 @@ class ContractTests : SpecmaticContractTest {
System.setProperty("endpointsAPI", ACTUATOR_MAPPINGS_ENDPOINT)

// Start Specmatic Http Stub and set the expectations
httpStub = createStub(listOf("./src/test/resources"), HTTP_STUB_HOST, HTTP_STUB_PORT)
httpStub = createStub(listOf("./src/test/resources/domain_service"), HTTP_STUB_HOST, HTTP_STUB_PORT)

// Start Specmatic Kafka Mock and set the expectations
kafkaMock = KafkaMock.startInMemoryBroker(KAFKA_MOCK_HOST, KAFKA_MOCK_PORT)
Expand Down
16 changes: 16 additions & 0 deletions src/test/resources/bff/test_find_available_products_book_200.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"http-request": {
"path": "/findAvailableProducts?type=book",
"method": "GET",
"headers": {
"pageSize": "10"
}
},
"http-response": {
"status": 200,
"body": [],
"headers": {
"Content-Type": "application/json"
}
}
}
30 changes: 30 additions & 0 deletions src/test/resources/domain_service/stub_products_200.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"http-request": {
"method": "GET",
"path": "/products?type={{@productTypeBasedLookup}}"
},
"http-response": {
"status": 200,
"body": [
{
"id": "{{@productTypeBasedLookup.productId}}",
"name": "{{@productTypeBasedLookup}}",
"inventory": "(number)",
"type": "{{REQUEST.QUERY-PARAMS.type}}"
}
],
"status-text": "OK"
},
"data": {
"@productTypeBasedLookup": {
"gadget": {
"name": "iPhone",
"productId": 10
},
"book": {
"name": "Harry Potter",
"productId": 20
}
}
}
}
File renamed without changes.
21 changes: 0 additions & 21 deletions src/test/resources/stub_products_200.json

This file was deleted.

0 comments on commit d7ba447

Please sign in to comment.