def test_adding_new_object_with_same_id_can_load_most_recent_object(self):
        blockchain_object_repository.store_object(
            object_id=test_object_id,
            data=valid_system_of_record_input_message_with_two_tags)

        loaded_first_object = blockchain_object_repository.load_most_recent_object_with_id(test_object_id)

        blockchain_object_repository.store_object(
            object_id=test_object_id,
            data=valid_system_of_record_input_message_with_two_tags)

        loaded_second_object = blockchain_object_repository.load_most_recent_object_with_id(test_object_id)

        self.assertNotEquals(loaded_first_object.blockchain_index, loaded_second_object.blockchain_index)
        self.assertGreater(loaded_second_object.blockchain_index, loaded_first_object.blockchain_index)
    def test_can_ingest_well_formed_message_with_tags(self):
        self.check_system_is_empty()

        # Ingest a message with 2 tags.
        blockchain_ingestor.ingest(valid_system_of_record_input_message_with_two_tags)

        # However, as the system was empty we're not expecting any tag messages, only the feeder queue message
        self.check_system_contains_a_number_of_messages(1)
        self.check_chain_queue_contains_a_number_of_messages(2)
        loaded_object = blockchain_object_repository.load_most_recent_object_with_id(test_object_id)


        # Check the loaded object looks like the one that we ingested
        loaded_data = loaded_object.as_dict()
        self.assertEquals(loaded_data['object']['data'],
                          valid_system_of_record_input_message_with_two_tags['object']['data'])

        self.assertEquals(loaded_data['object']['object_id'],
                          valid_system_of_record_input_message_with_two_tags['object']['object_id'])

        self.assertEqual(len(loaded_object.chains),
                         len(valid_system_of_record_input_message_with_two_tags['object']['chains']))

        # Now we'll add a new message with the same 2 tags
        blockchain_ingestor.ingest(valid_system_of_record_input_message_with_two_tags)

        # Now, we're expecting 2 items on the chain queue & db
        self.check_system_contains_a_number_of_messages(2)
        # 6 messages - the previous 2, and the new 4
        # Why 4? It's 2 chains * 2 results per chain.
        self.check_chain_queue_contains_a_number_of_messages(6)
    def load_object(self, object_id):
        loaded_object = blockchain_object_repository.load_most_recent_object_with_id(object_id)

        if loaded_object:
            return jsonify(loaded_object.as_dict())

        app.logger.info("Could not find object with ID: %s" % object_id)
        return abort(404)
    def test_can_store_object_data(self):
        blockchain_object_repository.store_object(
            object_id=test_object_id,
            data=valid_system_of_record_input_message_with_two_tags)

        loaded_object = blockchain_object_repository.load_most_recent_object_with_id(test_object_id)

        self.check_loaded_object(unicoded(loaded_object.as_dict()))
    def load_object(self, object_id):
        loaded_object = blockchain_object_repository.load_most_recent_object_with_id(
            object_id)

        if loaded_object:
            return jsonify(loaded_object.as_dict())

        app.logger.info("Could not find object with ID: %s" % object_id)
        return abort(404)
    def test_can_store_object_data(self):
        blockchain_object_repository.store_object(
            object_id=test_object_id,
            data=valid_system_of_record_input_message_with_two_tags)

        loaded_object = blockchain_object_repository.load_most_recent_object_with_id(
            test_object_id)

        self.check_loaded_object(unicoded(loaded_object.as_dict()))
    def test_adding_new_object_with_same_id_can_load_most_recent_object(self):
        blockchain_object_repository.store_object(
            object_id=test_object_id,
            data=valid_system_of_record_input_message_with_two_tags)

        loaded_first_object = blockchain_object_repository.load_most_recent_object_with_id(
            test_object_id)

        blockchain_object_repository.store_object(
            object_id=test_object_id,
            data=valid_system_of_record_input_message_with_two_tags)

        loaded_second_object = blockchain_object_repository.load_most_recent_object_with_id(
            test_object_id)

        self.assertNotEquals(loaded_first_object.blockchain_index,
                             loaded_second_object.blockchain_index)
        self.assertGreater(loaded_second_object.blockchain_index,
                           loaded_first_object.blockchain_index)
    def test_can_ingest_well_formed_message_with_tags(self):
        self.check_system_is_empty()

        # Ingest a message with 2 tags.
        blockchain_ingestor.ingest(
            valid_system_of_record_input_message_with_two_tags)

        # However, as the system was empty we're not expecting any tag messages, only the feeder queue message
        self.check_system_contains_a_number_of_messages(1)
        self.check_chain_queue_contains_a_number_of_messages(2)
        loaded_object = blockchain_object_repository.load_most_recent_object_with_id(
            test_object_id)

        # Check the loaded object looks like the one that we ingested
        loaded_data = loaded_object.as_dict()
        self.assertEquals(
            loaded_data['object']['data'],
            valid_system_of_record_input_message_with_two_tags['object']
            ['data'])

        self.assertEquals(
            loaded_data['object']['object_id'],
            valid_system_of_record_input_message_with_two_tags['object']
            ['object_id'])

        self.assertEqual(
            len(loaded_object.chains),
            len(valid_system_of_record_input_message_with_two_tags['object']
                ['chains']))

        # Now we'll add a new message with the same 2 tags
        blockchain_ingestor.ingest(
            valid_system_of_record_input_message_with_two_tags)

        # Now, we're expecting 2 items on the chain queue & db
        self.check_system_contains_a_number_of_messages(2)
        # 6 messages - the previous 2, and the new 4
        # Why 4? It's 2 chains * 2 results per chain.
        self.check_chain_queue_contains_a_number_of_messages(6)
    def test_can_load_historic_objects_given_chains(self):
        # Here we'll create three items in the global blockchain linked by a sub chain,
        # a->b->c
        # We'll then load the last objects chained to c, which should be b,c
        test_object_id = 'AB12345'

        data_for_a = unicoded({
            'schema_version': 1,
            'object': {
                'object_id':
                'AB12345',
                'data':
                'data-1',
                'created_by':
                'The Mint',
                'initial_request_timestamp':
                '123456',
                'reason_for_change':
                "str",
                'chains': [{
                    'chain_name': 'history',
                    'chain_value': 'AB12345',
                }, {
                    'chain_name': 'otherchain',
                    'chain_value': 'foo',
                }],
            }
        })

        data_for_b = unicoded({
            'schema_version': 1,
            'object': {
                'object_id':
                'AB12345',
                'data':
                'data-2',
                'created_by':
                'The Mint',
                'initial_request_timestamp':
                '123456',
                'reason_for_change':
                "str",
                'chains': [{
                    'chain_name': 'history',
                    'chain_value': 'AB12345',
                }, {
                    'chain_name': 'otherchain',
                    'chain_value': 'foo',
                }],
            }
        })

        data_for_c = unicoded({
            'schema_version': 1,
            'object': {
                'object_id':
                'AB12345',
                'data':
                'data-3',
                'created_by':
                'The Mint',
                'initial_request_timestamp':
                '123456',
                'reason_for_change':
                "str",
                'chains': [{
                    'chain_name': 'history',
                    'chain_value': 'AB12345',
                }, {
                    'chain_name': 'otherchain',
                    'chain_value': 'foo',
                }],
            }
        })

        print "*** PROCESSING A"

        blockchain_object_repository.store_object(object_id=test_object_id,
                                                  data=data_for_a)
        object_a = blockchain_object_repository.load_most_recent_object_with_id(
            test_object_id)
        self.assertTrue('data-1' in decompress(object_a.data))

        # Now we only have object A in the blockchain. It has sub-chains, but there should be
        # no historic items for these chains.
        # This means that we should load this object from the repository for the chain heads.
        chain_heads_for_a = chain_repository.load_chain_heads_for_object(
            object_a)
        print "heads for a" + repr(chain_heads_for_a)

        self.check_chained_object_are_correct(chain_heads_for_a['history'][0],
                                              object_a)
        self.check_chained_object_are_correct(
            chain_heads_for_a['otherchain'][0], object_a)

        print "*** PROCESSING B"

        blockchain_object_repository.store_object(object_id=test_object_id,
                                                  data=data_for_b)
        object_b = blockchain_object_repository.load_most_recent_object_with_id(
            test_object_id)
        self.assertTrue('data-2' in decompress(object_b.data))

        # Now, object a should be in our chain for both the chain tags on the test data
        chain_heads_for_b = chain_repository.load_chain_heads_for_object(
            object_b)
        print "heads for b" + repr(chain_heads_for_b)

        # We're expecting to see 'history' : object_a, 'otherchain': object_a here
        self.check_chained_object_are_correct(chain_heads_for_b['history'][0],
                                              object_b)
        self.check_chained_object_are_correct(chain_heads_for_b['history'][1],
                                              object_a)
        self.check_chained_object_are_correct(
            chain_heads_for_b['otherchain'][0], object_b)
        self.check_chained_object_are_correct(
            chain_heads_for_b['otherchain'][1], object_a)

        print "*** PROCESSING C"

        blockchain_object_repository.store_object(object_id=test_object_id,
                                                  data=data_for_c)
        object_c = blockchain_object_repository.load_most_recent_object_with_id(
            test_object_id)
        self.assertTrue('data-3' in decompress(object_c.data))

        # Now lets load the head of the chain for object C
        chain_heads_for_c = chain_repository.load_chain_heads_for_object(
            object_c)
        print "heads for c" + repr(chain_heads_for_c)

        self.check_chained_object_are_correct(chain_heads_for_c['history'][0],
                                              object_c)
        self.check_chained_object_are_correct(chain_heads_for_c['history'][1],
                                              object_b)
        self.check_chained_object_are_correct(
            chain_heads_for_c['otherchain'][0], object_c)
        self.check_chained_object_are_correct(
            chain_heads_for_c['otherchain'][1], object_b)
 def store_in_database(self, object_id, message):
     blockchain_object_repository.store_object(object_id, message)
     return blockchain_object_repository.load_most_recent_object_with_id(object_id)
    def test_can_load_historic_objects_given_chains(self):
        # Here we'll create three items in the global blockchain linked by a sub chain,
        # a->b->c
        # We'll then load the last objects chained to c, which should be b,c
        test_object_id = 'AB12345'

        data_for_a = unicoded({
            'schema_version': 1,

            'object': {
                'object_id': 'AB12345',
                'data': 'data-1',
                'created_by': 'The Mint',
                'initial_request_timestamp': '123456',
                'reason_for_change': "str",

                'chains': [
                    {
                        'chain_name': 'history',
                        'chain_value': 'AB12345',
                    },
                    {
                        'chain_name': 'otherchain',
                        'chain_value': 'foo',
                    }
                ],
            }
        })

        data_for_b = unicoded({
            'schema_version': 1,

            'object': {
                'object_id': 'AB12345',
                'data': 'data-2',
                'created_by': 'The Mint',
                'initial_request_timestamp': '123456',
                'reason_for_change': "str",

                'chains': [
                    {
                        'chain_name': 'history',
                        'chain_value': 'AB12345',
                    },
                    {
                        'chain_name': 'otherchain',
                        'chain_value': 'foo',
                    }
                ],
            }
        })

        data_for_c = unicoded({
            'schema_version': 1,

            'object': {
                'object_id': 'AB12345',
                'data': 'data-3',
                'created_by': 'The Mint',
                'initial_request_timestamp': '123456',
                'reason_for_change': "str",

                'chains': [
                    {
                        'chain_name': 'history',
                        'chain_value': 'AB12345',
                    },
                    {
                        'chain_name': 'otherchain',
                        'chain_value': 'foo',
                    }
                ],
            }
        })

        print "*** PROCESSING A"

        blockchain_object_repository.store_object(object_id=test_object_id, data=data_for_a)
        object_a = blockchain_object_repository.load_most_recent_object_with_id(test_object_id)
        self.assertTrue('data-1' in decompress(object_a.data))

        # Now we only have object A in the blockchain. It has sub-chains, but there should be
        # no historic items for these chains.
        # This means that we should load this object from the repository for the chain heads.
        chain_heads_for_a = chain_repository.load_chain_heads_for_object(object_a)
        print "heads for a" + repr(chain_heads_for_a)

        self.check_chained_object_are_correct(chain_heads_for_a['history'][0], object_a)
        self.check_chained_object_are_correct(chain_heads_for_a['otherchain'][0], object_a)

        print "*** PROCESSING B"

        blockchain_object_repository.store_object(object_id=test_object_id, data=data_for_b)
        object_b = blockchain_object_repository.load_most_recent_object_with_id(test_object_id)
        self.assertTrue('data-2' in decompress(object_b.data))

        # Now, object a should be in our chain for both the chain tags on the test data
        chain_heads_for_b = chain_repository.load_chain_heads_for_object(object_b)
        print "heads for b" + repr(chain_heads_for_b)

        # We're expecting to see 'history' : object_a, 'otherchain': object_a here
        self.check_chained_object_are_correct(chain_heads_for_b['history'][0], object_b)
        self.check_chained_object_are_correct(chain_heads_for_b['history'][1], object_a)
        self.check_chained_object_are_correct(chain_heads_for_b['otherchain'][0], object_b)
        self.check_chained_object_are_correct(chain_heads_for_b['otherchain'][1], object_a)

        print "*** PROCESSING C"

        blockchain_object_repository.store_object(object_id=test_object_id, data=data_for_c)
        object_c = blockchain_object_repository.load_most_recent_object_with_id(test_object_id)
        self.assertTrue('data-3' in decompress(object_c.data))


        # Now lets load the head of the chain for object C
        chain_heads_for_c = chain_repository.load_chain_heads_for_object(object_c)
        print "heads for c" + repr(chain_heads_for_c)

        self.check_chained_object_are_correct(chain_heads_for_c['history'][0], object_c)
        self.check_chained_object_are_correct(chain_heads_for_c['history'][1], object_b)
        self.check_chained_object_are_correct(chain_heads_for_c['otherchain'][0], object_c)
        self.check_chained_object_are_correct(chain_heads_for_c['otherchain'][1], object_b)