async def test_state_list(self): """Verifies a GET /state 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 leaves 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 '2' - a link property that ends in '/state?head=2&min=0&count=3' - a paging property that matches the paging response - a data property that is a list of 3 leaf dicts - three leaves that match those in Protobuf response """ paging = Mocks.make_paging_response(0, 3) leaves = Mocks.make_leaves(a=b'3', b=b'5', c=b'7') self.connection.preset_response(head_id='2', paging=paging, leaves=leaves) response = await self.get_assert_200('/state') 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, '/state?head=2') self.assert_has_valid_paging(response, paging) self.assert_has_valid_data_list(response, 3) self.assert_leaves_match(leaves, 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 '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'])
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_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_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'])
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) leaves = Mocks.make_leaves(c=b'3') self.connection.preset_response(head_id='d', paging=paging, leaves=leaves) 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(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_leaves_match(leaves, response['data'])
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'])
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 leaves 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 leaves that match those in Protobuf response """ paging = Mocks.make_paging_response(0, 3) leaves = Mocks.make_leaves(c=b'7', b=b'5', a=b'3') self.connection.preset_response(head_id='2', paging=paging, leaves=leaves) 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(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_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 leaves 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 leaves that match those in Protobuf response """ paging = Mocks.make_paging_response(0, 3) leaves = Mocks.make_leaves(c=b'7', b=b'5', a=b'3') self.connection.preset_response(head_id='2', paging=paging, leaves=leaves) 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( 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_leaves_match(leaves, response['data'])
async def test_state_list_sorted(self): """Verifies GET /state can send proper sort controls. 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 leaves with addresses/data of: * 'a': b'3' * 'b': b'5' * 'c': b'7' It should send a Protobuf request with: - empty paging controls - sort controls with a key of 'address' It should send back a JSON response with: - a status of 200 - a head property of '2' - a link property ending in '/state?head=2&sort=address' - a paging property that matches the paging response - a data property that is a list of 3 dicts - three leaves that match those in Protobuf response """ paging = Mocks.make_paging_response(0, 3) leaves = Mocks.make_leaves(a=b'3', b=b'5', c=b'7') self.connection.preset_response(head_id='2', paging=paging, leaves=leaves) response = await self.get_assert_200('/state?sort=address') page_controls = Mocks.make_paging_controls() sorting = Mocks.make_sort_controls('address') self.connection.assert_valid_request_sent(paging=page_controls, sorting=sorting) self.assert_has_valid_head(response, '2') self.assert_has_valid_link(response, '/state?head=2&sort=address') self.assert_has_valid_paging(response, paging) self.assert_has_valid_data_list(response, 3) self.assert_leaves_match(leaves, 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 leaves 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 leaves that match those received """ paging = Mocks.make_paging_response(1, 4, previous_id='d', next_id='a') leaves = Mocks.make_leaves(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=b&count=2') controls = Mocks.make_paging_controls(2, end_id='b') 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=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_leaves_match(leaves, response['data'])
async def test_state_list_sorted(self): """Verifies GET /state can send proper sort controls. 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 leaves with addresses/data of: * 'a': b'3' * 'b': b'5' * 'c': b'7' It should send a Protobuf request with: - empty paging controls - sort controls with a key of 'address' It should send back a JSON response with: - a status of 200 - a head property of '2' - a link property ending in '/state?head=2&sort=address' - a paging property that matches the paging response - a data property that is a list of 3 dicts - three leaves that match those in Protobuf response """ paging = Mocks.make_paging_response(0, 3) leaves = Mocks.make_leaves(a=b'3', b=b'5', c=b'7') self.connection.preset_response(head_id='2', paging=paging, leaves=leaves) response = await self.get_assert_200('/state?sort=address') page_controls = Mocks.make_paging_controls() sorting = Mocks.make_sort_controls('address') self.connection.assert_valid_request_sent( paging=page_controls, sorting=sorting) self.assert_has_valid_head(response, '2') self.assert_has_valid_link(response, '/state?head=2&sort=address') self.assert_has_valid_paging(response, paging) self.assert_has_valid_data_list(response, 3) self.assert_leaves_match(leaves, response['data'])
async def test_state_list_paginated_by_min_id(self): """Verifies GET /state paginated by a min id works properly. It will receive a Protobuf response with: - a head id of 'd' - a paging response with: * a start_index of 1 * total_resources of 4 * a previous_id of 'd' - three leaves 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 'c' 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=c&count=5' - paging that matches the response, with a previous link - a data property that is a list of 3 dicts - and those dicts are leaves that match those received """ paging = Mocks.make_paging_response(1, 4, previous_id='d') leaves = Mocks.make_leaves(c=b'3', b=b'2', a=b'1') self.stream.preset_response(head_id='d', paging=paging, leaves=leaves) response = await self.get_json_assert_200('/state?min=c&count=5') controls = Mocks.make_paging_controls(5, start_id='c') self.stream.assert_valid_request_sent(paging=controls) self.assert_has_valid_head(response, 'd') self.assert_has_valid_link(response, '/state?head=d&min=c&count=5') self.assert_has_valid_paging(response, paging, previous_link='/state?head=d&max=d&count=5') self.assert_has_valid_data_list(response, 3) self.assert_leaves_match(leaves, 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 '1' - a paging response with a start of 0, and 1 total resource - one leaf with addresses/data of: 'a': b'2' It should send a Protobuf request with: - a head_id property of '1' - 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 '1' - a link property that ends in '/state?head=1&min=0&count=1&address=a' - 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(a=b'2') self.stream.preset_response(head_id='1', paging=paging, leaves=leaves) response = await self.get_json_assert_200('/state?address=a&head=1') self.stream.assert_valid_request_sent( head_id='1', address='a', paging=Mocks.make_paging_controls()) self.assert_has_valid_head(response, '1') self.assert_has_valid_link(response, '/state?head=1&address=a') self.assert_has_valid_paging(response, paging) self.assert_has_valid_data_list(response, 1) self.assert_leaves_match(leaves, response['data'])