CORE-14586: Utxo Example Contract Tests (#51)
* CORE-14586: Utxo Example Contract Tests * CORE-14586: Use beta builds rather than alpha builds * CORE-14586: Add signing constraint
This commit is contained in:
		
							parent
							
								
									7b3144001d
								
							
						
					
					
						commit
						20e3dd38b3
					
				@ -55,6 +55,7 @@ dependencies {
 | 
				
			|||||||
    testImplementation "org.mockito:mockito-core:$mockitoVersion"
 | 
					    testImplementation "org.mockito:mockito-core:$mockitoVersion"
 | 
				
			||||||
    testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
 | 
					    testImplementation "org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion"
 | 
				
			||||||
    testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
 | 
					    testImplementation "org.hamcrest:hamcrest-library:$hamcrestVersion"
 | 
				
			||||||
 | 
					    testImplementation "com.r3.corda.ledger.utxo:contract-testing:$contractTestingVersion"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// The CordApp section.
 | 
					// The CordApp section.
 | 
				
			||||||
 | 
				
			|||||||
@ -13,37 +13,54 @@ public class ChatContract implements Contract {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private final static Logger log = LoggerFactory.getLogger(ChatContract.class);
 | 
					    private final static Logger log = LoggerFactory.getLogger(ChatContract.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Use constants to hold the error messages
 | 
				
			||||||
 | 
					    // This allows the tests to use them, meaning if they are updated you won't need to fix tests just because the wording was updated
 | 
				
			||||||
 | 
					    static final String REQUIRE_SINGLE_COMMAND = "Require a single command.";
 | 
				
			||||||
 | 
					    static final String UNKNOWN_COMMAND = "Unsupported command";
 | 
				
			||||||
 | 
					    static final String OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS = "The output state should have two and only two participants.";
 | 
				
			||||||
 | 
					    static final String TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS = "The transaction should have been signed by both participants.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static final String CREATE_COMMAND_SHOULD_HAVE_NO_INPUT_STATES = "When command is Create there should be no input states.";
 | 
				
			||||||
 | 
					    static final String CREATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE = "When command is Create there should be one and only one output state.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static final String UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_INPUT_STATE = "When command is Update there should be one and only one input state.";
 | 
				
			||||||
 | 
					    static final String UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE = "When command is Update there should be one and only one output state.";
 | 
				
			||||||
 | 
					    static final String UPDATE_COMMAND_ID_SHOULD_NOT_CHANGE = "When command is Update id must not change.";
 | 
				
			||||||
 | 
					    static final String UPDATE_COMMAND_CHATNAME_SHOULD_NOT_CHANGE = "When command is Update chatName must not change.";
 | 
				
			||||||
 | 
					    static final String UPDATE_COMMAND_PARTICIPANTS_SHOULD_NOT_CHANGE = "When command is Update participants must not change.";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static class Create implements Command { }
 | 
					    public static class Create implements Command { }
 | 
				
			||||||
    public static class Update implements Command { }
 | 
					    public static class Update implements Command { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public void verify(UtxoLedgerTransaction transaction) {
 | 
					    public void verify(UtxoLedgerTransaction transaction) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        requireThat( transaction.getCommands().size() == 1, "Require a single command.");
 | 
					        requireThat( transaction.getCommands().size() == 1, REQUIRE_SINGLE_COMMAND);
 | 
				
			||||||
        Command command = transaction.getCommands().get(0);
 | 
					        Command command = transaction.getCommands().get(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ChatState output = transaction.getOutputStates(ChatState.class).get(0);
 | 
					        ChatState output = transaction.getOutputStates(ChatState.class).get(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        requireThat(output.getParticipants().size() == 2, "The output state should have two and only two participants.");
 | 
					        requireThat(output.getParticipants().size() == 2, OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS);
 | 
				
			||||||
 | 
					        requireThat(transaction.getSignatories().containsAll(output.getParticipants()), TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(command.getClass() == Create.class) {
 | 
					        if(command.getClass() == Create.class) {
 | 
				
			||||||
            requireThat(transaction.getInputContractStates().isEmpty(), "When command is Create there should be no input states.");
 | 
					            requireThat(transaction.getInputContractStates().isEmpty(), CREATE_COMMAND_SHOULD_HAVE_NO_INPUT_STATES);
 | 
				
			||||||
            requireThat(transaction.getOutputContractStates().size() == 1, "When command is Create there should be one and only one output state.");
 | 
					            requireThat(transaction.getOutputContractStates().size() == 1, CREATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if(command.getClass() == Update.class) {
 | 
					        else if(command.getClass() == Update.class) {
 | 
				
			||||||
            requireThat(transaction.getInputContractStates().size() == 1, "When command is Update there should be one and only one input state.");
 | 
					            requireThat(transaction.getInputContractStates().size() == 1, UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_INPUT_STATE);
 | 
				
			||||||
            requireThat(transaction.getOutputContractStates().size() == 1, "When command is Update there should be one and only one output state.");
 | 
					            requireThat(transaction.getOutputContractStates().size() == 1, UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            ChatState input = transaction.getInputStates(ChatState.class).get(0);
 | 
					            ChatState input = transaction.getInputStates(ChatState.class).get(0);
 | 
				
			||||||
            requireThat(input.getId().equals(output.getId()), "When command is Update id must not change.");
 | 
					            requireThat(input.getId().equals(output.getId()), UPDATE_COMMAND_ID_SHOULD_NOT_CHANGE);
 | 
				
			||||||
            requireThat(input.getChatName().equals(output.getChatName()), "When command is Update chatName must not change.");
 | 
					            requireThat(input.getChatName().equals(output.getChatName()), UPDATE_COMMAND_CHATNAME_SHOULD_NOT_CHANGE);
 | 
				
			||||||
            requireThat(
 | 
					            requireThat(
 | 
				
			||||||
                    input.getParticipants().containsAll(output.getParticipants()) &&
 | 
					                    input.getParticipants().containsAll(output.getParticipants()) &&
 | 
				
			||||||
                    output.getParticipants().containsAll(input.getParticipants()),
 | 
					                    output.getParticipants().containsAll(input.getParticipants()),
 | 
				
			||||||
                    "When command is Update participants must not change.");
 | 
					                    UPDATE_COMMAND_PARTICIPANTS_SHOULD_NOT_CHANGE);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else {
 | 
					        else {
 | 
				
			||||||
            throw new CordaRuntimeException("Unsupported command");
 | 
					            throw new CordaRuntimeException(UNKNOWN_COMMAND);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,158 @@
 | 
				
			|||||||
 | 
					package com.r3.developers.csdetemplate.utxoexample.contracts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.r3.corda.ledger.utxo.testing.ContractTest;
 | 
				
			||||||
 | 
					import com.r3.developers.csdetemplate.utxoexample.states.ChatState;
 | 
				
			||||||
 | 
					import net.corda.v5.ledger.utxo.Command;
 | 
				
			||||||
 | 
					import net.corda.v5.ledger.utxo.StateAndRef;
 | 
				
			||||||
 | 
					import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction;
 | 
				
			||||||
 | 
					import org.junit.jupiter.api.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.UUID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static com.r3.developers.csdetemplate.utxoexample.contracts.ChatContract.*;
 | 
				
			||||||
 | 
					import static java.util.Collections.emptyList;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ChatContractCreateCommandTest extends ContractTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected ChatState outputChatState = new ChatState(
 | 
				
			||||||
 | 
					            UUID.randomUUID(),
 | 
				
			||||||
 | 
					            "aliceChatName",
 | 
				
			||||||
 | 
					            aliceName,
 | 
				
			||||||
 | 
					            "aliceChatMessage",
 | 
				
			||||||
 | 
					            List.of(aliceKey, bobKey)
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void happyPath() {
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .addSignatories(outputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertVerifies(transaction);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void missingCommand() {
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + REQUIRE_SINGLE_COMMAND);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void shouldNotAcceptUnknownCommand() {
 | 
				
			||||||
 | 
					        class MyDummyCommand implements Command {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new MyDummyCommand())
 | 
				
			||||||
 | 
					                .addSignatories(outputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, UNKNOWN_COMMAND);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void outputStateCannotHaveZeroParticipants() {
 | 
				
			||||||
 | 
					        ChatState state = new ChatState(
 | 
				
			||||||
 | 
					                UUID.randomUUID(),
 | 
				
			||||||
 | 
					                "myChatName",
 | 
				
			||||||
 | 
					                aliceName,
 | 
				
			||||||
 | 
					                "myChatMessage",
 | 
				
			||||||
 | 
					                emptyList()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(state)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void outputStateCannotHaveOneParticipant() {
 | 
				
			||||||
 | 
					        ChatState state = new ChatState(
 | 
				
			||||||
 | 
					                UUID.randomUUID(),
 | 
				
			||||||
 | 
					                "myChatName",
 | 
				
			||||||
 | 
					                aliceName,
 | 
				
			||||||
 | 
					                "myChatMessage",
 | 
				
			||||||
 | 
					                List.of(aliceKey)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(state)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void outputStateCannotHaveThreeParticipants() {
 | 
				
			||||||
 | 
					        ChatState state = new ChatState(
 | 
				
			||||||
 | 
					                UUID.randomUUID(),
 | 
				
			||||||
 | 
					                "myChatName",
 | 
				
			||||||
 | 
					                aliceName,
 | 
				
			||||||
 | 
					                "myChatMessage",
 | 
				
			||||||
 | 
					                List.of(aliceKey, bobKey, charlieKey)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(state)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + OUTPUT_STATE_SHOULD_ONLY_HAVE_TWO_PARTICIPANTS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void outputStateMustBeSigned() {
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void outputStateCannotBeSignedByOnlyOneParticipant() {
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .addSignatories(outputChatState.participants.get(0))
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void shouldNotIncludeInputState() {
 | 
				
			||||||
 | 
					        happyPath(); // generate an existing state to search for
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = getLedgerService().findUnconsumedStatesByType(ChatState.class).get(0); // doesn't matter which as this will fail validation
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .addSignatories(outputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + CREATE_COMMAND_SHOULD_HAVE_NO_INPUT_STATES);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void shouldNotHaveTwoOutputStates() {
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .addSignatories(outputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + CREATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,174 @@
 | 
				
			|||||||
 | 
					package com.r3.developers.csdetemplate.utxoexample.contracts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.r3.corda.ledger.utxo.testing.ContractTest;
 | 
				
			||||||
 | 
					import com.r3.developers.csdetemplate.utxoexample.states.ChatState;
 | 
				
			||||||
 | 
					import net.corda.v5.ledger.utxo.StateAndRef;
 | 
				
			||||||
 | 
					import net.corda.v5.ledger.utxo.transaction.UtxoSignedTransaction;
 | 
				
			||||||
 | 
					import org.junit.jupiter.api.Test;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.UUID;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static com.r3.developers.csdetemplate.utxoexample.contracts.ChatContract.*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class ChatContractUpdateCommandTest extends ContractTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private StateAndRef<ChatState> createInitialChatState() {
 | 
				
			||||||
 | 
					        ChatState outputChatState = new ChatContractCreateCommandTest().outputChatState;
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(outputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Create())
 | 
				
			||||||
 | 
					                .addSignatories(outputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        transaction.toLedgerTransaction();
 | 
				
			||||||
 | 
					        return (StateAndRef<ChatState>) transaction.getOutputStateAndRefs().get(0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void happyPath() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = existingState.getState().getContractState().updateMessage(bobName, "bobResponse");
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .addSignatories(updatedOutputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertVerifies(transaction);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void shouldNotHaveNoInputState() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = existingState.getState().getContractState().updateMessage(bobName, "bobResponse");
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .addSignatories(updatedOutputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_INPUT_STATE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void shouldNotHaveTwoInputStates() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = existingState.getState().getContractState().updateMessage(bobName, "bobResponse");
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .addSignatories(updatedOutputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_INPUT_STATE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void shouldNotHaveTwoOutputStates() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = existingState.getState().getContractState().updateMessage(bobName, "bobResponse");
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .addSignatories(updatedOutputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + UPDATE_COMMAND_SHOULD_HAVE_ONLY_ONE_OUTPUT_STATE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void idShouldNotChange() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState esDetails = existingState.getState().getContractState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = new ChatState(
 | 
				
			||||||
 | 
					                UUID.randomUUID(),
 | 
				
			||||||
 | 
					                esDetails.getChatName(),
 | 
				
			||||||
 | 
					                bobName,
 | 
				
			||||||
 | 
					                "bobResponse",
 | 
				
			||||||
 | 
					                esDetails.getParticipants()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .addSignatories(updatedOutputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + UPDATE_COMMAND_ID_SHOULD_NOT_CHANGE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void chatNameShouldNotChange() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState esDetails = existingState.getState().getContractState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = new ChatState(
 | 
				
			||||||
 | 
					                esDetails.getId(),
 | 
				
			||||||
 | 
					                "newName",
 | 
				
			||||||
 | 
					                bobName,
 | 
				
			||||||
 | 
					                "bobResponse",
 | 
				
			||||||
 | 
					                esDetails.getParticipants()
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .addSignatories(updatedOutputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + UPDATE_COMMAND_CHATNAME_SHOULD_NOT_CHANGE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void participantsShouldNotChange() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState esDetails = existingState.getState().getContractState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = new ChatState(
 | 
				
			||||||
 | 
					                esDetails.getId(),
 | 
				
			||||||
 | 
					                esDetails.getChatName(),
 | 
				
			||||||
 | 
					                bobName,
 | 
				
			||||||
 | 
					                "bobResponse",
 | 
				
			||||||
 | 
					                List.of(bobKey, charlieKey)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .addSignatories(updatedOutputChatState.participants)
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + UPDATE_COMMAND_PARTICIPANTS_SHOULD_NOT_CHANGE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void outputStateMustBeSigned() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = existingState.getState().getContractState().updateMessage(bobName, "bobResponse");
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Test
 | 
				
			||||||
 | 
					    public void outputStateCannotBeSignedByOnlyOneParticipant() {
 | 
				
			||||||
 | 
					        StateAndRef<ChatState> existingState = createInitialChatState();
 | 
				
			||||||
 | 
					        ChatState updatedOutputChatState = existingState.getState().getContractState().updateMessage(bobName, "bobResponse");
 | 
				
			||||||
 | 
					        UtxoSignedTransaction transaction = getLedgerService()
 | 
				
			||||||
 | 
					                .createTransactionBuilder()
 | 
				
			||||||
 | 
					                .addInputState(existingState.getRef())
 | 
				
			||||||
 | 
					                .addOutputState(updatedOutputChatState)
 | 
				
			||||||
 | 
					                .addCommand(new ChatContract.Update())
 | 
				
			||||||
 | 
					                .addSignatories(updatedOutputChatState.participants.get(0))
 | 
				
			||||||
 | 
					                .toSignedTransaction();
 | 
				
			||||||
 | 
					        assertFailsWith(transaction, "Failed requirement: " + TRANSACTION_SHOULD_BE_SIGNED_BY_ALL_PARTICIPANTS);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -35,6 +35,7 @@ junitVersion = 5.8.2
 | 
				
			|||||||
mockitoKotlinVersion=4.0.0
 | 
					mockitoKotlinVersion=4.0.0
 | 
				
			||||||
mockitoVersion=4.6.1
 | 
					mockitoVersion=4.6.1
 | 
				
			||||||
hamcrestVersion=2.2
 | 
					hamcrestVersion=2.2
 | 
				
			||||||
 | 
					contractTestingVersion=0.9.0-beta-+
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Specify the maximum amount of time allowed for the CPI upload
 | 
					# Specify the maximum amount of time allowed for the CPI upload
 | 
				
			||||||
# As your CorDapp grows you might need to increase this
 | 
					# As your CorDapp grows you might need to increase this
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user