### Question:
MessageValidator { public boolean validateProposal(final Proposal msg) { if (!signedDataValidator.validateProposal(msg.getSignedPayload())) { LOG.info("Illegal Proposal message, embedded signed data failed validation"); return false; } if (!validateBlock(msg.getBlock())) { return false; } if (!validateProposalAndRoundChangeAreConsistent(msg)) { LOG.info("Illegal Proposal message, embedded roundChange does not match proposal."); return false; } return proposalConsistencyValidator.validateProposalMatchesBlock( msg.getSignedPayload(), msg.getBlock()); } MessageValidator(
      final SignedDataValidator signedDataValidator,
      final ProposalBlockConsistencyValidator proposalConsistencyValidator,
      final BlockValidator blockValidator,
      final ProtocolContext protocolContext,
      final RoundChangeCertificateValidator roundChangeCertificateValidator); boolean validateProposal(final Proposal msg); boolean validatePrepare(final Prepare msg); boolean validateCommit(final Commit msg);  }### Answer:
@Test public void ifProposalConsistencyChecksFailProposalIsIllegal() { final Proposal proposal = messageFactory.createProposal(roundIdentifier, block, Optional.empty()); when(proposalBlockConsistencyValidator.validateProposalMatchesBlock(any(), any())) .thenReturn(false); assertThat(messageValidator.validateProposal(proposal)).isFalse(); verify(proposalBlockConsistencyValidator, times(1)) .validateProposalMatchesBlock(proposal.getSignedPayload(), proposal.getBlock()); }
@Test public void blockValidationFailureFailsValidation() { when(blockValidator.validateAndProcessBlock(any(), any(), any(), any())) .thenReturn(Optional.empty()); final Proposal proposalMsg = messageFactory.createProposal(roundIdentifier, block, Optional.empty()); assertThat(messageValidator.validateProposal(proposalMsg)).isFalse(); }
@Test public void proposalFailsValidationIfRoundChangeCertificateDoeNotMatchBlock() { final ConsensusRoundIdentifier nonZeroRound = new ConsensusRoundIdentifier(1, 1); when(roundChangeCertificateValidator.validateProposalMessageMatchesLatestPrepareCertificate( any(), any())) .thenReturn(false); final Proposal proposal = messageFactory.createProposal( nonZeroRound, block, Optional.of(new RoundChangeCertificate(emptyList()))); assertThat(messageValidator.validateProposal(proposal)).isFalse(); }
@Test public void proposalFailsValidationIfRoundChangeIsNotSelfConsistent() { final ConsensusRoundIdentifier nonZeroRound = new ConsensusRoundIdentifier(1, 1); when(roundChangeCertificateValidator.validateRoundChangeMessagesAndEnsureTargetRoundMatchesRoot( any(), any())) .thenReturn(false); final Proposal proposal = messageFactory.createProposal( nonZeroRound, block, Optional.of(new RoundChangeCertificate(emptyList()))); assertThat(messageValidator.validateProposal(proposal)).isFalse(); }
@Test public void proposalForRoundZeroFailsIfItContainsARoundChangeCertificate() { final Proposal proposal = messageFactory.createProposal( roundIdentifier, block, Optional.of(new RoundChangeCertificate(emptyList()))); assertThat(messageValidator.validateProposal(proposal)).isFalse(); verify(roundChangeCertificateValidator, never()) .validateRoundChangeMessagesAndEnsureTargetRoundMatchesRoot(any(), any()); verify(roundChangeCertificateValidator, never()) .validateProposalMessageMatchesLatestPrepareCertificate(any(), any()); }
@Test public void proposalForRoundsGreaterThanZeroFailIfNoRoundChangeCertificateAvailable() { final ConsensusRoundIdentifier nonZeroRound = new ConsensusRoundIdentifier(1, 1); final Proposal proposal = messageFactory.createProposal(nonZeroRound, block, Optional.empty()); assertThat(messageValidator.validateProposal(proposal)).isFalse(); verify(roundChangeCertificateValidator, never()) .validateRoundChangeMessagesAndEnsureTargetRoundMatchesRoot(any(), any()); verify(roundChangeCertificateValidator, never()) .validateProposalMessageMatchesLatestPrepareCertificate(any(), any()); }