async def test_block_list_paginated_by_start_id(self):
        """Verifies GET /blocks paginated by a start id works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with start of 0x0003 and limit of 5
            - three blocks with the ids ID_C, ID_B and ID_A

        It should send a Protobuf request with:
            - paging controls with a limit of 5, and a startof ID_C

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in '/blocks?head={}&start=0x0003&limit=5'.format(ID_C)
            - paging that matches the response, with a previous link
            - a data property that is a list of 3 dicts
            - and those dicts are full blocks with ids ID_C, ID_B, and ID_A
        """
        paging = Mocks.make_paging_response("", "0x0003", 5)
        blocks = Mocks.make_blocks(ID_C, ID_B, ID_A)
        self.connection.preset_response(head_id=ID_D,
                                        paging=paging,
                                        blocks=blocks)

        response = await self.get_assert_200('/blocks?start=0x0003&limit=5')
        controls = Mocks.make_paging_controls(5, start="0x0003")
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/blocks?head={}&start=0x0003&limit=5'.format(ID_D))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_blocks_well_formed(response['data'], ID_C, ID_B, ID_A)
    async def test_block_list_paginated_without_limit(self):
        """Verifies GET /blocks paginated without limit works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with start of 0x0002 and limit of 100
            - two blocks with the ids ID_B and ID_A

        It should send a Protobuf request with:
            - paging controls with a start of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in '/blocks?head={}&start=0x0002&limit=100'.format(ID_D)
            - paging that matches the response, with a previous link
            - a data property that is a list of 2 dicts
            - and those dicts are full blocks with ids ID_D and ID_C
        """
        paging = Mocks.make_paging_response("", "0x0002", DEFAULT_LIMIT)
        blocks = Mocks.make_blocks(ID_B, ID_A)
        self.connection.preset_response(head_id=ID_D,
                                        paging=paging,
                                        blocks=blocks)

        response = await self.get_assert_200('/blocks?start=0x0002')
        controls = Mocks.make_paging_controls(None, start="0x0002")
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/blocks?head={}&start=0x0002&limit=100'.format(ID_D))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_blocks_well_formed(response['data'], ID_B, ID_A)
    async def test_state_list_with_bad_address(self):
        """Verifies a GET /state breaks properly filtered by a bad address.

        It will receive a Protobuf response with:
            - a status of NO_RESOURCE
            - a head id of ID_C

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C
            - a link property that ends in
                '/state?head={}&start=c&limit=100address=bad'.format(ID_C)
            - a paging property with only a total_count of 0
            - a data property that is an empty list
        """
        paging = Mocks.make_paging_response("", "c", DEFAULT_LIMIT)
        self.connection.preset_response(
            self.status.NO_RESOURCE,
            state_root='beef',
            paging=paging)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_C,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))
        response = await self.get_assert_200('/state?address=bad')

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response,
            '/state?head={}&start=c&limit=100&address=bad'.format(ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 0)
    async def test_block_list_paginated_by_start_id(self):
        """Verifies GET /blocks paginated by a start id works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with start of 0x0003 and limit of 5
            - three blocks with the ids ID_C, ID_B and ID_A

        It should send a Protobuf request with:
            - paging controls with a limit of 5, and a startof ID_C

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/blocks?head={}&start=0x0003&limit=5'.format(ID_C)
            - paging that matches the response, with a previous link
            - a data property that is a list of 3 dicts
            - and those dicts are full blocks with ids ID_C, ID_B, and ID_A
        """
        paging = Mocks.make_paging_response("", "0x0003", 5)
        blocks = Mocks.make_blocks(ID_C, ID_B, ID_A)
        self.connection.preset_response(
            head_id=ID_D, paging=paging, blocks=blocks)

        response = await self.get_assert_200('/blocks?start=0x0003&limit=5')
        controls = Mocks.make_paging_controls(5, start="0x0003")
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/blocks?head={}&start=0x0003&limit=5'.format(ID_D))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_blocks_well_formed(response['data'], ID_C, ID_B, ID_A)
예제 #5
0
    async def test_state_list_paginated_by_max_index(self):
        """Verifies GET /state paginated by a max index works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with a start of 0, and 4 total resources
            - three leaves with the ids {'d': b'4'}, {'c': b'3'} and {'b': b'2'}

        It should send a Protobuf request with:
            - a paging controls with a count of 2 and an start_index of 0

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/state?head=d&min=3&count=7'
            - paging that matches the response, with a next link
            - a data property that is a list of 2 dicts
            - and those dicts are leaves that match those received
        """
        paging = Mocks.make_paging_response(0, 4)
        leaves = Mocks.make_leaves(d=b'4', c=b'3', b=b'2')
        self.connection.preset_response(head_id='d',
                                        paging=paging,
                                        leaves=leaves)

        response = await self.get_assert_200('/state?max=2&count=7')
        controls = Mocks.make_paging_controls(3, start_index=0)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/state?head=d&max=2&count=7')
        self.assert_has_valid_paging(response, paging,
                                     '/state?head=d&min=3&count=7')
        self.assert_has_valid_data_list(response, 3)
        self.assert_leaves_match(leaves, response['data'])
예제 #6
0
    async def test_txn_list_paginated_by_max_index(self):
        """Verifies GET /transactions paginated by a max index works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with a start of 0, and 4 total resources
            - three transactions with the ids 'd', 'c' and 'b'

        It should send a Protobuf request with:
            - paging controls with a count of 3, and an start_index of 0

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/transactions?head=d&min=3&count=7'
            - paging that matches the response, with a next link
            - a data property that is a list of 2 dicts
            - those dicts are full transactions with ids 'd', 'c', and 'b'
        """
        paging = Mocks.make_paging_response(0, 4)
        self.connection.preset_response(
            head_id='d',
            paging=paging,
            transactions=Mocks.make_txns('d', 'c', 'b'))

        response = await self.get_assert_200('/transactions?max=2&count=7')
        controls = Mocks.make_paging_controls(3, start_index=0)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/transactions?head=d&max=2&count=7')
        self.assert_has_valid_paging(response, paging,
                                     '/transactions?head=d&min=3&count=7')
        self.assert_has_valid_data_list(response, 3)
        self.assert_txns_well_formed(response['data'], 'd', 'c', 'b')
예제 #7
0
    async def test_state_list_paginated_without_count(self):
        """Verifies GET /state paginated without count works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with a start of 2, and 4 total resources
            - two leaves of {'b': b'2'} and {'a': b'1'}

        It should send a Protobuf request with:
            - a paging controls with a start_index of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/state?head=d&min=2&count=2'
            - paging that matches the response, with a previous link
            - a data property that is a list of 2 dicts
            - and those dicts are leaves that match those received
        """
        paging = Mocks.make_paging_response(2, 4)
        leaves = Mocks.make_leaves(b=b'2', a=b'1')
        self.connection.preset_response(head_id='d',
                                        paging=paging,
                                        leaves=leaves)

        response = await self.get_assert_200('/state?min=2')
        controls = Mocks.make_paging_controls(None, start_index=2)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/state?head=d&min=2')
        self.assert_has_valid_paging(
            response, paging, previous_link='/state?head=d&min=0&count=2')
        self.assert_has_valid_data_list(response, 2)
        self.assert_leaves_match(leaves, response['data'])
예제 #8
0
    async def test_txn_list_with_bad_ids(self):
        """Verifies GET /transactions with a bad id filter breaks properly.

        It will receive a Protobuf response with:
            - a status of NO_RESOURCE
            - a head id of '2'

        It should send back a JSON response with:
            - a response status of 200
            - a head property of '2', the latest
            - a link property that ends in '/transactions?head=2&id=bad,notgood'
            - a paging property with only a total_count of 0
            - a data property that is an empty list
        """
        paging = Mocks.make_paging_response(None, 0)
        self.connection.preset_response(
            self.status.NO_RESOURCE,
            head_id='2',
            paging=paging)
        response = await self.get_assert_200('/transactions?id=bad,notgood')

        self.assert_has_valid_head(response, '2')
        self.assert_has_valid_link(response, '/transactions?head=2&id=bad,notgood')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 0)
예제 #9
0
    async def test_txn_list_with_ids(self):
        """Verifies GET /transactions with an id filter works properly.

        It will receive a Protobuf response with:
            - a head id of '2'
            - a paging response with a start of 0, and 2 total resources
            - two transactions with ids of '0' and '2'

        It should send a Protobuf request with:
            - a transaction_ids property of ['0', '2']
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of '2', the latest
            - a link property that ends in '/transactions?head=2&id=0,2'
            - a paging property that matches the paging response
            - a data property that is a list of 2 dicts
            - those dicts are full transactions with ids '0' and '2'
        """
        paging = Mocks.make_paging_response(0, 2)
        transactions = Mocks.make_txns('0', '2')
        self.connection.preset_response(head_id='2', paging=paging, transactions=transactions)

        response = await self.get_assert_200('/transactions?id=0,2')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(transaction_ids=['0', '2'], paging=controls)

        self.assert_has_valid_head(response, '2')
        self.assert_has_valid_link(response, '/transactions?head=2&id=0,2')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_txns_well_formed(response['data'], '0', '2')
예제 #10
0
    async def test_txn_list(self):
        """Verifies a GET /transactions without parameters works properly.

        It will receive a Protobuf response with:
            - a head id of '2'
            - a paging response with a start of 0, and 3 total resources
            - three transactions with ids of '2', '1', and '0'

        It should send a Protobuf request with:
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of '2'
            - a link property that ends in '/transactions?head=2'
            - a paging property that matches the paging response
            - a data property that is a list of 3 dicts
            - those dicts are full transactions with ids '2', '1', and '0'
        """
        paging = Mocks.make_paging_response(0, 3)
        self.connection.preset_response(
            head_id='2',
            paging=paging,
            transactions=Mocks.make_txns('2', '1', '0'))

        response = await self.get_assert_200('/transactions')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, '2')
        self.assert_has_valid_link(response, '/transactions?head=2')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_txns_well_formed(response['data'], '2', '1', '0')
예제 #11
0
    async def test_state_list_with_address(self):
        """Verifies a GET /state works properly filtered by address.

        It will receive a Protobuf response with:
            - a head id of '2'
            - a paging response with a start of 0, and 1 total resource
            - one leaf with addresses/data of: 'c': b'7'

        It should send a Protobuf request with:
            - an address property of 'c'
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of '2'
            - a link property that ends in '/state?head=2&min=0&count=1&address=c'
            - a paging property that matches the paging response
            - a data property that is a list of 1 leaf dict
            - one leaf that matches the Protobuf response
        """
        paging = Mocks.make_paging_response(0, 1)
        leaves = Mocks.make_leaves(c=b'7')
        self.connection.preset_response(head_id='2',
                                        paging=paging,
                                        leaves=leaves)

        response = await self.get_assert_200('/state?address=c')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(address='c', paging=controls)

        self.assert_has_valid_head(response, '2')
        self.assert_has_valid_link(response, '/state?head=2&address=c')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 1)
        self.assert_leaves_match(leaves, response['data'])
    async def test_state_list_with_bad_address(self):
        """Verifies a GET /state breaks properly filtered by a bad address.

        It will receive a Protobuf response with:
            - a status of NO_RESOURCE
            - a head id of ID_C

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C
            - a link property that ends in '/state?head={}&start=c&limit=100address=bad'.format(ID_C)
            - a paging property with only a total_count of 0
            - a data property that is an empty list
        """
        paging = Mocks.make_paging_response("", "c", DEFAULT_LIMIT)
        self.connection.preset_response(self.status.NO_RESOURCE,
                                        state_root='beef',
                                        paging=paging)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_C,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))
        response = await self.get_assert_200('/state?address=bad')

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response,
            '/state?head={}&start=c&limit=100&address=bad'.format(ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 0)
예제 #13
0
    async def test_txn_list_with_bad_ids(self):
        """Verifies GET /transactions with a bad id filter breaks properly.

        It will receive a Protobuf response with:
            - a status of NO_RESOURCE
            - a head id of ID_C

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C, the latest
            - a link property that ends in
                '/transactions?head={}&start={}&limit=100&id={},{}'
                    .format(ID_C, ID_C, ID_B, ID_D))
            - a paging property with only a total_count of 0
            - a data property that is an empty list
        """
        paging = Mocks.make_paging_response("", ID_C, DEFAULT_LIMIT)
        self.connection.preset_response(
            self.status.NO_RESOURCE, head_id=ID_C, paging=paging)
        response = await self.get_assert_200('/transactions?id={},{}'.format(
            ID_B, ID_D))

        self.assert_has_valid_head(response, ID_C)
        link =\
            '/transactions?head={ID_C}&start={ID_C}&limit=100&id={ID_B},{ID_D}'

        self.assert_has_valid_link(
            response,
            link.format(ID_C=ID_C, ID_B=ID_B, ID_D=ID_D))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 0)
예제 #14
0
    async def test_batch_list_paginated_with_just_count(self):
        """Verifies GET /batches paginated just by count works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with a start of 0, and 4 total resources
            - two batches with the ids 'd' and 'c'

        It should send a Protobuf request with:
            - paging controls with a count of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/batches?head=d&count=2'
            - paging that matches the response with a next link
            - a data property that is a list of 2 dicts
            - and those dicts are full batches with ids 'd' and 'c'
        """
        paging = Mocks.make_paging_response(0, 4)
        batches = Mocks.make_batches('d', 'c')
        self.connection.preset_response(head_id='d',
                                        paging=paging,
                                        batches=batches)

        response = await self.get_assert_200('/batches?count=2')
        controls = Mocks.make_paging_controls(2)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/batches?head=d&count=2')
        self.assert_has_valid_paging(response, paging,
                                     '/batches?head=d&min=2&count=2')
        self.assert_has_valid_data_list(response, 2)
        self.assert_batches_well_formed(response['data'], 'd', 'c')
예제 #15
0
    async def test_batch_list_paginated(self):
        """Verifies GET /batches paginated by min id works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with a start of 1, and 4 total resources
            - one batch with the id 'c'

        It should send a Protobuf request with:
            - paging controls with a count of 1, and a start_index of 1

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/batches?head=d&min=1&count=1'
            - paging that matches the response, with next and previous links
            - a data property that is a list of 1 dict
            - and that dict is a full batch with the id 'c'
        """
        paging = Mocks.make_paging_response(1, 4)
        batches = Mocks.make_batches('c')
        self.connection.preset_response(head_id='d', paging=paging, batches=batches)

        response = await self.get_assert_200('/batches?min=1&count=1')
        controls = Mocks.make_paging_controls(1, start_index=1)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/batches?head=d&min=1&count=1')
        self.assert_has_valid_paging(response, paging,
                                     '/batches?head=d&min=2&count=1',
                                     '/batches?head=d&min=0&count=1')
        self.assert_has_valid_data_list(response, 1)
        self.assert_batches_well_formed(response['data'], 'c')
예제 #16
0
    async def test_txn_list_paginated_without_count(self):
        """Verifies GET /transactions paginated without count works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with a start of 2, and 4 total resources
            - two transactions with the ids 'b' and 'a'

        It should send a Protobuf request with:
            - paging controls with a start_index of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/transactions?head=d&min=2'
            - paging that matches the response, with a previous link
            - a data property that is a list of 2 dicts
            - those dicts are full transactions with ids 'd' and 'c'
        """
        paging = Mocks.make_paging_response(2, 4)
        self.connection.preset_response(
            head_id='d',
            paging=paging,
            transactions=Mocks.make_txns('b', 'a'))

        response = await self.get_assert_200('/transactions?min=2')
        controls = Mocks.make_paging_controls(None, start_index=2)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/transactions?head=d&min=2')
        self.assert_has_valid_paging(response, paging,
                                     previous_link='/transactions?head=d&min=0&count=2')
        self.assert_has_valid_data_list(response, 2)
        self.assert_txns_well_formed(response['data'], 'b', 'a')
    async def test_batch_list_paginated_without_count(self):
        """Verifies GET /batches paginated without count works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with start of ID_B and limit of 100
            - two batches with the ids ID_B and ID_A

        It should send a Protobuf request with:
            - paging controls with a start of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/batches?head={}&start={}&limit=100'.format(ID_D, ID_B)
            - paging that matches the response, with a previous link
            - a data property that is a list of 2 dicts
            - and those dicts are full batches with ids ID_D and ID_C
        """
        paging = Mocks.make_paging_response("", ID_B, DEFAULT_LIMIT)
        batches = Mocks.make_batches(ID_B, ID_A)
        self.connection.preset_response(
            head_id=ID_D, paging=paging, batches=batches)

        response = await self.get_assert_200('/batches?start={}'.format(ID_B))
        controls = Mocks.make_paging_controls(None, start=ID_B)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/batches?head={}&start={}&limit=100'.format(ID_D, ID_B))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_batches_well_formed(response['data'], ID_B, ID_A)
예제 #18
0
    async def test_block_list_with_bad_ids(self):
        """Verifies GET /blocks with a bad id filter breaks properly.

        It will receive a Protobuf response with:
            - a status of NO_RESOURCE
            - a head property of ID_C

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C, the latest
            - a link property that ends in
                '/blocks?head={}&start={}&limit=100&id={},{}'
                    .format(ID_C, ID_C, ID_B, ID_D))
            - a data property that is an empty list
        """
        paging = Mocks.make_paging_response("", ID_C, DEFAULT_LIMIT)
        self.connection.preset_response(self.status.NO_RESOURCE,
                                        head_id=ID_C,
                                        paging=paging)
        response = await self.get_assert_200('/blocks?id={},{}'.format(
            ID_B, ID_D))

        self.assert_has_valid_head(response, ID_C)
        link = '/blocks?head={ID_C}&start={ID_C}&limit=100&id={ID_B},{ID_D}'
        self.assert_has_valid_link(
            response, link.format(ID_C=ID_C, ID_B=ID_B, ID_D=ID_D))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 0)
    async def test_batch_list(self):
        """Verifies a GET /batches without parameters works properly.

        It will receive a Protobuf response with:
            - a head id of ID_C
            - a paging response with a start of ID_C and limit of 100
            - three batches with ids of ID_C, ID_B, and ID_A

        It should send a Protobuf request with:
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C
            - a link property that ends in
                '/batches?start={}&limit=100&head={}'.format(ID_C, ID_C)
            - a paging property that matches the paging response
            - a data property that is a list of 3 dicts
            - and those dicts are full batches with ids ID_C, ID_B, and ID_A
        """
        paging = Mocks.make_paging_response("", ID_C, DEFAULT_LIMIT)
        batches = Mocks.make_batches(ID_C, ID_B, ID_A)
        self.connection.preset_response(
            head_id=ID_C, paging=paging, batches=batches)

        response = await self.get_assert_200('/batches')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response, '/batches?head={}&start={}&limit=100'.format(ID_C, ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_batches_well_formed(response['data'], ID_C, ID_B, ID_A)
예제 #20
0
    async def test_batch_list_with_head(self):
        """Verifies a GET /batches with a head parameter works properly.

        It will receive a Protobuf response with:
            - a head id of '1'
            - a paging response with a start of 0, and 2 total resources
            - two batches with ids of 1' and '0'

        It should send a Protobuf request with:
            - a head_id property of '1'
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of '1'
            - a link property that ends in '/batches?head=1'
            - a paging property that matches the paging response
            - a data property that is a list of 2 dicts
            - and those dicts are full batches with ids '1' and '0'
        """
        paging = Mocks.make_paging_response(0, 2)
        batches = Mocks.make_batches('1', '0')
        self.connection.preset_response(head_id='1',
                                        paging=paging,
                                        batches=batches)

        response = await self.get_assert_200('/batches?head=1')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(head_id='1', paging=controls)

        self.assert_has_valid_head(response, '1')
        self.assert_has_valid_link(response, '/batches?head=1')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_batches_well_formed(response['data'], '1', '0')
    async def test_batch_list(self):
        """Verifies a GET /batches without parameters works properly.

        It will receive a Protobuf response with:
            - a head id of ID_C
            - a paging response with a start of ID_C and limit of 100
            - three batches with ids of ID_C, ID_B, and ID_A

        It should send a Protobuf request with:
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C
            - a link property that ends in '/batches?start={}&limit=100&head={}'.format(ID_C, ID_C)
            - a paging property that matches the paging response
            - a data property that is a list of 3 dicts
            - and those dicts are full batches with ids ID_C, ID_B, and ID_A
        """
        paging = Mocks.make_paging_response("", ID_C, DEFAULT_LIMIT)
        batches = Mocks.make_batches(ID_C, ID_B, ID_A)
        self.connection.preset_response(head_id=ID_C,
                                        paging=paging,
                                        batches=batches)

        response = await self.get_assert_200('/batches')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response, '/batches?head={}&start={}&limit=100'.format(ID_C, ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_batches_well_formed(response['data'], ID_C, ID_B, ID_A)
예제 #22
0
    async def test_state_list_paginated_with_just_count(self):
        """Verifies GET /state paginated just by count works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with a start of 0, and 4 total resources
            - two leaves of {'d': b'4'}, and {'c': b'3'}

        It should send a Protobuf request with:
            - a paging controls with a count of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/state?head=d&min=0&count=2'
            - paging that matches the response with a next link
            - a data property that is a list of 2 dicts
            - and those dicts are leaves that match those received
        """
        paging = Mocks.make_paging_response(0, 4)
        leaves = Mocks.make_leaves(d=b'4', c=b'3')
        self.connection.preset_response(head_id='d',
                                        paging=paging,
                                        leaves=leaves)

        response = await self.get_assert_200('/state?count=2')
        controls = Mocks.make_paging_controls(2)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/state?head=d&count=2')
        self.assert_has_valid_paging(response, paging,
                                     '/state?head=d&min=2&count=2')
        self.assert_has_valid_data_list(response, 2)
        self.assert_leaves_match(leaves, response['data'])
    async def test_state_list_sorted_by_many_keys(self):
        """Verifies a GET /state can send proper sort parameters.

        It will receive a Protobuf response with:
            - a head id of '2'
            - a paging response with a start of 0, and 3 total resources
            - three entries with addresses/data of:
                * 'c': b'7'
                * 'b': b'5'
                * 'a': b'3'

        It should send a Protobuf request with:
            - empty paging controls
            - multiple sort controls with:
                * a key of 'address' that is reversed
                * a key of 'value' that is sorted by length

        It should send back a JSON response with:
            - a status of 200
            - a head property of '2'
            - link with '/state?head=2&sort=-address,value.length'
            - a paging property that matches the paging response
            - a data property that is a list of 3 dicts
            - three entries that match those in Protobuf response
        """
        paging = Mocks.make_paging_response(0, 3)
        entries = Mocks.make_entries(c=b'7', b=b'5', a=b'3')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature='2',
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200(
            '/state?sort=-address,value.length')
        page_controls = Mocks.make_paging_controls()
        sorting = (Mocks.make_sort_controls('address', reverse=True) +
                   Mocks.make_sort_controls('value', compare_length=True))
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=page_controls,
                                                  sorting=sorting)

        self.assert_has_valid_head(response, '2')
        self.assert_has_valid_link(response,
                                   '/state?head=2&sort=-address,value.length')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_sorted_in_reverse(self):
        """Verifies a GET /state can send proper sort parameters.

        It will receive a Protobuf response with:
            - a head id of ID_C
            - a paging response with a start of c and  limit of 100
            - three entries with addresses/data of:
                * 'c': b'7'
                * 'b': b'5'
                * 'a': b'3'

        It should send a Protobuf request with:
            - empty paging controls
            - sort controls with a key of 'address' that is reversed

        It should send back a JSON response with:
            - a status of 200
            - a head property of ID_C
            - a link property ending in
                '/state?head={}&start=c&limit=100&reverse'.format(ID_C)
            - a paging property that matches the paging response
            - a data property that is a list of 3 dicts
            - three entries that match those in Protobuf response
        """
        paging = Mocks.make_paging_response("", "c", DEFAULT_LIMIT)
        entries = Mocks.make_entries(c=b'7', b=b'5', a=b'3')
        self.connection.preset_response(state_root='beef', paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_C,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?reverse')
        page_controls = Mocks.make_paging_controls()
        sorting = Mocks.make_sort_controls('default', reverse=True)
        self.connection.assert_valid_request_sent(
            state_root='beef',
            paging=page_controls,
            sorting=sorting)

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response, '/state?head={}&start=c&limit=100&reverse'.format(ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_sorted_in_reverse(self):
        """Verifies a GET /state can send proper sort parameters.

        It will receive a Protobuf response with:
            - a head id of ID_C
            - a paging response with a start of c and  limit of 100
            - three entries with addresses/data of:
                * 'c': b'7'
                * 'b': b'5'
                * 'a': b'3'

        It should send a Protobuf request with:
            - empty paging controls
            - sort controls with a key of 'address' that is reversed

        It should send back a JSON response with:
            - a status of 200
            - a head property of ID_C
            - a link property ending in
                '/state?head={}&start=c&limit=100&reverse'.format(ID_C)
            - a paging property that matches the paging response
            - a data property that is a list of 3 dicts
            - three entries that match those in Protobuf response
        """
        paging = Mocks.make_paging_response("", "c", DEFAULT_LIMIT)
        entries = Mocks.make_entries(c=b'7', b=b'5', a=b'3')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_C,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?reverse')
        page_controls = Mocks.make_paging_controls()
        sorting = Mocks.make_sort_controls('default', reverse=True)
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=page_controls,
                                                  sorting=sorting)

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response, '/state?head={}&start=c&limit=100&reverse'.format(ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_with_head_and_address(self):
        """Verifies GET /state works with a head and filtered by address.

        It will receive a Protobuf response with:
            - a head id of ID_B
            - a paging response with a start of a and a limit of 100
            - one leaf with addresses/data of: 'a': b'2'

        It should send a Protobuf request with:
            - a head_id property of ID_B
            - an address property of 'a'
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_B
            - a link property that ends in
                '/state?head={}&start=a&limit=100&address=a'.format(ID_B)
            - a paging property that matches the paging response
            - a data property that is a list of 1 leaf dict
            - one leaf that matches the Protobuf response
        """
        paging = Mocks.make_paging_response("", "a", DEFAULT_LIMIT)
        entries = Mocks.make_entries(a=b'2')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_B,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200(
            '/state?address=a&head={}'.format(ID_B))
        self.connection.assert_valid_request_sent(
            state_root='beef',
            address='a',
            paging=Mocks.make_paging_controls())

        self.assert_has_valid_head(response, ID_B)
        self.assert_has_valid_link(
            response,
            '/state?head={}&start=a&limit=100&address=a'.format(ID_B))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 1)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_paginated_by_max_id(self):
        """Verifies GET /state paginated by a max id works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with:
                * a start_index of 1
                * a total_resources of 4
                * a previous_id of 'd'
                * a next_id of 'a'
            - two entries of {'c': b'3'} and {'b': b'3'}

        It should send a Protobuf request with:
            - a paging controls with a count of 2 and an end_id of 'b'

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/state?head=d&max=b&count=2'
            - paging that matches the response, with next and previous links
            - a data property that is a list of 2 dicts
            - and those dicts are entries that match those received
        """
        paging = Mocks.make_paging_response(1, 4, previous_id='d', next_id='a')
        entries = Mocks.make_entries(c=b'3', b=b'2')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature='d',
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?max=b&count=2')
        controls = Mocks.make_paging_controls(2, end_id='b')
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/state?head=d&max=b&count=2')
        self.assert_has_valid_paging(response, paging,
                                     '/state?head=d&min=a&count=2',
                                     '/state?head=d&max=d&count=2')
        self.assert_has_valid_data_list(response, 2)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_with_head_and_address(self):
        """Verifies GET /state works with a head and filtered by address.

        It will receive a Protobuf response with:
            - a head id of ID_B
            - a paging response with a start of a and a limit of 100
            - one leaf with addresses/data of: 'a': b'2'

        It should send a Protobuf request with:
            - a head_id property of ID_B
            - an address property of 'a'
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_B
            - a link property that ends in
                '/state?head={}&start=a&limit=100&address=a'.format(ID_B)
            - a paging property that matches the paging response
            - a data property that is a list of 1 leaf dict
            - one leaf that matches the Protobuf response
        """
        paging = Mocks.make_paging_response("", "a", DEFAULT_LIMIT)
        entries = Mocks.make_entries(a=b'2')
        self.connection.preset_response(state_root='beef', paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_B,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200(
            '/state?address=a&head={}'.format(ID_B))
        self.connection.assert_valid_request_sent(
            state_root='beef',
            address='a',
            paging=Mocks.make_paging_controls())

        self.assert_has_valid_head(response, ID_B)
        self.assert_has_valid_link(
            response,
            '/state?head={}&start=a&limit=100&address=a'.format(ID_B))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 1)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list(self):
        """Verifies a GET /state without parameters works properly.

        It will receive a Protobuf response with:
            - a state root of ID_C
            - a paging response with start of "a" and a limit of 100
            - three entries with addresses/data of:
                * 'a': b'3'
                * 'b': b'5'
                * 'c': b'7'

        It should send a Protobuf request with:
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C
            - a link property that ends in
                /state?head={}&start=a&limit=100'.format(ID_C)
            - a paging property that matches the paging response
            - a data property that is a list of 3 leaf dicts
            - three entries that match those in Protobuf response
        """
        paging = Mocks.make_paging_response("", "a", DEFAULT_LIMIT)
        entries = Mocks.make_entries(a=b'3', b=b'5', c=b'7')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_C,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=controls)

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response, '/state?head={}&start=a&limit=100'.format(ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list(self):
        """Verifies a GET /state without parameters works properly.

        It will receive a Protobuf response with:
            - a state root of ID_C
            - a paging response with start of "a" and a limit of 100
            - three entries with addresses/data of:
                * 'a': b'3'
                * 'b': b'5'
                * 'c': b'7'

        It should send a Protobuf request with:
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C
            - a link property that ends in
                /state?head={}&start=a&limit=100'.format(ID_C)
            - a paging property that matches the paging response
            - a data property that is a list of 3 leaf dicts
            - three entries that match those in Protobuf response
        """
        paging = Mocks.make_paging_response("", "a", DEFAULT_LIMIT)
        entries = Mocks.make_entries(a=b'3', b=b'5', c=b'7')
        self.connection.preset_response(state_root='beef', paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_C,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(
            state_root='beef', paging=controls)

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response, '/state?head={}&start=a&limit=100'.format(ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_with_head(self):
        """Verifies a GET /state works properly with head specified.

        It will receive a Protobuf response with:
            - a head id of '1'
            - a paging response with a start of 0, and 2 total resources
            - two entries with addresses/data of:
                * 'a': b'2'
                * 'b': b'4'

        It should send a Protobuf request with:
            - a head_id property of '1'
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of '1'
            - a link property that ends in '/state?head=1&min=0&count=2'
            - a paging property that matches the paging response
            - a data property that is a list of 2 leaf dicts
            - three entries that match those in Protobuf response
        """
        paging = Mocks.make_paging_response(0, 2)
        entries = Mocks.make_entries(a=b'2', b=b'4')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature='1',
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?head=1')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=controls)

        self.assert_has_valid_head(response, '1')
        self.assert_has_valid_link(response, '/state?head=1')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_entries_match(entries, response['data'])
예제 #32
0
    async def test_batch_list_with_head_and_ids(self):
        """Verifies GET /batches with head and id parameters work properly.

        It should send a Protobuf request with:
            - a head_id property of ID_B
            - a paging reponse with a start of ID_B and limit of 100
            - a batch_ids property of [ID_A]

        It will receive a Protobuf response with:
            - a head id of ID_B
            - one batch with an id of ID_A
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_B
            - a link property that ends in
                '/batches?head={}&start={}&limit=100&id={}'
                    .format(ID_B, ID_B, ID_A)
            - a paging property that matches the paging response
            - a data property that is a list of 1 dict
            - and that dict is a full batch with an id of ID_A
        """
        paging = Mocks.make_paging_response("", ID_B, DEFAULT_LIMIT)
        batches = Mocks.make_batches(ID_A)
        self.connection.preset_response(head_id=ID_B,
                                        paging=paging,
                                        batches=batches)

        response = await self.get_assert_200('/batches?id={}&head={}'.format(
            ID_A, ID_B))
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(head_id=ID_B,
                                                  batch_ids=[ID_A],
                                                  paging=controls)

        self.assert_has_valid_head(response, ID_B)
        self.assert_has_valid_link(
            response,
            '/batches?head={ID_B}&start={ID_B}&limit=100&id={ID_A}'.format(
                ID_B=ID_B, ID_A=ID_A))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 1)
        self.assert_batches_well_formed(response['data'], ID_A)
예제 #33
0
    async def test_batch_list_with_head_and_ids(self):
        """Verifies GET /batches with head and id parameters work properly.

        It should send a Protobuf request with:
            - a head_id property of ID_B
            - a paging reponse with a start of ID_B and limit of 100
            - a batch_ids property of [ID_A]

        It will receive a Protobuf response with:
            - a head id of ID_B
            - one batch with an id of ID_A
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_B
            - a link property that ends in
                '/batches?head={}&start={}&limit=100&id={}'
                    .format(ID_B, ID_B, ID_A)
            - a paging property that matches the paging response
            - a data property that is a list of 1 dict
            - and that dict is a full batch with an id of ID_A
        """
        paging = Mocks.make_paging_response("", ID_B, DEFAULT_LIMIT)
        batches = Mocks.make_batches(ID_A)
        self.connection.preset_response(
            head_id=ID_B, paging=paging, batches=batches)

        response = await self.get_assert_200('/batches?id={}&head={}'.format(
            ID_A, ID_B))
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(
            head_id=ID_B,
            batch_ids=[ID_A],
            paging=controls)

        self.assert_has_valid_head(response, ID_B)
        self.assert_has_valid_link(
            response,
            '/batches?head={ID_B}&start={ID_B}&limit=100&id={ID_A}'.format(
                ID_B=ID_B, ID_A=ID_A))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 1)
        self.assert_batches_well_formed(response['data'], ID_A)
    async def test_state_list_with_address(self):
        """Verifies a GET /state works properly filtered by address.

        It will receive a Protobuf response with:
            - a head id of '2'
            - a paging response with a start of 0, and 1 total resource
            - one leaf with addresses/data of: 'c': b'7'

        It should send a Protobuf request with:
            - an address property of 'c'
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of '2'
            - a link property that ends in
            '/state?head=2&min=0&count=1&address=c'
            - a paging property that matches the paging response
            - a data property that is a list of 1 leaf dict
            - one leaf that matches the Protobuf response
        """
        paging = Mocks.make_paging_response(0, 1)
        entries = Mocks.make_entries(c=b'7')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature='2',
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?address=c')
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  address='c',
                                                  paging=controls)

        self.assert_has_valid_head(response, '2')
        self.assert_has_valid_link(response, '/state?head=2&address=c')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 1)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_paginated_with_just_limit(self):
        """Verifies GET /state paginated just by limit works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a start of d and limit of 2
            - two entries of {ID_D: b'4'}, and {'c': b'3'}

        It should send a Protobuf request with:
            - a paging controls with a limit of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/state?head={}&start=d&limit=2'.format(ID_D)
            - paging that matches the response with a next link
            - a data property that is a list of 2 dicts
            - and those dicts are entries that match those received
        """
        paging = Mocks.make_paging_response("b", "d", 2)
        entries = Mocks.make_entries(d=b'4', c=b'3')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_D,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?limit=2')
        controls = Mocks.make_paging_controls(2)
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/state?head={}&start=d&limit=2'.format(ID_D))
        self.assert_has_valid_paging(
            response, paging, '/state?head={}&start=b&limit=2'.format(ID_D))
        self.assert_has_valid_data_list(response, 2)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_paginated(self):
        """Verifies GET /state paginated by works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a start of 2
            - one leaf of {'c': b'3'}

        It should send a Protobuf request with:
            - a paging controls with a limit of 1, and a start of 1

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/state?head={}&start=c&limit=1'.format(ID_D)
            - paging that matches the response, with next and previous links
            - a data property that is a list of 1 dict
            - and that dict is a leaf that matches the one received
        """
        paging = Mocks.make_paging_response("b", "c", 1)
        entries = Mocks.make_entries(c=b'3')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_D,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?start=c&limit=1')
        controls = Mocks.make_paging_controls(1, start="c")
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/state?head={}&start=c&limit=1'.format(ID_D))
        self.assert_has_valid_paging(
            response, paging, '/state?head={}&start=b&limit=1'.format(ID_D))
        self.assert_has_valid_data_list(response, 1)
        self.assert_entries_match(entries, response['data'])
예제 #37
0
    async def test_batch_list_sorted_by_many_keys(self):
        """Verifies a GET /batches can send proper sort parameters.

        It will receive a Protobuf response with:
            - a head id of '2'
            - a paging response with a start of 0, and 3 total resources
            - three batches with ids '2', '1', and '0'

        It should send a Protobuf request with:
            - empty paging controls
            - multiple sort controls with:
                * a key of 'header_signature' that is reversed
                * a key of 'transactions' that is sorted by length

        It should send back a JSON response with:
            - a status of 200
            - a head property of '2'
            - link with '/batches?head=2&sort=-header_signature,transactions.length'
            - a paging property that matches the paging response
            - a data property that is a list of 3 dicts
            - and those dicts are full batches with ids '2', '1', and '0'
        """
        paging = Mocks.make_paging_response(0, 3)
        batches = Mocks.make_batches('2', '1', '0')
        self.connection.preset_response(head_id='2',
                                        paging=paging,
                                        batches=batches)

        response = await self.get_assert_200(
            '/batches?sort=-header_signature,transactions.length')
        page_controls = Mocks.make_paging_controls()
        sorting = (
            Mocks.make_sort_controls('header_signature', reverse=True) +
            Mocks.make_sort_controls('transactions', compare_length=True))
        self.connection.assert_valid_request_sent(paging=page_controls,
                                                  sorting=sorting)

        self.assert_has_valid_head(response, '2')
        self.assert_has_valid_link(
            response,
            '/batches?head=2&sort=-header_signature,transactions.length')
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_batches_well_formed(response['data'], '2', '1', '0')
    async def test_state_list_paginated(self):
        """Verifies GET /state paginated by works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a start of 2
            - one leaf of {'c': b'3'}

        It should send a Protobuf request with:
            - a paging controls with a limit of 1, and a start of 1

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/state?head={}&start=c&limit=1'.format(ID_D)
            - paging that matches the response, with next and previous links
            - a data property that is a list of 1 dict
            - and that dict is a leaf that matches the one received
        """
        paging = Mocks.make_paging_response("b", "c", 1)
        entries = Mocks.make_entries(c=b'3')
        self.connection.preset_response(state_root='beef', paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_D,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?start=c&limit=1')
        controls = Mocks.make_paging_controls(1, start="c")
        self.connection.assert_valid_request_sent(
            state_root='beef', paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/state?head={}&start=c&limit=1'.format(ID_D))
        self.assert_has_valid_paging(
            response, paging, '/state?head={}&start=b&limit=1'.format(ID_D))
        self.assert_has_valid_data_list(response, 1)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_paginated_with_just_limit(self):
        """Verifies GET /state paginated just by limit works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a start of d and limit of 2
            - two entries of {ID_D: b'4'}, and {'c': b'3'}

        It should send a Protobuf request with:
            - a paging controls with a limit of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/state?head={}&start=d&limit=2'.format(ID_D)
            - paging that matches the response with a next link
            - a data property that is a list of 2 dicts
            - and those dicts are entries that match those received
        """
        paging = Mocks.make_paging_response("b", "d", 2)
        entries = Mocks.make_entries(d=b'4', c=b'3')
        self.connection.preset_response(state_root='beef', paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_D,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?limit=2')
        controls = Mocks.make_paging_controls(2)
        self.connection.assert_valid_request_sent(
            state_root='beef', paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/state?head={}&start=d&limit=2'.format(ID_D))
        self.assert_has_valid_paging(
            response, paging, '/state?head={}&start=b&limit=2'.format(ID_D))
        self.assert_has_valid_data_list(response, 2)
        self.assert_entries_match(entries, response['data'])
예제 #40
0
    async def test_txn_list_with_ids(self):
        """Verifies GET /transactions with an id filter works properly.

        It will receive a Protobuf response with:
            - a head id of ID_C
            - a paging response with a start of ID_C and limit of 100
            - two transactions with ids of ID_A and ID_C

        It should send a Protobuf request with:
            - a transaction_ids property of [ID_A, ID_C]
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_C, the latest
            - a link property that ends in
                '/transactions?head={}&start={}&limit=100&id={},{}'
                    .format(ID_C, ID_C, ID_A, ID_C))
            - a paging property that matches the paging response
            - a data property that is a list of 2 dicts
            - those dicts are full transactions with ids ID_A and ID_C
        """
        paging = Mocks.make_paging_response("", ID_C, DEFAULT_LIMIT)
        transactions = Mocks.make_txns(ID_A, ID_C)
        self.connection.preset_response(
            head_id=ID_C, paging=paging, transactions=transactions)

        response = await self.get_assert_200('/transactions?id={},{}'.format(
            ID_A, ID_C))
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(
            transaction_ids=[ID_A, ID_C], paging=controls)

        self.assert_has_valid_head(response, ID_C)
        link =\
            '/transactions?head={ID_C}&start={ID_C}&limit=100&id={ID_A},{ID_C}'

        self.assert_has_valid_link(
            response,
            link.format(ID_C=ID_C, ID_A=ID_A))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_txns_well_formed(response['data'], ID_A, ID_C)
    async def test_state_list_paginated(self):
        """Verifies GET /state paginated by min id works properly.

        It will receive a Protobuf response with:
            - a head id of 'd'
            - a paging response with a start of 1, and 4 total resources
            - one leaf of {'c': b'3'}

        It should send a Protobuf request with:
            - a paging controls with a count of 1, and a start_index of 1

        It should send back a JSON response with:
            - a response status of 200
            - a head property of 'd'
            - a link property that ends in '/state?head=d&min=1&count=1'
            - paging that matches the response, with next and previous links
            - a data property that is a list of 1 dict
            - and that dict is a leaf that matches the one received
        """
        paging = Mocks.make_paging_response(1, 4)
        entries = Mocks.make_entries(c=b'3')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature='d',
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?min=1&count=1')
        controls = Mocks.make_paging_controls(1, start_index=1)
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=controls)

        self.assert_has_valid_head(response, 'd')
        self.assert_has_valid_link(response, '/state?head=d&min=1&count=1')
        self.assert_has_valid_paging(response, paging,
                                     '/state?head=d&min=2&count=1',
                                     '/state?head=d&min=0&count=1')
        self.assert_has_valid_data_list(response, 1)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_paginated_without_count(self):
        """Verifies GET /state paginated without count works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response start of "b" and limit of 100
            - two entries of {'b': b'2'} and {'a': b'1'}

        It should send a Protobuf request with:
            - a paging controls with a start of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/state?head={}&start=b&limit=100'.format(ID_D))
            - paging that matches the response, with a previous link
            - a data property that is a list of 2 dicts
            - and those dicts are entries that match those received
        """
        paging = Mocks.make_paging_response("", "b", DEFAULT_LIMIT)
        entries = Mocks.make_entries(b=b'2', a=b'1')
        self.connection.preset_response(state_root='beef',
                                        paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_D,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?start=2')
        controls = Mocks.make_paging_controls(None, start="2")
        self.connection.assert_valid_request_sent(state_root='beef',
                                                  paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/state?head={}&start=b&limit=100'.format(ID_D))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_paginated_without_count(self):
        """Verifies GET /state paginated without count works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response start of "b" and limit of 100
            - two entries of {'b': b'2'} and {'a': b'1'}

        It should send a Protobuf request with:
            - a paging controls with a start of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/state?head={}&start=b&limit=100'.format(ID_D))
            - paging that matches the response, with a previous link
            - a data property that is a list of 2 dicts
            - and those dicts are entries that match those received
        """
        paging = Mocks.make_paging_response("", "b", DEFAULT_LIMIT)
        entries = Mocks.make_entries(b=b'2', a=b'1')
        self.connection.preset_response(state_root='beef', paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_D,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?start=2')
        controls = Mocks.make_paging_controls(None, start="2")
        self.connection.assert_valid_request_sent(
            state_root='beef', paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/state?head={}&start=b&limit=100'.format(ID_D))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_entries_match(entries, response['data'])
    async def test_state_list_paginated_by_start_id(self):
        """Verifies GET /state paginated by a start id works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a start of c and limit of 5
            - three entries of {'c': b'3'}, {'b': b'2'}, and {'a': b'1'}

        It should send a Protobuf request with:
            - a paging controls with a start_id of ID_C

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/state?head={}&start=c&limit=5'.format(ID_D, ID_C)
            - paging that matches the response, with a previous link
            - a data property that is a list of 3 dicts
            - and those dicts are entries that match those received
        """
        paging = Mocks.make_paging_response("", "c", 5)
        entries = Mocks.make_entries(c=b'3', b=b'2', a=b'1')
        self.connection.preset_response(state_root='beef', paging=paging,
                                        entries=entries)
        self.connection.preset_response(
            proto=client_block_pb2.ClientBlockGetResponse,
            block=block_pb2.Block(
                header_signature=ID_D,
                header=block_pb2.BlockHeader(
                    state_root_hash='beef').SerializeToString()))

        response = await self.get_assert_200('/state?start=c&limit=5')
        controls = Mocks.make_paging_controls(5, "c")
        self.connection.assert_valid_request_sent(
            state_root='beef', paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/state?head={}&start=c&limit=5'.format(ID_D))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_entries_match(entries, response['data'])
예제 #45
0
    async def test_txn_list_sorted_in_reverse(self):
        """Verifies a GET /transactions can send proper sort parameters.

        It will receive a Protobuf response with:
            - a head id of ID_C
            - a paging response with start of ID_C and limit of 100
            - three transactions with ids ID_C, ID_B, and ID_A

        It should send a Protobuf request with:
            - empty paging controls
            - sort controls with a key of 'header_signature' that is reversed

        It should send back a JSON response with:
            - a status of 200
            - a head property of ID_C
            - a link property ending in
                '/transactions?head={}&start={}&limit=100&reverse'
                    .format(ID_C, ID_C))
            - a paging property that matches the paging response
            - a data property that is a list of 3 dicts
            - and those dicts are full transactions with ids ID_C,
              ID_B, and ID_A
        """
        paging = Mocks.make_paging_response("", ID_C, DEFAULT_LIMIT)
        transactions = Mocks.make_txns(ID_C, ID_B, ID_A)
        self.connection.preset_response(
            head_id=ID_C, paging=paging, transactions=transactions)
        response = await self.get_assert_200('/transactions?reverse')
        page_controls = Mocks.make_paging_controls()
        sorting = Mocks.make_sort_controls("default", reverse=True)
        self.connection.assert_valid_request_sent(
            paging=page_controls,
            sorting=sorting)

        self.assert_has_valid_head(response, ID_C)
        self.assert_has_valid_link(
            response,
            '/transactions?head={ID_C}&start={ID_C}&limit=100&reverse'.format(
                ID_C=ID_C))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 3)
        self.assert_txns_well_formed(response['data'], ID_C, ID_B, ID_A)
    async def test_block_list_paginated(self):
        """Verifies GET /blocks paginated by min id works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a next of '0x0002', start of
              0x0003 and limit of 1
            - one block with the id ID_C

        It should send a Protobuf request with:
            - paging controls with a limit of 1, and a start_id of
              start='0x0003'

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/blocks?head={}&start=1&limit=1'.format(ID_D)
            - paging that matches the response, with next and previous links
            - a data property that is a list of 1 dict
            - and that dict is a full block with the id ID_C

        """
        # Block list only returns a next id
        paging = Mocks.make_paging_response('0x0002', "0x0003", 1)
        blocks = Mocks.make_blocks(ID_C)
        self.connection.preset_response(
            head_id=ID_D, paging=paging, blocks=blocks)

        response = await self.get_assert_200('/blocks?start=0x0003&limit=1')
        controls = Mocks.make_paging_controls(1, start='0x0003')
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/blocks?head={}&start=0x0003&limit=1'.format(ID_D))
        self.assert_has_valid_paging(
            response, paging,
            '/blocks?head={}&start=0x0002&limit=1'.format(ID_D))
        self.assert_has_valid_data_list(response, 1)
        self.assert_blocks_well_formed(response['data'], ID_C)
예제 #47
0
    async def test_txn_list_paginated_with_just_limit(self):
        """Verifies GET /transactions paginated just by limit works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a start of ID_D, next of ID_B and
              limit of 2
            - two transactions with the ids ID_D and ID_C

        It should send a Protobuf request with:
            - paging controls with a limit of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/transactions?head={}&start={}&limit=2'.format(ID_D, ID_D))
            - paging that matches the response with a next link
            - a data property that is a list of 2 dicts
            - those dicts are full transactions with ids ID_D and ID_C
        """
        paging = Mocks.make_paging_response(ID_B, ID_D, 2)
        self.connection.preset_response(
            head_id=ID_D,
            paging=paging,
            transactions=Mocks.make_txns(ID_D, ID_C))

        response = await self.get_assert_200('/transactions?limit=2')
        controls = Mocks.make_paging_controls(2)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/transactions?head={ID_D}&start={ID_D}&limit=2'.format(
                ID_D=ID_D))
        self.assert_has_valid_paging(
            response, paging, '/transactions?head={}&start={}&limit=2'.format(
                ID_D, ID_B))
        self.assert_has_valid_data_list(response, 2)
        self.assert_txns_well_formed(response['data'], ID_D, ID_C)
예제 #48
0
    async def test_batch_list_paginated(self):
        """Verifies GET /batches paginated by start works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a start of ID_D, next of ID_C and
              limit of 1
            - one batch with the id ID_C

        It should send a Protobuf request with:
            - paging controls with a start of 1

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/batches?head={}&start={}&limit=1'.format(ID_D, ID_D)
            - paging that matches the response, with next and previous links
            - a data property that is a list of 1 dict
            - and that dict is a full batch with the id ID_C

        """
        paging = Mocks.make_paging_response(ID_C, ID_D, 1)
        batches = Mocks.make_batches(ID_C)
        self.connection.preset_response(
            head_id=ID_D, paging=paging, batches=batches)

        response = await self.get_assert_200('/batches?start=1&limit=1')
        controls = Mocks.make_paging_controls(1, start="1")
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/batches?head={ID_D}&start={ID_D}&limit=1'.format(
                ID_D=ID_D))
        self.assert_has_valid_paging(
            response, paging, '/batches?head={}&start={}&limit=1'.format(
                ID_D, ID_C))
        self.assert_has_valid_data_list(response, 1)
        self.assert_batches_well_formed(response['data'], ID_C)
예제 #49
0
    async def test_txn_list_with_head(self):
        """Verifies a GET /transactions with a head parameter works properly.

        It will receive a Protobuf response with:
            - a head id of ID_B
            - a paging response with a start of ID_B and limit of 100
            - two transactions with ids of 1' and ID_A

        It should send a Protobuf request with:
            - a head_id property of ID_B
            - empty paging controls

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_B
            - a link property that ends in
                '/transactions?head={}&start={}&limit=100'.format(ID_B, ID_B))
            - a paging property that matches the paging response
            - a data property that is a list of 2 dicts
            - those dicts are full transactions with ids ID_B and ID_A
        """
        paging = Mocks.make_paging_response("", ID_B, DEFAULT_LIMIT)
        self.connection.preset_response(
            head_id=ID_B,
            paging=paging,
            transactions=Mocks.make_txns(ID_B, ID_A))

        response = await self.get_assert_200(
            '/transactions?head={}'.format(ID_B))
        controls = Mocks.make_paging_controls()
        self.connection.assert_valid_request_sent(
            head_id=ID_B, paging=controls)
        self.assert_has_valid_head(response, ID_B)
        self.assert_has_valid_link(
            response,
            '/transactions?head={ID_B}&start={ID_B}&limit=100'.format(
                ID_B=ID_B))
        self.assert_has_valid_paging(response, paging)
        self.assert_has_valid_data_list(response, 2)
        self.assert_txns_well_formed(response['data'], ID_B, ID_A)
    async def test_block_list_paginated_with_just_limit(self):
        """Verifies GET /blocks paginated just by limit works properly.

        It will receive a Protobuf response with:
            - a head id of ID_D
            - a paging response with a next of 0x0002, start of 0x004
              and limit of 2
            - two blocks with the ids ID_D and ID_C

        It should send a Protobuf request with:
            - paging controls with a limit of 2

        It should send back a JSON response with:
            - a response status of 200
            - a head property of ID_D
            - a link property that ends in
                '/blocks?head={}&start=0x0004&limit=2'.format(ID_D)
            - paging that matches the response with a next link
            - a data property that is a list of 2 dicts
            - and those dicts are full blocks with ids ID_D and ID_C

        """
        # Block list only returns a next id
        paging = Mocks.make_paging_response('0x0002', '0x0004', 2)
        blocks = Mocks.make_blocks(ID_D, ID_C)
        self.connection.preset_response(
            head_id=ID_D, paging=paging, blocks=blocks)

        response = await self.get_assert_200('/blocks?limit=2')
        controls = Mocks.make_paging_controls(2)
        self.connection.assert_valid_request_sent(paging=controls)

        self.assert_has_valid_head(response, ID_D)
        self.assert_has_valid_link(
            response, '/blocks?head={}&start=0x0004&limit=2'.format(ID_D))
        self.assert_has_valid_paging(
            response, paging,
            '/blocks?head={}&start=0x0002&limit=2'.format(ID_D))
        self.assert_has_valid_data_list(response, 2)
        self.assert_blocks_well_formed(response['data'], ID_D, ID_C)