Skip to content

Commit

Permalink
feat: test for postDistributedInformation
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasBousselin committed Jan 23, 2025
1 parent 90eabea commit 65ea75e
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class DistributedEntityProvisionService(
} else responses to entity
}

private suspend fun postDistributedInformation(
internal suspend fun postDistributedInformation(
httpHeaders: HttpHeaders,
entity: CompactedEntity,
csr: ContextSourceRegistration,
Expand Down Expand Up @@ -163,7 +163,7 @@ class DistributedEntityProvisionService(
} else if (response == null) {
val message = "No error message received from CSR ${csr.id} at $uri"
logger.warn(message)
GatewayTimeoutException(message).left()
BadGatewayException(message).left()
} else {
logger.warn("Error creating an entity for CSR at $uri: $response")
ContextSourceException.fromResponse(response).left()
Expand All @@ -173,7 +173,7 @@ class DistributedEntityProvisionService(
onFailure = { e ->
logger.warn("Error contacting CSR at $uri: ${e.message}")
logger.warn(e.stackTraceToString())
BadGatewayException(
GatewayTimeoutException(
"Error connecting to CSR at $uri: \"${e.cause}:${e.message}\""
).left()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package com.egm.stellio.search.csr.service

import com.egm.stellio.search.csr.CsrUtils.gimmeRawCSR
import com.egm.stellio.search.support.WithKafkaContainer
import com.egm.stellio.search.support.WithTimescaleContainer
import com.egm.stellio.shared.model.ContextSourceException
import com.egm.stellio.shared.model.ErrorType
import com.egm.stellio.shared.model.GatewayTimeoutException
import com.egm.stellio.shared.util.APIC_COMPOUND_CONTEXT
import com.egm.stellio.shared.util.JsonLdUtils.compactEntity
import com.egm.stellio.shared.util.expandJsonLdEntity
import com.egm.stellio.shared.util.toUri
import com.github.tomakehurst.wiremock.client.WireMock.badRequest
import com.github.tomakehurst.wiremock.client.WireMock.post
import com.github.tomakehurst.wiremock.client.WireMock.stubFor
import com.github.tomakehurst.wiremock.client.WireMock.urlMatching
import com.github.tomakehurst.wiremock.junit5.WireMockTest
import com.ninjasquad.springmockk.SpykBean
import kotlinx.coroutines.test.runTest
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertInstanceOf
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpStatus
import org.springframework.test.context.ActiveProfiles

@SpringBootTest
@WireMockTest(httpPort = 8089)
@ActiveProfiles("test")
class DistributedEntityProvisionServiceTests : WithTimescaleContainer, WithKafkaContainer() {

@SpykBean
private lateinit var distributedEntityProvisionService: DistributedEntityProvisionService

// @Autowired
// private lateinit var applicationProperties: ApplicationProperties
//
// @MockkBean
// private lateinit var contextSourceRegistrationService: ContextSourceRegistrationService

private val apiaryId = "urn:ngsi-ld:Apiary:TEST"

private val entity =
"""
{
"id":"$apiaryId",
"type":"Apiary",
"name": {
"type":"Property",
"value":"ApiarySophia"
},
"@context":[ "$APIC_COMPOUND_CONTEXT" ]
}
""".trimIndent()

private val validErrorResponse =
"""
{
"type":"${ErrorType.BAD_REQUEST_DATA.type}",
"status": ${HttpStatus.BAD_REQUEST.value()},
"title": "A valid error",
"detail":"The detail of the valid Error"
}
""".trimIndent()

private val responseWithBadPayload = "error message not respecting specification"

@Test
fun `postDistributedInformation should process badly formed errors`() = runTest {
val csr = gimmeRawCSR()
val path = "/ngsi-ld/v1/entities"

stubFor(
post(urlMatching(path))
.willReturn(badRequest().withBody(responseWithBadPayload))
)

val entity = compactEntity(expandJsonLdEntity(entity), listOf(APIC_COMPOUND_CONTEXT))
val response = distributedEntityProvisionService.postDistributedInformation(HttpHeaders(), entity, csr, path)

assertTrue(response.isLeft())
assertEquals(response.leftOrNull()?.type, ErrorType.BAD_GATEWAY.type)
assertEquals(response.leftOrNull()?.status, HttpStatus.BAD_GATEWAY)
assertEquals(response.leftOrNull()?.detail, responseWithBadPayload)
}

@Test
fun `postDistributedInformation should return the received error`() = runTest {
val csr = gimmeRawCSR()
val path = "/ngsi-ld/v1/entities"

stubFor(
post(urlMatching(path))
.willReturn(badRequest().withBody(validErrorResponse))
)

val entity = compactEntity(expandJsonLdEntity(entity), listOf(APIC_COMPOUND_CONTEXT))
val response = distributedEntityProvisionService.postDistributedInformation(HttpHeaders(), entity, csr, path)

assertTrue(response.isLeft())
assertInstanceOf(ContextSourceException::class.java, response.leftOrNull())
assertEquals(response.leftOrNull()?.type, ErrorType.BAD_REQUEST_DATA.type)
assertEquals(response.leftOrNull()?.status, HttpStatus.BAD_REQUEST)
assertEquals(response.leftOrNull()?.detail, "The detail of the valid Error")
assertEquals(response.leftOrNull()?.message, "A valid error")
}

@Test
fun `postDistributedInformation should return a GateWayTimeOut if it receives no answer`() = runTest {
val csr = gimmeRawCSR().copy(endpoint = "http://localhost:invalid".toUri())
val path = "/ngsi-ld/v1/entities"
val entity = compactEntity(expandJsonLdEntity(entity), listOf(APIC_COMPOUND_CONTEXT))
val response = distributedEntityProvisionService.postDistributedInformation(HttpHeaders(), entity, csr, path)

assertTrue(response.isLeft())
assertInstanceOf(GatewayTimeoutException::class.java, response.leftOrNull())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ data class ContextSourceException(
) {
companion object {
fun fromResponse(response: String): ContextSourceException {
val responseMap = response.deserializeAsMap()
return kotlin.runCatching {
val responseMap = response.deserializeAsMap()
// mandatory
val type = responseMap[TYPE_PROPERTY].toString().toUri()
val title = responseMap[TITLE_PROPERTY]!!.toString()
Expand Down

0 comments on commit 65ea75e

Please sign in to comment.