Skip to content

Commit

Permalink
Merge pull request #20 from beckn/develop/v1
Browse files Browse the repository at this point in the history
Moving Api changes for Cancellation Reason to QA
  • Loading branch information
techframewirk authored Mar 28, 2022
2 parents 00b4947 + 0e0f87f commit 8036db2
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,8 @@ class DatabaseConfiguration @Autowired constructor(
@Bean
fun onOrderStatusResponseRepo(@Autowired database: MongoDatabase): BecknResponseRepository<OnOrderStatusDao> =
BecknResponseRepository(database.getCollectionOfName("on_order_status"))

@Bean
fun onCancellationReasonsResponseRepo(@Autowired database: MongoDatabase): BecknResponseRepository<OnCancellationReasonDao> =
BecknResponseRepository(database.getCollectionOfName("on_cancellation_reasons"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ class ProtocolServicesConfiguration {
@Autowired mapper: GenericResponseMapper<ProtocolOnCancel, OnCancelDao>
): ResponseStorageService<ProtocolOnCancel> = ResponseStorageServiceImpl(responseRepo, mapper)

@Bean
fun onCancellationReasonsStorageService(
@Autowired responseRepo: BecknResponseRepository<OnCancellationReasonDao>,
@Autowired mapper: GenericResponseMapper<ProtocolOnCancellationReasons, OnCancellationReasonDao>
): ResponseStorageService<ProtocolOnCancellationReasons> = ResponseStorageServiceImpl(responseRepo, mapper)

@Bean
fun onOrderStatusStorageService(
@Autowired responseRepo: BecknResponseRepository<OnOrderStatusDao>,
Expand Down Expand Up @@ -123,4 +129,12 @@ class ProtocolServicesConfiguration {
messageService: MessageService,
responseStorageService: ResponseStorageService<ProtocolOnOrderStatus>
) = PollForResponseService(messageService, responseStorageService)


@Bean
fun pollForCancellationReasonsResponseService(
messageService: MessageService,
responseStorageService: ResponseStorageService<ProtocolOnCancellationReasons>
) = PollForResponseService(messageService, responseStorageService)

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.beckn.one.sandbox.bap.message.entities

import org.beckn.protocol.schemas.Default
import org.beckn.protocol.schemas.ProtocolDescriptor
import java.time.LocalDateTime


interface BecknResponseDao {
Expand Down Expand Up @@ -86,6 +88,12 @@ data class OnCancelDao @Default constructor(
override val error: ErrorDao? = null
) : BecknResponseDao

data class OnCancellationReasonDao @Default constructor(
override val context: ContextDao,
val message: OnCancellationReasonsMessageDao? = null,
override val error: ErrorDao? = null
) : BecknResponseDao

data class OnCancelMessageDao @Default constructor(
val order: OrderDao? = null
)
Expand All @@ -99,3 +107,22 @@ data class OnOrderStatusDao @Default constructor(
data class OnOrderStatusMessageDao @Default constructor(
val order: OrderDao? = null
)

data class OnCancellationReasonsMessageDao @Default constructor(
val cancellationReasons: List<OnCancellationReasonsDescripterDao>? = null,
val ratingCategories: List<OnRatingCategoryDao>? = null
)

data class OnCancellationReasonsDescripterDao @Default constructor(
val id: String? = null,
val descriptor: DescriptorDao? = null
)

data class OnRatingCategoryDao @Default constructor(
val id: String,
val parentCategoryId: String? = null,
val descriptor: DescriptorDao,
val time: LocalDateTime? = null,
val tags: Map<String, String>? = null,
val question: String? = null
)
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,14 @@ interface OnOrderStatusResponseMapper : GenericResponseMapper<ProtocolOnOrderSta
override fun entityToProtocol(entity: OnOrderStatusDao): ProtocolOnOrderStatus
override fun protocolToEntity(schema: ProtocolOnOrderStatus): OnOrderStatusDao
}

@Mapper(
componentModel = "spring",
unmappedTargetPolicy = ReportingPolicy.WARN,
injectionStrategy = InjectionStrategy.CONSTRUCTOR,
uses = [DateMapper::class]
)
interface OnCancellationReasonResponseMapper : GenericResponseMapper<ProtocolOnCancellationReasons, OnCancellationReasonDao> {
override fun entityToProtocol(entity: OnCancellationReasonDao): ProtocolOnCancellationReasons
override fun protocolToEntity(schema: ProtocolOnCancellationReasons): OnCancellationReasonDao
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package org.beckn.one.sandbox.bap.protocol.cancellation.controller

import org.beckn.one.sandbox.bap.message.services.ResponseStorageService
import org.beckn.one.sandbox.bap.protocol.shared.controllers.AbstractCallbackController
import org.beckn.protocol.schemas.ProtocolOnCancel
import org.beckn.protocol.schemas.ProtocolOnCancellationReasons
import org.springframework.http.MediaType
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RestController

@RestController
class OnCancellationReasonCallbackController(
store: ResponseStorageService<ProtocolOnCancellationReasons>
) : AbstractCallbackController<ProtocolOnCancellationReasons>(store) {


@PostMapping(
"protocol/v1/cancellation_reasons",
consumes = [MediaType.APPLICATION_JSON_VALUE],
produces = [MediaType.APPLICATION_JSON_VALUE],
)
fun onCancellationReasons(@RequestBody cancellationReasonsRequest: ProtocolOnCancellationReasons) = onCallback(cancellationReasonsRequest)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.beckn.one.sandbox.bap.protocol.cancellation.controller

import org.beckn.one.sandbox.bap.protocol.shared.controllers.AbstractPollForResponseController
import org.beckn.one.sandbox.bap.protocol.shared.services.PollForResponseService
import org.beckn.one.sandbox.bap.schemas.factories.ContextFactory
import org.beckn.protocol.schemas.ProtocolOnCancel
import org.beckn.protocol.schemas.ProtocolOnCancellationReasons
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.bind.annotation.RestController

@RestController
class PollOnCancellationReasonResponseController @Autowired constructor(
responseService: PollForResponseService<ProtocolOnCancellationReasons>,
contextFactory: ContextFactory
) : AbstractPollForResponseController<ProtocolOnCancellationReasons>(responseService, contextFactory) {

@GetMapping("protocol/response/v1/on_cancellation_reasons")
@ResponseBody
fun getCancellationReasonsResponses(messageId: String) = findResponses(messageId)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package org.beckn.one.sandbox.bap.protocol.cancellation.controllers

import arrow.core.Either
import com.fasterxml.jackson.databind.ObjectMapper
import io.kotest.core.spec.style.DescribeSpec
import io.kotest.matchers.ints.shouldBeExactly
import io.kotest.matchers.shouldBe
import org.beckn.one.sandbox.bap.errors.database.DatabaseError
import org.beckn.one.sandbox.bap.message.entities.OnCancellationReasonDao
import org.beckn.one.sandbox.bap.message.entities.OnRatingDao
import org.beckn.one.sandbox.bap.message.factories.ProtocolContextFactory
import org.beckn.one.sandbox.bap.message.repositories.BecknResponseRepository
import org.beckn.one.sandbox.bap.message.services.ResponseStorageService
import org.beckn.one.sandbox.bap.protocol.cancellation.controller.OnCancellationReasonCallbackController
import org.beckn.one.sandbox.bap.protocol.rating.controllers.OnRatingController
import org.beckn.protocol.schemas.*
import org.mockito.kotlin.mock
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.TestPropertySource
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers


@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles(value = ["test"])
@TestPropertySource(locations = ["/application-test.yml"])
internal class OnCancellationReasonCallbackControllerSpec @Autowired constructor(
@Autowired
private val mockMvc: MockMvc,
@Autowired
private val mapper: ObjectMapper,
@Autowired
private val OoCancellationReasonDao: BecknResponseRepository<OnCancellationReasonDao>,
) : DescribeSpec() {
private val postOnRatingUrl = "/protocol/v1/cancellation_reasons"
val onCancellationReasonsResponse = ProtocolOnCancellationReasons(
context = ProtocolContextFactory.fixed,
message = ProtocolOnCancellationReasonMessage(
cancellationReasons = listOf(ProtocolOption(
id = "item id 1",
descriptor = ProtocolDescriptor(name ="item id 1 descriptor")
))
)
)

init {

describe("Protocol On Cancellation Reasons API") {

context("when posted to with a valid response") {
OoCancellationReasonDao.clear()
val postOnRatingResponse = mockMvc
.perform(
MockMvcRequestBuilders.post(postOnRatingUrl)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.content(mapper.writeValueAsBytes(onCancellationReasonsResponse))
)

it("should respond with status as 200") {
postOnRatingResponse.andExpect(MockMvcResultMatchers.status().isOk)
}

it("should save on rating response in db") {
OoCancellationReasonDao.findByMessageId(onCancellationReasonsResponse.context!!.messageId).size shouldBeExactly 1
}
}

context("when error occurs when processing request") {
val mockService = mock<ResponseStorageService<ProtocolOnCancellationReasons>> {
onGeneric { save(onCancellationReasonsResponse) }.thenReturn(Either.Left(DatabaseError.OnWrite))
}
val controller = OnCancellationReasonCallbackController(mockService)

it("should respond with internal server error") {
val response = controller.onCancellationReasons(onCancellationReasonsResponse)
response.statusCode shouldBe DatabaseError.OnWrite.status()
}
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package org.beckn.one.sandbox.bap.protocol.cancellation.controllers

import arrow.core.Either
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import io.kotest.core.spec.style.DescribeSpec
import io.kotest.matchers.ints.shouldBeExactly
import io.kotest.matchers.shouldBe
import org.beckn.one.sandbox.bap.errors.database.DatabaseError
import org.beckn.one.sandbox.bap.message.entities.*
import org.beckn.one.sandbox.bap.message.factories.ProtocolOnRatingMessageFeedbackFactory
import org.beckn.one.sandbox.bap.message.repositories.BecknResponseRepository
import org.beckn.one.sandbox.bap.message.repositories.GenericRepository
import org.beckn.one.sandbox.bap.protocol.cancellation.controller.PollOnCancellationReasonResponseController
import org.beckn.one.sandbox.bap.protocol.shared.services.PollForResponseService
import org.beckn.one.sandbox.bap.schemas.factories.ContextFactory
import org.beckn.protocol.schemas.ProtocolOnCancellationReasons
import org.beckn.protocol.schemas.ProtocolOnRating
import org.mockito.kotlin.any
import org.mockito.kotlin.mock
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.http.HttpHeaders
import org.springframework.http.MediaType
import org.springframework.test.context.ActiveProfiles
import org.springframework.test.context.TestPropertySource
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers.status
import java.time.Clock
import java.time.Instant
import java.time.OffsetDateTime
import java.time.ZoneId

@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles(value = ["test"])
@TestPropertySource(locations = ["/application-test.yml"])
internal class PollOnCancellationReasonsResponseControllerSpec @Autowired constructor(
private val onCancellationReasonRepo: BecknResponseRepository<OnCancellationReasonDao>,
private val messageRepository: GenericRepository<MessageDao>,
private val contextFactory: ContextFactory,
private val mapper: ObjectMapper,
private val mockMvc: MockMvc
) : DescribeSpec() {

private val fixedClock = Clock.fixed(
Instant.parse("2018-11-30T18:35:24.00Z"),
ZoneId.of("UTC")
)
private val entityContext = ContextDao(
domain = "LocalRetail",
country = "IN",
action = ContextDao.Action.CANCEL,
city = "Pune",
coreVersion = "0.9.1-draft03",
bapId = "http://host.bap.com",
bapUri = "http://host.bap.com/v1",
bppId = "http://host.bpp.com",
bppUri = "http://host.bpp.com/v1",
transactionId = "222",
messageId = "222",
timestamp = OffsetDateTime.now(fixedClock)
)

init {
describe("PollOnCancellationReasonsResponseController") {
onCancellationReasonRepo.clear()
messageRepository.insertOne(MessageDao(id = entityContext.messageId, type = MessageDao.Type.Track))
onCancellationReasonRepo.insertMany(onCancellationReasonResponse())

context("when called for given message id") {
val onCancellationReasonCall = mockMvc
.perform(
MockMvcRequestBuilders.get("/protocol/response/v1/on_cancellation_reasons")
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.param("messageId", entityContext.messageId)
)

it("should respond with status ok") {
onCancellationReasonCall.andExpect(status().isOk)
}

it("should respond with all cancellation reasons responses in body") {
val results = onCancellationReasonCall.andReturn()
val body = results.response.contentAsString
val response: List<ProtocolOnCancellationReasons> = mapper.readValue(body)
response.size shouldBeExactly 2
response.forEach { it.context!!.bppId shouldBe entityContext.bppId }
}
}

context("when failure occurs during request processing") {
val mockOnPollService = mock<PollForResponseService<ProtocolOnCancellationReasons>> {
onGeneric { findResponses(any()) }.thenReturn(Either.Left(DatabaseError.OnRead))
}
val pollOnCancellationReasonResponseController = PollOnCancellationReasonResponseController(mockOnPollService, contextFactory)
it("should respond with failure") {
val response = pollOnCancellationReasonResponseController.findResponses(entityContext.messageId)
response.statusCode shouldBe DatabaseError.OnRead.status()
}
}
}
}

fun onCancellationReasonResponse(): List<OnCancellationReasonDao> {
val entityCancellationReasonsResponse = OnCancellationReasonDao(
context = entityContext,
message = OnCancellationReasonsMessageDao(
cancellationReasons = listOf(OnCancellationReasonsDescripterDao(
id = "item",
descriptor = DescriptorDao(name = "Item is cancelled")
))
)
)
return listOf(
entityCancellationReasonsResponse,
entityCancellationReasonsResponse,
entityCancellationReasonsResponse.copy(context = entityContext.copy(messageId = "123"))
)
}
}

0 comments on commit 8036db2

Please sign in to comment.