def test_on_user_introduction(self, store_patch, api_patch): # We'll be introducer the user to the bank. So remove user from the bank self.api_bank.db.delete(self.user) self.assertFalse(store_patch.called) # Set them as false to override the defaults store = update = forward = False message_name = u"introduce_user" candidate = LoopbackCandidate() self.community.send_introduce_user([self.user.type], {self.user.type: self.user}, candidate) self.assertTrue(store_patch.called) args, _ = store_patch.call_args self.assertEqual(type(args[0]), list) message = args[0][0] self.assertEqual(message.name, message_name) # Receive the user as the bank and check if it is found in the database. self.assertIsNone(self.api_bank._get_user(self.user)) # Send it to the bank self.assertFalse(api_patch.called) self.community_bank.on_user_introduction([message]) self.assertTrue(api_patch.called) # Check if received args, _ = api_patch.call_args self.assertEqual(self.user.id, args[1].id)
def test_check_add_genesis_block(self): """ This test checks the functionality of adding a block to an empty blockchain. """ # Check if there are already blocks in the blockchain, if not add genesis block self.db.check_add_genesis_block() # Get the genesis block genesis_block = self.db.create_genesis_block() meta = self.community.get_meta_message(u"signed_confirm") message = meta.impl( authentication=([self.member, self.member_bank], ), distribution=(self.community.claim_global_time(), ), payload=self.payload, destination=(LoopbackCandidate(), )) block = DatabaseBlock.from_signed_confirm_message(message) # Add the block to the blockchain self.db.add_block(block) # Get the block by the hash of the block result = self.db.get_by_hash(block.hash_block) # Check whether the genesis block and the first block are added correctly self.assertEqual(result.previous_hash, genesis_block.hash_block)
def test_from_signed_confirmed(self): """ This test checks the functionality of making a block with the payload from a message. """ meta = self.community.get_meta_message(u"signed_confirm") message = meta.impl( authentication=([self.member, self.member_bank], ), distribution=(self.community.claim_global_time(), ), payload=self.payload, destination=(LoopbackCandidate(), )) block = DatabaseBlock.from_signed_confirm_message(message) self.assertEqual(block.benefactor, message.payload.benefactor) self.assertEqual(block.beneficiary, message.payload.beneficiary) self.assertEqual(DatabaseModel.decode(block.agreement_benefactor), message.payload.agreement_benefactor) self.assertEqual(DatabaseModel.decode(block.agreement_beneficiary), message.payload.agreement_beneficiary) self.assertEqual(block.sequence_number_benefactor, message.payload.sequence_number_benefactor) self.assertEqual(block.sequence_number_beneficiary, message.payload.sequence_number_beneficiary) self.assertEqual(block.previous_hash_benefactor, message.payload.previous_hash_benefactor) self.assertEqual(block.previous_hash_beneficiary, message.payload.previous_hash_beneficiary) self.assertEqual(block.insert_time, message.payload.insert_time)
def test_update_block_with_beneficiary(self): """ This test checks the functionality of updating a block in the blockchain. """ meta = self.community.get_meta_message(u"signed_confirm") message_no_ben = meta.impl( authentication=([self.member, self.member_bank], ), distribution=(self.community.claim_global_time(), ), payload=self.payload2, destination=(LoopbackCandidate(), )) message_ben = meta.impl( authentication=([self.member, self.member_bank], ), distribution=(self.community.claim_global_time(), ), payload=self.payload, destination=(LoopbackCandidate(), )) # Add the block with only the information from benefactor to the blockchain self.community.persist_signature(message_no_ben) # Create the block manually for assertions block_benefactor = DatabaseBlock.from_signed_confirm_message( message_no_ben) # Update the block with the information from the beneficiary self.community.update_signature(message_ben) # Create the block manually for assertions block_beneficiary = DatabaseBlock.from_signed_confirm_message( message_ben) # Get the updated block by the hash of the block result = self.db.get_by_hash(block_beneficiary.hash_block) self.assertEqualBlocks(block_beneficiary, result) # Get the updated block by the public key and the sequence number result_benefactor = self.db.get_by_public_key_and_sequence_number( message_ben.payload.benefactor, block_benefactor.sequence_number_benefactor) result_beneficiary = self.db.get_by_public_key_and_sequence_number( message_ben.payload.beneficiary, block_beneficiary.sequence_number_beneficiary) # Check whether the block was updated correctly self.assertEqualBlocks(result_benefactor, result_beneficiary) self.assertEqualBlocks(result_benefactor, result) self.assertEqualBlocks(result_beneficiary, result)
def test_add_multiple_blocks(self): """ This test checks the functionality of adding two blocks to the blockchain. """ meta = self.community.get_meta_message(u"signed_confirm") message1 = meta.impl( authentication=([self.member, self.member_bank], ), distribution=(self.community.claim_global_time(), ), payload=self.payload, destination=(LoopbackCandidate(), )) message2 = meta.impl( authentication=([self.member, self.member_bank], ), distribution=(self.community.claim_global_time(), ), payload=self.payload2, destination=(LoopbackCandidate(), )) block1 = DatabaseBlock.from_signed_confirm_message(message1) block2 = DatabaseBlock.from_signed_confirm_message(message2) # Add the blocks to the blockchain self.db.add_block(block1) self.bank_db.add_block(block1) self.db.add_block(block2) self.bank_db.add_block(block2) # Get the blocks by the hash of the block result1 = self.db.get_by_hash(block1.hash_block) result2 = self.db.get_by_hash(block2.hash_block) # Get the latest hash latest_hash_benefactor = self.db.get_latest_hash() latest_hash_beneficiary = self.bank_db.get_latest_hash() # Check whether the blocks were added correctly self.assertEqualBlocks(block1, result1) self.assertEqualBlocks(block2, result2) self.assertNotEqual(block1.hash_block, block2.hash_block) self.assertEqual(latest_hash_benefactor, latest_hash_beneficiary) self.assertEqual(latest_hash_benefactor, block2.hash_block) self.assertEqual(latest_hash_beneficiary, block2.hash_block) self.assertNotEqual(latest_hash_benefactor, block1.hash_block) self.assertNotEqual(latest_hash_beneficiary, block1.hash_block)
def test_signature_request_flow(self, persist, update, next_seq, next_hash, create_sig): persist.return_value = True update.return_value = True next_seq.return_value = 1 next_hash.return_value = 'hasdhashdsa' create_sig.return_value = True # Attempt to sign without having a user candidate self.assertFalse( self.community_bank.publish_signed_confirm_request_message( self.user.id, self.mortgage)) # Set the candidate for the user candidate = LoopbackCandidate() candidate.associate(self.member) self.api_bank.user_candidate[self.user.id] = candidate # Attempt to sign without having a user candidate self.assertTrue( self.community_bank.publish_signed_confirm_request_message( self.user.id, self.mortgage)) self.assertTrue(create_sig.called)
def test_encode_signed_confirm(self): payload_list = [] for k in range(1, 12): payload_list.append(None) payload_list[0] = self.user.id # benefactor, 0 payload_list[1] = self.bank.id # beneficiary, 1 payload_list[2] = self.loan_request payload_list[3] = None # agreement beneficiary payload_list[4] = 0 payload_list[5] = 0 # sequence number beneficiary payload_list[6] = 'hashsas' payload_list[7] = 'asdasdas' # previous hash beneficiary payload_list[8] = 'sig1' # Signature benefactor payload_list[9] = 'sig2' # Signature beneficiary payload_list[10] = 324325252 meta = self.community.get_meta_message(u"signed_confirm") loop = LoopbackCandidate() message = meta.impl( authentication=([self.member, self.member], ), distribution=(self.community.claim_global_time(), ), payload=tuple(payload_list)) encoded_message = self.conversion._encode_signed_confirm(message)[0] decoded_payload = self.conversion._decode_signed_confirm( message, 0, encoded_message)[1] p1 = message.payload p2 = decoded_payload assert isinstance(p1, SignedConfirmPayload.Implementation) assert isinstance(p2, SignedConfirmPayload.Implementation) self.assertEqual(p1.agreement_benefactor, p2.agreement_benefactor) self.assertEqual(p1.agreement_beneficiary, p2.agreement_beneficiary) self.assertEqual(p1.benefactor, p2.benefactor) self.assertEqual(p1.beneficiary, p2.beneficiary) self.assertEqual(p1.previous_hash_benefactor, p2.previous_hash_benefactor) self.assertEqual(p1.previous_hash_beneficiary, p2.previous_hash_beneficiary) self.assertEqual(p1.sequence_number_benefactor, p2.sequence_number_benefactor) self.assertEqual(p1.sequence_number_beneficiary, p2.sequence_number_beneficiary) self.assertEqual(p1.signature_beneficiary, p2.signature_beneficiary) self.assertEqual(p1.signature_benefactor, p1.signature_benefactor) self.assertEqual(p1.insert_time, p2.insert_time)
def test_encode_introduce_user(self): meta = self.community.get_meta_message(u"introduce_user") message = meta.impl( authentication=(self.member, ), distribution=(self.community.claim_global_time(), ), payload=([self.user.type], { self.user.type: self.user }), destination=(LoopbackCandidate(), )) encoded_message = self.conversion._encode_model(message)[0] decoded_payload = self.conversion._decode_model( message, 0, encoded_message)[1] self.assertEqual(message.payload.fields, decoded_payload.fields) self.assertEqual(message.payload.models, decoded_payload.models)
def test_encode_api_request_candidate(self): meta = self.community.get_meta_message(u"api_message_candidate") message = meta.impl( authentication=(self.member, ), distribution=(self.community.claim_global_time(), ), payload=( APIMessage.MORTGAGE_OFFER.value, [self.user.type], { self.user.type: self.user }, ), destination=(LoopbackCandidate(), )) encoded_message = self.conversion._encode_api_message(message)[0] decoded_payload = self.conversion._decode_api_message( message, 0, encoded_message)[1] self.assertEqual(message.payload.models, decoded_payload.models)
def test_add_get(self): """ This test checks the functionality of adding a block to the blockchain then retrieving it. """ meta = self.community.get_meta_message(u"signed_confirm") message = meta.impl( authentication=([self.member, self.member_bank], ), distribution=(self.community.claim_global_time(), ), payload=self.payload, destination=(LoopbackCandidate(), )) block = DatabaseBlock.from_signed_confirm_message(message) # Add the block to the blockchain self.db.add_block(block) # Get the block by the hash of the block result = self.db.get_by_hash(block.hash_block) # Check whether the block was added correctly self.assertEqualBlocks(block, result)
def test_send_introduce_user(self, patch): self.assertFalse(patch.called) # Set them as false to override the defaults store = update = forward = False message_name = u"introduce_user" candidate = LoopbackCandidate() self.community.send_introduce_user([self.user.type], {self.user.type: self.user}, candidate, store, update, forward) self.assertTrue(patch.called) args, kwargs = patch.call_args self.assertEqual(type(args[0]), list) message = args[0][0] self.assertEqual(message.name, message_name) self.assertEqual(args[1], store) self.assertEqual(args[2], update) self.assertEqual(args[3], forward)
def test_send_candidate_message(self, patch): self.assertFalse(patch.called) # Set them as false to override the defaults store = update = forward = False message_name = APIMessage.MORTGAGE_OFFER.value candidates = (LoopbackCandidate(), ) self.community.send_api_message_candidate( message_name, [self.loan_request.type], {self.loan_request.type: self.loan_request}, candidates, store, update, forward) self.assertTrue(patch.called) args, kwargs = patch.call_args self.assertEqual(type(args[0]), list) message = args[0][0] self.assertEqual(message.payload.request, message_name) self.assertEqual(args[1], store) self.assertEqual(args[2], update) self.assertEqual(args[3], forward)
def test_create_signed_confirm_request_message(self, persist, update, next_seq, next_hash, create_sig): persist.return_value = True update.return_value = True next_seq.return_value = 1 next_hash.return_value = 'hasdhashdsa' create_sig.return_value = True # Save the agreement for the user self.mortgage.post_or_put(self.api.db) self.loan_request.post_or_put(self.api_bank.db) # Set the candidate for the user candidate = LoopbackCandidate() candidate.associate(self.member) self.api_bank.user_candidate[self.user.id] = candidate # Attempt to sign without having a user candidate message = self.community_bank.create_signed_confirm_request_message( candidate, self.mortgage) self.assertEqual(message.name, u"signed_confirm") self.assertEqual(message.payload.agreement_benefactor, self.mortgage) self.assertEqual(message.payload.benefactor, self.bank.id) self.assertTrue(next_hash.called) self.assertTrue(next_seq.called) self.assertTrue(persist.called) self.assertFalse(update.called) persist.reset_mock() next_hash.reset_mock() next_seq.reset_mock() message2 = self.community.allow_signed_confirm_request(message) self.assertTrue(next_hash.called) self.assertTrue(next_seq.called) self.assertTrue(persist.called) self.assertFalse(update.called) self.assertEqual(message.name, message2.name) self.assertEqual(message.payload.benefactor, message2.payload.benefactor) self.assertNotEqual(message.payload.beneficiary, message2.payload.beneficiary) # Finally check if the update call works persist.reset_mock() next_hash.reset_mock() next_seq.reset_mock() self.assertTrue( self.community_bank.allow_signed_confirm_response( message, message2, True)) self.assertFalse(next_hash.called) self.assertFalse(next_seq.called) self.assertFalse(persist.called) self.assertFalse(update.called) self.community_bank.received_signed_confirm_response([message2]) self.assertTrue(update.called)