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_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 setUp(self): super(AddressGeneratorTestCase, self).setUp() # Addresses that correspond to the digests defined in # :py:meth:`_mock_get_digest`. self.addy0 =\ Address( b'VOPYUSDRHYGGOHLAYDWCLLOFWBLK99PYYKENW9IQ' b'IVIOYMLCCPXGICDBZKCQVJLDWWJLTTUVIXCTOZ9TN' ) self.addy1 =\ Address( b'SKKMQAGLZMXWSXRVVRFWMGN9TIXDACQMCXZJRPMS' b'UFNSXMFOGEBZZPUJBVKVSJNYPSGSXQIUHTRKECVQE' ) self.addy2 =\ Address( b'VMMFSGEYJ9SANRULNIMKEZUYVRTWMVR9UKCYDZXW' b'9TENBWIRMFODOSNMDH9QOVBLQWALOHMSBGEVIXSXY' ) self.addy3 =\ Address( b'G9PLHPOMET9NWIBGRGMIF9HFVETTWGKCXWGFYRNG' b'CFANWBQFGMFKITZBJDSYLGXYUIQVCMXFWSWFRNHRV' )
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_fail_transfers_contents_invalid(self): """ ``transfers`` is a non-empty array, but it contains invalid values. """ self.assertFilterErrors( { 'transfers': [ None, # This value is valid; just adding it to make sure the filter # doesn't cheat! ProposedTransaction(address=Address(self.trytes2), value=42), {'address': Address(self.trytes2), 'value': 42}, ], 'depth': 100, 'minWeightMagnitude': 18, 'seed': Seed(self.trytes1), }, { 'transfers.0': [f.Required.CODE_EMPTY], 'transfers.2': [f.Type.CODE_WRONG_TYPE], }, )
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' )
def test_pass_happy_path(self): """ Request is valid. """ request = { 'changeAddress': Address(self.trytes1), 'depth': 100, 'minWeightMagnitude': 18, 'seed': Seed(self.trytes2), 'inputs': [ Address(self.trytes3), Address(self.trytes4), ], 'transfers': [ self.transfer1, self.transfer2 ], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, request)
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 test_pass_compatible_types(self): """ The incoming request contains values that can be converted to the expected types. """ request = { 'addresses': [ binary_type(self.trytes1), bytearray(self.trytes2), ], 'threshold': 80, } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'addresses': [ Address(self.trytes1), Address(self.trytes2), ], 'threshold': 80, }, )
def test_checksum_valid(self): """ An address is created with a valid checksum. """ addy = Address(b'RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE' b'9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAFOXM9MUBX') self.assertTrue(addy.is_checksum_valid()) self.assertEqual( binary_type(addy.with_valid_checksum()), b'RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE' b'9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAFOXM9MUBX')
def test_pass_happy_path(self): """ Typical invocation of ``getBalances``. """ request = { 'addresses': [ Address(self.trytes1), Address(self.trytes2), ], 'threshold': 80, } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual(filter_.cleaned_data, request)
def test_init_automatic_pad(self): """ Addresses are automatically padded to 81 trytes. """ addy = Address(b'JVMTDGDPDFYHMZPMWEKKANBQSLSDTIIHAYQUMZOK' b'HXXXGJHJDQPOMDOMNRDKYCZRUFZROZDADTHZC') self.assertEqual( binary_type(addy), # Note the extra 9's added to the end. b'JVMTDGDPDFYHMZPMWEKKANBQSLSDTIIHAYQUMZOK' b'HXXXGJHJDQPOMDOMNRDKYCZRUFZROZDADTHZC9999', ) # This attribute will make more sense once we start working with # address checksums. self.assertEqual( binary_type(addy.address), b'JVMTDGDPDFYHMZPMWEKKANBQSLSDTIIHAYQUMZOK' b'HXXXGJHJDQPOMDOMNRDKYCZRUFZROZDADTHZC9999', ) # Checksum is not generated automatically. self.assertIsNone(addy.checksum)
def from_tryte_string(cls, trytes): # type: (TrytesCompatible) -> Transaction """ Creates a Transaction object from a sequence of trytes. """ tryte_string = TransactionTrytes(trytes) hash_ = [0] * HASH_LENGTH # type: MutableSequence[int] sponge = Curl() sponge.absorb(tryte_string.as_trits()) sponge.squeeze(hash_) return cls( hash_=TransactionHash.from_trits(hash_), signature_message_fragment=Fragment(tryte_string[0:2187]), address=Address(tryte_string[2187:2268]), value=int_from_trits(tryte_string[2268:2295].as_trits()), tag=Tag(tryte_string[2295:2322]), timestamp=int_from_trits(tryte_string[2322:2331].as_trits()), current_index=int_from_trits(tryte_string[2331:2340].as_trits()), last_index=int_from_trits(tryte_string[2340:2349].as_trits()), bundle_hash=BundleHash(tryte_string[2349:2430]), trunk_transaction_hash=TransactionHash(tryte_string[2430:2511]), branch_transaction_hash=TransactionHash(tryte_string[2511:2592]), nonce=Hash(tryte_string[2592:2673]), )
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', ), }, )
def test_checksum_null(self): """ An address is created without a checksum. """ trytes = (b'ZKIUDZXQYQAWSHPKSAATJXPAQZPGYCDCQDRSMWWCGQJNI' b'PCOORMDRNREDUDKBMUYENYTFVUNEWDBAKXMV') addy = Address(trytes) self.assertFalse(addy.is_checksum_valid()) self.assertEqual( binary_type(addy.with_valid_checksum()), b'ZKIUDZXQYQAWSHPKSAATJXPAQZPGYCDCQDRSMWWCGQJNI' b'PCOORMDRNREDUDKBMUYENYTFVUNEWDBAKXMVSDPEKQPMM', )
def test_pass_compatible_types(self): """ Request contains values that can be converted to the expected types. """ filter_ = self._filter({ # Any TrytesCompatible values will work here. 'changeAddress': binary_type(self.trytes1), 'seed': bytearray(self.trytes2), 'inputs': [ binary_type(self.trytes3), bytearray(self.trytes4), ], # These values must have the correct type, however. 'transfers': [ self.transfer1, self.transfer2 ], 'depth': 100, 'minWeightMagnitude': 18, }) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'changeAddress': Address(self.trytes1), 'depth': 100, 'minWeightMagnitude': 18, 'seed': Seed(self.trytes2), 'inputs': [ Address(self.trytes3), Address(self.trytes4), ], 'transfers': [ self.transfer1, self.transfer2 ], } )
def test_fail_key_index_null(self): """ Incoming value does not have ``key_index`` set. """ self.assertFilterErrors( Address(b''), [GeneratedAddress.CODE_NO_KEY_INDEX], )
def test_checksum_invalid(self): """ An address is created with an invalid checksum. """ trytes = (b'IGKUOZGEFNSVJXETLIBKRSUZAWMYSVDPMHGQPCETEFNZP' b'XSJLZMBLAWDRLUBWPIPKFNEPADIWMXMYYRKQ') addy = Address(trytes + b'IGUKNUNAX' # <- Last tryte s/b 'W'. ) self.assertFalse(addy.is_checksum_valid()) self.assertEqual( binary_type(addy.with_valid_checksum()), b'IGKUOZGEFNSVJXETLIBKRSUZAWMYSVDPMHGQPCETEFNZP' b'XSJLZMBLAWDRLUBWPIPKFNEPADIWMXMYYRKQIGUKNUNAW', )
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 setUp(self): super(SendTransferRequestFilterTestCase, self).setUp() # Define some tryte sequences that we can reuse between tests. self.trytes1 = ( b'TESTVALUEONE9DONTUSEINPRODUCTION99999JBW' b'GEC99GBXFFBCHAEJHLC9DX9EEPAI9ICVCKBX9FFII' ) self.trytes2 = ( b'TESTVALUETWO9DONTUSEINPRODUCTION99999THZ' b'BODYHZM99IR9KOXLZXVUOJM9LQKCQJBWMTY999999' ) self.trytes3 = ( b'TESTVALUETHREE9DONTUSEINPRODUCTIONG99999' b'GTQ9CSNUFPYW9MBQ9LFQJSORCF9LGTY9BWQFY9999' ) self.trytes4 = ( b'TESTVALUEFOUR9DONTUSEINPRODUCTION99999ZQ' b'HOGCBZCOTZVZRFBEHQKHENBIZWDTUQXTOVWEXRIK9' ) self.transfer1 =\ ProposedTransaction( address = Address( b'TESTVALUEFIVE9DONTUSEINPRODUCTION99999MG' b'AAAHJDZ9BBG9U9R9XEOHCBVCLCWCCCCBQCQGG9WHK' ), value = 42, ) self.transfer2 =\ ProposedTransaction( address = Address( b'TESTVALUESIX9DONTUSEINPRODUCTION99999GGT' b'FODSHHELBDERDCDRBCINDCGQEI9NAWDJBC9TGPFME' ), value = 86, )
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' )
def mock_generate_address(address_generator, key_iterator): # type: (AddressGenerator, KeyIterator) -> Address # Insert a teensy delay, to make it more likely that multiple # threads hit the cache concurrently. sleep(0.01) # Note that in this test, the address generator always returns a # new instance. return Address(self.addy, key_index=key_iterator.current)
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_pass_threshold_optional(self): """ The incoming request does not contain a ``threshold`` value, so the default value is assumed. """ request = { 'addresses': [Address(self.trytes1)], } filter_ = self._filter(request) self.assertFilterPasses(filter_) self.assertDictEqual( filter_.cleaned_data, { 'addresses': [Address(self.trytes1)], 'threshold': 100, }, )
def test_init_error_too_long(self): """ Attempting to create an address longer than 81 trytes. """ with self.assertRaises(ValueError): Address( # Extra padding at the end is not ignored. # If it's an address (without checksum), then it must be 81 # trytes exactly. b'JVMTDGDPDFYHMZPMWEKKANBQSLSDTIIHAYQUMZOK' b'HXXXGJHJDQPOMDOMNRDKYCZRUFZROZDADTHZC99999')
def test_init_error_checksum_too_long(self): """ Attempting to create an address longer than 90 trytes. """ with self.assertRaises(ValueError): Address( # Extra padding at the end is not ignored. # If it's a checksummed address, then it must be 90 trytes # exactly. b'RVORZ9SIIP9RCYMREUIXXVPQIPHVCNPQ9HZWYKFWYWZRE' b'9JQKG9REPKIASHUUECPSQO9JT9XNMVKWYGVAFOXM9MUBX9')
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 setUp(self): super(MemoryAddressCacheTestCase, self).setUp() # Define some values we can reuse across tests. # noinspection SpellCheckingInspection self.addy =\ Address( trytes = b'TESTVALUE9DONTUSEINPRODUCTION99999J9XDHH' b'LHKET9PHTEUAHFFCDCP9ECIDPALFMFSCTCIHMD9CY', key_index = 42, )
def test_fail_threshold_too_small(self): """ ``threshold`` is less than 0. """ self.assertFilterErrors( { 'threshold': -1, 'addresses': [Address(self.trytes1)], }, { 'threshold': [f.Min.CODE_TOO_SMALL], }, )
def test_fail_threshold_too_big(self): """ ``threshold`` is greater than 100. """ self.assertFilterErrors( { 'threshold': 101, 'addresses': [Address(self.trytes1)], }, { 'threshold': [f.Max.CODE_TOO_BIG], }, )