Skip to content

Commit

Permalink
test: rewrite kitchen pact on order service
Browse files Browse the repository at this point in the history
  • Loading branch information
jangjunha committed Sep 15, 2023
1 parent adf0c27 commit 89df428
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 31 deletions.
14 changes: 14 additions & 0 deletions eventuate-tram-test-util/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
plugins {
id("org.jetbrains.kotlin.jvm")
}

group = "me.jangjunha.ftgo"
version = "unspecified"

repositories {
mavenCentral()
}

dependencies {
implementation("io.eventuate.tram.sagas:eventuate-tram-sagas-orchestration-simple-dsl")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package me.jangjunha.ftgo.eventuate.tram.testutil

import io.eventuate.tram.messaging.common.Message

interface MessageReceiver {

fun receive(destination: String): Message
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package me.jangjunha.ftgo.eventuate.tram.testutil

import io.eventuate.common.id.IdGenerator
import io.eventuate.common.json.mapper.JSonMapper
import io.eventuate.tram.commands.common.Command
import io.eventuate.tram.commands.consumer.CommandWithDestination
import io.eventuate.tram.sagas.orchestration.CommandWithDestinationAndType
import io.eventuate.tram.sagas.orchestration.SagaCommandProducer
import io.eventuate.tram.sagas.simpledsl.CommandEndpoint

class SagaMessagingTestHelper(
private val messageReceiver: MessageReceiver,
private val sagaCommandProducer: SagaCommandProducer,
private val idGenerator: IdGenerator,
) {

fun <C : Command, R : Any> sendAndReceiveCommand(
commandEndpoint: CommandEndpoint<C>,
command: C,
replyClass: Class<R>,
sagaType: String
): R {
val sagaId = idGenerator.genId().asString()

val replyTo = "$sagaType-reply"
sagaCommandProducer.sendCommands(
sagaType,
sagaId,
mutableListOf(
CommandWithDestinationAndType.command(
CommandWithDestination(
commandEndpoint.commandChannel,
null,
command
)
)
),
replyTo
)

val response = messageReceiver.receive(replyTo)
return JSonMapper.fromJson(response.payload, replyClass)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package me.jangjunha.ftgo.kitchen_service.api;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import java.util.UUID;

public class CreateTicketReply {
Expand Down Expand Up @@ -29,4 +32,14 @@ public long getSequence() {
public void setSequence(long sequence) {
this.sequence = sequence;
}

@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}

@Override
public boolean equals(Object obj) {
return EqualsBuilder.reflectionEquals(this, obj);
}
}
2 changes: 2 additions & 0 deletions ftgo-order-service/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ dependencies {
requireCapability("me.jangjunha.ftgo:ftgo-pact-provider")
}
}
testImplementation(project(':eventuate-tram-test-util'))
testImplementation 'io.eventuate.tram.core:eventuate-tram-spring-in-memory'
testImplementation 'io.eventuate.tram.sagas:eventuate-tram-sagas-spring-in-memory'
testRuntimeOnly 'com.h2database:h2'

integrationTestImplementation 'io.eventuate.tram.core:eventuate-tram-spring-in-memory'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package me.jangjunha.ftgo.order_service
package me.jangjunha.ftgo.order_service.sagaparticipants

import au.com.dius.pact.consumer.dsl.Matchers
import au.com.dius.pact.consumer.dsl.PactDslJsonBody
Expand All @@ -10,17 +10,29 @@ import au.com.dius.pact.core.model.PactSpecVersion
import au.com.dius.pact.core.model.V4Interaction
import au.com.dius.pact.core.model.V4Pact
import au.com.dius.pact.core.model.annotations.Pact
import io.eventuate.common.json.mapper.JSonMapper
import io.eventuate.tram.consumer.common.NoopDuplicateMessageDetector
import io.eventuate.tram.spring.events.common.TramEventsCommonAutoConfiguration
import io.eventuate.tram.spring.inmemory.TramInMemoryCommonConfiguration
import au.com.dius.pact.core.model.v4.MessageContents
import com.ninjasquad.springmockk.MockkBean
import io.eventuate.common.id.IdGenerator
import io.eventuate.tram.messaging.common.Message
import io.eventuate.tram.messaging.common.MessageImpl
import io.eventuate.tram.sagas.orchestration.SagaCommandProducer
import io.eventuate.tram.sagas.spring.inmemory.TramSagaInMemoryConfiguration
import io.eventuate.tram.sagas.spring.orchestration.SagaOrchestratorConfiguration
import io.eventuate.tram.spring.commands.common.TramCommandsCommonAutoConfiguration
import io.eventuate.tram.spring.messaging.common.TramMessagingCommonAutoConfiguration
import io.mockk.every
import me.jangjunha.ftgo.eventuate.tram.testutil.MessageReceiver
import me.jangjunha.ftgo.eventuate.tram.testutil.SagaMessagingTestHelper
import me.jangjunha.ftgo.kitchen_service.api.CreateTicketReply
import me.jangjunha.ftgo.kitchen_service.api.TicketDetails
import me.jangjunha.ftgo.kitchen_service.api.commands.CreateTicket
import me.jangjunha.ftgo.order_service.sagas.createorder.CreateOrderSaga
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.extension.ExtendWith
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import
import java.util.*
Expand All @@ -32,7 +44,14 @@ import java.util.*
providerType = ProviderType.SYNCH_MESSAGE,
pactVersion = PactSpecVersion.V4
)
class KitchenPactTest {
class KitchenServiceProxyPactTest {

@MockkBean
lateinit var messageReceiver: MessageReceiver

@Autowired
lateinit var sagaMessagingTestHelper: SagaMessagingTestHelper


@Pact(consumer = "ftgo-order-service")
fun createTicketCommand(builder: SynchronousMessagePactBuilder): V4Pact = builder
Expand All @@ -56,13 +75,14 @@ class KitchenPactTest {
.uuid("orderId", "6f2d06a3-5dd2-4096-8644-6084d64eae35")
.uuid("restaurantId", "97e3c4c2-f336-4435-9314-ad1a633495df")
.`object`(
"ticketDetails")
.eachLike("lineItems")
.numberType("quantity", 2)
.stringType("menuItemId", "americano")
.stringType("name", "Americano")
.closeObject()!!
.closeArray()!!
"ticketDetails"
)
.eachLike("lineItems")
.numberType("quantity", 2)
.stringType("menuItemId", "americano")
.stringType("name", "Americano")
.closeObject()!!
.closeArray()!!
.closeObject()!!
)
}
Expand All @@ -84,33 +104,50 @@ class KitchenPactTest {
@Test
@PactTestFor(pactMethod = "createTicketCommand")
fun testCreateTicketCommand(message: V4Interaction.SynchronousMessages) {
// assert(message.request.metadata == mutableMapOf(
// Pair("command_type", "me.jangjunha.ftgo.kitchen_service.api.commands.CreateTicket"),
// Pair("command_saga_type", "me.jangjunha.ftgo.order_service.sagas.createorder.CreateOrderSaga"),
// Pair("command_saga_id", "87a5f784-2254-4996-bc94-53474f4cdee8"),
// Pair("command_reply_to", "me.jangjunha.ftgo.order_service.sagas.createorder.CreateOrderSaga-Reply"),
// ))
println(message.request.contents.valueAsString())
assert(JSonMapper.fromJson(message.request.contents.valueAsString(), CreateTicket::class.java) == CreateTicket(
val command = CreateTicket(
UUID.fromString("6f2d06a3-5dd2-4096-8644-6084d64eae35"),
TicketDetails(listOf(
TicketDetails.LineItem(2, "americano", "Americano"),
)),
UUID.fromString("97e3c4c2-f336-4435-9314-ad1a633495df"),
))
TicketDetails(
listOf(
TicketDetails.LineItem(2, "americano", "Americano"),
),
),
UUID.fromString("97e3c4c2-f336-4435-9314-ad1a633495df")
)
val expectedReply = CreateTicketReply(UUID.fromString("6f2d06a3-5dd2-4096-8644-6084d64eae35"), 101L)
val sagaType = CreateOrderSaga::class.java.name
every { messageReceiver.receive(eq("$sagaType-reply")) }.returns(buildMessage(message.response[0]))

// TODO: test consume
val reply = sagaMessagingTestHelper.sendAndReceiveCommand(
KitchenServiceProxy.create,
command,
CreateTicketReply::class.java,
sagaType
)
assert(reply == expectedReply)
}

private fun buildMessage(contents: MessageContents): Message = MessageImpl(
contents.contents.valueAsString(),
contents.metadata.mapValues { it.value.toString() },
)

@Configuration
@EnableAutoConfiguration
@Import(
value = [
NoopDuplicateMessageDetector::class,
TramMessagingCommonAutoConfiguration::class,
TramEventsCommonAutoConfiguration::class,
TramInMemoryCommonConfiguration::class,
TramCommandsCommonAutoConfiguration::class,
TramSagaInMemoryConfiguration::class,
SagaOrchestratorConfiguration::class,
]
)
class TestConfiguration
class TestConfiguration {

@Bean
fun sagaMessagingTestHelper(
messageReceiver: MessageReceiver,
sagaCommandProducer: SagaCommandProducer,
idGenerator: IdGenerator
) = SagaMessagingTestHelper(messageReceiver, sagaCommandProducer, idGenerator)
}
}
1 change: 1 addition & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ include 'eventuate-tram-producer-kafka'
include 'ftgo-order-history-service'
include 'ftgo-api-gateway'
include 'ftgo-pact'
include 'eventuate-tram-test-util'

0 comments on commit 89df428

Please sign in to comment.