diff --git a/config/combined-worker-compose.yaml b/config/combined-worker-compose.yaml index 3cfdacc6..10748a82 100644 --- a/config/combined-worker-compose.yaml +++ b/config/combined-worker-compose.yaml @@ -49,7 +49,7 @@ services: ] corda: - image: corda-os-docker.software.r3.com/corda-os-combined-worker-kafka:5.2.0.0-RC02 + image: corda-os-docker.software.r3.com/corda-os-combined-worker-kafka:5.2.0.0 depends_on: - postgresql - kafka diff --git a/contracts/src/test/kotlin/com/r3/developers/apples/contracts/AppleStampContractIssueCommandTest.kt b/contracts/src/test/kotlin/com/r3/developers/apples/contracts/AppleStampContractIssueCommandTest.kt deleted file mode 100644 index edeb17d9..00000000 --- a/contracts/src/test/kotlin/com/r3/developers/apples/contracts/AppleStampContractIssueCommandTest.kt +++ /dev/null @@ -1,119 +0,0 @@ -package com.r3.developers.apples.contracts - -import com.r3.corda.ledger.utxo.testing.buildTransaction -import com.r3.developers.apples.states.AppleStamp -import net.corda.v5.ledger.utxo.Command -import org.junit.jupiter.api.Test - -/** - * This class is an implementation of the ApplesContractTest which implements the ContractTest abstract class. - * The ContractTest class provides functions to easily perform unit tests on contracts. - * The ApplesContractTest adds additional default values for states as well as helper functions to make utxoLedgerTransactions. - * This allows us to test our implementation of contracts without having to trigger a workflow. - **/ - -// This specific class is involved with testing the scenarios involving the AppleStamp state and the AppleCommands.Issue command. -class AppleStampContractIssueCommandTest : ApplesContractTest() { - - /** - * All Tests must start with the @Test annotation. Tests can be run individually by running them with your IDE. - * Alternatively, tests can be grouped up and tested by running the test from the line defining the class above. - * If you need help to write tests, think of a happy path scenario and then think of every line of code in the contract - * where the transaction could fail. - * It helps to meaningfully name tests so that you know exactly what success case or specific error you are testing for. - **/ - - @Test - fun happyPath() { - // The following test builds a transaction that should pass all the contract verification checks. - // The buildTransaction function helps create a utxoLedgerTransaction that can be referenced for contract tests - val transaction = buildTransaction { - addCommand(AppleCommands.Issue()) - addOutputState(outputAppleStampState) - addSignatories(outputAppleStampStateParticipants) - } - /** - * The assertVerifies function is the general way to test if a contract test passes or fails a transaction. - * If the transaction is verified, then it means that the contract tests pass. - **/ - assertVerifies(transaction) - } - - @Test - fun outputContractStateSizeNotOne() { - // The following test builds a transaction that would fail due to not meeting the expectation that a transaction - // in this CorDapp for this state should only contain one output state. - val transaction = buildTransaction { - addCommand(AppleCommands.Issue()) - addOutputState(outputAppleStampState) - addOutputState(outputAppleStampState) - addSignatories(outputAppleStampStateParticipants) - } - /** - * The assertFailsWith function is the general way to test for unhappy path test cases contract tests. - * - * The transaction defined above will fail because the contract expects only one output state. However, we built - * a transaction with two output states. So we expect the transaction to fail, and only 'pass' our test if we - * can match the error message we expect. - * - * NOTE: the assertFailsWith method tests if the exact string of the error message matches the expected message - * to test if the string of the error message contains a substring within the error message, use the - * assertFailsWithMessageContaining() function using the same arguments. - **/ - assertFailsWith( - transaction, - "This transaction should only have one AppleStamp state as output" - ) - } - - @Test - fun blankStampDescription() { - // The following test builds a transaction that would fail due to having an empty stamp description string - val transaction = buildTransaction { - addCommand(AppleCommands.Issue()) - addOutputState( - // 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. - AppleStamp( - outputAppleStampStateId, - "", - outputAppleStampStateIssuer, - outputAppleStampStateHolder, - outputAppleStampStateParticipants - ) - ) - addSignatories(outputAppleStampStateParticipants) - } - assertFailsWith( - transaction, - "The output AppleStamp state should have clear description of the type of redeemable goods" - ) - } - - @Test - fun missingCommand() { - // The following test builds a transaction that would fail due to not having a command. - val transaction = buildTransaction { - addOutputState(outputAppleStampState) - addSignatories(outputAppleStampStateParticipants) - } - assertFailsWith(transaction, "List is empty.") - } - - @Test - fun unknownCommand() { - // The following test builds a transaction that would fail due to providing an invalid command. - class MyDummyCommand : Command; - - val transaction = buildTransaction { - addCommand(MyDummyCommand()) - addOutputState(outputAppleStampState) - addSignatories(outputAppleStampStateParticipants) - } - assertFailsWith( - transaction, - "Incorrect type of AppleStamp commands: com.r3.developers.apples.contracts." + - "AppleStampContractIssueCommandTest\$unknownCommand\$MyDummyCommand" - ) - } -} \ No newline at end of file diff --git a/contracts/src/test/kotlin/com/r3/developers/apples/contracts/ApplesContractTest.kt b/contracts/src/test/kotlin/com/r3/developers/apples/contracts/ApplesContractTest.kt deleted file mode 100644 index f79ce593..00000000 --- a/contracts/src/test/kotlin/com/r3/developers/apples/contracts/ApplesContractTest.kt +++ /dev/null @@ -1,85 +0,0 @@ -package com.r3.developers.apples.contracts - -import com.r3.corda.ledger.utxo.testing.ContractTest -import com.r3.corda.ledger.utxo.testing.buildTransaction -import com.r3.developers.apples.states.AppleStamp -import com.r3.developers.apples.states.BasketOfApples -import net.corda.v5.ledger.utxo.StateAndRef -import java.security.PublicKey -import java.util.UUID - -/** - * The following is the base implementation of the Contract Tests for the Apples CorDapp template tutorial. - * - * - The AppleContractTest abstract class implements the ContractTest class. - * - For full contract test coverage, we generally create a class for every command scenario for every state. - * - Each of these classes will implement the abstract class to incorporate ContractTest general testing functionality - * as well as the functionality specific for this CordApp tutorial example. - * - * In this case, we have 3 scenarios (you can refer to contract files for the apples tutorial): - * 1. AppleStamp state, AppleCommands.Issue command - * 2. BasketOfApples state, AppleCommand.PackBasket command - * 3. BasketOfApples state, AppleCommand.Redeem command - * - * The variables and methods within this abstract class are written to enable code re-use such that states are set up - * automatically so that you only need to worry about the logic of your contracts - **/ - -@Suppress("UnnecessaryAbstractClass", "UtilityClassWithPublicConstructor") -abstract class ApplesContractTest : ContractTest() { - - /** - * The following are implementations of default values for the AppleStamp state for contract testing. - * Some values such as the public keys already have default values implemented by the ContractTest class. - * for more information, navigate to their declaration - */ - // Default values for AppleStamp state - protected val outputAppleStampStateId: UUID = UUID.randomUUID() - protected val outputAppleStampStateStampDesc: String = "Can be exchanged for a single basket of apples" - protected val outputAppleStampStateIssuer: PublicKey = bobKey - protected val outputAppleStampStateHolder: PublicKey = daveKey - protected val outputAppleStampStateParticipants: List = listOf(bobKey, daveKey) - protected val outputAppleStampState: AppleStamp = AppleStamp( - outputAppleStampStateId, - outputAppleStampStateStampDesc, - outputAppleStampStateIssuer, - outputAppleStampStateHolder, - outputAppleStampStateParticipants - ) - - // Default values for BasketOfApples state - protected val outputBasketOfApplesStateDescription: String = "Golden delicious apples, picked on 11th May 2023" - protected val outputBasketOfApplesStateFarm: PublicKey = bobKey - protected val outputBasketOfApplesStateOwner: PublicKey = bobKey - protected val outputBasketOfApplesStateWeight: Int = 214 - protected val outputBasketOfApplesStateParticipants: List = listOf(bobKey) - internal val outputBasketOfApplesState: BasketOfApples = BasketOfApples( - outputBasketOfApplesStateDescription, - outputBasketOfApplesStateFarm, - outputBasketOfApplesStateOwner, - outputBasketOfApplesStateWeight, - outputBasketOfApplesStateParticipants - ) - - // Helper function to create input AppleStamp state when building a transaction for contract testing. - // The argument for outputState for this and the next helper function is set to the default apple state for happy path scenarios. - // To capture negative test cases or other edge cases, they are written within individual tests. - protected fun createInputStateAppleStamp(outputState: AppleStamp = outputAppleStampState): StateAndRef { - val transaction = buildTransaction { - addOutputState(outputState) - addCommand(AppleCommands.Issue()) - addSignatories(outputState.participants) - } - return transaction.toLedgerTransaction().getOutputStateAndRefs(AppleStamp::class.java).single() - } - - // Helper function to create input BasketOfApples state when building a transaction for contract testing. - protected fun createInputStateBasketOfApples(outputState: BasketOfApples = outputBasketOfApplesState): StateAndRef { - val transaction = buildTransaction { - addOutputState(outputState) - addCommand(AppleCommands.PackBasket()) - addSignatories(outputState.participants) - } - return transaction.toLedgerTransaction().getOutputStateAndRefs(BasketOfApples::class.java).single() - } -} \ No newline at end of file diff --git a/contracts/src/test/kotlin/com/r3/developers/apples/contracts/BasketOfApplesContractPackBasketCommandTest.kt b/contracts/src/test/kotlin/com/r3/developers/apples/contracts/BasketOfApplesContractPackBasketCommandTest.kt deleted file mode 100644 index 507d5fcf..00000000 --- a/contracts/src/test/kotlin/com/r3/developers/apples/contracts/BasketOfApplesContractPackBasketCommandTest.kt +++ /dev/null @@ -1,151 +0,0 @@ -package com.r3.developers.apples.contracts - -import com.r3.corda.ledger.utxo.testing.buildTransaction -import com.r3.developers.apples.states.BasketOfApples -import net.corda.v5.ledger.utxo.Command -import org.junit.jupiter.api.Test - -/** - * This class is an implementation of the ApplesContractTest which implements the ContractTest abstract class. - * The ContractTest class provides functions to easily perform unit tests on contracts. - * The ApplesContractTest adds additional default values for states as well as helper functions to make utxoLedgerTransactions. - * This allows us to test our implementation of contracts without having to trigger a workflow. - **/ - -// This specific class is involved with testing the scenarios involving the BasketOfApples state and the AppleCommands.PackBasket command. -class BasketOfApplesContractPackBasketCommandTest : ApplesContractTest() { - - /** - * All Tests must start with the @Test annotation. Tests can be run individually by running them with your IDE. - * Alternatively, tests can be grouped up and tested by running the test from the line defining the class above. - * If you need help to write tests, think of a happy path scenario and then think of every line of code in the contract - * where the transaction could fail. - * It helps to meaningfully name tests so that you know exactly what success case or specific error you are testing for. - **/ - - @Test - fun happyPath() { - // The following test builds a transaction that should pass all the contract verification checks. - // The buildTransaction function helps create a utxoLedgerTransaction that can be referenced for contract tests. - val transaction = buildTransaction { - addCommand(AppleCommands.PackBasket()) - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - /** - * The assertVerifies function is the general way to test if a contract test passes or fails a transaction. - * If the transaction is verified, then it means that the contract tests pass. - **/ - assertVerifies(transaction) - } - - @Test - fun outputContractStateSizeNotOne() { - // The following test builds a transaction that would fail due to not meeting the expectation that a transaction - // in this CorDapp for this state should only contain one output state. - val transaction = buildTransaction { - addCommand(AppleCommands.PackBasket()) - addOutputState(outputBasketOfApplesState) - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - /** - * The assertFailsWith function is the general way to test for unhappy path test cases contract tests. - * - * The transaction defined above will fail because the contract expects only one output state. However, we built - * a transaction with two output states. So we expect the transaction to fail, and only 'pass' our test if we - * can match the error message we expect. - * - * NOTE: the assertFailsWith method tests if the exact string of the error message matches the expected message - * to test if the string of the error message contains a substring within the error message, use the - * assertFailsWithMessageContaining() function using the same arguments. - **/ - assertFailsWith(transaction, "This transaction should only output one BasketOfApples state") - } - - @Test - fun blankDescription() { - // The following test builds a transaction that would fail due to having an empty stamp description string. - val transaction = buildTransaction { - addCommand(AppleCommands.PackBasket()) - addOutputState( - // 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. - BasketOfApples( - "", - outputBasketOfApplesStateFarm, - outputBasketOfApplesStateOwner, - outputBasketOfApplesStateWeight, - outputBasketOfApplesStateParticipants - ) - ) - addSignatories(outputBasketOfApplesStateParticipants) - } - assertFailsWith(transaction, "The output BasketOfApples state should have clear description of Apple product") - } - - @Test - fun basketWeightIsZero() { - // The following test builds a transaction that would fail due to having a weight not greater than 0 - val transaction = buildTransaction { - addCommand(AppleCommands.PackBasket()) - addOutputState( - BasketOfApples( - outputBasketOfApplesStateDescription, - outputBasketOfApplesStateFarm, - outputBasketOfApplesStateOwner, - 0, - outputBasketOfApplesStateParticipants - ) - ) - addSignatories(outputBasketOfApplesStateParticipants) - } - assertFailsWith(transaction, "The output BasketOfApples state should have non zero weight") - } - - @Test - fun basketWeightIsNegative() { - // The following test builds a transaction that would fail due to having a weight not greater than 0 - val transaction = buildTransaction { - addCommand(AppleCommands.PackBasket()) - addOutputState( - BasketOfApples( - outputBasketOfApplesStateDescription, - outputBasketOfApplesStateFarm, - outputBasketOfApplesStateOwner, - -1, - outputBasketOfApplesStateParticipants - ) - ) - addSignatories(outputBasketOfApplesStateParticipants) - } - assertFailsWith(transaction, "The output BasketOfApples state should have non zero weight") - } - - @Test - fun missingCommand() { - // The following test builds a transaction that would fail due to not having a command. - val transaction = buildTransaction { - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - assertFailsWith(transaction, "List is empty.") - } - - @Test - fun unknownCommand() { - // The following test builds a transaction that would fail due to providing an invalid command. - class MyDummyCommand : Command - - val transaction = buildTransaction { - addCommand(MyDummyCommand()) - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - assertFailsWith( - transaction, - "Incorrect type of BasketOfApples commands: com.r3.developers.apples.contracts." + - "BasketOfApplesContractPackBasketCommandTest\$unknownCommand\$MyDummyCommand" - ) - } -} \ No newline at end of file diff --git a/contracts/src/test/kotlin/com/r3/developers/apples/contracts/BasketOfApplesContractRedeemCommandTest.kt b/contracts/src/test/kotlin/com/r3/developers/apples/contracts/BasketOfApplesContractRedeemCommandTest.kt deleted file mode 100644 index 1cc68858..00000000 --- a/contracts/src/test/kotlin/com/r3/developers/apples/contracts/BasketOfApplesContractRedeemCommandTest.kt +++ /dev/null @@ -1,144 +0,0 @@ -package com.r3.developers.apples.contracts - -import com.r3.corda.ledger.utxo.testing.buildTransaction -import com.r3.developers.apples.states.AppleStamp -import com.r3.developers.apples.states.BasketOfApples -import org.junit.jupiter.api.Test - -/** - * This class is an implementation of the ApplesContractTest which implements the ContractTest abstract class. - * The ContractTest class provides functions to easily perform unit tests on contracts. - * The ApplesContractTest adds additional default values for states as well as helper functions to make utxoLedgerTransactions. - * This allows us to test our implementation of contracts without having to trigger a workflow. - **/ - -// This specific class is involved with testing the scenarios involving the BasketOfApples state and the AppleCommands.Redeem command. -class BasketOfApplesContractRedeemCommandTest : ApplesContractTest() { - - /** - * All Tests must start with the @Test annotation. Tests can be run individually by running them with your IDE. - * Alternatively, tests can be grouped up and tested by running the test from the line defining the class above. - * If you need help to write tests, think of a happy path scenario and then think of every line of code in the contract - * where the transaction could fail. - * It helps to meaningfully name tests so that you know exactly what success case or specific error you are testing for. - **/ - - @Test - fun happyPath() { - // The following test builds a transaction that should pass all the contract verification checks. - // The buildTransaction function helps create a utxoLedgerTransaction that can be referenced for contract tests - - // Notice the use of the helper functions written in ApplesContractTest to help build the transaction. - // This is because we need to refer to the state reference of an input state, which is not so easy to repeatably - // make without helper functions. - val inputAppleStampState = createInputStateAppleStamp() - val inputBasketOfApplesState = createInputStateBasketOfApples() - val transaction = buildTransaction { - addInputStates(listOf(inputAppleStampState.ref, inputBasketOfApplesState.ref)) - addCommand(AppleCommands.Redeem()) - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - /** - * The assertVerifies function is the general way to test if a contract test passes or fails a transaction. - * If the transaction is verified, then it means that the contract tests pass. - **/ - assertVerifies(transaction) - } - - @Test - fun inputContractStateSizeNotTwo() { - // The following test builds a transaction that would fail due to not meeting the expectation that a transaction - // in this CorDapp for this state should consume exactly two input states. - val inputAppleStampState = createInputStateAppleStamp() - val transaction = buildTransaction { - addInputState(inputAppleStampState.ref) - addCommand(AppleCommands.Redeem()) - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - /** - * The assertFailsWith function is the general way to test for unhappy path test cases contract tests. - * - * The transaction defined above will fail because the contract expects two input states. However, we built - * a transaction with one input states. So we expect the transaction to fail, and only 'pass' our test if we - * can match the error message we expect. - * - * NOTE: the assertFailsWith method tests if the exact string of the error message matches the expected message - * to test if the string of the error message contains a substring within the error message, use the - * assertFailsWithMessageContaining() function using the same arguments. - **/ - assertFailsWith(transaction, "This transaction should consume two states") - } - - @Test - fun twoAppleStampStateInputs() { - // The following test builds a transaction that would fail due to not meeting the expectation that a transaction - // must contain exactly one AppleStamp state and one BasketOfApplesState state. - val inputAppleStampState = createInputStateAppleStamp() - val transaction = buildTransaction { - addInputStates(listOf(inputAppleStampState.ref, inputAppleStampState.ref)) - addCommand(AppleCommands.Redeem()) - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - assertFailsWith( - transaction, - "This transaction should have exactly one AppleStamp and one BasketOfApples input state" - ) - } - - @Test - fun appleStampIssuerDifferentFromBasketFarm() { - // The following test builds a transaction that would fail due to having the issuer not matching the farm. - // This is because the issuer of the apple stamp should be the farm that grew the apples. - val inputAppleStampState = createInputStateAppleStamp( - AppleStamp( - outputAppleStampStateId, - outputAppleStampStateStampDesc, - aliceKey, - outputAppleStampStateHolder, - outputAppleStampStateParticipants - ) - ) - val inputBasketOfApplesState = createInputStateBasketOfApples() - val transaction = buildTransaction { - addInputStates(listOf(inputAppleStampState.ref, inputBasketOfApplesState.ref)) - addCommand(AppleCommands.Redeem()) - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - assertFailsWith( - transaction, - "The issuer of the Apple stamp should be the producing farm of this basket of apple" - ) - } - - @Test - fun basketWeightIsZero() { - // The following test builds a transaction that would fail due to asking to redeem a basket without a valid weight. - val inputAppleStampState = createInputStateAppleStamp() - val inputBasketOfApplesState = createInputStateBasketOfApples( - BasketOfApples( - outputBasketOfApplesStateDescription, - outputBasketOfApplesStateFarm, - outputBasketOfApplesStateOwner, - 0, - outputBasketOfApplesStateParticipants - ) - ) - val transaction = buildTransaction { - addInputStates(listOf(inputAppleStampState.ref, inputBasketOfApplesState.ref)) - addCommand(AppleCommands.Redeem()) - addOutputState(outputBasketOfApplesState) - addSignatories(outputBasketOfApplesStateParticipants) - } - assertFailsWith(transaction, "The basket of apple has to weigh more than 0") - } - - /** - * Note how this test suite does not contain tests to check for missing or invalid commands. - * This is because The class to test for BasketOfApples state and AppleCommands.PackBasket command already included - * tests for the same contract, so implementing it again would be redundantly testing the contract - **/ -} \ No newline at end of file diff --git a/contracts/src/test/kotlin/com/r3/developers/cordapptemplate/utxoexample/contracts/ChatContractCreateCommandTest.kt b/contracts/src/test/kotlin/com/r3/developers/cordapptemplate/utxoexample/contracts/ChatContractCreateCommandTest.kt deleted file mode 100644 index e662f55d..00000000 --- a/contracts/src/test/kotlin/com/r3/developers/cordapptemplate/utxoexample/contracts/ChatContractCreateCommandTest.kt +++ /dev/null @@ -1,197 +0,0 @@ -package com.r3.developers.cordapptemplate.utxoexample.contracts - -import com.r3.corda.ledger.utxo.testing.ContractTest -import com.r3.corda.ledger.utxo.testing.buildTransaction -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.CREATE_COMMAND_SHOULD_HAVE_NO_INPUT_STATES -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.CREATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.REQUIRE_SINGLE_COMMAND -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.UNKNOWN_COMMAND -import com.r3.developers.cordapptemplate.utxoexample.states.ChatState -import net.corda.v5.ledger.utxo.Command -import org.junit.jupiter.api.Test -import java.util.* - -/** - * This class is an implementation of ContractTest. This provides functions to easily perform unit tests on contracts. - * This allows us to unit test our implementation of contracts without having to trigger a workflow. - **/ - -// This specific class is involved with testing the scenarios involving the ChatState state and the Create command. -class ChatContractCreateCommandTest : ContractTest() { - - // The following are default values for states so that tests can easily refer and re-use them - private val outputChatStateChatName = "aliceChatName" - private val outputChatStateChatMessage = "aliceChatMessage" - internal val outputChatState = ChatState( - UUID.randomUUID(), - outputChatStateChatName, - aliceName, - outputChatStateChatMessage, - listOf(aliceKey, bobKey) - ) - - /** - * All Tests must start with the @Test annotation. Tests can be run individually by running them with your IDE. - * Alternatively, tests can be grouped up and tested by running the test from the line defining the class above. - * If you need help to write tests, think of a happy path scenario and then think of every line of code in the contract - * where the transaction could fail. - * It helps to meaningfully name tests so that you know exactly what success case or specific error you are testing for. - **/ - - @Test - fun happyPath() { - // The following test builds a transaction that should pass all the contract verification checks. - // The buildTransaction function helps create a utxoLedgerTransaction that can be referenced for contract tests - val transaction = buildTransaction { - addOutputState(outputChatState) - addCommand(ChatContract.Create()) - addSignatories(outputChatState.participants) - } - /** - * The assertVerifies function is the general way to test if a contract test passes or fails a transaction. - * If the transaction is verified, then it means that the contract tests pass. - **/ - assertVerifies(transaction) - } - - @Test - fun missingCommand() { - // The following test builds a transaction that would fail due to not having a command. - val transaction = buildTransaction { - addOutputState(outputChatState) - addSignatories(outputChatState.participants) - } - /** - * The assertFailsWith function is the general way to test for unhappy path test cases contract tests. - * - * The transaction defined above will fail because the transaction does not include a command, whilst the contract - * expected one. So, we expect the transaction to fail, and only 'pass' our test if we can match the error message - * we expect. - * - * NOTE: the assertFailsWith method tests if the exact string of the error message matches the expected message - * to test if the string of the error message contains a substring within the error message, use the - * assertFailsWithMessageContaining() function using the same arguments. - **/ - assertFailsWith(transaction, REQUIRE_SINGLE_COMMAND) - } - - @Test - fun shouldNotAcceptUnknownCommand() { - // The following test builds a transaction that would fail due to providing an invalid command. - class MyDummyCommand : Command - - val transaction = buildTransaction { - addOutputState(outputChatState) - addCommand(MyDummyCommand()) - addSignatories(outputChatState.participants) - } - - assertFailsWith(transaction, UNKNOWN_COMMAND) - } - - @Test - fun outputStateCannotHaveZeroParticipants() { - // The following test builds a transaction that would fail due to not providing participants, when the contract - // expects exactly two participants. - val state = ChatState( - UUID.randomUUID(), - "myChatName", - aliceName, - "myChatMessage", - emptyList() - ) - val transaction = buildTransaction { - addOutputState(state) - addCommand(ChatContract.Create()) - } - assertFailsWith(transaction, "Failed requirement: $OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS") - } - - @Test - fun outputStateCannotHaveOneParticipant() { - // The following test builds a transaction that would fail due to not providing the right number of participants. - // This test provides a list of only one participant, when the contract expects exactly two participants. - val state = ChatState( - UUID.randomUUID(), - "myChatName", - aliceName, - "myChatMessage", - listOf(aliceKey) - ) - val transaction = buildTransaction { - addOutputState(state) - addCommand(ChatContract.Create()) - } - assertFailsWith(transaction, "Failed requirement: $OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS") - } - - @Test - fun outputStateCannotHaveThreeParticipants() { - // The following test builds a transaction that would fail due to not providing the right number of participants. - // This test provides a list of three participants, when the contract expects exactly two participants. - val state = ChatState( - UUID.randomUUID(), - "myChatName", - aliceName, - "myChatMessage", - listOf(aliceKey, bobKey, charlieKey) - ) - val transaction = buildTransaction { - addOutputState(state) - addCommand(ChatContract.Create()) - } - assertFailsWith(transaction, "Failed requirement: $OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS") - } - - @Test - fun shouldBeSigned() { - // The following test builds a transaction that would fail due to not signing the transaction. - val transaction = buildTransaction { - addOutputState(outputChatState) - addCommand(ChatContract.Create()) - } - assertFailsWith(transaction, "Failed requirement: $TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS") - } - - @Test - fun cannotBeSignedByOnlyOneParticipant() { - // The following test builds a transaction that would fail due to being signed by only one participant and not - // all participants. - val transaction = buildTransaction { - addOutputState(outputChatState) - addCommand(ChatContract.Create()) - addSignatories(outputChatState.participants[0]) - } - assertFailsWith(transaction, "Failed requirement: $TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS") - } - - @Test - fun shouldNotIncludeInputState() { - // The following test builds a transaction that would fail due to providing an input state when the contract did - // not expect one - happyPath() // generate an existing state to search for - val existingState = ledgerService.findUnconsumedStatesByType(ChatState::class.java).first() // doesn't matter which as this will fail validation - val transaction = buildTransaction { - addInputState(existingState.ref) - addOutputState(outputChatState) - addCommand(ChatContract.Create()) - addSignatories(outputChatState.participants) - } - assertFailsWith(transaction, "Failed requirement: $CREATE_COMMAND_SHOULD_HAVE_NO_INPUT_STATES") - } - - @Test - fun shouldNotHaveTwoOutputStates() { - // The following test builds a transaction that would fail due to providing two output states when the contract - // only - val transaction = buildTransaction { - addOutputState(outputChatState) - addOutputState(outputChatState) - addCommand(ChatContract.Create()) - addSignatories(outputChatState.participants) - } - assertFailsWith(transaction, "Failed requirement: $CREATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE") - } -} \ No newline at end of file diff --git a/contracts/src/test/kotlin/com/r3/developers/cordapptemplate/utxoexample/contracts/ChatContractUpdateCommandTest.kt b/contracts/src/test/kotlin/com/r3/developers/cordapptemplate/utxoexample/contracts/ChatContractUpdateCommandTest.kt deleted file mode 100644 index e47d76c2..00000000 --- a/contracts/src/test/kotlin/com/r3/developers/cordapptemplate/utxoexample/contracts/ChatContractUpdateCommandTest.kt +++ /dev/null @@ -1,197 +0,0 @@ -package com.r3.developers.cordapptemplate.utxoexample.contracts - -import com.r3.corda.ledger.utxo.testing.ContractTest -import com.r3.corda.ledger.utxo.testing.buildTransaction -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.UPDATE_COMMAND_CHATNAME_SHOULD_NOT_CHANGE -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.UPDATE_COMMAND_ID_SHOULD_NOT_CHANGE -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.UPDATE_COMMAND_PARTICIPANTS_SHOULD_NOT_CHANGE -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_INPUT_STATE -import com.r3.developers.cordapptemplate.utxoexample.contracts.ChatContract.Companion.UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE -import com.r3.developers.cordapptemplate.utxoexample.states.ChatState -import net.corda.v5.ledger.utxo.StateAndRef -import org.junit.jupiter.api.Test -import java.util.* - -/** - * This class is an implementation of ContractTest. This provides functions to easily perform unit tests on contracts. - * This allows us to unit test our implementation of contracts without having to trigger a workflow. - **/ - -// This specific class is involved with testing the scenarios involving the ChatState state and the Update command. -class ChatContractUpdateCommandTest : ContractTest() { - - // The following is a helper function to create a ChatState with default values. - // This is done so that we can easily re-use this block of code when writing our tests that require an input state - @Suppress("UNCHECKED_CAST") - private fun createInitialChatState(): StateAndRef { - val outputState = ChatContractCreateCommandTest().outputChatState - val transaction = buildTransaction { - addOutputState(outputState) - addCommand(ChatContract.Create()) - addSignatories(outputState.participants) - } - transaction.toLedgerTransaction() - return transaction.outputStateAndRefs.first() as StateAndRef - } - - /** - * All Tests must start with the @Test annotation. Tests can be run individually by running them with your IDE. - * Alternatively, tests can be grouped up and tested by running the test from the line defining the class above. - * If you need help to write tests, think of a happy path scenario and then think of every line of code in the contract - * where the transaction could fail. - * It helps to meaningfully name tests so that you know exactly what success case or specific error you are testing for. - **/ - - @Test - fun happyPath() { - // The following test builds a transaction that should pass all the contract verification checks. - // The buildTransaction function helps create a utxoLedgerTransaction that can be referenced for contract tests - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState.updateMessage(bobName, "bobResponse") - val transaction = buildTransaction { - addInputState(existingState.ref) - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - addSignatories(updatedOutputChatState.participants) - } - /** - * The assertVerifies function is the general way to test if a contract test passes or fails a transaction. - * If the transaction is verified, then it means that the contract tests pass. - **/ - assertVerifies(transaction) - } - - @Test - fun shouldHaveOneInputState(){ - // The following test builds a transaction that would fail due to not providing a input state, when the contract - // expects exactly one input state - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState.updateMessage(bobName, "bobResponse") - val transaction = buildTransaction { - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - addSignatories(updatedOutputChatState.participants) - } - /** - * The assertFailsWith function is the general way to test for unhappy path test cases contract tests. - * - * NOTE: the assertFailsWith method tests if the exact string of the error message matches the expected message - * to test if the string of the error message contains a substring within the error message, use the - * assertFailsWithMessageContaining() function using the same arguments. - **/ - assertFailsWith(transaction, "Failed requirement: $UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_INPUT_STATE") - } - - @Test - fun shouldNotHaveTwoInputStates(){ - // The following test builds a transaction that would fail due to having two input states, when the contract - // expects exactly one. - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState.updateMessage(bobName, "bobResponse") - val transaction = buildTransaction { - addInputState(existingState.ref) - addInputState(existingState.ref) - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - addSignatories(updatedOutputChatState.participants) - } - assertFailsWith(transaction, "Failed requirement: $UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_INPUT_STATE") - } - - @Test - fun shouldNotHaveTwoOutputStates(){ - // The following test builds a transaction that would fail due to having two output states, when the contract - // expects exactly one. - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState.updateMessage(bobName, "bobResponse") - val transaction = buildTransaction { - addInputState(existingState.ref) - addOutputState(updatedOutputChatState) - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - addSignatories(updatedOutputChatState.participants) - } - assertFailsWith(transaction, "Failed requirement: $UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE") - } - - @Test - fun idShouldNotChange(){ - // The following test builds a transaction that would fail because the contract makes sure that the id of the - // output state does not change from the input state. - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState - .updateMessage(bobName, "bobResponse") - .copy(id = UUID.randomUUID()) - val transaction = buildTransaction { - addInputState(existingState.ref) - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - addSignatories(updatedOutputChatState.participants) - } - assertFailsWith(transaction, "Failed requirement: $UPDATE_COMMAND_ID_SHOULD_NOT_CHANGE") - } - - @Test - fun chatNameShouldNotChange(){ - // The following test builds a transaction that would fail because the contract makes sure that the chatName of - // the output state does not change from the chat name from the input state. - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState - .updateMessage(bobName, "bobResponse") - .copy(chatName = "newName") - val transaction = buildTransaction { - addInputState(existingState.ref) - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - addSignatories(updatedOutputChatState.participants) - } - assertFailsWith(transaction, "Failed requirement: $UPDATE_COMMAND_CHATNAME_SHOULD_NOT_CHANGE") - } - - @Test - fun participantsShouldNotChange(){ - // The following test builds a transaction that would fail because the contract makes sure that the list of - // participants from the output state does not change from the list of participants from the input state. - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState - .updateMessage(bobName, "bobResponse") - .copy(participants = listOf(bobKey, charlieKey)) // The input state lists 'Alice' and 'Bob' as the participants - val transaction = buildTransaction { - addInputState(existingState.ref) - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - addSignatories(updatedOutputChatState.participants) - } - assertFailsWith(transaction, "Failed requirement: $UPDATE_COMMAND_PARTICIPANTS_SHOULD_NOT_CHANGE") - } - - @Test - fun outputStateMustBeSigned() { - // The following test builds a transaction that would fail because it does not include signatories, where the - // contract expects all the participants to be signatories. - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState.updateMessage(bobName, "bobResponse") - val transaction = buildTransaction { - addInputState(existingState.ref) - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - } - assertFailsWith(transaction, "Failed requirement: $TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS") - } - - @Test - fun outputStateCannotBeSignedByOnlyOneParticipant() { - // The following test builds a transaction that would fail because it only includes one signatory, where the - // contract expects all the participants to be signatories. - val existingState = createInitialChatState() - val updatedOutputChatState = existingState.state.contractState.updateMessage(bobName, "bobResponse") - val transaction = buildTransaction { - addInputState(existingState.ref) - addOutputState(updatedOutputChatState) - addCommand(ChatContract.Update()) - addSignatories(updatedOutputChatState.participants[0]) - } - assertFailsWith(transaction, "Failed requirement: $TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS") - } -} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 3259bf9a..51fb3f11 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,17 +2,17 @@ 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.2.0.49-RC02 +cordaApiVersion=5.2.0.52 # 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.2.0.0-RC02 +cordaNotaryPluginsVersion=5.2.0.0 # Specify the version of the cordapp-cpb and cordapp-cpk plugins cordaPluginsVersion=7.0.4 # Specify the version of the Corda runtime Gradle plugin to use -cordaGradlePluginVersion=5.2.0.0-RC02 +cordaGradlePluginVersion=5.2.0.0 # Specify the name of the workflows module # This will be the name of the generated cpk and cpb files