Fix bug in destinations amounts

This commit is contained in:
Michał Sałaban 2019-03-12 11:07:38 +01:00
parent 24856cfafd
commit d81b29182f
10 changed files with 82 additions and 21 deletions

View File

@ -247,7 +247,7 @@ class JSONRPCWallet(object):
} }
if 'destinations' in data: if 'destinations' in data:
result['destinations'] = [ result['destinations'] = [
(address(x['address']), from_atomic(data['amount'])) (address(x['address']), from_atomic(x['amount']))
for x in data.get('destinations') for x in data.get('destinations')
] ]
return result return result

View File

@ -4,3 +4,4 @@ pip>=9
pytest-cov~=2.5 pytest-cov~=2.5
pytest-runner~=4.2 pytest-runner~=4.2
pytest~=3.6 pytest~=3.6
responses

15
tests/base.py Normal file
View File

@ -0,0 +1,15 @@
import json
import os
import unittest
class JSONTestCase(unittest.TestCase):
jsonrpc_url = 'http://127.0.0.1:18088/json_rpc'
data_subdir = None
def _read(self, *args):
path = os.path.join(os.path.dirname(__file__), 'data')
if self.data_subdir:
path = os.path.join(path, self.data_subdir)
path = os.path.join(path, *args)
with open(path, 'r') as fh:
return json.loads(fh.read())

View File

@ -0,0 +1,16 @@
{"id": 0,
"jsonrpc": "2.0",
"result": {"subaddress_accounts": [{"account_index": 0,
"balance": 141601990026,
"base_address": "56cXYWG13YKaT9z1aEy2hb9TZNnxrW3zE9S4nTQVDux5Qq7UYsmjuux3Zstxkorj9HAufyWLU3FwHW4uERQF6tkeUVogGN3",
"label": "Primary account",
"tag": "",
"unlocked_balance": 141601990026},
{"account_index": 1,
"balance": 1000000000000,
"base_address": "79kTZg96pMf2Dt9rLEWnLzTUB8XC1wMhxaJyxa79hJu6bK9CfFnfbSL1GJNZbqhv9xPqJhRj2Yfb7QUWa2zeEw56H4KiUfN",
"label": "(Untitled account)",
"tag": "",
"unlocked_balance": 1000000000000}],
"total_balance": 1141601990026,
"total_unlocked_balance": 1141601990026}}

View File

@ -0,0 +1,20 @@
{"id": 0,
"jsonrpc": "2.0",
"result": {"out": [{"address": "56cXYWG13YKaT9z1aEy2hb9TZNnxrW3zE9S4nTQVDux5Qq7UYsmjuux3Zstxkorj9HAufyWLU3FwHW4uERQF6tkeUVogGN3",
"amount": 1000000000000,
"confirmations": 66,
"destinations": [{"address": "76yuj8ZcnuNhSCciBJHDzhBoGBXRoDVkeLbzD7gW2yiFc9ypd9ArzSBc2bkBHMsULU3LcXDBV681YbhLJn2bYbKq5mc2xsU",
"amount": 700000000000},
{"address": "77LbfWj3yyhggccY2oLy2AcuBLqEvXKCSAYQUD6dfzBGcZXXBHgVrgy4VgBkZAaBnCdjwAC6koinjdxpXdfRjMT84neunYJ",
"amount": 300000000000}],
"double_spend_seen": false,
"fee": 477360000,
"height": 278441,
"note": "",
"payment_id": "0000000000000000",
"subaddr_index": {"major": 0, "minor": 0},
"suggested_confirmations_threshold": 1,
"timestamp": 1552346064,
"txid": "f107123ae0611de2b732f4c6ad65a2c077d465a4e0708d3619dd44054b932f52",
"type": "out",
"unlock_time": 0}]}}

View File

@ -1,11 +1,10 @@
from datetime import datetime from datetime import datetime
from decimal import Decimal from decimal import Decimal
import unittest import responses
try: try:
from unittest.mock import patch, Mock from unittest.mock import patch, Mock
except ImportError: except ImportError:
from mock import patch, Mock from mock import patch, Mock
import warnings
from monero.wallet import Wallet from monero.wallet import Wallet
from monero.address import BaseAddress, Address from monero.address import BaseAddress, Address
@ -13,7 +12,10 @@ from monero.seed import Seed
from monero.transaction import IncomingPayment, OutgoingPayment, Transaction from monero.transaction import IncomingPayment, OutgoingPayment, Transaction
from monero.backends.jsonrpc import JSONRPCWallet from monero.backends.jsonrpc import JSONRPCWallet
class SubaddrWalletTestCase(unittest.TestCase): from .base import JSONTestCase
class JSONRPCWalletTestCase(JSONTestCase):
data_subdir = 'test_jsonrpcwallet'
accounts_result = {'id': 0, accounts_result = {'id': 0,
'jsonrpc': '2.0', 'jsonrpc': '2.0',
'result': {'subaddress_accounts': [{'account_index': 0, 'result': {'subaddress_accounts': [{'account_index': 0,
@ -925,6 +927,22 @@ class SubaddrWalletTestCase(unittest.TestCase):
self.assertIsInstance(pmt.transaction.fee, Decimal) self.assertIsInstance(pmt.transaction.fee, Decimal)
self.assertIs(pmt.transaction.height, None) self.assertIs(pmt.transaction.height, None)
@responses.activate
def test_multiple_destinations(self):
responses.add(responses.POST, self.jsonrpc_url,
json=self._read('test_multiple_destinations-accounts.json'),
status=200)
responses.add(responses.POST, self.jsonrpc_url,
json=self._read('test_multiple_destinations-incoming.json'),
status=200)
self.wallet = Wallet(JSONRPCWallet())
out = self.wallet.outgoing()
self.assertEqual(len(out), 1)
pmt = out[0]
self.assertEqual(pmt.amount, 1)
self.assertEqual(len(pmt.destinations), 2)
self.assertEqual(pmt.destinations[0][1] + pmt.destinations[1][1], pmt.amount)
@patch('monero.backends.jsonrpc.requests.post') @patch('monero.backends.jsonrpc.requests.post')
def test_send_transfer(self, mock_post): def test_send_transfer(self, mock_post):
mock_post.return_value.status_code = 200 mock_post.return_value.status_code = 200

View File

@ -1,27 +1,18 @@
import json
import os
import unittest
from monero.backends.offline import OfflineWallet from monero.backends.offline import OfflineWallet
from monero.wallet import Wallet from monero.wallet import Wallet
from tests.utils import classproperty from .base import JSONTestCase
from .utils import classproperty
class Tests(object): class SubaddrTest(object):
@classproperty data_subdir = 'test_offline'
def __test__(cls):
return issubclass(cls, unittest.TestCase)
def setUp(self): def setUp(self):
self.subaddresses = json.load(open(os.path.join(
os.path.dirname(__file__),
'data',
'{}-subaddrs.json'.format(self.net))))
self.wallet = Wallet(OfflineWallet(self.addr, view_key=self.svk)) self.wallet = Wallet(OfflineWallet(self.addr, view_key=self.svk))
def test_subaddresses(self): def test_subaddresses(self):
major = 0 major = 0
for acc in self.subaddresses: for acc in self._read('{}-subaddrs.json'.format(self.net)):
minor = 0 minor = 0
for subaddr in acc: for subaddr in acc:
self.assertEqual( self.assertEqual(
@ -32,7 +23,7 @@ class Tests(object):
major += 1 major += 1
class AddressTestCase(Tests, unittest.TestCase): class AddressTestCase(SubaddrTest, JSONTestCase):
addr = '47ewoP19TN7JEEnFKUJHAYhGxkeTRH82sf36giEp9AcNfDBfkAtRLX7A6rZz18bbNHPNV7ex6WYbMN3aKisFRJZ8Ebsmgef' addr = '47ewoP19TN7JEEnFKUJHAYhGxkeTRH82sf36giEp9AcNfDBfkAtRLX7A6rZz18bbNHPNV7ex6WYbMN3aKisFRJZ8Ebsmgef'
ssk = 'e0fe01d5794e240a26609250c0d7e01673219eececa3f499d5cfa20a75739b0a' ssk = 'e0fe01d5794e240a26609250c0d7e01673219eececa3f499d5cfa20a75739b0a'
svk = '6d9056aa2c096bfcd2f272759555e5764ba204dd362604a983fa3e0aafd35901' svk = '6d9056aa2c096bfcd2f272759555e5764ba204dd362604a983fa3e0aafd35901'
@ -45,14 +36,14 @@ class AddressTestCase(Tests, unittest.TestCase):
self.assertRaises(ValueError, self.wallet.get_address, 2**32, 1) self.assertRaises(ValueError, self.wallet.get_address, 2**32, 1)
class TestnetAddressTestCase(Tests, unittest.TestCase): class TestnetAddressTestCase(SubaddrTest, JSONTestCase):
addr = '9wuKTHsxGiwEsMp2fYzJiVahyhU2aZi1oZ6R6fK5U64uRa1Pxi8diZh2S1GJFqYXRRhcbfzfWiPD819zKEZkXTMwP7hMs5N' addr = '9wuKTHsxGiwEsMp2fYzJiVahyhU2aZi1oZ6R6fK5U64uRa1Pxi8diZh2S1GJFqYXRRhcbfzfWiPD819zKEZkXTMwP7hMs5N'
ssk = '4f5b7af2c1942067ba33d34318b9735cb46ab5d50b75294844c82a9dd872c201' ssk = '4f5b7af2c1942067ba33d34318b9735cb46ab5d50b75294844c82a9dd872c201'
svk = '60cf228f2bf7f6a70643afe9468fde254145dbd3aab4072ede14bf8bae914103' svk = '60cf228f2bf7f6a70643afe9468fde254145dbd3aab4072ede14bf8bae914103'
net = 'testnet' net = 'testnet'
class StagenetAddressTestCase(Tests, unittest.TestCase): class StagenetAddressTestCase(SubaddrTest, JSONTestCase):
addr = '52jzuBBUMty3xPL3JsQxGP74LDuV6E1LS8Zda1PbdqQjGzFmH6N9ep9McbFKMALujVT9S5mKpbEgC5VPhfoAiVj8LdAqbp6' addr = '52jzuBBUMty3xPL3JsQxGP74LDuV6E1LS8Zda1PbdqQjGzFmH6N9ep9McbFKMALujVT9S5mKpbEgC5VPhfoAiVj8LdAqbp6'
ssk = 'a8733c61797115db4ec8a5ce39fb811f81dd4ec163b880526683e059c7e62503' ssk = 'a8733c61797115db4ec8a5ce39fb811f81dd4ec163b880526683e059c7e62503'
svk = 'fd5c0d25f8f994268079a4f7844274dc870a7c2b88fbfc24ba318375e1d9430f' svk = 'fd5c0d25f8f994268079a4f7844274dc870a7c2b88fbfc24ba318375e1d9430f'