From 7177aa4404627696ac7ee1701a83d6f1b4171743 Mon Sep 17 00:00:00 2001 From: Tony Lawson Date: Wed, 13 Dec 2023 14:10:16 +0000 Subject: [PATCH] ES-1585: Update template so regpack can build successfully (#119) * ES-1585: Update template so regpack can build successfully * ES-1585: Remove codeowners as there is no team --- .github/CODEOWNERS | 12 - .../ChatContractCreateCommandTest.kt | 32 --- gradle.properties | 12 +- workflows/build.gradle | 26 -- .../com/r3/developers/JsonSerializers.kt | 21 -- .../apples/workflows/ApplesFlowDriverTests.kt | 107 -------- .../workflows/MyFirstFlowDriverTest.kt | 88 ------- .../workflows/ChatFlowDriverTest.kt | 237 ------------------ 8 files changed, 4 insertions(+), 531 deletions(-) delete mode 100644 .github/CODEOWNERS delete mode 100644 workflows/src/test/kotlin/com/r3/developers/JsonSerializers.kt delete mode 100644 workflows/src/test/kotlin/com/r3/developers/apples/workflows/ApplesFlowDriverTests.kt delete mode 100644 workflows/src/test/kotlin/com/r3/developers/csdetemplate/flowexample/workflows/MyFirstFlowDriverTest.kt delete mode 100644 workflows/src/test/kotlin/com/r3/developers/csdetemplate/utxoexample/workflows/ChatFlowDriverTest.kt diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 76f1f80a..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,12 +0,0 @@ - -# Jenkins files should be audited by BLT -# Any changes to source code to be reviewed by dev ex - - -.ci/** @corda/blt - -*.gradle @corda/C5-developer-experience -gradle.properties @corda/C5-developer-experience - -*.kt @corda/C5-developer-experience -*.java @corda/C5-developer-experience diff --git a/contracts/src/test/kotlin/com/r3/developers/csdetemplate/utxoexample/contracts/ChatContractCreateCommandTest.kt b/contracts/src/test/kotlin/com/r3/developers/csdetemplate/utxoexample/contracts/ChatContractCreateCommandTest.kt index dff9440a..668de026 100644 --- a/contracts/src/test/kotlin/com/r3/developers/csdetemplate/utxoexample/contracts/ChatContractCreateCommandTest.kt +++ b/contracts/src/test/kotlin/com/r3/developers/csdetemplate/utxoexample/contracts/ChatContractCreateCommandTest.kt @@ -60,38 +60,6 @@ class ChatContractCreateCommandTest : ContractTest() { assertVerifies(transaction) } - @Test - fun addAttachmentsNotSupported() { - // The following transaction will fail due to the fact that we currently do not support the feature for attachments - // onto transactions for the mock ledger. - - // Where a specific piece of test data is used only once, it makes sense to create it within the test - // rather than at a class/parent class level. - val secureHash: SecureHash = object : SecureHash { - override fun getAlgorithm(): String { - return null.toString() - } - - override fun toHexString(): String { - return null.toString(); - } - } - val exception: Exception = assertThrows( - UnsupportedOperationException::class.java - ) { - ledgerService - .createTransactionBuilder() - .addAttachment(secureHash) - .addOutputState(outputChatState) - .addCommand(Create()) - .addSignatories(outputChatState.participants) - .toSignedTransaction() - } - val expectedMessage = "This method is not implemented for the mock ledger" - val actualMessage = exception.message - assertTrue(actualMessage!!.contains(expectedMessage)) - } - @Test fun missingCommand() { // The following test builds a transaction that would fail due to not having a command. diff --git a/gradle.properties b/gradle.properties index 44418a4e..37043155 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,19 +2,15 @@ kotlin.code.style=official # Specify the version of the Corda-API to use. # This needs to match the version supported by the Corda Cluster the CorDapp will run on. -cordaApiVersion=5.1.0.12-HC03 +cordaApiVersion=5.1.0.39 # Specify the version of the notary plugins to use. # Currently packaged as part of corda-runtime-os, so should be set to a corda-runtime-os version. -cordaNotaryPluginsVersion=5.1.0.0-HC03 +cordaNotaryPluginsVersion=5.1.0.0 # Specify the version of the Combined Worker to use # Currently packaged as part of corda-runtime-os, so should be set to a corda-runtime-os version. -combinedWorkerJarVersion=5.1.0.0-HC03 - -# Specify the version of the Corda Driver to use for testing -# Currently packaged as part of corda-runtime-os, so should be set to a corda-runtime-os version. -cordaDriverVersion=5.1.0-DRIVER.0-+ +combinedWorkerJarVersion=5.1.0.0 # Specify the version of the cordapp-cpb and cordapp-cpk plugins cordaPluginsVersion=7.0.3 @@ -58,7 +54,7 @@ mockitoKotlinVersion=4.0.0 mockitoVersion=4.6.1 hamcrestVersion=2.2 assertjVersion = 3.24.1 -contractTestingVersion=0.9.1-beta-+ +contractTestingVersion=1.0.0-beta-+ jacksonVersion=2.15.2 slf4jVersion=1.7.36 diff --git a/workflows/build.gradle b/workflows/build.gradle index ad218fd8..761e10c5 100644 --- a/workflows/build.gradle +++ b/workflows/build.gradle @@ -61,32 +61,6 @@ dependencies { testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion" testImplementation "org.assertj:assertj-core:$assertjVersion" testImplementation "com.fasterxml.jackson.module:jackson-module-kotlin:$jacksonVersion" - testImplementation "net.corda:corda-driver:$cordaDriverVersion" - testRuntimeOnly "net.corda:corda-driver-engine:$cordaDriverVersion" - testRuntimeOnly files(configurations.archives.artifacts.files) - testRuntimeOnly files("${System.getProperty("user.home")}/$cordaBinariesDirectory/notaryServer/notary-plugin-non-validating-server-$cordaNotaryPluginsVersion-package.cpb") -} - -tasks.withType(Test).configureEach { - dependsOn(':getNotaryServerCPB') - doFirst { - jvmArgs '--add-opens', 'java.base/java.lang=ALL-UNNAMED', - '--add-opens', 'java.base/java.lang.invoke=ALL-UNNAMED', - '--add-opens', 'java.base/java.nio=ALL-UNNAMED', - '--add-opens', 'java.base/java.time=ALL-UNNAMED', - '--add-opens', 'java.base/java.util=ALL-UNNAMED' - - systemProperty 'co.paralleluniverse.fibers.verifyInstrumentation', true - systemProperty 'java.io.tmpdir', buildDir.absolutePath - - systemProperty 'org.slf4j.simpleLogger.defaultLogLevel', 'info' - systemProperty 'org.slf4j.simpleLogger.dateTimeFormat', 'yyyy-MM-dd HH:mm:ss:SSS Z' - systemProperty 'org.slf4j.simpleLogger.showDateTime', true - systemProperty 'org.slf4j.simpleLogger.showShortLogName', true - systemProperty 'org.slf4j.simpleLogger.showThreadName', false - systemProperty 'org.slf4j.simpleLogger.logFile', 'System.out' - systemProperty 'org.slf4j.simpleLogger.log.org.apache.aries.spifly.BaseActivator', 'OFF' - } } // The CordApp section. diff --git a/workflows/src/test/kotlin/com/r3/developers/JsonSerializers.kt b/workflows/src/test/kotlin/com/r3/developers/JsonSerializers.kt deleted file mode 100644 index e5e1e4f5..00000000 --- a/workflows/src/test/kotlin/com/r3/developers/JsonSerializers.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.r3.developers - -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonDeserializer -import com.fasterxml.jackson.databind.JsonSerializer -import com.fasterxml.jackson.databind.SerializerProvider -import net.corda.v5.base.types.MemberX500Name - -object MemberX500NameSerializer : JsonSerializer() { - override fun serialize(value: MemberX500Name, generator: JsonGenerator, provider: SerializerProvider?) { - generator.writeString(value.toString()) - } -} - -object MemberX500NameDeserializer : JsonDeserializer() { - override fun deserialize(parser: JsonParser, ctxt: DeserializationContext?): MemberX500Name { - return MemberX500Name.parse(parser.text) - } -} diff --git a/workflows/src/test/kotlin/com/r3/developers/apples/workflows/ApplesFlowDriverTests.kt b/workflows/src/test/kotlin/com/r3/developers/apples/workflows/ApplesFlowDriverTests.kt deleted file mode 100644 index c30f9f39..00000000 --- a/workflows/src/test/kotlin/com/r3/developers/apples/workflows/ApplesFlowDriverTests.kt +++ /dev/null @@ -1,107 +0,0 @@ -package com.r3.developers.apples.workflows - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.module.SimpleModule -import com.fasterxml.jackson.module.kotlin.KotlinModule -import com.r3.developers.MemberX500NameDeserializer -import com.r3.developers.MemberX500NameSerializer -import net.corda.testing.driver.DriverDSL -import net.corda.testing.driver.DriverNodes -import net.corda.testing.driver.runFlow -import net.corda.v5.base.types.MemberX500Name -import net.corda.virtualnode.VirtualNodeInfo -import org.assertj.core.api.Assertions.assertThat -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.extension.RegisterExtension -import org.junit.jupiter.api.fail -import org.slf4j.LoggerFactory -import java.util.UUID - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -class ApplesFlowDriverTests { - - private val logger = LoggerFactory.getLogger(ApplesFlowDriverTests::class.java) - private val alice = MemberX500Name.parse("CN=Alice, OU=Application, O=R3, L=London, C=GB") - private val bob = MemberX500Name.parse("CN=Bob, OU=Application, O=R3, L=London, C=GB") - private val notary = MemberX500Name.parse("CN=Notary, OU=Application, O=R3, L=London, C=GB") - private val jsonMapper = ObjectMapper().apply { - registerModule(KotlinModule.Builder().build()) - - val module = SimpleModule().apply { - addSerializer(MemberX500Name::class.java, MemberX500NameSerializer) - addDeserializer(MemberX500Name::class.java, MemberX500NameDeserializer) - } - registerModule(module) - } - - @Suppress("JUnitMalformedDeclaration") - @RegisterExtension - private val driver = DriverNodes(alice, bob).withNotary(notary, 1).forAllTests() - - private lateinit var vNodes: Map - - @BeforeAll - fun setup() { - vNodes = driver.let { dsl -> - dsl.startNodes(setOf(alice, bob)) - dsl.nodesFor("workflows") - } - assertThat(vNodes).withFailMessage("Failed to populate vNodes").isNotEmpty() - } - - @Test - fun `test that CreateAndIssueAppleStampFlow returns correct message`() { - val stampId = createAndIssueAppleStamp("Stamp # 0001", bob, alice) - logger.info("result: {}", stampId) - } - - @Test - fun `test that PackageApplesFlow is successful`() { - val txId = packageApples("Basket of apples # 0001", 100, alice) - logger.info("PackageApples: {}", txId) - } - - @Test - fun `test that RedeemApplesFlow is successful`() { - val stampId = createAndIssueAppleStamp("Stamp # 0002", bob, alice)!! - packageApples("Basket of apples # 0002", 350, alice) - val redeemApplesFlowArgs = RedeemApplesFlow.RedeemApplesRequest(bob, notary, stampId) - val result = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail("Missing vNode for Alice")) { - jsonMapper.writeValueAsString(redeemApplesFlowArgs) - } - } - logger.info("RedeemApplesRequest returns {}", result) - assertThat(result) - .withFailMessage { "Not SHA-256 hash: '$result'" } - .isNotNull().startsWith("SHA-256D:") - } - - private fun packageApples(description: String, weight: Int, packer: MemberX500Name): String { - val packageApplesFlowArgs = PackageApplesFlow.PackApplesRequest(description, weight, notary) - val result = driver.let { dsl: DriverDSL -> - dsl.runFlow(vNodes[packer] ?: fail(String.format("Missing vNode {}", jsonMapper.writeValueAsString(packer)))) { - jsonMapper.writeValueAsString(packageApplesFlowArgs) - } - } ?: fail("PackageApples returned null") - assertThat(result) - .withFailMessage { "Not SHA-256 hash: '$result'" } - .startsWith("SHA-256D:") - return result - } - - private fun createAndIssueAppleStamp(description: String, member: MemberX500Name, issuer: MemberX500Name): UUID? { - val createAndIssueFlowArgs = CreateAndIssueAppleStampFlow.CreateAndIssueAppleStampRequest(description, member, notary) - val result = driver.let { dsl -> - dsl.runFlow( - vNodes[issuer] ?: fail(String.format("Missing vNode {}", jsonMapper.writeValueAsString(issuer))) - ) { - jsonMapper.writeValueAsString(createAndIssueFlowArgs) - } - } - assertThat(result).withFailMessage("CreateAndIssueAppleStampFlow returned null").isNotNull() - return UUID.fromString(result) - } -} diff --git a/workflows/src/test/kotlin/com/r3/developers/csdetemplate/flowexample/workflows/MyFirstFlowDriverTest.kt b/workflows/src/test/kotlin/com/r3/developers/csdetemplate/flowexample/workflows/MyFirstFlowDriverTest.kt deleted file mode 100644 index 5df277ce..00000000 --- a/workflows/src/test/kotlin/com/r3/developers/csdetemplate/flowexample/workflows/MyFirstFlowDriverTest.kt +++ /dev/null @@ -1,88 +0,0 @@ -package com.r3.developers.csdetemplate.flowexample.workflows - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.module.SimpleModule -import com.fasterxml.jackson.module.kotlin.KotlinModule -import com.r3.developers.MemberX500NameDeserializer -import com.r3.developers.MemberX500NameSerializer -import net.corda.testing.driver.DriverNodes -import net.corda.testing.driver.EachTestDriver -import net.corda.testing.driver.runFlow -import net.corda.v5.base.types.MemberX500Name -import net.corda.virtualnode.VirtualNodeInfo -import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.api.Assertions.fail -import org.junit.jupiter.api.BeforeEach -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS -import org.junit.jupiter.api.extension.RegisterExtension - -@TestInstance(PER_CLASS) -class MyFirstFlowDriverTest { - - /** - * Step 1. - * Declare member identities needed for the tests - * As well as any other data you want to share across tests - */ - - private val alice = MemberX500Name.parse("CN=Alice, OU=Application, O=R3, L=London, C=GB") - private val bob = MemberX500Name.parse("CN=Bob, OU=Application, O=R3, L=London, C=GB") - private val jsonMapper = ObjectMapper().apply { - registerModule(KotlinModule.Builder().build()) - - val module = SimpleModule().apply { - addSerializer(MemberX500Name::class.java, MemberX500NameSerializer) - addDeserializer(MemberX500Name::class.java, MemberX500NameDeserializer) - } - registerModule(module) - } - - private lateinit var vNodes: Map - - /** - * Step 2. - * Declare a test driver - * Choose between an [EachTestDriver] which will create a fresh instance for each test. Use this if you are worried about tests clashing. - * Or an [AllTestsDriver] which will only be created once, and reused for all tests. Use this when tests can co-exist as the tests will run faster. - */ - - @Suppress("JUnitMalformedDeclaration") - @RegisterExtension - private val driver = DriverNodes(alice, bob).forEachTest() - - /** - * Step 3. - * Start the nodes - */ - - @BeforeEach - fun setup() { - vNodes = driver.let { dsl -> - dsl.startNodes(setOf(alice, bob)) - dsl.nodesFor("workflows") - } - assertThat(vNodes).withFailMessage("Failed to populate vNodes").isNotEmpty() - } - - /** - * Step 4. - * Write some tests. - * The FlowDriver runs your flows, and returns the output result for you to assert on. - */ - - @Test - fun `test that MyFirstFlow returns correct message`() { - val result = driver.let { dsl -> - // Run the flow, using the initiating flow class, from Alice to Bob - dsl.runFlow(vNodes[alice] ?: fail("Missing vNode for Alice")) { - // serialise request body as JSON in a string - jsonMapper.writeValueAsString(MyFirstFlowStartArgs(bob)) - } - } ?: fail("result should not be null") - - // Assert the flow response is the expected message - assertThat(result).isEqualTo("Hello Alice, best wishes from Bob") - } -} diff --git a/workflows/src/test/kotlin/com/r3/developers/csdetemplate/utxoexample/workflows/ChatFlowDriverTest.kt b/workflows/src/test/kotlin/com/r3/developers/csdetemplate/utxoexample/workflows/ChatFlowDriverTest.kt deleted file mode 100644 index baf9caec..00000000 --- a/workflows/src/test/kotlin/com/r3/developers/csdetemplate/utxoexample/workflows/ChatFlowDriverTest.kt +++ /dev/null @@ -1,237 +0,0 @@ -package com.r3.developers.csdetemplate.utxoexample.workflows - -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.module.SimpleModule -import com.fasterxml.jackson.module.kotlin.KotlinModule -import com.fasterxml.jackson.module.kotlin.readValue -import com.r3.developers.MemberX500NameDeserializer -import com.r3.developers.MemberX500NameSerializer -import net.corda.testing.driver.DriverNodes -import net.corda.testing.driver.EachTestDriver -import net.corda.testing.driver.runFlow -import net.corda.v5.base.types.MemberX500Name -import net.corda.virtualnode.VirtualNodeInfo -import org.assertj.core.api.Assertions.assertThat -import org.assertj.core.api.Assertions.fail -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.extension.RegisterExtension -import org.slf4j.LoggerFactory -import java.util.* - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -class ChatFlowDriverTest { - - /** - * Step 1. - * Declare member identities needed for the tests - * As well as any other data you want to share across tests - */ - - private val logger = LoggerFactory.getLogger(this::class.java) - private val alice = MemberX500Name.parse("CN=Alice, OU=Application, O=R3, L=London, C=GB") - private val bob = MemberX500Name.parse("CN=Bob, OU=Application, O=R3, L=London, C=GB") - private val notary = MemberX500Name.parse("CN=Notary, OU=Application, O=R3, L=London, C=GB") - private val jsonMapper = ObjectMapper().apply { - registerModule(KotlinModule.Builder().build()) - - val module = SimpleModule().apply { - addSerializer(MemberX500Name::class.java, MemberX500NameSerializer) - addDeserializer(MemberX500Name::class.java, MemberX500NameDeserializer) - } - registerModule(module) - } - - private lateinit var vNodes: Map - - // avoid repeating String literals - private val noBody = "" - private val missingAliceVNode = "Missing vNode for Alice" - private val missingBobVNode = "Missing vNode for Bob" - private val resultShouldNotBeNull = "result should not be null" - private val startOfTransactionId = "SHA-256D:" - - /** - * Step 2. - * Declare a test driver - * Choose between an [EachTestDriver] which will create a fresh instance for each test. Use this if you are worried about tests clashing. - * Or an [AllTestsDriver] which will only be created once, and reused for all tests. Use this when tests can co-exist as the tests will run faster. - */ - - @Suppress("JUnitMalformedDeclaration") - @RegisterExtension - private val driver = DriverNodes(alice, bob).withNotary(notary, 1).forAllTests() - - /** - * Step 3. - * Start the nodes - */ - - @BeforeAll - fun setup() { - vNodes = driver.let { dsl -> - dsl.startNodes(setOf(alice, bob)) - dsl.nodesFor("workflows") - } - assertThat(vNodes).withFailMessage("Failed to populate vNodes").isNotEmpty() - } - - /** - * Step 4. - * Write some tests. - * The FlowDriver runs your flows, and returns the output result for you to assert on. - */ - - @Test - fun `test that CreateNewChatFlow returns correct message`() { - val chatFlowArgs = CreateNewChatFlowArgs("myChatName", "Hello Bob, from Alice", bob.toString()) - - val result = driver.let { dsl -> - // Run the flow, using the initiating flow class, from Alice to Bob - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { - // serialise request body as JSON in a string - jsonMapper.writeValueAsString(chatFlowArgs) - } - } ?: fail(resultShouldNotBeNull) - - // Assert the flow response is the expected value - // example of returned value SHA-256D:4A577FF830E12BCA050F70760E4739192F2C561BCB9FB5CAF3B384ECB2DD1AE3 - assertThat(result).contains(startOfTransactionId) - } - - @Test - fun `test that listChatsFlow returns correct values`() { - // Get the current count before we start - val listOfChatMessages1 = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { noBody } - } ?: fail(resultShouldNotBeNull) - val sizeBeforeSendingMessage = jsonMapper.readValue>(listOfChatMessages1).size - - // Send a new message, so there is another chat in list of chats - `test that CreateNewChatFlow returns correct message`() - - // Get the latest count, and assert it has increased - val listOfChatMessages2 = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { noBody } - } ?: fail(resultShouldNotBeNull) - val listAfterSendingMessage: List = jsonMapper.readValue(listOfChatMessages2) - val sizeAfterSendingMessage = listAfterSendingMessage.size - assertThat(sizeAfterSendingMessage).isGreaterThan(sizeBeforeSendingMessage) - - // Assert the response contains all the values - val firstMessageInList = listAfterSendingMessage.first() - assertThat(firstMessageInList).hasNoNullFieldsOrProperties() - } - - @Test - fun `test that UpdateChatFlow returns correct values`() { - // Send a message - `test that CreateNewChatFlow returns correct message`() - - // List the messages and retrieve the id - val listMessagesResult = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { noBody } - } ?: fail(resultShouldNotBeNull) - val messageList: List = jsonMapper.readValue(listMessagesResult) - val firstMessageId = messageList.last().id - - // Update the message - val expectedMessage = "Updated message" - val updateChatFlowArgs = UpdateChatFlowArgs(firstMessageId, expectedMessage) - val updateMessageResult = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { - jsonMapper.writeValueAsString(updateChatFlowArgs) - } - } ?: fail(resultShouldNotBeNull) - assertThat(updateMessageResult).contains(startOfTransactionId) - - // List the message and validate updated message is present - val listUpdatedMessagesResult = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { noBody } - } ?: fail(resultShouldNotBeNull) - val updatedMessageList: List = jsonMapper.readValue(listUpdatedMessagesResult) - val updatedMessageValue = updatedMessageList.single { - it.id == firstMessageId - }.message - assertThat(updatedMessageValue).isEqualTo(expectedMessage) - } - - @Test - fun `test that getChatFlow returns correct values`() { - // Alice sends a message to Bob - `test that CreateNewChatFlow returns correct message`() - - // List the messages and retrieve the id - val listMessagesResult = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { noBody } - } ?: fail(resultShouldNotBeNull) - val messageList: List = jsonMapper.readValue(listMessagesResult) - val firstMessageId = messageList.last().id - - // Get the latest message - val getChatFlowArgs = GetChatFlowArgs(firstMessageId, 1) - val gatheredMessageResult1 = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { - jsonMapper.writeValueAsString(getChatFlowArgs) - } - } ?: fail(resultShouldNotBeNull) - val listOfMessages1: List = jsonMapper.readValue(gatheredMessageResult1) - assertThat(listOfMessages1.size).isEqualTo(1) - val message1Values = listOfMessages1.single() - assertThat(message1Values.messageFrom).isEqualTo(alice.toString()) - - // Alice sends an updated message to Bob - val secondMessageExpectedValue = "Hello Bob, It's Alice again" - val aliceUpdatedMessageArgs = UpdateChatFlowArgs(firstMessageId, secondMessageExpectedValue) - driver.run { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { - jsonMapper.writeValueAsString(aliceUpdatedMessageArgs) - } - } - - // Get the latest message and assert the message content is updated value - val gatheredMessageResult2 = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { - jsonMapper.writeValueAsString(getChatFlowArgs) - } - } ?: fail(resultShouldNotBeNull) - val listOfMessages2: List = jsonMapper.readValue(gatheredMessageResult2) - assertThat(listOfMessages2.size).isEqualTo(1) - val message2Values = listOfMessages2.single() - assertThat(message2Values.messageFrom).isEqualTo(alice.toString()) - assertThat(message2Values.message).isEqualTo(secondMessageExpectedValue) - - // Bob sends an update message to Alice - val thirdMessageExpectedValue = "Hello Alice, I've been busy. Bob" - val bobUpdatedMessageArgs = UpdateChatFlowArgs(firstMessageId, thirdMessageExpectedValue) - driver.run { dsl -> - dsl.runFlow(vNodes[bob] ?: fail(missingBobVNode)) { - jsonMapper.writeValueAsString(bobUpdatedMessageArgs) - } - } - - // Get the latest message and assert the message content is updated value - val gatheredMessageResult3 = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { - jsonMapper.writeValueAsString(getChatFlowArgs) - } - } ?: fail(resultShouldNotBeNull) - val listOfMessages3: List = jsonMapper.readValue(gatheredMessageResult3) - assertThat(listOfMessages3.size).isEqualTo(1) - val message3Values = listOfMessages3.single() - assertThat(message3Values.messageFrom).isEqualTo(bob.toString()) - assertThat(message3Values.message).isEqualTo(thirdMessageExpectedValue) - - // Get full back-chain - val getFullChatFlowArgs = GetChatFlowArgs(firstMessageId, 9999) - val gatheredAllMessagesResult = driver.let { dsl -> - dsl.runFlow(vNodes[alice] ?: fail(missingAliceVNode)) { - jsonMapper.writeValueAsString(getFullChatFlowArgs) - } - } ?: fail(resultShouldNotBeNull) - val listOfAllMessages: List = jsonMapper.readValue(gatheredAllMessagesResult) - logger.info("listOfAllMessages : {}", listOfAllMessages) - assertThat(listOfAllMessages.size).isEqualTo(3) - } -} \ No newline at end of file