def test_routing(self): """ Routing commands to different adapters. """ default_adapter = MockAdapter() pow_adapter = MockAdapter() wrapper = (RoutingWrapper(default_adapter).add_route( 'attachToTangle', pow_adapter).add_route('interruptAttachingToTangle', pow_adapter)) default_adapter.seed_response('getNodeInfo', {'id': 'default1'}) pow_adapter.seed_response('attachToTangle', {'id': 'pow1'}) pow_adapter.seed_response('interruptAttachingToTangle', {'id': 'pow2'}) self.assertDictEqual( wrapper.send_request({'command': 'attachToTangle'}), {'id': 'pow1'}, ) self.assertDictEqual( wrapper.send_request({'command': 'interruptAttachingToTangle'}), {'id': 'pow2'}, ) # Any commands that aren't routed go to the default adapter. self.assertDictEqual( wrapper.send_request({'command': 'getNodeInfo'}), {'id': 'default1'}, )
def setUp(self): super(GetInputsCommandTestCase, self).setUp() self.adapter = MockAdapter() self.command = GetInputsCommand(self.adapter) # Define some valid tryte sequences that we can reuse between # tests. self.addy0 =\ Address( trytes = b'TESTVALUE9DONTUSEINPRODUCTION99999FIODSG' b'IC9CCIFCNBTBDFIEHHE9RBAEVGK9JECCLCPBIINAX', key_index = 0, ) self.addy1 =\ Address( trytes = b'TESTVALUE9DONTUSEINPRODUCTION999999EPCNH' b'MBTEH9KDVFMHHESDOBTFFACCGBFGACEDCDDCGICIL', key_index = 1, ) self.addy2 =\ Address( trytes = b'TESTVALUE9DONTUSEINPRODUCTION99999YDOHWF' b'U9PFOFHGKFACCCBGDALGI9ZBEBABFAMBPDSEQ9XHJ', key_index = 2, )
def setUp(self): super(BroadcastAndStoreCommandTestCase, self).setUp() self.adapter = MockAdapter() self.command = BroadcastAndStoreCommand(self.adapter) # Define a few valid values that we can reuse across tests. self.trytes1 = b'RBTC9D9DCDQAEASBYBCCKBFA' self.trytes2 =\ b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA'
class GetTransactionsToApproveResponseFilterTestCase(BaseFilterTestCase): filter_type =\ GetTransactionsToApproveCommand(MockAdapter()).get_response_filter skip_value_check = True # noinspection SpellCheckingInspection def test_pass_happy_path(self): """ Typical ``getTransactionsToApprove`` response. """ response = { 'trunkTransaction': 'TKGDZ9GEI9CPNQGHEATIISAKYPPPSXVCXBSR9EIW' 'CTHHSSEQCD9YLDPEXYERCNJVASRGWMAVKFQTC9999', 'branchTransaction': 'TKGDZ9GEI9CPNQGHEATIISAKYPPPSXVCXBSR9EIW' 'CTHHSSEQCD9YLDPEXYERCNJVASRGWMAVKFQTC9999', 'duration': 936, } filter_ = self._filter(response) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'trunkTransaction': TransactionHash(b'TKGDZ9GEI9CPNQGHEATIISAKYPPPSXVCXBSR9EIW' b'CTHHSSEQCD9YLDPEXYERCNJVASRGWMAVKFQTC9999'), 'branchTransaction': TransactionHash(b'TKGDZ9GEI9CPNQGHEATIISAKYPPPSXVCXBSR9EIW' b'CTHHSSEQCD9YLDPEXYERCNJVASRGWMAVKFQTC9999'), 'duration': 936, }, )
def setUp(self): super(SendTrytesCommandTestCase, self).setUp() self.adapter = MockAdapter() self.command = SendTrytesCommand(self.adapter) # Define a few valid values that we can reuse across tests. self.trytes1 = b'RBTC9D9DCDQAEASBYBCCKBFA' self.trytes2 =\ b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA' self.transaction1 = (b'TKGDZ9GEI9CPNQGHEATIISAKYPPPSXVCXBSR9EIW' b'CTHHSSEQCD9YLDPEXYERCNJVASRGWMAVKFQTC9999') self.transaction2 = (b'TKGDZ9GEI9CPNQGHEATIISAKYPPPSXVCXBSR9EIW' b'CTHHSSEQCD9YLDPEXYERCNJVASRGWMAVKFQTC9999')
def setUp(self): super(GetAccountDataCommandTestCase, self).setUp() self.adapter = MockAdapter() self.command = GetAccountDataCommand(self.adapter) # Define some tryte sequences we can re-use between tests. self.addy1 =\ Address( b'TESTVALUEONE9DONTUSEINPRODUCTION99999YDZ' b'E9TAFAJGJA9CECKDAEPHBICDR9LHFCOFRBQDHC9IG', key_index = 0, ) self.addy2 =\ Address( b'TESTVALUETWO9DONTUSEINPRODUCTION99999TES' b'GINEIDLEEHRAOGEBMDLENFDAFCHEIHZ9EBZDD9YHL', key_index = 1, ) self.hash1 =\ TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION99999O99IDB' b'MBPAPDXBSDWAMHV9DASEGCOGHBV9VAF9UGRHFDPFJ' ) self.hash2 =\ TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION99999OCNCHC' b'TEPBHEPBJEWFXERHSCQCH9TAAANDBBCCHCIDEAVBV' )
class GetBalancesResponseFilterTestCase(BaseFilterTestCase): filter_type = GetBalancesCommand(MockAdapter()).get_response_filter skip_value_check = True def test_balances(self): """ Typical ``getBalances`` response. """ filter_ = self._filter({ 'balances': ['114544444', '0', '8175737'], 'duration': 42, 'milestoneIndex': 128, 'milestone': 'INRTUYSZCWBHGFGGXXPWRWBZACYAFGVRRP9VYEQJ' 'OHYD9URMELKWAFYFMNTSP9MCHLXRGAFMBOZPZ9999', }) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'balances': [114544444, 0, 8175737], 'duration': 42, 'milestoneIndex': 128, 'milestone': Address( b'INRTUYSZCWBHGFGGXXPWRWBZACYAFGVRRP9VYEQJ' b'OHYD9URMELKWAFYFMNTSP9MCHLXRGAFMBOZPZ9999', ), }, )
class FindTransactionsResponseFilterTestCase(BaseFilterTestCase): filter_type = FindTransactionsCommand(MockAdapter()).get_response_filter skip_value_check = True # noinspection SpellCheckingInspection def setUp(self): super(FindTransactionsResponseFilterTestCase, self).setUp() # Define a few valid values here that we can reuse across multiple # tests. self.trytes1 = b'RBTC9D9DCDQAEASBYBCCKBFA' self.trytes2 =\ b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA' def test_no_results(self): """ The incoming response contains no hashes. """ response = { 'hashes': [], 'duration': 42, } filter_ = self._filter(response) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, response) # noinspection SpellCheckingInspection def test_search_results(self): """ The incoming response contains lots of hashes. """ filter_ = self._filter({ 'hashes': [ 'RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFW' 'YWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVA', 'ZJVYUGTDRPDYFGFXMKOTV9ZWSGFK9CFPXTITQLQN' 'LPPG9YNAARMKNKYQO9GSCSBIOTGMLJUFLZWSY9999', ], 'duration': 42, }) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'hashes': [ TransactionHash( b'RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFW' b'YWZRE9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVA', ), TransactionHash( b'ZJVYUGTDRPDYFGFXMKOTV9ZWSGFK9CFPXTITQLQN' b'LPPG9YNAARMKNKYQO9GSCSBIOTGMLJUFLZWSY9999', ), ], 'duration': 42, }, )
class GetTipsRequestFilterTestCase(BaseFilterTestCase): filter_type = GetTipsCommand(MockAdapter()).get_request_filter skip_value_check = True def test_pass_empty(self): """ The incoming response is (correctly) empty. """ request = {} filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, request) def test_fail_unexpected_parameters(self): """ The incoming response contains unexpected parameters. """ self.assertFilterErrors( { # All you had to do was nothing! How did you screw that up?! 'foo': 'bar', }, { 'foo': [f.FilterMapper.CODE_EXTRA_KEY], }, )
class GetNeighborsRequestFilterTestCase(BaseFilterTestCase): filter_type = GetNeighborsCommand(MockAdapter()).get_request_filter skip_value_check = True def test_pass_empty(self): """ The request is (correctly) empty. """ filter_ = self._filter({}) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, {}) def test_fail_unexpected_parameters(self): """ The request contains unexpected parameters. """ self.assertFilterErrors( { # Fool of a Took! 'foo': 'bar', }, { 'foo': [f.FilterMapper.CODE_EXTRA_KEY], }, )
def setUp(self): super(GetNewAddressesCommandTestCase, self).setUp() self.adapter = MockAdapter() self.command = GetNewAddressesCommand(self.adapter) # Create a few TryteStrings we can reuse across tests. self.addy1 =\ Address( b'ADDYONE999AHHKVD9SBEYWQFNVQSNTGYQSQ9AGWD' b'JDZKBYCVTODUHFEVVMNMPQMIXOVXVCZRUENAWYNTO' ) self.addy2 =\ Address( b'ADDYTWO999AGAQKYXHRMSFAQNPWCIYUYTXPWUEUR' b'VNZTCTFUPQ9ESTKNSSLLIZWDQISJVEWIJDVGIECXF' )
def test_unregistered_command(self): """ Attempting to create an unsupported command. """ api = Strictcornode(MockAdapter()) with self.assertRaises(InvalidCommand): # noinspection PyStatementEffect api.helloWorld
def setUp(self): super(GetTransfersCommandTestCase, self).setUp() self.adapter = MockAdapter() self.command = GetTransfersCommand(self.adapter) # Define some tryte sequences we can re-use between tests. self.addy1 =\ Address( b'TESTVALUEONE9DONTUSEINPRODUCTION99999YDZ' b'E9TAFAJGJA9CECKDAEPHBICDR9LHFCOFRBQDHC9IG' ) self.addy2 =\ Address( b'TESTVALUETWO9DONTUSEINPRODUCTION99999TES' b'GINEIDLEEHRAOGEBMDLENFDAFCHEIHZ9EBZDD9YHL' )
class BroadcastAndStoreCommandTestCase(TestCase): # noinspection SpellCheckingInspection def setUp(self): super(BroadcastAndStoreCommandTestCase, self).setUp() self.adapter = MockAdapter() self.command = BroadcastAndStoreCommand(self.adapter) # Define a few valid values that we can reuse across tests. self.trytes1 = b'RBTC9D9DCDQAEASBYBCCKBFA' self.trytes2 =\ b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA' def test_wireup(self): """ Verify that the command is wired up correctly. """ self.assertIsInstance( cornode(self.adapter).broadcastAndStore, BroadcastAndStoreCommand, ) def test_happy_path(self): """ Successful invocation of ``broadcastAndStore``. """ self.adapter.seed_response( 'broadcastTransactions', { 'trytes': [ text_type(self.trytes1, 'ascii'), text_type(self.trytes2, 'ascii'), ], }) self.adapter.seed_response('storeTransactions', {}) trytes = [ TransactionTrytes(self.trytes1), TransactionTrytes(self.trytes2), ] response = self.command(trytes=trytes) self.assertDictEqual(response, {'trytes': trytes})
class GetTrytesResponseFilter(BaseFilterTestCase): filter_type = GetTrytesCommand(MockAdapter()).get_response_filter skip_value_check = True # noinspection SpellCheckingInspection def setUp(self): super(GetTrytesResponseFilter, self).setUp() # Define some valid tryte sequences that we can re-use between # tests. self.trytes1 = b'RBTC9D9DCDQAEASBYBCCKBFA' self.trytes2 =\ b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA' def test_pass_transactions(self): """ The response contains data for multiple transactions. """ filter_ = self._filter({ 'trytes': [ # In real life, these values would be a lot longer, but for the # purposes of this test, any sequence of trytes will do. text_type(self.trytes1, 'ascii'), text_type(self.trytes2, 'ascii'), ], 'duration': 42, }) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'trytes': [ TryteString(self.trytes1), TryteString(self.trytes2), ], 'duration': 42, }, ) def test_pass_no_transactions(self): """ The response does not contain any transactions. """ response = { 'trytes': [], 'duration': 42, } filter_ = self._filter(response) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, response)
def test_registered_command(self): """ Preparing a documented command. """ api = Strictcornode(MockAdapter()) # We just need to make sure the correct command type is # instantiated; individual commands have their own unit tests. command = api.getNodeInfo self.assertIsInstance(command, GetNodeInfoCommand)
def test_create_command(self): """ Preparing an experimental/undocumented command. """ api = Strictcornode(MockAdapter()) custom_command = api.create_command('helloWorld') self.assertIsInstance(custom_command, CustomCommand) self.assertEqual(custom_command.command, 'helloWorld')
class GetTipsResponseFilterTestCase(BaseFilterTestCase): filter_type = GetTipsCommand(MockAdapter()).get_response_filter skip_value_check = True # noinspection SpellCheckingInspection def test_pass_lots_of_hashes(self): """ The response contains lots of hashes. """ response = { 'hashes': [ 'YVXJOEOP9JEPRQUVBPJMB9MGIB9OMTIJJLIUYPM9' 'YBIWXPZ9PQCCGXYSLKQWKHBRVA9AKKKXXMXF99999', 'ZUMARCWKZOZRMJM9EEYJQCGXLHWXPRTMNWPBRCAG' 'SGQNRHKGRUCIYQDAEUUEBRDBNBYHAQSSFZZQW9999', 'QLQECHDVQBMXKD9YYLBMGQLLIQ9PSOVDRLYCLLFM' 'S9O99XIKCUHWAFWSTARYNCPAVIQIBTVJROOYZ9999', ], 'duration': 4 } filter_ = self._filter(response) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'hashes': [ Address(b'YVXJOEOP9JEPRQUVBPJMB9MGIB9OMTIJJLIUYPM9' b'YBIWXPZ9PQCCGXYSLKQWKHBRVA9AKKKXXMXF99999'), Address(b'ZUMARCWKZOZRMJM9EEYJQCGXLHWXPRTMNWPBRCAG' b'SGQNRHKGRUCIYQDAEUUEBRDBNBYHAQSSFZZQW9999'), Address(b'QLQECHDVQBMXKD9YYLBMGQLLIQ9PSOVDRLYCLLFM' b'S9O99XIKCUHWAFWSTARYNCPAVIQIBTVJROOYZ9999'), ], 'duration': 4, }) def test_pass_no_hashes(self): """ The response doesn't contain any hashes. """ response = { 'hashes': [], 'duration': 4, } filter_ = self._filter(response) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, response)
def setUp(self): super(GetLatestInclusionCommandTestCase, self).setUp() self.adapter = MockAdapter() self.command = GetLatestInclusionCommand(self.adapter) # Define some tryte sequences that we can re-use across tests. self.milestone =\ TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION99999W9KDIH' b'BALAYAFCADIDU9HCXDKIXEYDNFRAKHN9IEIDZFWGJ' ) self.hash1 =\ TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION99999TBPDM9' b'ADFAWCKCSFUALFGETFIFG9UHIEFE9AYESEHDUBDDF' ) self.hash2 =\ TransactionHash( b'TESTVALUE9DONTUSEINPRODUCTION99999CIGCCF' b'KIUFZF9EP9YEYGQAIEXDTEAAUGAEWBBASHYCWBHDX' )
class AttachToTangleResponseFilterTestCase(BaseFilterTestCase): filter_type = AttachToTangleCommand(MockAdapter()).get_response_filter skip_value_check = True # noinspection SpellCheckingInspection def setUp(self): super(AttachToTangleResponseFilterTestCase, self).setUp() # Define a few valid values here that we can reuse across multiple # tests. self.trytes1 = b'RBTC9D9DCDQAEASBYBCCKBFA' self.trytes2 =\ b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA' def test_pass_happy_path(self): """The incoming response contains valid values.""" filter_ = self._filter({ # Trytes arrive from the node as strings. 'trytes': [ text_type(self.trytes1, 'ascii'), text_type(self.trytes2, 'ascii'), ], 'duration': 42, }) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'trytes': [ TransactionTrytes(self.trytes1), TransactionTrytes(self.trytes2), ], 'duration': 42, }, )
class InterruptAttachingToTangleRequestFilterTestCase(BaseFilterTestCase): filter_type =\ InterruptAttachingToTangleCommand(MockAdapter()).get_request_filter skip_value_check = True def test_pass_empty(self): filter_ = self._filter({}) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, {}) def test_fail_unexpected_parameters(self): """ The request contains unexpected parameters. """ self.assertFilterErrors( { # You're tearing me apart Lisa! 'foo': 'bar', }, { 'foo': [f.FilterMapper.CODE_EXTRA_KEY], }, )
def setUp(self): super(FindTransactionsCommandTestCase, self).setUp() self.adapter = MockAdapter()
class FindTransactionsRequestFilterTestCase(BaseFilterTestCase): filter_type = FindTransactionsCommand(MockAdapter()).get_request_filter skip_value_check = True # noinspection SpellCheckingInspection def setUp(self): super(FindTransactionsRequestFilterTestCase, self).setUp() # Define a few valid values that we can reuse across tests. self.trytes1 = b'RBTC9D9DCDQAEASBYBCCKBFA' self.trytes2 =\ b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA' self.trytes3 = b'999999999999999999999999999' def test_pass_all_parameters(self): """ The request contains valid values for all parameters. """ request = { 'bundles': [ TransactionHash(self.trytes1), TransactionHash(self.trytes2), ], 'addresses': [ Address(self.trytes1), Address(self.trytes2), ], 'tags': [ Tag(self.trytes1), Tag(self.trytes3), ], 'approvees': [ TransactionHash(self.trytes1), TransactionHash(self.trytes3), ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, request) def test_pass_compatible_types(self): """ The request contains values that can be converted to the expected types. """ filter_ = self._filter({ 'bundles': [ binary_type(self.trytes1), bytearray(self.trytes2), ], 'addresses': [ binary_type(self.trytes1), bytearray(self.trytes2), ], 'tags': [ binary_type(self.trytes1), bytearray(self.trytes3), ], 'approvees': [ binary_type(self.trytes1), bytearray(self.trytes3), ], }) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'bundles': [ TransactionHash(self.trytes1), TransactionHash(self.trytes2), ], 'addresses': [ Address(self.trytes1), Address(self.trytes2), ], 'tags': [ Tag(self.trytes1), Tag(self.trytes3), ], 'approvees': [ TransactionHash(self.trytes1), TransactionHash(self.trytes3), ], }, ) def test_pass_bundles_only(self): """ The request only includes bundles. """ request = { 'bundles': [ TransactionHash(self.trytes1), TransactionHash(self.trytes2), ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'bundles': [ TransactionHash(self.trytes1), TransactionHash(self.trytes2), ], 'addresses': [], 'approvees': [], 'tags': [], }, ) def test_pass_addresses_only(self): """ The request only includes addresses. """ request = { 'addresses': [ Address(self.trytes1), Address(self.trytes2), ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'addresses': [ Address(self.trytes1), Address(self.trytes2), ], 'approvees': [], 'bundles': [], 'tags': [], }, ) def test_pass_tags_only(self): """ The request only includes tags. """ request = { 'tags': [ Tag(self.trytes1), Tag(self.trytes3), ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'tags': [ Tag(self.trytes1), Tag(self.trytes3), ], 'addresses': [], 'approvees': [], 'bundles': [], }, ) def test_pass_approvees_only(self): """ The request only includes approvees. """ request = { 'approvees': [ TransactionHash(self.trytes1), TransactionHash(self.trytes3), ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'approvees': [ TransactionHash(self.trytes1), TransactionHash(self.trytes3), ], 'addresses': [], 'bundles': [], 'tags': [], }, ) def test_fail_empty(self): """ The request does not contain any parameters. """ self.assertFilterErrors( {}, { '': [FindTransactionsRequestFilter.CODE_NO_SEARCH_VALUES], }, ) def test_fail_all_parameters_empty(self): """ The request contains all parameters, but every one is empty. """ self.assertFilterErrors( { 'addresses': [], 'approvees': [], 'bundles': [], 'tags': [], }, { '': [FindTransactionsRequestFilter.CODE_NO_SEARCH_VALUES], }, ) def test_fail_unexpected_parameters(self): """ The request contains unexpected parameters. """ self.assertFilterErrors( { 'addresses': [Address(self.trytes1)], 'approvees': [TransactionHash(self.trytes1)], 'bundles': [TransactionHash(self.trytes1)], 'tags': [Tag(self.trytes1)], # Hey, you're not allowed in he-argh! 'foo': 'bar', }, { 'foo': [f.FilterMapper.CODE_EXTRA_KEY], }, ) def test_fail_bundles_wrong_type(self): """ ``bundles`` is not an array. """ self.assertFilterErrors( { 'bundles': TransactionHash(self.trytes1), }, { 'bundles': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_bundles_contents_invalid(self): """ ``bundles`` is an array, but it contains invalid values. """ self.assertFilterErrors( { 'bundles': [ b'', text_type(self.trytes1, 'ascii'), True, None, b'not valid trytes', # This is actually valid; I just added it to make sure the # filter isn't cheating! TryteString(self.trytes2), 2130706433, b'9' * 82, ], }, { 'bundles.0': [f.Required.CODE_EMPTY], 'bundles.1': [f.Type.CODE_WRONG_TYPE], 'bundles.2': [f.Type.CODE_WRONG_TYPE], 'bundles.3': [f.Required.CODE_EMPTY], 'bundles.4': [Trytes.CODE_NOT_TRYTES], 'bundles.6': [f.Type.CODE_WRONG_TYPE], 'bundles.7': [Trytes.CODE_WRONG_FORMAT], }, ) def test_fail_addresses_wrong_type(self): """ ``addresses`` is not an array. """ self.assertFilterErrors( { 'addresses': Address(self.trytes1), }, { 'addresses': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_addresses_contents_invalid(self): """ ``addresses`` is an array, but it contains invalid values. """ self.assertFilterErrors( { 'addresses': [ b'', text_type(self.trytes1, 'ascii'), True, None, b'not valid trytes', # This is actually valid; I just added it to make sure the # filter isn't cheating! TryteString(self.trytes2), 2130706433, b'9' * 82, ], }, { 'addresses.0': [f.Required.CODE_EMPTY], 'addresses.1': [f.Type.CODE_WRONG_TYPE], 'addresses.2': [f.Type.CODE_WRONG_TYPE], 'addresses.3': [f.Required.CODE_EMPTY], 'addresses.4': [Trytes.CODE_NOT_TRYTES], 'addresses.6': [f.Type.CODE_WRONG_TYPE], 'addresses.7': [Trytes.CODE_WRONG_FORMAT], }, ) def test_fail_tags_wrong_type(self): """ ``tags`` is not an array. """ self.assertFilterErrors( { 'tags': Tag(self.trytes1), }, { 'tags': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_tags_contents_invalid(self): """ ``tags`` is an array, but it contains invalid values. """ self.assertFilterErrors( { 'tags': [ b'', text_type(self.trytes1, 'ascii'), True, None, b'not valid trytes', # This is actually valid; I just added it to make sure the # filter isn't cheating! TryteString(self.trytes1), 2130706433, b'9' * 28, ], }, { 'tags.0': [f.Required.CODE_EMPTY], 'tags.1': [f.Type.CODE_WRONG_TYPE], 'tags.2': [f.Type.CODE_WRONG_TYPE], 'tags.3': [f.Required.CODE_EMPTY], 'tags.4': [Trytes.CODE_NOT_TRYTES], 'tags.6': [f.Type.CODE_WRONG_TYPE], 'tags.7': [Trytes.CODE_WRONG_FORMAT], }, ) def test_fail_approvees_wrong_type(self): """ ``approvees`` is not an array. """ self.assertFilterErrors( { 'approvees': TransactionHash(self.trytes1), }, { 'approvees': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_approvees_contents_invalid(self): """ ``approvees`` is an array, but it contains invalid values. """ self.assertFilterErrors( { 'approvees': [ b'', text_type(self.trytes1, 'ascii'), True, None, b'not valid trytes', # This is actually valid; I just added it to make sure the # filter isn't cheating! TryteString(self.trytes2), 2130706433, b'9' * 82, ], }, { 'approvees.0': [f.Required.CODE_EMPTY], 'approvees.1': [f.Type.CODE_WRONG_TYPE], 'approvees.2': [f.Type.CODE_WRONG_TYPE], 'approvees.3': [f.Required.CODE_EMPTY], 'approvees.4': [Trytes.CODE_NOT_TRYTES], 'approvees.6': [f.Type.CODE_WRONG_TYPE], 'approvees.7': [Trytes.CODE_WRONG_FORMAT], }, )
def setUp(self): super(AttachToTangleCommandTestCase, self).setUp() self.adapter = MockAdapter()
class AttachToTangleRequestFilterTestCase(BaseFilterTestCase): filter_type = AttachToTangleCommand(MockAdapter()).get_request_filter skip_value_check = True # noinspection SpellCheckingInspection def setUp(self): super(AttachToTangleRequestFilterTestCase, self).setUp() # Define a few valid values here that we can reuse across multiple # tests. self.txn_id = (b'JVMTDGDPDFYHMZPMWEKKANBQSLSDTIIHAYQUMZOK' b'HXXXGJHJDQPOMDOMNRDKYCZRUFZROZDADTHZC9999') self.trytes1 = b'RBTC9D9DCDQAEASBYBCCKBFA' self.trytes2 =\ b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA' def test_pass_happy_path(self): """ The incoming request is valid. """ request = { 'trunkTransaction': TransactionHash(self.txn_id), 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 20, 'trytes': [ TransactionTrytes(self.trytes1), TransactionTrytes(self.trytes2), ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, request) # noinspection SpellCheckingInspection def test_pass_compatible_types(self): """ Incoming values can be converted into the expected types. """ filter_ = self._filter({ # Any value that can be converted into a TransactionHash is valid # here. 'trunkTransaction': binary_type(self.txn_id), 'branchTransaction': bytearray(self.txn_id), 'trytes': [ # ``trytes`` can contain any value that can be converted into a # TryteString. binary_type(self.trytes1), # This is probably wrong, but technically it's valid. TransactionHash( b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHDWCTCEAKDCDFD9DSCSA', ), ], # This still has to be an int, however. 'minWeightMagnitude': 30, }) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, # After running through the filter, all of the values have been # converted to the correct types. { 'trunkTransaction': TransactionHash(self.txn_id), 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 30, 'trytes': [ TransactionTrytes(self.trytes1), TransactionTrytes( b'CCPCBDVC9DTCEAKDXC9D9DEARCWCPCBDVCTCEAHD' b'WCTCEAKDCDFD9DSCSA99999999999999999999999', ), ], }) def test_fail_empty(self): """ The incoming request is empty. """ self.assertFilterErrors( {}, { 'branchTransaction': [f.FilterMapper.CODE_MISSING_KEY], 'minWeightMagnitude': [f.FilterMapper.CODE_MISSING_KEY], 'trunkTransaction': [f.FilterMapper.CODE_MISSING_KEY], 'trytes': [f.FilterMapper.CODE_MISSING_KEY], }, ) def test_fail_unexpected_parameters(self): """ The incoming request contains unexpected parameters. """ self.assertFilterErrors( { 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 20, 'trunkTransaction': TransactionHash(self.txn_id), 'trytes': [TryteString(self.trytes1)], # Hey, how'd that get in there? 'foo': 'bar', }, { 'foo': [f.FilterMapper.CODE_EXTRA_KEY], }, ) def test_fail_trunk_transaction_null(self): """ ``trunkTransaction`` is null. """ self.assertFilterErrors( { 'trunkTransaction': None, 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 13, 'trytes': [TryteString(self.trytes1)], }, { 'trunkTransaction': [f.Required.CODE_EMPTY], }, ) def test_fail_trunk_transaction_wrong_type(self): """ ``trunkTransaction`` can't be converted to a TryteString. """ self.assertFilterErrors( { # Unicode strings are not valid tryte sequences. 'trunkTransaction': text_type(self.txn_id, 'ascii'), 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 13, 'trytes': [TryteString(self.trytes1)], }, { 'trunkTransaction': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_branch_transaction_null(self): """ ``branchTransaction`` is null. """ self.assertFilterErrors( { 'branchTransaction': None, 'minWeightMagnitude': 13, 'trunkTransaction': TransactionHash(self.txn_id), 'trytes': [TryteString(self.trytes1)], }, { 'branchTransaction': [f.Required.CODE_EMPTY], }, ) def test_fail_branch_transaction_wrong_type(self): """ ``branchTransaction`` can't be converted to a TryteString. """ self.assertFilterErrors( { # Strings are not valid tryte sequences. 'branchTransaction': text_type(self.txn_id, 'ascii'), 'minWeightMagnitude': 13, 'trunkTransaction': TransactionHash(self.txn_id), 'trytes': [TryteString(self.trytes1)], }, { 'branchTransaction': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_min_weight_magnitude_null(self): """ ``minWeightMagnitude`` is null. """ self.assertFilterErrors( { 'minWeightMagnitude': None, 'branchTransaction': TransactionHash(self.txn_id), 'trunkTransaction': TransactionHash(self.txn_id), 'trytes': [TryteString(self.trytes1)], }, { 'minWeightMagnitude': [f.Required.CODE_EMPTY], }, ) def test_fail_min_weight_magnitude_float(self): """ ``minWeightMagnitude`` is a float. """ self.assertFilterErrors( { # I don't care if the fpart is empty; it's still not an int! 'minWeightMagnitude': 20.0, 'branchTransaction': TransactionHash(self.txn_id), 'trunkTransaction': TransactionHash(self.txn_id), 'trytes': [TryteString(self.trytes1)], }, { 'minWeightMagnitude': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_min_weight_magnitude_string(self): """ ``minWeightMagnitude`` is a string. """ self.assertFilterErrors( { # For want of an int cast, the transaction was lost. 'minWeightMagnitude': '20', 'branchTransaction': TransactionHash(self.txn_id), 'trunkTransaction': TransactionHash(self.txn_id), 'trytes': [TryteString(self.trytes1)], }, { 'minWeightMagnitude': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_min_weight_magnitude_too_small(self): """ ``minWeightMagnitude`` is less than 1. """ self.assertFilterErrors( { 'minWeightMagnitude': 0, 'branchTransaction': TransactionHash(self.txn_id), 'trunkTransaction': TransactionHash(self.txn_id), 'trytes': [TryteString(self.trytes1)], }, { 'minWeightMagnitude': [f.Min.CODE_TOO_SMALL], }, ) def test_fail_trytes_null(self): """ ``trytes`` is null. """ self.assertFilterErrors( { 'trytes': None, 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 13, 'trunkTransaction': TransactionHash(self.txn_id), }, { 'trytes': [f.Required.CODE_EMPTY], }, ) def test_fail_trytes_wrong_type(self): """ ``trytes`` is not an array. """ self.assertFilterErrors( { # You have to specify an array, even if you only want to attach # a single tryte sequence. 'trytes': TryteString(self.trytes1), 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 13, 'trunkTransaction': TransactionHash(self.txn_id), }, { 'trytes': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_trytes_empty(self): """ ``trytes`` is an array, but it's empty. """ self.assertFilterErrors( { # Ok, you got the list part down, but you have to put something # inside it. 'trytes': [], 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 13, 'trunkTransaction': TransactionHash(self.txn_id), }, { 'trytes': [f.Required.CODE_EMPTY], }, ) def test_fail_trytes_contents_invalid(self): """ ``trytes`` is an array, but it contains invalid values. """ self.assertFilterErrors( { 'trytes': [ b'', text_type(self.trytes1, 'ascii'), True, None, b'not valid trytes', # This is actually valid; I just added it to make sure the # filter isn't cheating! TryteString(self.trytes2), 2130706433, b'9' * (TransactionTrytes.LEN + 1), ], 'branchTransaction': TransactionHash(self.txn_id), 'minWeightMagnitude': 13, 'trunkTransaction': TransactionHash(self.txn_id), }, { 'trytes.0': [f.NotEmpty.CODE_EMPTY], 'trytes.1': [f.Type.CODE_WRONG_TYPE], 'trytes.2': [f.Type.CODE_WRONG_TYPE], 'trytes.3': [f.Required.CODE_EMPTY], 'trytes.4': [Trytes.CODE_NOT_TRYTES], 'trytes.6': [f.Type.CODE_WRONG_TYPE], 'trytes.7': [Trytes.CODE_WRONG_FORMAT], }, )
class GetTrytesRequestFilterTestCase(BaseFilterTestCase): filter_type = GetTrytesCommand(MockAdapter()).get_request_filter skip_value_check = True # noinspection SpellCheckingInspection def setUp(self): super(GetTrytesRequestFilterTestCase, self).setUp() # Define some valid tryte sequences that we can re-use between # tests. self.trytes1 = ( b'OAATQS9VQLSXCLDJVJJVYUGONXAXOFMJOZNSYWRZ' b'SWECMXAQQURHQBJNLD9IOFEPGZEPEMPXCIVRX9999' ) self.trytes2 = ( b'ZIJGAJ9AADLRPWNCYNNHUHRRAC9QOUDATEDQUMTN' b'OTABUVRPTSTFQDGZKFYUUIE9ZEBIVCCXXXLKX9999' ) def test_pass_happy_path(self): """ The request is valid. """ request = { 'hashes': [ TransactionHash(self.trytes1), TransactionHash(self.trytes2), ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, request) def test_pass_compatible_types(self): """ The request contains values that can be converted to the expected types. """ filter_ = self._filter({ 'hashes': [ # Any sequence that can be converted into a TransactionHash is # valid. binary_type(self.trytes1), bytearray(self.trytes2), ], }) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'hashes': [ TransactionHash(self.trytes1), TransactionHash(self.trytes2), ], }, ) def test_fail_empty(self): """ The request is empty. """ self.assertFilterErrors( {}, { 'hashes': [f.FilterMapper.CODE_MISSING_KEY], }, ) def test_fail_unexpected_parameters(self): """ The request contains unexpected parameters. """ self.assertFilterErrors( { 'hashes': [TransactionHash(self.trytes1)], # This is why we can't have nice things! 'foo': 'bar', }, { 'foo': [f.FilterMapper.CODE_EXTRA_KEY], }, ) def test_fail_hashes_null(self): """ ``hashes`` is null. """ self.assertFilterErrors( { 'hashes': None, }, { 'hashes': [f.Required.CODE_EMPTY], }, ) def test_fail_hashes_wrong_type(self): """ ``hashes`` is not an array. """ self.assertFilterErrors( { # ``hashes`` must be an array, even if we're only querying # against a single transaction. 'hashes': TransactionHash(self.trytes1), }, { 'hashes': [f.Type.CODE_WRONG_TYPE], }, ) def test_fail_hashes_empty(self): """ ``hashes`` is an array, but it is empty. """ self.assertFilterErrors( { 'hashes': [], }, { 'hashes': [f.Required.CODE_EMPTY], }, ) def test_fail_hashes_contents_invalid(self): """ ``hashes`` is an array, but it contains invalid values. """ self.assertFilterErrors( { 'hashes': [ b'', text_type(self.trytes1, 'ascii'), True, None, b'not valid trytes', # This is actually valid; I just added it to make sure the # filter isn't cheating! TryteString(self.trytes1), 2130706433, b'9' * 82, ], }, { 'hashes.0': [f.Required.CODE_EMPTY], 'hashes.1': [f.Type.CODE_WRONG_TYPE], 'hashes.2': [f.Type.CODE_WRONG_TYPE], 'hashes.3': [f.Required.CODE_EMPTY], 'hashes.4': [Trytes.CODE_NOT_TRYTES], 'hashes.6': [f.Type.CODE_WRONG_TYPE], 'hashes.7': [Trytes.CODE_WRONG_FORMAT], }, )
def test_adapter_instance(self): """ Resolving an adapter instance. """ adapter = MockAdapter() self.assertIs(resolve_adapter(adapter), adapter)
def setUp(self): super(AddNeighborsCommandTestCase, self).setUp() self.adapter = MockAdapter()
class AddNeighborsRequestFilterTestCase(BaseFilterTestCase): filter_type = AddNeighborsCommand(MockAdapter()).get_request_filter skip_value_check = True def test_pass_valid_request(self): """ The incoming request is valid. """ request = { 'uris': [ 'udp://node1.cornodetoken.com', 'udp://localhost:14265/', ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, request) def test_fail_empty(self): """ The incoming request is empty. """ self.assertFilterErrors( {}, { 'uris': [f.FilterMapper.CODE_MISSING_KEY], }, ) def test_fail_unexpected_parameters(self): """ The incoming request contains unexpected parameters. """ self.assertFilterErrors( { 'uris': ['udp://localhost'], # I've never seen that before in my life, officer. 'foo': 'bar', }, { 'foo': [f.FilterMapper.CODE_EXTRA_KEY], }, ) def test_fail_neighbors_null(self): """ ``uris`` is null. """ self.assertFilterErrors( { 'uris': None, }, { 'uris': [f.Required.CODE_EMPTY], }, ) def test_fail_uris_wrong_type(self): """ ``uris`` is not an array. """ self.assertFilterErrors( { # Nope; it's gotta be an array, even if you only want to add # a single neighbor. 'uris': 'udp://localhost:8080/' }, {'uris': [f.Type.CODE_WRONG_TYPE]}, ) def test_fail_uris_empty(self): """ ``uris`` is an array, but it's empty. """ self.assertFilterErrors( { # Insert "Forever Alone" meme here. 'uris': [], }, { 'uris': [f.Required.CODE_EMPTY], }, ) def test_fail_uris_contents_invalid(self): """ ``uris`` is an array, but it contains invalid values. """ self.assertFilterErrors( { 'uris': [ '', False, None, b'udp://localhost:8080/', 'not a valid uri', # This is actually valid; I just added it to make sure the # filter isn't cheating! 'udp://localhost:14265', # Only UDP URIs are allowed. 'http://localhost:14265', 2130706433, ], }, { 'uris.0': [f.Required.CODE_EMPTY], 'uris.1': [f.Type.CODE_WRONG_TYPE], 'uris.2': [f.Required.CODE_EMPTY], 'uris.3': [f.Type.CODE_WRONG_TYPE], 'uris.4': [NodeUri.CODE_NOT_NODE_URI], 'uris.6': [NodeUri.CODE_NOT_NODE_URI], 'uris.7': [f.Type.CODE_WRONG_TYPE], }, )
def setUp(self): super(GetTrytesCommandTestCase, self).setUp() self.adapter = MockAdapter()